/** * Returns the set of SQL values needed to insert the data for this * internal object into the database. */ function getStorageSQL($internalObject) { if (method_exists('SMWDIWikiPage', 'getSubobjectName')) { // SMW 1.6 $ioID = $this->makeSMWPageID($internalObject->getName(), $internalObject->getNamespace(), '', ''); } else { $ioID = $this->makeSMWPageID($internalObject->getName(), $internalObject->getNamespace(), ''); } $upRels2 = array(); $upAtts2 = array(); $upText2 = array(); $upCoords = array(); // set all the properties pointing from this internal object foreach ($internalObject->getPropertyValuePairs() as $propertyValuePair) { list($property, $value) = $propertyValuePair; $tableid = SMWSQLStore2::findPropertyTableID($property); $isRelation = $tableid == 'smw_rels2'; $isAttribute = $tableid == 'smw_atts2'; $isText = $tableid == 'smw_text2'; $isCoords = $tableid == 'smw_coords'; if ($isRelation) { if (method_exists('SMWDIWikiPage', 'getSubobjectName')) { // SMW 1.6 $mainPageID = $this->makeSMWPageID($value->getDBkey(), $value->getNamespace(), $value->getInterwiki(), ''); } else { $mainPageID = $this->makeSMWPageID($value->getDBkey(), $value->getNamespace(), $value->getInterwiki()); } $upRels2[] = array('s_id' => $ioID, 'p_id' => $this->makeSMWPropertyID($property), 'o_id' => $mainPageID); } elseif ($isAttribute) { if (class_exists('SMWCompatibilityHelpers')) { // SMW 1.6 $dataItem = $value->getDataItem(); $keys = SMWCompatibilityHelpers::getDBkeysFromDataItem($dataItem); $valueNum = $dataItem->getSortKey(); } else { $keys = $value->getDBkeys(); if (method_exists($value, 'getValueKey')) { $valueNum = $value->getValueKey(); } else { $valueNum = $value->getNumericValue(); } } $upAttr = array('s_id' => $ioID, 'p_id' => $this->makeSMWPropertyID($property), 'value_xsd' => $keys[0], 'value_num' => $valueNum); // 'value_unit' DB field was removed in SMW 1.6 if (version_compare(SMW_VERSION, '1.6 alpha', '<')) { $upAttr['value_unit'] = $value->getUnit(); } $upAtts2[] = $upAttr; } elseif ($isText) { if (method_exists($value, 'getShortWikiText')) { // SMW 1.6 $key = $value->getShortWikiText(); } else { $keys = $value->getDBkeys(); $key = $keys[0]; } $upText2[] = array('s_id' => $ioID, 'p_id' => $this->makeSMWPropertyID($property), 'value_blob' => $key); } elseif ($isCoords) { $keys = $value->getDBkeys(); $upCoords[] = array('s_id' => $ioID, 'p_id' => $this->makeSMWPropertyID($property), 'lat' => $keys[0], 'lon' => $keys[1]); } } return array($upRels2, $upAtts2, $upText2, $upCoords); }
/** * Extend the given update array to account for the data in the * SMWSemanticData object. The subject page of the data container is * ignored, and the given $sid (subject page id) is used directly. If * this ID is 0, then $subject is used to find an ID. This is usually * the case for all internal objects that are created in writing * container values. * * The function returns the id that was used for writing. Especially, * any newly created internal id is returned. * * @param $updates array * @param $data SMWSemanticData * @param $sid integer pre-computed id if available or 0 if ID should be sought * @param $subject SMWDIWikiPage subject to which the data refers */ protected function prepareDBUpdates(&$updates, SMWSemanticData $data, $sid, SMWDIWikiPage $subject) { $subSemanticData = $data->getSubSemanticData(); if ($sid == 0) { $sid = $this->makeSMWPageID($subject->getDBkey(), $subject->getNamespace(), $subject->getInterwiki(), $subject->getSubobjectName(), true, str_replace('_', ' ', $subject->getDBkey()) . $subject->getSubobjectName()); } $proptables = self::getPropertyTables(); foreach ($data->getProperties() as $property) { if ($property->getKey() == '_SKEY' || $property->getKey() == '_REDI') { continue; // skip these here, we store them differently } $tableid = self::findPropertyTableID($property); $proptable = $proptables[$tableid]; foreach ($data->getPropertyValues($property) as $di) { if ($di instanceof SMWDIError) { // error values, ignore continue; } // redirects were treated above // To support compatibility with the new handling of Subobjects if ($di->getDIType() == SMWDataItem::TYPE_WIKIPAGE && array_key_exists($di->getSubobjectName(), $subSemanticData)) { $di = new SMWDIContainer($subSemanticData[$di->getSubobjectName()]); } ///TODO check needed if subject is null (would happen if a user defined proptable with !idsubject was used on an internal object -- currently this is not possible $uvals = $proptable->idsubject ? array('s_id' => $sid) : array('s_title' => $subject->getDBkey(), 's_namespace' => $subject->getNamespace()); if ($proptable->fixedproperty == false) { $uvals['p_id'] = $this->makeSMWPropertyID($property); } if ($di instanceof SMWDIContainer) { // process subobjects recursively $subObject = $di->getSemanticData()->getSubject(); $subObjectId = $this->prepareDBUpdates($updates, $di->getSemanticData(), 0, $subObject); // Note: tables for container objects MUST have objectfields == array(<somename> => 'p') reset($proptable->objectfields); $uvals[key($proptable->objectfields)] = $subObjectId; } else { $dbkeys = SMWCompatibilityHelpers::getDBkeysFromDataItem($di); reset($dbkeys); foreach ($proptable->objectfields as $fieldname => $typeid) { if ($typeid != 'p') { $uvals[$fieldname] = current($dbkeys); } else { $uvals[$fieldname] = $this->makeSMWPageID($di->getDBkey(), $di->getNamespace(), $di->getInterwiki(), $di->getSubobjectName()); } next($dbkeys); } } if (!array_key_exists($proptable->name, $updates)) { $updates[$proptable->name] = array(); } $updates[$proptable->name][] = $uvals; } } return $sid; }
/** * Given an SMWDescription that is just a conjunction or disjunction of * SMWValueDescription objects, create and return a plain WHERE condition * string for it. * * @param $query * @param SMWDescription $description * @param SMWSQLStore2Table $proptable * @param integer $valueIndex * @param string $operator */ protected function compileAttributeWhere($query, SMWDescription $description, SMWSQLStore2Table $proptable, $valueIndex, $operator = 'AND') { $where = ''; if ($description instanceof SMWValueDescription) { $dataItem = $description->getDataItem(); $keys = SMWCompatibilityHelpers::getDBkeysFromDataItem($dataItem); // Try comparison based on value field and comparator. if ($valueIndex >= 0) { // Find field name for comparison. $smwidjoinfield = false; $fieldName = $this->getDBFieldsForDVIndex($proptable->objectfields, $valueIndex, $smwidjoinfield); // Do not support smw_id joined data for now. if ($fieldName && !$smwidjoinfield) { $comparator = false; $customSQL = false; // See if the getSQLCondition method exists and call it if this is the case. if (method_exists($description, 'getSQLCondition')) { $customSQL = $description->getSQLCondition($query->alias, array_keys($proptable->objectfields), $this->m_dbs); } if ($customSQL) { $where = $customSQL; } else { $value = $keys[$valueIndex]; switch ($description->getComparator()) { case SMW_CMP_EQ: $comparator = '='; break; case SMW_CMP_LESS: $comparator = '<'; break; case SMW_CMP_GRTR: $comparator = '>'; break; case SMW_CMP_LEQ: $comparator = '<='; break; case SMW_CMP_GEQ: $comparator = '>='; break; case SMW_CMP_NEQ: $comparator = '!='; break; case SMW_CMP_LIKE: case SMW_CMP_NLKE: $comparator = ' LIKE '; if ($description->getComparator() == SMW_CMP_NLKE) { $comparator = " NOT{$comparator}"; } $value = str_replace(array('%', '_', '*', '?'), array('\\%', '\\_', '%', '_'), $value); } if ($comparator) { $where = "{$query->alias}.{$fieldName}{$comparator}" . $this->m_dbs->addQuotes($value); } } } } if ($where === '') { // comparators did not apply; match all fields $i = 0; foreach ($proptable->objectfields as $fname => $ftype) { if ($i >= count($keys)) { break; } if ($ftype == 'p') { // Special case: page id, resolve this in advance $oid = $this->getSMWPageID($dataItem->getDBkey(), $dataItem->getNamespace(), $dataItem->getInterwiki(), $dataItem->getSubobjectName()); $where .= ($where ? ' AND ' : '') . "{$query->alias}.{$fname}=" . $this->m_dbs->addQuotes($oid); break; } elseif ($ftype != 'l') { // plain value, but not a text blob $where .= ($where ? ' AND ' : '') . "{$query->alias}.{$fname}=" . $this->m_dbs->addQuotes($keys[$i]); } $i++; } } } elseif ($description instanceof SMWConjunction || $description instanceof SMWDisjunction) { $op = $description instanceof SMWConjunction ? 'AND' : 'OR'; foreach ($description->getDescriptions() as $subdesc) { $this->compileAttributeWhere($query, $subdesc, $proptable, $valueIndex, $op); } } if ($where !== '') { $query->where .= ($query->where ? " {$operator} " : '') . "({$where})"; } }