/** * Empty all tables so they can be repopulated for tests */ private function resetDB() { if ($this->db) { if ($this->db->getType() == 'oracle') { if (self::$useTemporaryTables) { wfGetLB()->closeAll(); $this->db = wfGetDB(DB_MASTER); } else { foreach ($this->tablesUsed as $tbl) { if ($tbl == 'interwiki') { continue; } $this->db->query('TRUNCATE TABLE ' . $this->db->tableName($tbl), __METHOD__); } } } else { foreach ($this->tablesUsed as $tbl) { if ($tbl == 'interwiki' || $tbl == 'user') { continue; } $this->db->delete($tbl, '*', __METHOD__); } } } }
/** * (MySQL only) Adds back fulltext index after populating the table. */ private function createMysqlTextIndex() { $searchindex = $this->db->tableName('searchindex'); $this->output("\nRebuild the index...\n"); $sql = "ALTER TABLE {$searchindex} ADD FULLTEXT si_title (si_title), " . "ADD FULLTEXT si_text (si_text)"; $this->db->query($sql, __METHOD__); }
/** * Find pages in mainspace that have a prefix of the new namespace * so we know titles that will need migrating * @param $ns int Namespace id (id for new namespace?) * @param $name String Prefix that is being made a namespace */ private function getConflicts( $ns, $name ) { $page = 'page'; $table = $this->db->tableName( $page ); $prefix = $this->db->strencode( $name ); $encNamespace = $this->db->addQuotes( $ns ); $titleSql = "TRIM(LEADING '$prefix:' FROM {$page}_title)"; if( $ns == 0 ) { // An interwiki; try an alternate encoding with '-' for ':' $titleSql = $this->db->buildConcat( array( "'$prefix-'", $titleSql ) ); } $sql = "SELECT {$page}_id AS id, {$page}_title AS oldtitle, $encNamespace + {$page}_namespace AS namespace, $titleSql AS title, {$page}_namespace AS oldnamespace FROM {$table} WHERE ( {$page}_namespace=0 OR {$page}_namespace=1 ) AND {$page}_title " . $this->db->buildLike( $name . ':', $this->db->anyString() ); $result = $this->db->query( $sql, __METHOD__ ); $set = array(); foreach( $result as $row ) { $set[] = $row; } return $set; }
private static function __getCategories($aParamValues, &$parser) { wfProfileIn(__METHOD__); self::$aCategoryNames = $aParamValues; $aPages = array(); if (!empty($aParamValues)) { # RT 26917 $aParamValues = array_map("strip_tags", array_map(array("self", "__parseCategories"), $aParamValues, array($parser))); // set timestamp option, if set $timestampLimit = BLOGS_TIMESTAMP; if (!empty(self::$aOptions['timestamp'])) { $timestampLimit = self::$aOptions['timestamp']; } /* set max length of group concat query */ self::$dbr->query('SET group_concat_max_len = ' . GROUP_CONCAT, __METHOD__); /* run query */ $res = self::$dbr->select(array(self::$dbr->tableName('page'), self::$dbr->tableName('categorylinks')), array("cl_to", "GROUP_CONCAT(DISTINCT cl_from SEPARATOR ',') AS cl_page"), array("page_namespace" => NS_BLOG_ARTICLE, "page_id = cl_from", "cl_to in (" . self::$dbr->makeList($aParamValues) . ")", "page_touched >= " . self::$dbr->addQuotes($timestampLimit)), __METHOD__, array('GROUP BY' => 'cl_to')); while ($oRow = self::$dbr->fetchObject($res)) { // BugId:49408 // Since GROUP_CONCAT respects group_concat_max_len arbitrarily, // sometimes we end up with a comma or a truncated item, which // we don't want. if (GROUP_CONCAT == strlen($oRow->cl_page)) { $aPages[] = preg_replace('/,\\d+,?$/', '', $oRow->cl_page); } else { $aPages[] = $oRow->cl_page; } } self::$dbr->freeResult($res); } wfProfileOut(__METHOD__); return $aPages; }
/** * @param DatabaseBase $db * @param string $table * @param string $field * @return null|PostgresField */ static function fromText($db, $table, $field) { $q = <<<SQL SELECT attnotnull, attlen, conname AS conname, atthasdef, adsrc, COALESCE(condeferred, 'f') AS deferred, COALESCE(condeferrable, 'f') AS deferrable, CASE WHEN typname = 'int2' THEN 'smallint' WHEN typname = 'int4' THEN 'integer' WHEN typname = 'int8' THEN 'bigint' WHEN typname = 'bpchar' THEN 'char' ELSE typname END AS typname FROM pg_class c JOIN pg_namespace n ON (n.oid = c.relnamespace) JOIN pg_attribute a ON (a.attrelid = c.oid) JOIN pg_type t ON (t.oid = a.atttypid) LEFT JOIN pg_constraint o ON (o.conrelid = c.oid AND a.attnum = ANY(o.conkey) AND o.contype = 'f') LEFT JOIN pg_attrdef d on c.oid=d.adrelid and a.attnum=d.adnum WHERE relkind = 'r' AND nspname=%s AND relname=%s AND attname=%s; SQL; $table = $db->tableName($table, 'raw'); $res = $db->query(sprintf($q, $db->addQuotes($db->getCoreSchema()), $db->addQuotes($table), $db->addQuotes($field))); $row = $db->fetchObject($res); if (!$row) { return null; } $n = new PostgresField(); $n->type = $row->typname; $n->nullable = $row->attnotnull == 'f'; $n->name = $field; $n->tablename = $table; $n->max_length = $row->attlen; $n->deferrable = $row->deferrable == 't'; $n->deferred = $row->deferred == 't'; $n->conname = $row->conname; $n->has_default = $row->atthasdef === 't'; $n->default = $row->adsrc; return $n; }
function execute() { $this->dbw = wfGetDB(DB_MASTER); $logging = $this->dbw->tableName('logging'); $logging_1_10 = $this->dbw->tableName('logging_1_10'); $logging_pre_1_10 = $this->dbw->tableName('logging_pre_1_10'); if ($this->dbw->tableExists('logging_pre_1_10') && !$this->dbw->tableExists('logging')) { # Fix previous aborted run echo "Cleaning up from previous aborted run\n"; $this->dbw->query("RENAME TABLE {$logging_pre_1_10} TO {$logging}", __METHOD__); } if ($this->dbw->tableExists('logging_pre_1_10')) { echo "This script has already been run to completion\n"; return; } # Create the target table if (!$this->dbw->tableExists('logging_1_10')) { global $wgDBTableOptions; $sql = <<<EOT CREATE TABLE {$logging_1_10} ( -- Log ID, for referring to this specific log entry, probably for deletion and such. log_id int unsigned NOT NULL auto_increment, -- Symbolic keys for the general log type and the action type -- within the log. The output format will be controlled by the -- action field, but only the type controls categorization. log_type varbinary(10) NOT NULL default '', log_action varbinary(10) NOT NULL default '', -- Timestamp. Duh. log_timestamp binary(14) NOT NULL default '19700101000000', -- The user who performed this action; key to user_id log_user int unsigned NOT NULL default 0, -- Key to the page affected. Where a user is the target, -- this will point to the user page. log_namespace int NOT NULL default 0, log_title varchar(255) binary NOT NULL default '', -- Freeform text. Interpreted as edit history comments. log_comment varchar(255) NOT NULL default '', -- LF separated list of miscellaneous parameters log_params blob NOT NULL, -- rev_deleted for logs log_deleted tinyint unsigned NOT NULL default '0', PRIMARY KEY log_id (log_id), KEY type_time (log_type, log_timestamp), KEY user_time (log_user, log_timestamp), KEY page_time (log_namespace, log_title, log_timestamp), KEY times (log_timestamp) ) {$wgDBTableOptions} EOT; echo "Creating table logging_1_10\n"; $this->dbw->query($sql, __METHOD__); } # Synchronise the tables echo "Doing initial sync...\n"; $this->sync('logging', 'logging_1_10'); echo "Sync done\n\n"; # Rename the old table away echo "Renaming the old table to {$logging_pre_1_10}\n"; $this->dbw->query("RENAME TABLE {$logging} TO {$logging_pre_1_10}", __METHOD__); # Copy remaining old rows # Done before the new table is active so that $copyPos is accurate echo "Doing final sync...\n"; $this->sync('logging_pre_1_10', 'logging_1_10'); # Move the new table in echo "Moving the new table in...\n"; $this->dbw->query("RENAME TABLE {$logging_1_10} TO {$logging}", __METHOD__); echo "Finished.\n"; }
function tableName($name, $format = 'quoted') { /* Replace reserved words with better ones Using uppercase because that's the only way Oracle can handle quoted tablenames */ switch ($name) { case 'user': $name = 'MWUSER'; break; case 'text': $name = 'PAGECONTENT'; break; } return parent::tableName(strtoupper($name), $format); }
/** * Use MySQL's naming (accounts for prefix etc) but remove surrounding backticks * * @param $name * @param $format String * @return string */ function tableName($name, $format = 'quoted') { // table names starting with sqlite_ are reserved if (strpos($name, 'sqlite_') === 0) { return $name; } return str_replace('"', '', parent::tableName($name, $format)); }
function realTableName($name, $format = 'quoted') { return parent::tableName($name, $format); }
/** * call this instead of tableName() in the updater when renaming tables * @param string $name * @param string $format One of quoted, raw, or split * @return string */ function realTableName($name, $format = 'quoted') { $table = parent::tableName($name, $format); if ($format == 'split') { // Used internally, we want the schema split off from the table name and returned // as a list with 3 elements (database, schema, table) $table = explode('.', $table); if (count($table) == 2) { array_unshift($table, false); } } return $table; }
/** * Make sure that each of the column descriptions in the given array is * indexed by *one* index in the given DB table. * * @param string $tableName table name. Does not need to have been passed to DatabaseBase->tableName yet. * @param array $indexes array of strings, each a comma separated list with column names to index * @param DatabaseBase|Database $db DatabaseBase or Database * @param object $reportTo object to report messages to; since 1.8 */ public static function setupIndex($rawTableName, array $indexes, $db, $reportTo = null) { global $wgDBtype; $tableName = $wgDBtype == 'postgres' ? $db->tableName($rawTableName, 'raw') : $db->tableName($rawTableName); self::reportProgress("Checking index structures for table {$tableName} ...\n", $reportTo); // First remove obsolete indexes. $oldIndexes = self::getIndexInfo($db, $tableName); if ($wgDBtype == 'sqlite') { // SQLite /// TODO We do not currently get the right column definitions in /// SQLLite; hence we can only drop all indexes. Wasteful. foreach ($oldIndexes as $key => $index) { self::dropIndex($db, $key, $tableName, $key, $reportTo); } } else { foreach ($oldIndexes as $key => $indexColumn) { $id = array_search($indexColumn, $indexes); if ($id !== false || $key == 'PRIMARY') { self::reportProgress(" ... index {$indexColumn} is fine.\n", $reportTo); unset($indexes[$id]); } else { // Duplicate or unrequired index. self::dropIndex($db, $key, $tableName, $indexColumn, $reportTo); } } } // Add new indexes. foreach ($indexes as $key => $index) { // If the index is an array, it contains the column // name as first element, and index type as second one. if (is_array($index)) { $columns = $index[0]; $type = count($index) > 1 ? $index[1] : 'INDEX'; } else { $columns = $index; $type = 'INDEX'; } self::createIndex($db, $type, "{$tableName}_index{$key}", $tableName, $columns, $reportTo); } self::reportProgress(" ... done.\n", $reportTo); return true; }
/** * @param DatabaseBase $dbw * @return void */ private function truncate($dbw) { $test = $dbw->tableName('test'); $dbw->query("TRUNCATE TABLE {$test}"); }
public function testTableNameRawForeign() { $this->assertEquals($this->prefixAndQuote('tablename', 'databasename', '', 'raw'), $this->db->tableName('databasename.tablename', 'raw')); }
/** * Use MySQL's naming (accounts for prefix etc) but remove surrounding backticks */ function tableName($name) { return str_replace('`', '', parent::tableName($name)); }
/** * Truncate a table. * @param string $table The table name to be truncated */ function clearTable($table) { print "Clearing {$table}...\n"; $tableName = $this->db->tableName($table); $this->db->query("TRUNCATE {$tableName}"); }
function tableName($name, $quoted = true) { # Replace reserved words with better ones switch ($name) { case 'user': return 'mwuser'; case 'text': return 'pagecontent'; default: return parent::tableName($name, $quoted); } }