/** * @dataProvider propertyObjectProvider */ public function testRemovePropertyObjectValue($property, $dataItem) { $instance = StubSemanticData::newFromSemanticData(new SemanticData(new DIWikiPage('Foo', NS_MAIN)), $this->store); $instance->addPropertyObjectValue($property, $dataItem); $this->assertFalse($instance->isEmpty()); $instance->removePropertyObjectValue($property, $dataItem); $this->assertTrue($instance->isEmpty()); }
/** * This method adds property-values of a subject from a property-value * table into the given SemanticData object. * * @todo Share code with getSemanticDatafromTable above? The problem is * that this method must not return too much, so it is hard to use the * cache. * * @param SMWSql3StubSemanticData $semData * @param SMWSQLStore3Table $proptable * * @since 1.8 */ public function addTableSemanticData($sid, SMWSql3StubSemanticData $semData, SMWSQLStore3Table $proptable) { $subject = $semData->getSubject(); $data = $this->fetchSemanticData($sid, $subject, $proptable); foreach ($data as $d) { $semData->addPropertyStubValue(reset($d), end($d)); } }
/** * Set the semantic data cache to hold exactly the given value for the * given ID. * * @since 1.8 * @param integer $sid * @param SMWSemanticData $semanticData */ protected function setSemanticDataCache($sid, SMWSemanticData $semanticData) { $this->store->m_semdata[$sid] = SMWSql3StubSemanticData::newFromSemanticData($semanticData, $this->store); // This is everything one can know: $this->store->m_sdstate[$sid] = array(); foreach (SMWSQLStore3::getPropertyTables() as $tableId => $tableDeclaration) { $this->store->m_sdstate[$sid][$tableId] = true; } }
/** * @see SMWStore::doDataUpdate * * @param SMWSemanticData $data */ public function doDataUpdate(SMWSemanticData $data) { wfProfileIn("SMWSQLStore3::updateData (SMW)"); wfRunHooks('SMWSQLStore3::updateDataBefore', array($this->store, $data)); $subject = $data->getSubject(); $redirects = $data->getPropertyValues(new SMWDIProperty('_REDI')); if (count($redirects) > 0) { $redirect = end($redirects); // at most one redirect per page $this->updateRedirects($subject->getDBkey(), $subject->getNamespace(), $redirect->getDBkey(), $redirect->getNameSpace()); wfProfileOut("SMWSQLStore3::updateData (SMW)"); return; // Stop here -- no support for annotations on redirect pages! } else { $this->updateRedirects($subject->getDBkey(), $subject->getNamespace()); } $sortkeyDataItems = $data->getPropertyValues(new SMWDIProperty('_SKEY')); $sortkeyDataItem = end($sortkeyDataItems); if ($sortkeyDataItem instanceof SMWDIString) { $sortkey = $sortkeyDataItem->getString(); } else { // default sortkey $sortkey = str_replace('_', ' ', $subject->getDBkey()); } // Always make an ID (pages without ID cannot be in query results, not even in fixed value queries!): $sid = $this->store->smwIds->makeSMWPageID($subject->getDBkey(), $subject->getNamespace(), $subject->getInterwiki(), $subject->getSubobjectName(), true, $sortkey, true); if ($subject->getSubobjectName() == '') { $this->updateSubSemanticData($data); } $updates = array(); // collect data for bulk updates; format: tableid => updatearray $this->prepareDBUpdates($updates, $data, $sid, $subject); $db = wfGetDB(DB_MASTER); $oldHashes = $this->store->smwIds->getPropertyTableHashes($sid); $hashIsChanged = false; //old SemanticData container for this subject (This will only hold Semantic data that will be deleted) $oldData = new SMWSql3StubSemanticData($subject, $this->store, false); //new SemanticData container for this subject (This will only hold Semantic data that will be newly added) $newData = new SMWSql3StubSemanticData($subject, $this->store, false); //tables into which data has been changed or added (not considering the ones where data is only deleted) $modifiedTables = array(); foreach (SMWSQLStore3::getPropertyTables() as $tableId => $tableDeclaration) { $tableName = $tableDeclaration->name; if ($tableName == 'smw_fpt_redi') { // TODO - handle these for updating property counts continue; //smw_fpt_redi are not considered here. } if (array_key_exists($tableName, $updates)) { $newHash = md5(serialize($updates[$tableName])); if (array_key_exists($tableName, $oldHashes) && $newHash == $oldHashes[$tableName]) { //table was used before and value didn't change, nothing to do here continue; } else { //data didn't exist before or has changed $this->store->getReader()->addTableSemanticData($sid, $oldData, $tableDeclaration); // Add data for this table // Concepts are not just written but carefully updated, // preserving existing metadata (cache ...) for a concept: if ($tableName == 'smw_fpt_conc') { $row = $db->selectRow('smw_fpt_conc', array('cache_date', 'cache_count'), array('s_id' => $sid), 'SMWSQLStoreQueries::updateConcData'); if ($row === false && $updates['smw_fpt_conc']['concept_txt'] !== '') { // insert newly given data $db->insert('smw_fpt_conc', $updates['smw_fpt_conc'], 'SMW::updateConcData'); } elseif ($row !== false) { // update data, preserve existing entries $db->update('smw_fpt_conc', $updates['smw_fpt_conc'], array('s_id' => $sid), 'SMW::updateConcData'); } } else { $this->deleteTableSemanticData($sid, $tableDeclaration); $db->insert($tableName, $updates[$tableName], "SMW::updateData{$tableName}"); } $oldHashes[$tableName] = $newHash; $hashIsChanged = true; $modifiedTables[$tableId] = $tableDeclaration; } } elseif (array_key_exists($tableName, $oldHashes)) { //data existed before but not now (Concepts data is not deleted here) $this->store->getReader()->addTableSemanticData($sid, $oldData, $tableDeclaration); // Add data for this table $this->deleteTableSemanticData($sid, $tableDeclaration); unset($oldHashes[$tableName]); $hashIsChanged = true; } } if ($hashIsChanged) { $this->store->smwIds->setPropertyTableHashes($sid, $oldHashes); } // Finally update caches (may be important if jobs are directly following this call) $this->store->m_semdata[$sid] = SMWSql3StubSemanticData::newFromSemanticData($data, $this->store); // Everything that one can know. $this->store->m_sdstate[$sid] = array(); foreach (SMWSQLStore3::getPropertyTables() as $tableId => $tableDeclaration) { $this->store->m_sdstate[$sid][$tableId] = true; } //Add newly added property-values to $newData //and remove property-values that hasn't been modified from $oldData foreach ($data->getProperties() as $propKey => $diProp) { $propTable = $this->store->findPropertyTableID($diProp); if (!array_key_exists($propTable, $modifiedTables)) { continue; //Properties in these table have been taken care of already } $dataPropVals = $data->getPropertyValues($diProp); //remove common property-values from $oldData and add new ones to $newData $oldPropVals = $oldData->getPropertyValues($diProp); foreach ($dataPropVals as $di) { if (in_array($di, $oldPropVals)) { $oldData->removePropertyObjectValue($diProp, $di); } else { $newData->addPropertyObjectValue($diProp, $di); } } } $this->doDiffandUpdateCount($oldData, $newData); wfRunHooks('SMWSQLStore3::updateDataAfter', array($this->store, $data)); wfProfileOut("SMWSQLStore3::updateData (SMW)"); }