/** * Get the array of all stored values for some property. * * @param $property SMWDIProperty * @return array of SMWDataItem */ public function getPropertyValues(SMWDIProperty $property) { if ($property->isInverse()) { // we never have any data for inverses return array(); } if (array_key_exists($property->getKey(), $this->mStubPropVals)) { $this->unstubProperty($property->getKey(), $property); $propertyTypeId = $property->findPropertyTypeID(); $propertyDiId = SMWDataValueFactory::getDataItemId($propertyTypeId); foreach ($this->mStubPropVals[$property->getKey()] as $dbkeys) { try { if ($propertyDiId == SMWDataItem::TYPE_CONTAINER) { $diSubWikiPage = SMWCompatibilityHelpers::dataItemFromDBKeys('_wpg', $dbkeys); $semanticData = new SMWContainerSemanticData($diSubWikiPage); $semanticData->copyDataFrom(smwfGetStore()->getSemanticData($diSubWikiPage)); $di = new SMWDIContainer($semanticData); } else { $di = SMWCompatibilityHelpers::dataItemFromDBKeys($propertyTypeId, $dbkeys); } if ($this->mNoDuplicates) { $this->mPropVals[$property->getKey()][$di->getHash()] = $di; } else { $this->mPropVals[$property->getKey()][] = $di; } } catch (SMWDataItemException $e) { // ignore data } } unset($this->mStubPropVals[$property->getKey()]); } return parent::getPropertyValues($property); }
/** * Creates and returns a new SWLPropertyChange instance from a serialization. * * @param string|null $oldValue * @param string|null $newValue * * @return SWLPropertyChange */ public static function newFromSerialization(SMWDIProperty $property, $oldValue, $newValue) { $diType = SMWDataValueFactory::getDataItemId($property->findPropertyTypeID()); //var_dump($property); //if($diType!=7) {throw new Exception();exit;} return new self(is_null($oldValue) ? null : SMWDataItem::newFromSerialization($diType, $oldValue), is_null($newValue) ? null : SMWDataItem::newFromSerialization($diType, $newValue)); }
/** * Creates and returns a new SWLPropertyChange instance from a serialization. * * @param string|null $oldValue * @param string|null $newValue * * @return SWLPropertyChange */ public static function newFromSerialization( SMWDIProperty $property, $oldValue, $newValue ) { $diType = SMWDataValueFactory::getDataItemId( $property->findPropertyTypeID() ); return new self( is_null( $oldValue ) ? null : SMWDataItem::newFromSerialization( $diType, $oldValue ), is_null( $newValue ) ? null : SMWDataItem::newFromSerialization( $diType, $newValue ) ); }
public function execute() { global $wgDBtype; if ($this->hasOption('setup')) { $store = new SMWSQLStore3(); // Lets do a drop to ensure the user doesn't has any Store3 tables already (happens when running this script twice) $tables = array('smw_stats'); foreach (SMWSQLStore3::getPropertyTables() as $proptable) { $tables[] = $proptable->name; } $dbw = wfGetDB(DB_MASTER); foreach ($tables as $table) { $name = $dbw->tableName($table); $dbw->query('DROP TABLE ' . ($wgDBtype == 'postgres' ? '' : 'IF EXISTS ') . $name, 'SMWMigrate::drop'); } $store->setup(); //enter user defined properties into smw_stats (internal ones are handled by setup already ) $query = 'Replace into ' . $dbw->tableName('smw_stats') . ' (pid,usage_count) Select smw_id,0 from ' . $dbw->tableName('smw_ids') . ' where smw_namespace = ' . SMW_NS_PROPERTY . ' and smw_iw = "" '; $dbw->query($query, 'SMWMigrate:commandLine'); } elseif ($this->hasOption('migrate')) { $options = array(); if ($this->hasArg(0)) { if ($this->hasArg(1)) { $options['LIMIT'] = $this->getArg(0); $options['OFFSET'] = $this->getArg(1); } } $dbw = wfGetDB(DB_MASTER); $oldStore = new SMWSQLStore2(); $newStore = new SMWSQLStore3(); $proptables = SMWSQLStore3::getPropertyTables(); //get properties $res = $dbw->select('smw_ids', array('smw_id', 'smw_title', 'smw_namespace'), array('smw_namespace' => SMW_NS_PROPERTY), __METHOD__, $options); foreach ($res as $row) { $property = new SMWDIProperty($row->smw_title); echo 'Now migrating data for Property ' . $property->getLabel() . " into Store3 \n"; //get the table $tableId = SMWSQLStore3::findPropertyTableID($property); $proptable = $proptables[$tableId]; //get the DIHandler $dataItemId = SMWDataValueFactory::getDataItemId($property->findPropertyTypeId()); $diHandler = $newStore->getDataItemHandlerForDIType($dataItemId); $subjects = $oldStore->getPropertySubjects($property, null); $insertions = array(); foreach ($subjects as $subject) { $sid = $newStore->makeSMWPageID($subject->getDBkey(), $subject->getNamespace(), $subject->getInterwiki(), $subject->getSubobjectName(), true, str_replace('_', ' ', $subject->getDBkey()) . $subject->getSubobjectName()); //now prepare udpates $propvals = $oldStore->getPropertyValues($subject, $property); $uvals = $proptable->idsubject ? array('s_id' => $sid) : array('s_title' => $subject->getDBkey(), 's_namespace' => $subject->getNamespace()); if ($proptable->fixedproperty == false) { $uvals['p_id'] = $newStore->makeSMWPropertyID($property); } foreach ($propvals as $propval) { $uvals = array_merge($uvals, $diHandler->getInsertValues($propval)); $insertions[] = $uvals; } } // now write to the DB for all subjects (is this too much?) $dbw->insert($proptable->name, $insertions, "SMW::migrate{$proptable->name}"); } $dbw->freeResult($res); } else { echo "Sorry I refuse to work without any options currently"; } }
/** * Find the id of all property tables where data items of the given * type could possibly be stored. * * @param $dataItemId integer * @return array of string */ public static function findAllDiTypeTableIds($dataItemId) { $result = array(self::findDiTypeTableId($dataItemId)); foreach (self::$special_tables as $specialTableId) { if ($dataItemId == SMWDataValueFactory::getDataItemId($dataItemId)) { $result[] = $specialTableId; } } return $result; }
/** * Return the array of predefined property table declarations, initialising * it if necessary. The result is an array of SMWSQLStore3Table objects * indexed by table ids. * * It is ensured that the keys of the returned array agree with the name of * the table that they refer to. * * @since 1.8 * @return SMWSQLStore3Table[] */ public static function getPropertyTables() { if (isset(self::$prop_tables)) { return self::$prop_tables; // Don't initialise twice. } /** * @var SMWSQLStore3Table[] $propertyTables */ $propertyTables = array(); //tables for each DI type foreach (self::$di_type_tables as $tableDIType => $tableName) { $propertyTables[$tableName] = new SMWSQLStore3Table($tableDIType, $tableName); } //tables for special properties foreach (self::$special_tables as $propertyKey) { $typeId = SMWDIProperty::getPredefinedPropertyTypeId($propertyKey); $diType = SMWDataValueFactory::getDataItemId($typeId); $tableName = 'smw_fpt' . strtolower($propertyKey); $propertyTables[$tableName] = new SMWSQLStore3Table($diType, $tableName, $propertyKey); } // Redirect table uses another subject scheme for historic reasons // TODO This should be changed if possible $propertyTables['smw_fpt_redi']->setUsesIdSubject(false); // Get all the tables for the properties that are declared as fixed // (overly used and thus having separate tables) foreach (self::$fixedProperties as $propertyKey => $tableDIType) { $tableName = 'smw_fpt_' . md5($propertyKey); $propertyTables[$tableName] = new SMWSQLStore3Table($tableDIType, $tableName, $propertyKey); } wfRunHooks('SMWPropertyTables', array(&$propertyTables)); self::$prop_tables = $propertyTables; // Build index for finding property tables self::$fixedPropertyTableIds = array(); foreach (self::$prop_tables as $tid => $propTable) { if ($propTable->isFixedPropertyTable()) { self::$fixedPropertyTableIds[$propTable->getFixedProperty()] = $tid; } } // Specifically set properties that must not be stored in any // property table to null here. Any function that hits this // null unprepared is doing something wrong anyway. self::$fixedPropertyTableIds['_SKEY'] = null; return self::$prop_tables; }
/** * Extend the given SPARQL condition by a suitable order by variable, * if an order by property is set. * * @param SMWSparqlCondition $sparqlCondition condition to modify * @param string $mainVariable the variable that represents the value to be ordered * @param mixed $orderByProperty SMWDIProperty or null * @param integer $diType DataItem type id if known, or SMWDataItem::TYPE_NOTYPE to determine it from the property */ protected function addOrderByDataForProperty(SMWSparqlCondition &$sparqlCondition, $mainVariable, $orderByProperty, $diType = SMWDataItem::TYPE_NOTYPE) { if (is_null($orderByProperty)) { return; } if ($diType == SMWDataItem::TYPE_NOTYPE) { $typeId = $orderByProperty->findPropertyTypeID(); $diType = SMWDataValueFactory::getDataItemId($typeId); } $this->addOrderByData($sparqlCondition, $mainVariable, $diType); }
/** * Modify the given query object to account for some property condition for * the given property. If it is not possible to generate a query for the * given data, the query type is changed to SMWSQLStore3Query::Q_NOQUERY. Callers need * to check for this and discard the query in this case. * * @note This method does not support sortkey (_SKEY) property queries, * since they do not have a normal property table. This should not be a * problem since comparators on sortkeys are supported indirectly when * using comparators on wikipages. There is no reason to create any * query with _SKEY ad users cannot do so either (no user label). * * @since 1.8 */ protected function compileSomePropertyDescription(SMWSQLStore3Query $query, SMWSomeProperty $description) { $property = $description->getProperty(); $tableid = SMWSQLStore3::findPropertyTableID($property); if ($tableid === '') { // Give up $query->type = SMWSQLStore3Query::Q_NOQUERY; return; } $proptables = SMWSQLStore3::getPropertyTables(); $proptable = $proptables[$tableid]; if (!$proptable->usesIdSubject()) { // no queries with such tables // (only redirects are affected in practice) $query->type = SMWSQLStore3Query::Q_NOQUERY; return; } $typeid = $property->findPropertyTypeID(); $diType = SMWDataValueFactory::getDataItemId($typeid); if ($property->isInverse() && $diType != SMWDataItem::TYPE_WIKIPAGE) { // can only invert properties that point to pages $query->type = SMWSQLStore3Query::Q_NOQUERY; return; } $diHandler = $this->m_store->getDataItemHandlerForDIType($diType); $indexField = $diHandler->getIndexField(); $sortkey = $property->getKey(); // TODO: strictly speaking, the DB key is not what we want here, since sortkey is based on a "wiki value" // *** Now construct the query ... ***// $query->jointable = $proptable->getName(); // *** Add conditions for selecting rows for this property ***// if (!$proptable->isFixedPropertyTable()) { $pid = $this->m_store->smwIds->getSMWPropertyID($property); // Construct property hierarchy: $pqid = SMWSQLStore3Query::$qnum; $pquery = new SMWSQLStore3Query(); $pquery->type = SMWSQLStore3Query::Q_PROP_HIERARCHY; $pquery->joinfield = array($pid); $query->components[$pqid] = "{$query->alias}.p_id"; $this->m_queries[$pqid] = $pquery; // Alternative code without property hierarchies: // $query->where = "{$query->alias}.p_id=" . $this->m_dbs->addQuotes( $pid ); } // else: no property column, no hierarchy queries // *** Add conditions on the value of the property ***// if ($diType == SMWDataItem::TYPE_WIKIPAGE) { $o_id = $indexField; if ($property->isInverse()) { $s_id = $o_id; $o_id = 's_id'; } else { $s_id = 's_id'; } $query->joinfield = "{$query->alias}.{$s_id}"; // process page description like main query $sub = $this->compileQueries($description->getDescription()); if ($sub >= 0) { $query->components[$sub] = "{$query->alias}.{$o_id}"; } if (array_key_exists($sortkey, $this->m_sortkeys)) { // TODO: This SMW IDs table is possibly duplicated in the query. // Example: [[has capital::!Berlin]] with sort=has capital // Can we prevent that? (PERFORMANCE) $query->from = ' INNER JOIN ' . $this->m_dbs->tableName(SMWSql3SmwIds::tableName) . " AS ids{$query->alias} ON ids{$query->alias}.smw_id={$query->alias}.{$o_id}"; $query->sortfields[$sortkey] = "ids{$query->alias}.smw_sortkey"; } } else { // non-page value description $query->joinfield = "{$query->alias}.s_id"; $this->compilePropertyValueDescription($query, $description->getDescription(), $proptable, $diHandler, 'AND'); if (array_key_exists($sortkey, $this->m_sortkeys)) { $query->sortfields[$sortkey] = "{$query->alias}.{$indexField}"; } } }
/** * @see SMWStore::getPropertyValues * * @since 1.8 * @param $subject mixed SMWDIWikiPage or null * @param $property SMWDIProperty * @param $requestoptions SMWRequestOptions * @return array of SMWDataItem */ public function getPropertyValues($subject, SMWDIProperty $property, $requestoptions = null) { wfProfileIn("SMWSQLStore3::getPropertyValues (SMW)"); if ($property->isInverse()) { // inverses are working differently $noninverse = new SMWDIProperty($property->getKey(), false); $result = $this->getPropertySubjects($noninverse, $subject, $requestoptions); } elseif (!is_null($subject)) { // subject given, use semantic data cache $sid = $this->store->smwIds->getSMWPageID($subject->getDBkey(), $subject->getNamespace(), $subject->getInterwiki(), $subject->getSubobjectName(), true); if ($sid == 0) { $result = array(); } else { $proptables = SMWSQLStore3::getPropertyTables(); $sd = $this->getSemanticDataFromTable($sid, $subject, $proptables[$this->store->findPropertyTableID($property)]); $result = $this->store->applyRequestOptions($sd->getPropertyValues($property), $requestoptions); } } else { // no subject given, get all values for the given property $pid = $this->store->smwIds->getSMWPropertyID($property); $tableid = SMWSQLStore3::findPropertyTableID($property); if ($pid == 0 || $tableid === '') { wfProfileOut("SMWSQLStore3::getPropertyValues (SMW)"); return array(); } $proptables = SMWSQLStore3::getPropertyTables(); $data = $this->fetchSemanticData($pid, $property, $proptables[$tableid], false, $requestoptions); $result = array(); $propertyTypeId = $property->findPropertyTypeID(); $propertyDiId = SMWDataValueFactory::getDataItemId($propertyTypeId); foreach ($data as $dbkeys) { try { $diHandler = $this->store->getDataItemHandlerForDIType($propertyDiId); $result[] = $diHandler->dataItemFromDBKeys($dbkeys); } catch (SMWDataItemException $e) { // maybe type assignment changed since data was stored; // don't worry, but we can only drop the data here } } } wfProfileOut("SMWSQLStore3::getPropertyValues (SMW)"); return $result; }
/** * Get the array of all stored values for some property. * * @since 1.8 * * @param $property SMWDIProperty * * @return array of SMWDataItem */ public function getPropertyValues(SMWDIProperty $property) { if ($property->isInverse()) { // we never have any data for inverses return array(); } if (array_key_exists($property->getKey(), $this->mStubPropVals)) { // Not catching exception here; the $this->unstubProperty($property->getKey(), $property); $propertyTypeId = $property->findPropertyTypeID(); $propertyDiId = SMWDataValueFactory::getDataItemId($propertyTypeId); foreach ($this->mStubPropVals[$property->getKey()] as $dbkeys) { try { $diHandler = $this->store->getDataItemHandlerForDIType($propertyDiId); $di = $diHandler->dataItemFromDBKeys($dbkeys); if ($this->mNoDuplicates) { $this->mPropVals[$property->getKey()][$di->getHash()] = $di; } else { $this->mPropVals[$property->getKey()][] = $di; } } catch (SMWDataItemException $e) { // ignore data } } unset($this->mStubPropVals[$property->getKey()]); } return parent::getPropertyValues($property); }
/** * Return the array of predefined property table declarations, initialising * it if necessary. The result is an array of SMWSQLStore3Table objects * indexed by table ids. Note that the ids are only for accessing the data * and should not be assumed to agree with the table name. * * @return array of SMWSQLStore3Table */ public static function getPropertyTables() { if (isset(self::$prop_tables)) { return self::$prop_tables; // Don't initialise twice. } self::$prop_tables = array(); //tables for each DI type foreach (self::$di_type_tables as $tableDIType => $tableName) { self::$prop_tables[$tableName] = new SMWSQLStore3Table($tableDIType, $tableName); } //tables for special properties foreach (self::$special_tables as $propertyKey) { $typeId = SMWDIProperty::getPredefinedPropertyTypeId($propertyKey); $diType = SMWDataValueFactory::getDataItemId($typeId); $tableName = 'smw_fpt' . strtolower($propertyKey); self::$prop_tables[$tableName] = new SMWSQLStore3Table($diType, $tableName, $propertyKey); } // Redirect table uses another subject scheme for historic reasons // TODO This should be changed if possible self::$prop_tables['smw_fpt_redi']->idsubject = false; // Get all the tables for the properties that are declared as fixed // (overly used and thus having separate tables) foreach (self::$fixedProperties as $propertyKey => $tableDIType) { $tableName = 'smw_fpt_' . md5($propertyKey); self::$prop_tables[$tableName] = new SMWSQLStore3Table($tableDIType, $tableName, $propertyKey); } wfRunHooks('SMWPropertyTables', array(&self::$prop_tables)); // Build index for finding property tables self::$fixedPropertyTableIds = array(); foreach (self::$prop_tables as $tid => $proptable) { if ($proptable->fixedproperty) { self::$fixedPropertyTableIds[$proptable->fixedproperty] = $tid; } } return self::$prop_tables; }
/** * Method to create a dataitem from a type ID and array of DB keys. * Throws SMWDataItemException if problems occur, to get our callers * used to it. * * @param $typeid string id for the given type * @param $dbkeys array of mixed * * @return SMWDataItem */ public static function dataItemFromDBKeys($typeid, $dbkeys) { switch (SMWDataValueFactory::getDataItemId($typeid)) { case SMWDataItem::TYPE_ERROR: case SMWDataItem::TYPE_NOTYPE: break; case SMWDataItem::TYPE_NUMBER: return SMWDINumber::doUnserialize($dbkeys[0]); case SMWDataItem::TYPE_STRING: return new SMWDIString($dbkeys[0]); case SMWDataItem::TYPE_BLOB: return new SMWDIBlob($dbkeys[0]); case SMWDataItem::TYPE_BOOLEAN: return new SMWDIBoolean($dbkeys[0] == '1'); case SMWDataItem::TYPE_URI: if ($typeid == '__typ' && $dbkeys[0][0] == '_') { // b/c: old data stored as type ids return SMWTypesValue::getTypeUriFromTypeId($dbkeys[0]); } else { return SMWDIUri::doUnserialize($dbkeys[0]); } case SMWDataItem::TYPE_TIME: $timedate = explode('T', $dbkeys[0], 2); if (count($dbkeys) == 2 && count($timedate) == 2) { $date = reset($timedate); $year = $month = $day = $hours = $minutes = $seconds = $timeoffset = false; if (end($timedate) === '' || SMWTimeValue::parseTimeString(end($timedate), $hours, $minutes, $seconds, $timeoffset) == true) { $d = explode('/', $date, 3); if (count($d) == 3) { list($year, $month, $day) = $d; } elseif (count($d) == 2) { list($year, $month) = $d; } elseif (count($d) == 1) { list($year) = $d; } if ($month === '') { $month = false; } if ($day === '') { $day = false; } $calendarmodel = SMWDITime::CM_GREGORIAN; return new SMWDITime($calendarmodel, $year, $month, $day, $hours, $minutes, $seconds); } } break; case SMWDataItem::TYPE_GEO: return new SMWDIGeoCoord(array('lat' => (double) $dbkeys[0], 'lon' => (double) $dbkeys[1])); case SMWDataItem::TYPE_CONTAINER: // provided for backwards compatibility only; // today containers are read from the store as substructures, // not retrieved as single complex values $semanticData = SMWContainerSemanticData::makeAnonymousContainer(); foreach (reset($dbkeys) as $value) { if (is_array($value) && count($value) == 2) { $diP = new SMWDIProperty(reset($value), false); $diV = self::dataItemFromDBKeys($diP->findPropertyTypeID(), end($value)); $semanticData->addPropertyObjectValue($diP, $diV); } } return new SMWDIContainer($semanticData); case SMWDataItem::TYPE_WIKIPAGE: if ($typeid == '__spf') { $pagedbkey = str_replace(' ', '_', $dbkeys[0]); return new SMWDIWikiPage($pagedbkey, SF_NS_FORM, ''); } elseif (count($dbkeys) >= 5) { // with subobject name (and sortkey) return new SMWDIWikiPage($dbkeys[0], intval($dbkeys[1]), $dbkeys[2], $dbkeys[4]); } elseif (count($dbkeys) >= 3) { // without subobject name (just for b/c) return new SMWDIWikiPage($dbkeys[0], intval($dbkeys[1]), $dbkeys[2]); } break; case SMWDataItem::TYPE_CONCEPT: if (count($dbkeys) >= 5) { return new SMWDIConcept($dbkeys[0], smwfXMLContentEncode($dbkeys[1]), $dbkeys[2], $dbkeys[3], $dbkeys[4]); } break; case SMWDataItem::TYPE_PROPERTY: return new SMWDIProperty($dbkeys[0], false); } throw new SMWDataItemException('Failed to create data item from DB keys.'); }