/** * Sets up the property tables. * * @param array $dbtypes * @param $db * @param $reportTo SMWSQLStore2 or null */ protected function setupPropertyTables(array $dbtypes, $db, $reportTo) { $addedCustomTypeSignatures = false; foreach (self::getPropertyTables() as $proptable) { if ($proptable->idsubject) { $fieldarray = array('s_id' => $dbtypes['p'] . ' NOT NULL'); $indexes = array('s_id'); } else { $fieldarray = array('s_title' => $dbtypes['t'] . ' NOT NULL', 's_namespace' => $dbtypes['n'] . ' NOT NULL'); $indexes = array('s_title,s_namespace'); } if (!$proptable->fixedproperty) { $fieldarray['p_id'] = $dbtypes['p'] . ' NOT NULL'; $indexes[] = 'p_id'; } foreach ($proptable->objectfields as $fieldname => $typeid) { // If the type signature is not recognized and the custom signatures have not been added, add them. if (!$addedCustomTypeSignatures && !array_key_exists($typeid, $dbtypes)) { wfRunHooks('SMWCustomSQLStoreFieldType', array(&$dbtypes)); $addedCustomTypeSignatures = true; } // Only add the type when the signature was recognized, otherwise ignore it silently. if (array_key_exists($typeid, $dbtypes)) { $fieldarray[$fieldname] = $dbtypes[$typeid]; } } $indexes = array_merge($indexes, $proptable->indexes); SMWSQLHelpers::setupTable($proptable->name, $fieldarray, $db, $reportTo); SMWSQLHelpers::setupIndex($proptable->name, $indexes, $db); } }
/** * Create required SQL tables. This function also performs upgrades of table contents * when required. */ protected function setupTables($verbose, $db) { $reportTo = $verbose ? $this : null; // Use $this to report back from static SMWSQLHelpers. SMWSQLHelpers::setupTable('smwsimple_data', array('pageid' => SMWSQLHelpers::getStandardDBType('id') . ' NOT NULL', 'propname' => SMWSQLHelpers::getStandardDBType('title') . ' NOT NULL', 'value' => SMWSQLHelpers::getStandardDBType('blob') . ' NOT NULL'), $db, $reportTo); SMWSQLHelpers::setupIndex('smwsimple_data', array('pageid', 'propname', 'propname,value(256)'), $db); SMWSQLHelpers::setupTable('smwsimple_special', array('pageid' => SMWSQLHelpers::getStandardDBType('id') . ' NOT NULL', 'propname' => SMWSQLHelpers::getStandardDBType('title') . ' NOT NULL', 'value' => SMWSQLHelpers::getStandardDBType('title') . ' NOT NULL'), $db, $reportTo); SMWSQLHelpers::setupIndex('smwsimple_special', array('pageid', 'pageid,propname', 'propname', 'propname,value'), $db); $this->reportProgress("Database initialised successfully.\n\n", $verbose); }
/** * Sets up the property tables. * * @since 1.8 * @param array $dbtypes * @param DatabaseBase|Database $db * @param SMWSQLStore3SetupHandlers|null $reportTo */ protected function setupPropertyTables(array $dbtypes, $db, SMWSQLStore3SetupHandlers $reportTo = null) { $addedCustomTypeSignatures = false; foreach ($this->store->getPropertyTables() as $proptable) { // Only extensions that aren't setup correctly can force an exception // and to avoid a failure during setup, ensure that standard tables // are correctly initialized otherwise SMW can't recover try { $diHandler = $this->store->getDataItemHandlerForDIType($proptable->getDiType()); } catch (\Exception $e) { continue; } // Prepare indexes. By default, property-value tables // have the following indexes: // // sp: getPropertyValues(), getSemanticData(), getProperties() // po: ask, getPropertySubjects() // // The "p" component is omitted for tables with fixed property. $indexes = array(); if ($proptable->usesIdSubject()) { $fieldarray = array('s_id' => $dbtypes['p'] . ' NOT NULL'); $indexes['sp'] = 's_id'; } else { $fieldarray = array('s_title' => $dbtypes['t'] . ' NOT NULL', 's_namespace' => $dbtypes['n'] . ' NOT NULL'); $indexes['sp'] = 's_title,s_namespace'; } $indexes['po'] = $diHandler->getIndexField(); if (!$proptable->isFixedPropertyTable()) { $fieldarray['p_id'] = $dbtypes['p'] . ' NOT NULL'; $indexes['po'] = 'p_id,' . $indexes['po']; $indexes['sp'] = $indexes['sp'] . ',p_id'; } // TODO Special handling; concepts should be handled differently // in the future. See comments in SMW_DIHandler_Concept.php. if ($proptable->getDiType() == SMWDataItem::TYPE_CONCEPT) { unset($indexes['po']); } $indexes = array_merge($indexes, $diHandler->getTableIndexes()); $indexes = array_unique($indexes); foreach ($diHandler->getTableFields() as $fieldname => $typeid) { // If the type signature is not recognized and the custom signatures have not been added, add them. if (!$addedCustomTypeSignatures && !array_key_exists($typeid, $dbtypes)) { wfRunHooks('SMWCustomSQLStoreFieldType', array(&$dbtypes)); $addedCustomTypeSignatures = true; } // Only add the type when the signature was recognized, otherwise ignore it silently. if (array_key_exists($typeid, $dbtypes)) { $fieldarray[$fieldname] = $dbtypes[$typeid]; } } SMWSQLHelpers::setupTable($proptable->getName(), $fieldarray, $db, $reportTo); SMWSQLHelpers::setupIndex($proptable->getName(), $indexes, $db, $reportTo); } }
/** * Update a table given an array of field names and field types. * * @param string $tableName The table name. * @param array $columns The fields and their types the table should have. * @param DatabaseBase|Database $db * @param object $reportTo Object to report back to. */ protected static function updateTable($tableName, array $fields, $db, $reportTo) { global $wgDBtype; $currentFields = self::getFields($tableName, $db, $reportTo); $isPostgres = $wgDBtype == 'postgres'; if (!$isPostgres) { $position = 'FIRST'; } // Loop through all the field definitions, and handle each definition for either postgres or MySQL. foreach ($fields as $fieldName => $fieldType) { if ($isPostgres) { self::updatePostgresField($tableName, $fieldName, $fieldType, $currentFields, $db, $reportTo); } else { self::updateMySqlField($tableName, $fieldName, $fieldType, $currentFields, $db, $reportTo, $position); $position = "AFTER {$fieldName}"; } $currentFields[$fieldName] = false; } // The updated fields have their value set to false, so if a field has a value // that differs from false, it's an obsolete one that should be removed. foreach ($currentFields as $fieldName => $value) { if ($value !== false) { SMWSQLHelpers::reportProgress(" ... deleting obsolete field {$fieldName} ... ", $reportTo); if ($isPostgres) { $db->query('ALTER TABLE "' . $tableName . '" DROP COLUMN "' . $fieldName . '"', __METHOD__); } elseif ($wgDBtype == 'sqlite') { // DROP COLUMN not supported in Sqlite3 SMWSQLHelpers::reportProgress(" ... deleting obsolete field {$fieldName} not possible in SQLLite ... you could delete and reinitialize the tables to remove obsolete data, or just keep it ... ", $reportTo); } else { $db->query("ALTER TABLE {$tableName} DROP COLUMN `{$fieldName}`", __METHOD__); } SMWSQLHelpers::reportProgress("done.\n", $reportTo); } } }