/**
  * @see SMWDescription::getSQLCondition
  *
  * FIXME: store specific code should be in the store component
  *
  * @since 0.6
  * 
  * @param string $tableName
  * @param array $fieldNames
  * @param DatabaseBase $dbs
  * 
  * @return boolean
  */
 public function getSQLCondition($tableName, array $fieldNames, DatabaseBase $dbs)
 {
     $dataItem = $this->getDataItem();
     // Only execute the query when the description's type is geographical coordinates,
     // the description is valid, and the near comparator is used.
     if ($dataItem instanceof SMWDIGeoCoord) {
         switch ($this->getComparator()) {
             case SMW_CMP_EQ:
                 $comparator = '=';
                 break;
             case SMW_CMP_LEQ:
                 $comparator = '<=';
                 break;
             case SMW_CMP_GEQ:
                 $comparator = '>=';
                 break;
             case SMW_CMP_NEQ:
                 $comparator = '!=';
                 break;
             default:
                 return false;
         }
         $lat = $dbs->addQuotes($dataItem->getLatitude());
         $lon = $dbs->addQuotes($dataItem->getLongitude());
         $conditions = array();
         $conditions[] = "{$tableName}.{$fieldNames['1']} {$comparator} {$lat}";
         $conditions[] = "{$tableName}.{$fieldNames['2']} {$comparator} {$lon}";
         return implode(' AND ', $conditions);
     }
     return false;
 }
 public function refreshBatch(DatabaseBase $dbr, UUID $continue, $countableActions, UUID $stop)
 {
     $rows = $dbr->select('flow_revision', array('rev_id', 'rev_user_id'), array('rev_id > ' . $dbr->addQuotes($continue->getBinary()), 'rev_id <= ' . $dbr->addQuotes($stop->getBinary()), 'rev_user_id > 0', 'rev_user_wiki' => wfWikiID(), 'rev_change_type' => $countableActions), __METHOD__, array('ORDER BY' => 'rev_id ASC', 'LIMIT' => $this->mBatchSize));
     // end of data
     if (!$rows || $rows->numRows() === 0) {
         return false;
     }
     foreach ($rows as $row) {
         // User::incEditCount only allows for edit count to be increased 1
         // at a time. It'd be better to immediately be able to increase the
         // edit count by the exact number it should be increased with, but
         // I'd rather re-use existing code, especially in a run-once script,
         // where performance is not the most important thing ;)
         $user = User::newFromId($row->rev_user_id);
         $user->incEditCount();
         // save updates so we can print them when the script is done running
         if (!isset($this->updates[$user->getId()])) {
             $this->updates[$user->getId()] = 0;
         }
         $this->updates[$user->getId()]++;
         // set value for next batch to continue at
         $continue = $row->rev_id;
     }
     return UUID::create($continue);
 }
Example #3
0
 public function testAddQuotesStringQuote()
 {
     $check = "'string''s cause trouble'";
     if ($this->db->getType() === 'mysql') {
         $check = "'string\\'s cause trouble'";
     }
     $this->assertEquals($check, $this->db->addQuotes("string's cause trouble"));
 }
 /**
  * @see PropertyStatisticsStore::addToUsageCount
  *
  * @since 1.9
  *
  * @param integer $propertyId
  * @param integer $value
  *
  * @return boolean Success indicator
  * @throws MWException
  */
 public function addToUsageCount($propertyId, $value)
 {
     if (!is_int($value)) {
         throw new MWException('The value to add must be an integer');
     }
     if (!is_int($propertyId) || $propertyId <= 0) {
         throw new MWException('The property id to add must be a positive integer');
     }
     if ($value == 0) {
         return true;
     }
     return $this->dbConnection->update($this->table, array('usage_count = usage_count ' . ($value > 0 ? '+ ' : '- ') . $this->dbConnection->addQuotes(abs($value))), array('p_id' => $propertyId), __METHOD__);
 }
Example #5
0
 /**
  * Check and repair the destination fields in a link table
  * @param string $table The link table name
  * @param string $fieldPrefix The field prefix in the link table
  * @param int $ns Destination namespace id
  * @param string $name
  * @param array $options Associative array of validated command-line options
  * @param array $extraConds Extra conditions for the SQL query
  */
 private function checkLinkTable($table, $fieldPrefix, $ns, $name, $options, $extraConds = array())
 {
     $batchConds = array();
     $fromField = "{$fieldPrefix}_from";
     $namespaceField = "{$fieldPrefix}_namespace";
     $titleField = "{$fieldPrefix}_title";
     $batchSize = 500;
     while (true) {
         $res = $this->db->select($table, array($fromField, $namespaceField, $titleField), array_merge($batchConds, $extraConds, array($namespaceField => 0, $titleField . $this->db->buildLike("{$name}:", $this->db->anyString()))), __METHOD__, array('ORDER BY' => array($titleField, $fromField), 'LIMIT' => $batchSize));
         if ($res->numRows() == 0) {
             break;
         }
         foreach ($res as $row) {
             $logTitle = "from={$row->{$fromField}} ns={$row->{$namespaceField}} " . "dbk={$row->{$titleField}}";
             $destTitle = $this->getDestinationTitle($ns, $name, $row->{$namespaceField}, $row->{$titleField}, $options);
             $this->totalLinks++;
             if (!$destTitle) {
                 $this->output("{$table} {$logTitle} *** INVALID\n");
                 continue;
             }
             $this->resolvableLinks++;
             if (!$options['fix']) {
                 $this->output("{$table} {$logTitle} -> " . $destTitle->getPrefixedDBkey() . " DRY RUN\n");
                 continue;
             }
             $this->db->update($table, array($namespaceField => $destTitle->getNamespace(), $titleField => $destTitle->getDBkey()), array($namespaceField => 0, $titleField => $row->{$titleField}, $fromField => $row->{$fromField}), __METHOD__, array('IGNORE'));
             $this->output("{$table} {$logTitle} -> " . $destTitle->getPrefixedDBkey() . "\n");
         }
         $encLastTitle = $this->db->addQuotes($row->{$titleField});
         $encLastFrom = $this->db->addQuotes($row->{$fromField});
         $batchConds = array("{$titleField} > {$encLastTitle} " . "OR ({$titleField} = {$encLastTitle} AND {$fromField} > {$encLastFrom})");
         wfWaitForSlaves();
     }
 }
 /**
  * Uses the primary key list and the maximal result row from the
  * previous iteration to build an SQL condition sufficient for
  * selecting the next page of results.  All except the final key use
  * `=` conditions while the final key uses a `>` condition
  *
  * Example output:
  * 	  array( '( foo = 42 AND bar > 7 ) OR ( foo > 42 )' )
  *
  * @return array The SQL conditions necessary to select the next set
  *  of rows in the batched query
  */
 protected function buildConditions()
 {
     if (!$this->current) {
         return $this->conditions;
     }
     $maxRow = end($this->current);
     $maximumValues = array();
     foreach ($this->primaryKey as $column) {
         $maximumValues[$column] = $this->db->addQuotes($maxRow->{$column});
     }
     $pkConditions = array();
     // For example: If we have 3 primary keys
     // first run through will generate
     //   col1 = 4 AND col2 = 7 AND col3 > 1
     // second run through will generate
     //   col1 = 4 AND col2 > 7
     // and the final run through will generate
     //   col1 > 4
     while ($maximumValues) {
         $pkConditions[] = $this->buildGreaterThanCondition($maximumValues);
         array_pop($maximumValues);
     }
     $conditions = $this->conditions;
     $conditions[] = sprintf('( %s )', implode(' ) OR ( ', $pkConditions));
     return $conditions;
 }
Example #7
0
 /**
  * fixTemplate
  *
  * This code ensures that the version of the Template that was in existence
  * at the same time as the Memento gets loaded and displayed with the
  * Memento.
  *
  * @fixme make this compatible with parser cache
  * @param Title $title
  * @param Parser $parser
  * @param integer $id
  *
  * @return array containing the text, finalTitle, and deps
  */
 public function fixTemplate(Title $title, Parser $parser, &$id)
 {
     // stopgap measure until we can find a better way
     // to work with parser cache
     $parser->disableCache();
     $request = $parser->getUser()->getRequest();
     if ($request->getHeader('ACCEPT-DATETIME')) {
         $requestDatetime = $request->getHeader('ACCEPT-DATETIME');
         $mwMementoTimestamp = $this->parseRequestDateTime($requestDatetime);
         $firstRev = $title->getFirstRevision();
         // if the template no longer exists, return gracefully
         if ($firstRev != null) {
             if ($firstRev->getTimestamp() < $mwMementoTimestamp) {
                 $pgID = $title->getArticleID();
                 $this->db->begin();
                 $res = $this->db->selectRow('revision', array('rev_id'), array('rev_page' => $pgID, 'rev_timestamp <=' . $this->db->addQuotes($mwMementoTimestamp)), __METHOD__, array('ORDER BY' => 'rev_id DESC', 'LIMIT' => '1'));
                 $id = $res->rev_id;
             } else {
                 // if we get something prior to the first memento, just
                 // go with the first one
                 $id = $firstRev->getId();
             }
         }
     }
 }
	/**
	 * 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;
	}
 public function updateRevision($columnPrefix, DatabaseBase $dbw, $continue = null)
 {
     $rows = $dbw->select('flow_revision', array('rev_id', 'rev_type'), array('rev_id > ' . $dbw->addQuotes($continue), "{$columnPrefix}_id > 0", "{$columnPrefix}_ip IS NOT NULL"), __METHOD__, array('LIMIT' => $this->mBatchSize, 'ORDER BY' => 'rev_id'));
     $ids = $objs = array();
     foreach ($rows as $row) {
         $id = UUID::create($row->rev_id);
         $type = self::$types[$row->rev_type];
         $om = $this->storage->getStorage($type);
         $obj = $om->get($id);
         if ($obj) {
             $om->merge($obj);
             $ids[] = $row->rev_id;
             $objs[] = $obj;
         } else {
             $this->error(__METHOD__ . ": Failed loading {$type}: " . $id->getAlphadecimal());
         }
     }
     if (!$ids) {
         return null;
     }
     $dbw->update('flow_revision', array("{$columnPrefix}_ip" => null), array('rev_id' => $ids), __METHOD__);
     foreach ($objs as $obj) {
         $this->storage->cachePurge($obj);
     }
     $this->completeCount += count($ids);
     return end($ids);
 }
Example #10
0
 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;
 }
Example #11
0
 /**
  * Find pages in mainspace that have a prefix of the new namespace
  * so we know titles that will need migrating
  *
  * @param int $ns Namespace id (id for new namespace?)
  * @param string $name Prefix that is being made a namespace
  *
  * @return array
  */
 private function getConflicts($ns, $name)
 {
     $titleSql = "TRIM(LEADING {$this->db->addQuotes("{$name}:")} FROM page_title)";
     if ($ns == 0) {
         // An interwiki; try an alternate encoding with '-' for ':'
         $titleSql = $this->db->buildConcat(array($this->db->addQuotes("{$name}-"), $titleSql));
     }
     return iterator_to_array($this->db->select('page', array('id' => 'page_id', 'oldtitle' => 'page_title', 'namespace' => $this->db->addQuotes($ns) . ' + page_namespace', 'title' => $titleSql, 'oldnamespace' => 'page_namespace'), array('page_namespace' => array(0, 1), 'page_title' . $this->db->buildLike("{$name}:", $this->db->anyString())), __METHOD__));
 }
Example #12
0
    /**
     * @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;
    }
Example #13
0
 protected function doCollationUpdate()
 {
     global $wgCategoryCollation;
     if ($this->db->selectField('categorylinks', 'COUNT(*)', 'cl_collation != ' . $this->db->addQuotes($wgCategoryCollation), __METHOD__) == 0) {
         $this->output("...collations up-to-date.\n");
         return;
     }
     $task = new UpdateCollation();
     $task->execute();
 }
 protected function buildUpdateCondition(DatabaseBase $dbw)
 {
     $rcNew = $dbw->addQuotes(RC_NEW);
     $rcSrcNew = $dbw->addQuotes(RecentChange::SRC_NEW);
     $rcEdit = $dbw->addQuotes(RC_EDIT);
     $rcSrcEdit = $dbw->addQuotes(RecentChange::SRC_EDIT);
     $rcLog = $dbw->addQuotes(RC_LOG);
     $rcSrcLog = $dbw->addQuotes(RecentChange::SRC_LOG);
     $rcExternal = $dbw->addQuotes(RC_EXTERNAL);
     $rcSrcExternal = $dbw->addQuotes(RecentChange::SRC_EXTERNAL);
     return "rc_source = CASE\n\t\t\t\t\tWHEN rc_type = {$rcNew} THEN {$rcSrcNew}\n\t\t\t\t\tWHEN rc_type = {$rcEdit} THEN {$rcSrcEdit}\n\t\t\t\t\tWHEN rc_type = {$rcLog} THEN {$rcSrcLog}\n\t\t\t\t\tWHEN rc_type = {$rcExternal} THEN {$rcSrcExternal}\n\t\t\t\t\tELSE ''\n\t\t\t\tEND";
 }
Example #15
0
 public static function buildPostInExpr(\DatabaseBase $db, array $arr)
 {
     $range = '';
     foreach ($arr as $post) {
         if ($range) {
             $range .= ',';
         }
         $range .= $db->addQuotes($post->id->getBin());
     }
     return ' IN(' . $range . ')';
 }
 /**
  * @param array $array array to sanitize
  * @return array
  */
 protected function sqlSanitizeArray($array)
 {
     if ($array == null) {
         return null;
     }
     $resultArray = [];
     foreach ($array as $i => $v) {
         $resultArray[] = $this->databaseConnection->addQuotes($v);
     }
     return $resultArray;
 }
 /**
  * Update CategoryLinks collation
  */
 protected function doCollationUpdate()
 {
     global $wgCategoryCollation;
     if ($this->db->selectField('categorylinks', 'COUNT(*)', 'cl_collation != ' . $this->db->addQuotes($wgCategoryCollation), __METHOD__) == 0) {
         $this->output("...collations up-to-date.\n");
         return;
     }
     $this->output("Updating category collations...");
     $task = $this->maintenance->runChild('UpdateCollation');
     $task->execute();
     $this->output("...done.\n");
 }
 /**
  * @param DatabaseBase $dbw
  * @param string $table
  * @param string $column
  * @param string $wiki
  */
 function doDeletes($dbw, $table, $column, $wiki)
 {
     if (!$dbw->tableExists($table)) {
         $this->error("Maintenance script cannot be run on this wiki as there is no {$table} table", 1);
     }
     $this->output("{$table}:\n");
     $count = 0;
     do {
         $wikiQuoted = $dbw->addQuotes($wiki);
         $dbw->query("DELETE FROM {$table} WHERE {$column}={$wikiQuoted} LIMIT 500", __METHOD__);
         $affected = $dbw->affectedRows();
         $count += $affected;
         $this->output("{$count}\n");
         wfWaitForSlaves();
     } while ($affected === 500);
     $this->output("{$count} {$table} rows deleted\n");
 }
Example #19
0
 /**
  * Copy all rows from $srcTable to $dstTable
  */
 function sync($srcTable, $dstTable)
 {
     $batchSize = 1000;
     $minTs = $this->dbw->selectField($srcTable, 'MIN(log_timestamp)', false, __METHOD__);
     $minTsUnix = wfTimestamp(TS_UNIX, $minTs);
     $numRowsCopied = 0;
     while (true) {
         $maxTs = $this->dbw->selectField($srcTable, 'MAX(log_timestamp)', false, __METHOD__);
         $copyPos = $this->dbw->selectField($dstTable, 'MAX(log_timestamp)', false, __METHOD__);
         $maxTsUnix = wfTimestamp(TS_UNIX, $maxTs);
         $copyPosUnix = wfTimestamp(TS_UNIX, $copyPos);
         if ($copyPos === null) {
             $percent = 0;
         } else {
             $percent = ($copyPosUnix - $minTsUnix) / ($maxTsUnix - $minTsUnix) * 100;
         }
         printf("%s  %.2f%%\n", $copyPos, $percent);
         # Handle all entries with timestamp equal to $copyPos
         if ($copyPos !== null) {
             $numRowsCopied += $this->copyExactMatch($srcTable, $dstTable, $copyPos);
         }
         # Now copy a batch of rows
         if ($copyPos === null) {
             $conds = false;
         } else {
             $conds = array('log_timestamp > ' . $this->dbw->addQuotes($copyPos));
         }
         $srcRes = $this->dbw->select($srcTable, '*', $conds, __METHOD__, array('LIMIT' => $batchSize, 'ORDER BY' => 'log_timestamp'));
         if (!$srcRes->numRows()) {
             # All done
             break;
         }
         $batch = array();
         foreach ($srcRes as $srcRow) {
             $batch[] = (array) $srcRow;
         }
         $this->dbw->insert($dstTable, $batch, __METHOD__);
         $numRowsCopied += count($batch);
         wfWaitForSlaves();
     }
     echo "Copied {$numRowsCopied} rows\n";
 }
 public function updateRevision(DatabaseBase $dbw, $continue = null)
 {
     $rows = $dbw->select('flow_revision', array('rev_id', 'rev_user_id', 'rev_user_text', 'rev_mod_user_id', 'rev_mod_user_text', 'rev_edit_user_id', 'rev_edit_user_text'), array('rev_id > ' . $dbw->addQuotes($continue), $dbw->makeList(array('rev_user_id' => 0, 'rev_mod_user_id' => 0, 'rev_edit_user_id' => 0), LIST_OR)), __METHOD__, array('LIMIT' => $this->mBatchSize, 'ORDER BY' => 'rev_id'));
     $continue = null;
     foreach ($rows as $row) {
         $continue = $row->rev_id;
         $updates = array();
         if ($row->rev_user_id == 0) {
             $updates['rev_user_ip'] = $row->rev_user_text;
         }
         if ($row->rev_mod_user_id == 0) {
             $updates['rev_mod_user_ip'] = $row->rev_mod_user_text;
         }
         if ($row->rev_edit_user_id == 0) {
             $updates['rev_edit_user_ip'] = $row->rev_edit_user_text;
         }
         if ($updates) {
             $dbw->update('flow_revision', $updates, array('rev_id' => $row->rev_id), __METHOD__);
         }
     }
     return $continue;
 }
 /**
  * @param DatabaseBase $dbw
  * @param string $table
  * @param string $column
  * @param string $wiki
  */
 function doDeletes($dbw, $table, $column, $wiki)
 {
     if (!$dbw->tableExists($table)) {
         $this->error("Maintenance script cannot be run on this wiki as there is no {$table} table", 1);
     }
     $this->output("{$table}:\n");
     $count = 0;
     do {
         // https://bugzilla.wikimedia.org/show_bug.cgi?id=52868
         //$dbw->delete(
         //	$table,
         //	array( $column => $wiki ),
         //	__METHOD__,
         //	array( 'LIMIT' => 500 ),
         //);
         $wikiQuoted = $dbw->addQuotes($wiki);
         $dbw->query("DELETE FROM {$table} WHERE {$column}={$wikiQuoted} LIMIT 500", __METHOD__);
         $affected = $dbw->affectedRows();
         $count += $affected;
         $this->output("{$count}\n");
         wfWaitForSlaves();
     } while ($affected === 500);
     $this->output("{$count} {$table} rows deleted\n");
 }
 /**
  * Create some initial DB entries for important built-in properties. Having the DB contents predefined
  * allows us to safe DB calls when certain data is needed. At the same time, the entries in the DB
  * make sure that DB-based functions work as with all other properties.
  */
 protected function setupPredefinedProperties($verbose, DatabaseBase $db)
 {
     global $wgDBtype;
     $this->reportProgress("Setting up internal property indices ...\n", $verbose);
     // Check if we already have this structure
     $borderiw = $db->selectField(SMWSQLStore3::ID_TABLE, 'smw_iw', 'smw_id=' . $db->addQuotes(\SMWSql3SmwIds::FXD_PROP_BORDER_ID));
     if ($borderiw != SMW_SQL3_SMWBORDERIW) {
         $this->reportProgress("   ... allocating space for internal properties ...\n", $verbose);
         $this->store->smwIds->moveSMWPageID(\SMWSql3SmwIds::FXD_PROP_BORDER_ID);
         // make sure position 50 is empty
         $db->insert(SMWSQLStore3::ID_TABLE, array('smw_id' => \SMWSql3SmwIds::FXD_PROP_BORDER_ID, 'smw_title' => '', 'smw_namespace' => 0, 'smw_iw' => SMW_SQL3_SMWBORDERIW, 'smw_subobject' => '', 'smw_sortkey' => ''), 'SMW::setup');
         // put dummy "border element" on index 50
         $this->reportProgress('   ', $verbose);
         for ($i = 0; $i < \SMWSql3SmwIds::FXD_PROP_BORDER_ID; $i++) {
             // make way for built-in ids
             $this->store->smwIds->moveSMWPageID($i);
             $this->reportProgress('.', $verbose);
         }
         $this->reportProgress("   done.\n", $verbose);
     } else {
         $this->reportProgress("   ... space for internal properties already allocated.\n", $verbose);
     }
     // now write actual properties; do that each time, it is cheap enough and we can update sortkeys by current language
     $this->reportProgress("   ... writing entries for internal properties ...", $verbose);
     foreach (SMWSql3SmwIds::$special_ids as $prop => $id) {
         $p = new SMWDIProperty($prop);
         $db->replace(SMWSQLStore3::ID_TABLE, array('smw_id'), array('smw_id' => $id, 'smw_title' => $p->getKey(), 'smw_namespace' => SMW_NS_PROPERTY, 'smw_iw' => $this->store->smwIds->getPropertyInterwiki($p), 'smw_subobject' => '', 'smw_sortkey' => $p->getLabel()), 'SMW::setup');
     }
     $this->reportProgress(" done.\n", $verbose);
     if ($wgDBtype == 'postgres') {
         $sequenceIndex = SMWSQLStore3::ID_TABLE . '_smw_id_seq';
         $this->reportProgress(" ... updating {$sequenceIndex} sequence accordingly.\n", $verbose);
         $max = $db->selectField(SMWSQLStore3::ID_TABLE, 'max(smw_id)', array(), __METHOD__);
         $max += 1;
         $db->query("ALTER SEQUENCE {$sequenceIndex} RESTART WITH {$max}", __METHOD__);
     }
     $this->reportProgress("Internal properties initialized successfully.\n", $verbose);
 }
 /**
  * Update the query cache as needed
  *
  * @param DatabaseBase $dbw
  * @param int $days How many days user must be idle before he is considered inactive
  * @param int $window Maximum time range of new data to scan (in seconds)
  * @return int|bool UNIX timestamp the cache is now up-to-date as of (false on error)
  */
 protected static function doQueryCacheUpdate(DatabaseBase $dbw, $days, $window)
 {
     $lockKey = wfWikiID() . '-activeusers';
     if (!$dbw->lock($lockKey, __METHOD__, 1)) {
         return false;
         // exclusive update (avoids duplicate entries)
     }
     $now = time();
     $cTime = $dbw->selectField('querycache_info', 'qci_timestamp', array('qci_type' => 'activeusers'));
     $cTimeUnix = $cTime ? wfTimestamp(TS_UNIX, $cTime) : 1;
     // Pick the date range to fetch from. This is normally from the last
     // update to till the present time, but has a limited window for sanity.
     // If the window is limited, multiple runs are need to fully populate it.
     $sTimestamp = max($cTimeUnix, $now - $days * 86400);
     $eTimestamp = min($sTimestamp + $window, $now);
     // Get all the users active since the last update
     $res = $dbw->select(array('recentchanges'), array('rc_user_text', 'lastedittime' => 'MAX(rc_timestamp)'), array('rc_user > 0', 'rc_type != ' . $dbw->addQuotes(RC_EXTERNAL), 'rc_log_type IS NULL OR rc_log_type != ' . $dbw->addQuotes('newusers'), 'rc_timestamp >= ' . $dbw->addQuotes($dbw->timestamp($sTimestamp)), 'rc_timestamp <= ' . $dbw->addQuotes($dbw->timestamp($eTimestamp))), __METHOD__, array('GROUP BY' => array('rc_user_text'), 'ORDER BY' => 'NULL'));
     $names = array();
     foreach ($res as $row) {
         $names[$row->rc_user_text] = $row->lastedittime;
     }
     // Rotate out users that have not edited in too long (according to old data set)
     $dbw->delete('querycachetwo', array('qcc_type' => 'activeusers', 'qcc_value < ' . $dbw->addQuotes($now - $days * 86400)), __METHOD__);
     // Find which of the recently active users are already accounted for
     if (count($names)) {
         $res = $dbw->select('querycachetwo', array('user_name' => 'qcc_title'), array('qcc_type' => 'activeusers', 'qcc_namespace' => NS_USER, 'qcc_title' => array_keys($names)), __METHOD__);
         foreach ($res as $row) {
             unset($names[$row->user_name]);
         }
     }
     // Insert the users that need to be added to the list (which their last edit time
     if (count($names)) {
         $newRows = array();
         foreach ($names as $name => $lastEditTime) {
             $newRows[] = array('qcc_type' => 'activeusers', 'qcc_namespace' => NS_USER, 'qcc_title' => $name, 'qcc_value' => wfTimestamp(TS_UNIX, $lastEditTime), 'qcc_namespacetwo' => 0, 'qcc_titletwo' => '');
         }
         foreach (array_chunk($newRows, 500) as $rowBatch) {
             $dbw->insert('querycachetwo', $rowBatch, __METHOD__);
             if (!$dbw->trxLevel()) {
                 wfWaitForSlaves();
             }
         }
     }
     // Touch the data freshness timestamp
     $dbw->replace('querycache_info', array('qci_type'), array('qci_type' => 'activeusers', 'qci_timestamp' => $dbw->timestamp($eTimestamp)), __METHOD__);
     $dbw->unlock($lockKey, __METHOD__);
     return $eTimestamp;
 }
 /**
  * @param DatabaseBase $db
  * @param string $ip
  * @param string|bool $xfor
  * @return mixed array/false conditions
  */
 public static function getIpConds($db, $ip, $xfor = false)
 {
     $type = $xfor ? 'xff' : 'ip';
     // IPv4 CIDR, 16-32 bits
     $matches = array();
     if (preg_match('#^(\\d+\\.\\d+\\.\\d+\\.\\d+)/(\\d+)$#', $ip, $matches)) {
         if ($matches[2] < 16 || $matches[2] > 32) {
             return false;
             // invalid
         }
         list($start, $end) = IP::parseRange($ip);
         return array('cuc_' . $type . '_hex BETWEEN ' . $db->addQuotes($start) . ' AND ' . $db->addQuotes($end));
     } elseif (preg_match('#^\\w{1,4}:\\w{1,4}:\\w{1,4}:\\w{1,4}:\\w{1,4}:\\w{1,4}:\\w{1,4}:\\w{1,4}/(\\d+)$#', $ip, $matches)) {
         // IPv6 CIDR, 64-128 bits
         if ($matches[1] < 64 || $matches[1] > 128) {
             return false;
             // invalid
         }
         list($start, $end) = IP::parseRange($ip);
         return array('cuc_' . $type . '_hex BETWEEN ' . $db->addQuotes($start) . ' AND ' . $db->addQuotes($end));
     } elseif (preg_match('#^(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)$#', $ip)) {
         // 32 bit IPv4
         $ip_hex = IP::toHex($ip);
         return array('cuc_' . $type . '_hex' => $ip_hex);
     } elseif (preg_match('#^\\w{1,4}:\\w{1,4}:\\w{1,4}:\\w{1,4}:\\w{1,4}:\\w{1,4}:\\w{1,4}:\\w{1,4}$#', $ip)) {
         // 128 bit IPv6
         $ip_hex = IP::toHex($ip);
         return array('cuc_' . $type . '_hex' => $ip_hex);
     }
     // throw away this query, incomplete IP, these don't get through the entry point anyway
     return false;
     // invalid
 }
Example #25
0
 /**
  * @param string $s
  * @return string
  */
 public function addQuotes($s)
 {
     if ($s instanceof MssqlBlob) {
         return $s->fetch();
     } elseif ($s instanceof Blob) {
         // this shouldn't really ever be called, but it's here if needed
         // (and will quite possibly make the SQL error out)
         $blob = new MssqlBlob($s->fetch());
         return $blob->fetch();
     } else {
         if (is_bool($s)) {
             $s = $s ? 1 : 0;
         }
         return parent::addQuotes($s);
     }
 }
 protected function populateRevisionOrArchive(DatabaseBase $dbw, $table, $ns)
 {
     $prefix = $table === 'archive' ? 'ar' : 'rev';
     $model_column = "{$prefix}_content_model";
     $format_column = "{$prefix}_content_format";
     $key = "{$prefix}_id";
     if ($table === 'archive') {
         $selectTables = 'archive';
         $fields = array('ar_namespace', 'ar_title');
         $join_conds = array();
         $where = $ns === 'all' ? array() : array('ar_namespace' => $ns);
     } else {
         // revision
         $selectTables = array('revision', 'page');
         $fields = array('page_title', 'page_namespace');
         $join_conds = array('page' => array('INNER JOIN', 'rev_page=page_id'));
         $where = $ns === 'all' ? array() : array('page_namespace' => $ns);
     }
     $toSave = array();
     $lastId = 0;
     do {
         $rows = $dbw->select($selectTables, array_merge($fields, array($model_column, $format_column, $key)), array($model_column => null, "{$key} > " . $dbw->addQuotes($lastId)) + $where, __METHOD__, array('LIMIT' => $this->mBatchSize, 'ORDER BY' => "{$key} ASC"), $join_conds);
         $this->output("Fetched {$rows->numRows()} rows.\n");
         foreach ($rows as $row) {
             if ($table === 'archive') {
                 $title = Title::makeTitle($row->ar_namespace, $row->ar_title);
             } else {
                 $title = Title::newFromRow($row);
             }
             $lastId = $row->{$key};
             try {
                 $handler = ContentHandler::getForTitle($title);
             } catch (MWException $e) {
                 $this->error("Invalid content model for {$title}");
                 continue;
             }
             $defaultModel = $handler->getModelID();
             $defaultFormat = $handler->getDefaultFormat();
             $dbModel = $row->{$model_column};
             $dbFormat = $row->{$format_column};
             $id = $row->{$key};
             if ($dbModel === null && $dbFormat === null) {
                 // Set the defaults
                 $toSave[$defaultModel][] = $row->{$key};
             } else {
                 // $dbModel === null, $dbFormat set.
                 if ($dbFormat === $defaultFormat) {
                     $toSave[$defaultModel][] = $row->{$key};
                 } else {
                     // non-default format, just update now
                     $this->output("Updating model to match format for {$table} {$id} of {$title}... ");
                     $dbw->update($table, array($model_column => $defaultModel), array($key => $id), __METHOD__);
                     wfWaitForSlaves();
                     $this->output("done.\n");
                     continue;
                 }
             }
             if (count($toSave[$defaultModel]) >= $this->mBatchSize) {
                 $this->updateRevisionOrArchiveRows($dbw, $toSave[$defaultModel], $defaultModel, $table);
                 unset($toSave[$defaultModel]);
             }
         }
     } while ($rows->numRows() >= $this->mBatchSize);
     foreach ($toSave as $model => $ids) {
         $this->updateRevisionOrArchiveRows($dbw, $ids, $model, $table);
     }
 }
 /**
  * Change the usage count for the property of the given ID by the given
  * value. The method does nothing if the count is 0.
  *
  * @since 1.8
  * @param integer $propertyId
  * @param integer $value
  * @param DatabaseBase $dbw used for writing
  * @return boolean success indicator
  */
 protected function addToPropertyUsageCount($propertyId, $value, DatabaseBase $dbw)
 {
     if ($value == 0) {
         return true;
     }
     return $dbw->update(SMWSQLStore3::PROPERTY_STATISTICS_TABLE, array('usage_count = usage_count + ' . $dbw->addQuotes($value)), array('p_id' => $propertyId), __METHOD__);
 }
Example #28
0
 function addQuotes($s)
 {
     if ($s instanceof Blob) {
         return "'" . $s->fetch($s) . "'";
     } else {
         return parent::addQuotes($s);
     }
 }
Example #29
0
 /**
  * SQL clause to skip forbidden log types for this user
  *
  * @param DatabaseBase $db
  * @param string $audience Public/user
  * @param User $user User to check, or null to use $wgUser
  * @return string|bool String on success, false on failure.
  */
 public static function getExcludeClause($db, $audience = 'public', User $user = null)
 {
     global $wgLogRestrictions;
     if ($audience != 'public' && $user === null) {
         global $wgUser;
         $user = $wgUser;
     }
     // Reset the array, clears extra "where" clauses when $par is used
     $hiddenLogs = array();
     // Don't show private logs to unprivileged users
     foreach ($wgLogRestrictions as $logType => $right) {
         if ($audience == 'public' || !$user->isAllowed($right)) {
             $hiddenLogs[] = $logType;
         }
     }
     if (count($hiddenLogs) == 1) {
         return 'log_type != ' . $db->addQuotes($hiddenLogs[0]);
     } elseif ($hiddenLogs) {
         return 'log_type NOT IN (' . $db->makeList($hiddenLogs) . ')';
     }
     return false;
 }
Example #30
0
 /**
  * Return an SQL expression selecting rows which sort above the given row,
  * assuming an ordering of cl_from, cl_to
  * @param stdClass $row
  * @param DatabaseBase $dbw
  * @return string
  */
 function getBatchCondition($row, $dbw)
 {
     $fields = array('cl_from', 'cl_to');
     $first = true;
     $cond = false;
     $prefix = false;
     foreach ($fields as $field) {
         $encValue = $dbw->addQuotes($row->{$field});
         $inequality = "{$field} > {$encValue}";
         $equality = "{$field} = {$encValue}";
         if ($first) {
             $cond = $inequality;
             $prefix = $equality;
             $first = false;
         } else {
             $cond .= " OR ({$prefix} AND {$inequality})";
             $prefix .= " AND {$equality}";
         }
     }
     return $cond;
 }