Example #1
0
	/**
	 * @return Collation
	 */
	static function singleton() {
		if ( !self::$instance ) {
			global $wgCategoryCollation;
			self::$instance = self::factory( $wgCategoryCollation );
		}
		return self::$instance;
	}
Example #2
0
 function doCategoryQuery()
 {
     $dbr = wfGetDB(DB_SLAVE, 'category');
     $this->nextPage = array('page' => null, 'subcat' => null, 'file' => null);
     $this->flip = array('page' => false, 'subcat' => false, 'file' => false);
     foreach (array('page', 'subcat', 'file') as $type) {
         # Get the sortkeys for start/end, if applicable.  Note that if
         # the collation in the database differs from the one
         # set in $wgCategoryCollation, pagination might go totally haywire.
         $extraConds = array('cl_type' => $type);
         if ($this->from[$type] !== null) {
             $extraConds[] = 'cl_sortkey >= ' . $dbr->addQuotes($this->collation->getSortKey($this->from[$type]));
         } elseif ($this->until[$type] !== null) {
             $extraConds[] = 'cl_sortkey < ' . $dbr->addQuotes($this->collation->getSortKey($this->until[$type]));
             $this->flip[$type] = true;
         }
         /* Wikia change begin - @author: TomekO */
         /* Changed by MoLi (1.19 ugrade) */
         wfRunHooks('CategoryViewer::beforeCategoryData', array(&$extraConds));
         /* Wikia change end */
         $res = $dbr->select(array('page', 'categorylinks', 'category'), array('page_id', 'page_title', 'page_namespace', 'page_len', 'page_is_redirect', 'cl_sortkey', 'cat_id', 'cat_title', 'cat_subcats', 'cat_pages', 'cat_files', 'cl_sortkey_prefix', 'cl_collation'), array_merge(array('cl_to' => $this->title->getDBkey()), $extraConds), __METHOD__, array('USE INDEX' => array('categorylinks' => 'cl_sortkey'), 'LIMIT' => is_integer($this->limit) ? $this->limit + 1 : null, 'ORDER BY' => $this->flip[$type] ? 'cl_sortkey DESC' : 'cl_sortkey'), array('categorylinks' => array('INNER JOIN', 'cl_from = page_id'), 'category' => array('LEFT JOIN', 'cat_title = page_title AND page_namespace = ' . NS_CATEGORY)));
         $count = 0;
         foreach ($res as $row) {
             $title = Title::newFromRow($row);
             if ($row->cl_collation === '') {
                 // Hack to make sure that while updating from 1.16 schema
                 // and db is inconsistent, that the sky doesn't fall.
                 // See r83544. Could perhaps be removed in a couple decades...
                 $humanSortkey = $row->cl_sortkey;
             } else {
                 $humanSortkey = $title->getCategorySortkey($row->cl_sortkey_prefix);
             }
             if (++$count > $this->limit && is_integer($this->limit)) {
                 # We've reached the one extra which shows that there
                 # are additional pages to be had. Stop here...
                 $this->nextPage[$type] = $humanSortkey;
                 break;
             }
             if ($title->getNamespace() == NS_CATEGORY) {
                 $cat = Category::newFromRow($row, $title);
                 $this->addSubcategoryObject($cat, $humanSortkey, $row->page_len);
             } elseif ($title->getNamespace() == NS_FILE) {
                 $this->addImage($title, $humanSortkey, $row->page_len, $row->page_is_redirect);
             } else {
                 # <Wikia>
                 if (wfRunHooks("CategoryViewer::addPage", array(&$this, &$title, &$row, $humanSortkey))) {
                     $this->addPage($title, $humanSortkey, $row->page_len, $row->page_is_redirect);
                 }
                 # </Wikia>
             }
         }
     }
 }
Example #3
0
 function doCategoryQuery()
 {
     $dbr = wfGetDB(DB_REPLICA, 'category');
     $this->nextPage = ['page' => null, 'subcat' => null, 'file' => null];
     $this->prevPage = ['page' => null, 'subcat' => null, 'file' => null];
     $this->flip = ['page' => false, 'subcat' => false, 'file' => false];
     foreach (['page', 'subcat', 'file'] as $type) {
         # Get the sortkeys for start/end, if applicable.  Note that if
         # the collation in the database differs from the one
         # set in $wgCategoryCollation, pagination might go totally haywire.
         $extraConds = ['cl_type' => $type];
         if (isset($this->from[$type]) && $this->from[$type] !== null) {
             $extraConds[] = 'cl_sortkey >= ' . $dbr->addQuotes($this->collation->getSortKey($this->from[$type]));
         } elseif (isset($this->until[$type]) && $this->until[$type] !== null) {
             $extraConds[] = 'cl_sortkey < ' . $dbr->addQuotes($this->collation->getSortKey($this->until[$type]));
             $this->flip[$type] = true;
         }
         $res = $dbr->select(['page', 'categorylinks', 'category'], array_merge(LinkCache::getSelectFields(), ['page_namespace', 'page_title', 'cl_sortkey', 'cat_id', 'cat_title', 'cat_subcats', 'cat_pages', 'cat_files', 'cl_sortkey_prefix', 'cl_collation']), array_merge(['cl_to' => $this->title->getDBkey()], $extraConds), __METHOD__, ['USE INDEX' => ['categorylinks' => 'cl_sortkey'], 'LIMIT' => $this->limit + 1, 'ORDER BY' => $this->flip[$type] ? 'cl_sortkey DESC' : 'cl_sortkey'], ['categorylinks' => ['INNER JOIN', 'cl_from = page_id'], 'category' => ['LEFT JOIN', ['cat_title = page_title', 'page_namespace' => NS_CATEGORY]]]);
         Hooks::run('CategoryViewer::doCategoryQuery', [$type, $res]);
         $linkCache = MediaWikiServices::getInstance()->getLinkCache();
         $count = 0;
         foreach ($res as $row) {
             $title = Title::newFromRow($row);
             $linkCache->addGoodLinkObjFromRow($title, $row);
             if ($row->cl_collation === '') {
                 // Hack to make sure that while updating from 1.16 schema
                 // and db is inconsistent, that the sky doesn't fall.
                 // See r83544. Could perhaps be removed in a couple decades...
                 $humanSortkey = $row->cl_sortkey;
             } else {
                 $humanSortkey = $title->getCategorySortkey($row->cl_sortkey_prefix);
             }
             if (++$count > $this->limit) {
                 # We've reached the one extra which shows that there
                 # are additional pages to be had. Stop here...
                 $this->nextPage[$type] = $humanSortkey;
                 break;
             }
             if ($count == $this->limit) {
                 $this->prevPage[$type] = $humanSortkey;
             }
             if ($title->getNamespace() == NS_CATEGORY) {
                 $cat = Category::newFromRow($row, $title);
                 $this->addSubcategoryObject($cat, $humanSortkey, $row->page_len);
             } elseif ($title->getNamespace() == NS_FILE) {
                 $this->addImage($title, $humanSortkey, $row->page_len, $row->page_is_redirect);
             } else {
                 $this->addPage($title, $humanSortkey, $row->page_len, $row->page_is_redirect);
             }
         }
     }
 }
Example #4
0
 public function execute()
 {
     global $wgCategoryCollation, $wgMiserMode;
     $dbw = wfGetDB(DB_MASTER);
     $force = $this->getOption('force');
     $options = array('LIMIT' => self::BATCH_SIZE);
     if ($force) {
         $options['ORDER BY'] = 'cl_from, cl_to';
         $collationConds = array();
     } else {
         $collationConds = array(0 => 'cl_collation != ' . $dbw->addQuotes($wgCategoryCollation));
         if (!$wgMiserMode) {
             $count = $dbw->selectField('categorylinks', 'COUNT(*)', $collationConds, __METHOD__);
             if ($count == 0) {
                 $this->output("Collations up-to-date.\n");
                 return;
             }
             $this->output("Fixing collation for {$count} rows.\n");
         }
     }
     $count = 0;
     $row = false;
     $batchConds = array();
     do {
         $this->output('Processing next ' . self::BATCH_SIZE . ' rows... ');
         $res = $dbw->select(array('categorylinks', 'page'), array('cl_from', 'cl_to', 'cl_sortkey_prefix', 'cl_collation', 'cl_sortkey', 'page_namespace', 'page_title'), array_merge($collationConds, $batchConds, array('cl_from = page_id')), __METHOD__, $options);
         $dbw->begin();
         foreach ($res as $row) {
             $title = Title::newFromRow($row);
             if (!$row->cl_collation) {
                 # This is an old-style row, so the sortkey needs to be
                 # converted.
                 if ($row->cl_sortkey == $title->getText() || $row->cl_sortkey == $title->getPrefixedText()) {
                     $prefix = '';
                 } else {
                     # Custom sortkey, use it as a prefix
                     $prefix = $row->cl_sortkey;
                 }
             } else {
                 $prefix = $row->cl_sortkey_prefix;
             }
             # cl_type will be wrong for lots of pages if cl_collation is 0,
             # so let's update it while we're here.
             if ($title->getNamespace() == NS_CATEGORY) {
                 $type = 'subcat';
             } elseif ($title->getNamespace() == NS_FILE) {
                 $type = 'file';
             } else {
                 $type = 'page';
             }
             $dbw->update('categorylinks', array('cl_sortkey' => Collation::singleton()->getSortKey($title->getCategorySortkey($prefix)), 'cl_sortkey_prefix' => $prefix, 'cl_collation' => $wgCategoryCollation, 'cl_type' => $type, 'cl_timestamp = cl_timestamp'), array('cl_from' => $row->cl_from, 'cl_to' => $row->cl_to), __METHOD__);
         }
         $dbw->commit();
         if ($force && $row) {
             $encFrom = $dbw->addQuotes($row->cl_from);
             $encTo = $dbw->addQuotes($row->cl_to);
             $batchConds = array("(cl_from = {$encFrom} AND cl_to > {$encTo}) " . " OR cl_from > {$encFrom}");
         }
         $count += $res->numRows();
         $this->output("{$count} done.\n");
         $this->syncDBs();
     } while ($res->numRows() == self::BATCH_SIZE);
 }
Example #5
0
 /**
  * @param User $user
  * @param string $reason
  * @param bool $createRedirect
  * @return Status
  */
 public function move(User $user, $reason, $createRedirect)
 {
     global $wgCategoryCollation;
     Hooks::run('TitleMove', [$this->oldTitle, $this->newTitle, $user]);
     // If it is a file, move it first.
     // It is done before all other moving stuff is done because it's hard to revert.
     $dbw = wfGetDB(DB_MASTER);
     if ($this->oldTitle->getNamespace() == NS_FILE) {
         $file = wfLocalFile($this->oldTitle);
         $file->load(File::READ_LATEST);
         if ($file->exists()) {
             $status = $file->move($this->newTitle);
             if (!$status->isOK()) {
                 return $status;
             }
         }
         // Clear RepoGroup process cache
         RepoGroup::singleton()->clearCache($this->oldTitle);
         RepoGroup::singleton()->clearCache($this->newTitle);
         # clear false negative cache
     }
     $dbw->startAtomic(__METHOD__);
     Hooks::run('TitleMoveStarting', [$this->oldTitle, $this->newTitle, $user]);
     $pageid = $this->oldTitle->getArticleID(Title::GAID_FOR_UPDATE);
     $protected = $this->oldTitle->isProtected();
     // Do the actual move; if this fails, it will throw an MWException(!)
     $nullRevision = $this->moveToInternal($user, $this->newTitle, $reason, $createRedirect);
     // Refresh the sortkey for this row.  Be careful to avoid resetting
     // cl_timestamp, which may disturb time-based lists on some sites.
     // @todo This block should be killed, it's duplicating code
     // from LinksUpdate::getCategoryInsertions() and friends.
     $prefixes = $dbw->select('categorylinks', ['cl_sortkey_prefix', 'cl_to'], ['cl_from' => $pageid], __METHOD__);
     if ($this->newTitle->getNamespace() == NS_CATEGORY) {
         $type = 'subcat';
     } elseif ($this->newTitle->getNamespace() == NS_FILE) {
         $type = 'file';
     } else {
         $type = 'page';
     }
     foreach ($prefixes as $prefixRow) {
         $prefix = $prefixRow->cl_sortkey_prefix;
         $catTo = $prefixRow->cl_to;
         $dbw->update('categorylinks', ['cl_sortkey' => Collation::singleton()->getSortKey($this->newTitle->getCategorySortkey($prefix)), 'cl_collation' => $wgCategoryCollation, 'cl_type' => $type, 'cl_timestamp=cl_timestamp'], ['cl_from' => $pageid, 'cl_to' => $catTo], __METHOD__);
     }
     $redirid = $this->oldTitle->getArticleID();
     if ($protected) {
         # Protect the redirect title as the title used to be...
         $res = $dbw->select('page_restrictions', '*', ['pr_page' => $pageid], __METHOD__, 'FOR UPDATE');
         $rowsInsert = [];
         foreach ($res as $row) {
             $rowsInsert[] = ['pr_page' => $redirid, 'pr_type' => $row->pr_type, 'pr_level' => $row->pr_level, 'pr_cascade' => $row->pr_cascade, 'pr_user' => $row->pr_user, 'pr_expiry' => $row->pr_expiry];
         }
         $dbw->insert('page_restrictions', $rowsInsert, __METHOD__, ['IGNORE']);
         // Build comment for log
         $comment = wfMessage('prot_1movedto2', $this->oldTitle->getPrefixedText(), $this->newTitle->getPrefixedText())->inContentLanguage()->text();
         if ($reason) {
             $comment .= wfMessage('colon-separator')->inContentLanguage()->text() . $reason;
         }
         // reread inserted pr_ids for log relation
         $insertedPrIds = $dbw->select('page_restrictions', 'pr_id', ['pr_page' => $redirid], __METHOD__);
         $logRelationsValues = [];
         foreach ($insertedPrIds as $prid) {
             $logRelationsValues[] = $prid->pr_id;
         }
         // Update the protection log
         $logEntry = new ManualLogEntry('protect', 'move_prot');
         $logEntry->setTarget($this->newTitle);
         $logEntry->setComment($comment);
         $logEntry->setPerformer($user);
         $logEntry->setParameters(['4::oldtitle' => $this->oldTitle->getPrefixedText()]);
         $logEntry->setRelations(['pr_id' => $logRelationsValues]);
         $logId = $logEntry->insert();
         $logEntry->publish($logId);
     }
     // Update *_from_namespace fields as needed
     if ($this->oldTitle->getNamespace() != $this->newTitle->getNamespace()) {
         $dbw->update('pagelinks', ['pl_from_namespace' => $this->newTitle->getNamespace()], ['pl_from' => $pageid], __METHOD__);
         $dbw->update('templatelinks', ['tl_from_namespace' => $this->newTitle->getNamespace()], ['tl_from' => $pageid], __METHOD__);
         $dbw->update('imagelinks', ['il_from_namespace' => $this->newTitle->getNamespace()], ['il_from' => $pageid], __METHOD__);
     }
     # Update watchlists
     $oldtitle = $this->oldTitle->getDBkey();
     $newtitle = $this->newTitle->getDBkey();
     $oldsnamespace = MWNamespace::getSubject($this->oldTitle->getNamespace());
     $newsnamespace = MWNamespace::getSubject($this->newTitle->getNamespace());
     if ($oldsnamespace != $newsnamespace || $oldtitle != $newtitle) {
         $store = MediaWikiServices::getInstance()->getWatchedItemStore();
         $store->duplicateAllAssociatedEntries($this->oldTitle, $this->newTitle);
     }
     Hooks::run('TitleMoveCompleting', [$this->oldTitle, $this->newTitle, $user, $pageid, $redirid, $reason, $nullRevision]);
     $dbw->endAtomic(__METHOD__);
     $params = [&$this->oldTitle, &$this->newTitle, &$user, $pageid, $redirid, $reason, $nullRevision];
     // Keep each single hook handler atomic
     DeferredUpdates::addUpdate(new AtomicSectionUpdate($dbw, __METHOD__, function () use($params) {
         Hooks::run('TitleMoveComplete', $params);
     }));
     return Status::newGood();
 }
Example #6
0
File: form.php Project: cebe/chive
';
	var row = $('#' + idPrefix).closest("tr").prev();
	row.attr('id', 'columns_<?php 
    echo $column->COLUMN_NAME;
    ?>
');
	row.children('td:eq(1)').html('<?php 
    echo $column->COLUMN_NAME;
    ?>
');
	row.children('td:eq(2)').html(<?php 
    echo CJSON::encode($column->COLUMN_TYPE);
    ?>
);
	row.children('td:eq(3)').html('<?php 
    echo $column->COLLATION_NAME ? '<dfn class="collation" title="' . Collation::getDefinition($column->COLLATION_NAME) . '">' . $column->COLLATION_NAME . '</dfn>' : '';
    ?>
');
	row.children('td:eq(4)').html('<?php 
    echo Yii::t('core', $column->isNullable ? 'yes' : 'no');
    ?>
');
	row.children('td:eq(5)').html(<?php 
    echo !is_null($column->COLUMN_DEFAULT) ? CJSON::encode($column->COLUMN_DEFAULT) : ($column->isNullable ? CJSON::encode('<span class="null">NULL</span>') : '\'\'');
    ?>
);
	row.children('td:eq(6)').html('<?php 
    echo $column->EXTRA;
    ?>
');
	$('#' + idPrefix).parent().slideUp(500, function() {
Example #7
0
 /**
  * Move a title to a new location
  *
  * @param $nt Title the new title
  * @param $auth Bool indicates whether $wgUser's permissions
  *  should be checked
  * @param $reason String the reason for the move
  * @param $createRedirect Bool Whether to create a redirect from the old title to the new title.
  *  Ignored if the user doesn't have the suppressredirect right.
  * @return Mixed true on success, getUserPermissionsErrors()-like array on failure
  */
 public function moveTo(&$nt, $auth = true, $reason = '', $createRedirect = true)
 {
     global $wgUser;
     $err = $this->isValidMoveOperation($nt, $auth, $reason);
     if (is_array($err)) {
         // Auto-block user's IP if the account was "hard" blocked
         $wgUser->spreadAnyEditBlock();
         return $err;
     }
     // If it is a file, move it first. It is done before all other moving stuff is
     // done because it's hard to revert
     $dbw = wfGetDB(DB_MASTER);
     if ($this->getNamespace() == NS_FILE) {
         $file = wfLocalFile($this);
         if ($file->exists()) {
             $status = $file->move($nt);
             if (!$status->isOk()) {
                 return $status->getErrorsArray();
             }
         }
     }
     $dbw->begin();
     # If $file was a LocalFile, its transaction would have closed our own.
     $pageid = $this->getArticleID(self::GAID_FOR_UPDATE);
     $protected = $this->isProtected();
     $pageCountChange = ($createRedirect ? 1 : 0) - ($nt->exists() ? 1 : 0);
     // Do the actual move
     $err = $this->moveToInternal($nt, $reason, $createRedirect);
     if (is_array($err)) {
         # @todo FIXME: What about the File we have already moved?
         $dbw->rollback();
         return $err;
     }
     $redirid = $this->getArticleID();
     // Refresh the sortkey for this row.  Be careful to avoid resetting
     // cl_timestamp, which may disturb time-based lists on some sites.
     $prefixes = $dbw->select('categorylinks', array('cl_sortkey_prefix', 'cl_to'), array('cl_from' => $pageid), __METHOD__);
     foreach ($prefixes as $prefixRow) {
         $prefix = $prefixRow->cl_sortkey_prefix;
         $catTo = $prefixRow->cl_to;
         $dbw->update('categorylinks', array('cl_sortkey' => Collation::singleton()->getSortKey($nt->getCategorySortkey($prefix)), 'cl_timestamp=cl_timestamp'), array('cl_from' => $pageid, 'cl_to' => $catTo), __METHOD__);
     }
     if ($protected) {
         # Protect the redirect title as the title used to be...
         $dbw->insertSelect('page_restrictions', 'page_restrictions', array('pr_page' => $redirid, 'pr_type' => 'pr_type', 'pr_level' => 'pr_level', 'pr_cascade' => 'pr_cascade', 'pr_user' => 'pr_user', 'pr_expiry' => 'pr_expiry'), array('pr_page' => $pageid), __METHOD__, array('IGNORE'));
         # Update the protection log
         $log = new LogPage('protect');
         $comment = wfMsgForContent('prot_1movedto2', $this->getPrefixedText(), $nt->getPrefixedText());
         if ($reason) {
             $comment .= wfMsgForContent('colon-separator') . $reason;
         }
         // @todo FIXME: $params?
         $log->addEntry('move_prot', $nt, $comment, array($this->getPrefixedText()));
     }
     # Update watchlists
     $oldnamespace = $this->getNamespace() & ~1;
     $newnamespace = $nt->getNamespace() & ~1;
     $oldtitle = $this->getDBkey();
     $newtitle = $nt->getDBkey();
     if ($oldnamespace != $newnamespace || $oldtitle != $newtitle) {
         WatchedItem::duplicateEntries($this, $nt);
     }
     # Update search engine
     $u = new SearchUpdate($pageid, $nt->getPrefixedDBkey());
     $u->doUpdate();
     $u = new SearchUpdate($redirid, $this->getPrefixedDBkey(), '');
     $u->doUpdate();
     $dbw->commit();
     # Update site_stats
     if ($this->isContentPage() && !$nt->isContentPage()) {
         # No longer a content page
         # Not viewed, edited, removing
         $u = new SiteStatsUpdate(0, 1, -1, $pageCountChange);
     } elseif (!$this->isContentPage() && $nt->isContentPage()) {
         # Now a content page
         # Not viewed, edited, adding
         $u = new SiteStatsUpdate(0, 1, +1, $pageCountChange);
     } elseif ($pageCountChange) {
         # Redirect added
         $u = new SiteStatsUpdate(0, 0, 0, 1);
     } else {
         # Nothing special
         $u = false;
     }
     if ($u) {
         $u->doUpdate();
     }
     # Update message cache for interface messages
     if ($this->getNamespace() == NS_MEDIAWIKI) {
         # @bug 17860: old article can be deleted, if this the case,
         # delete it from message cache
         if ($this->getArticleID() === 0) {
             MessageCache::singleton()->replace($this->getDBkey(), false);
         } else {
             $oldarticle = new Article($this);
             MessageCache::singleton()->replace($this->getDBkey(), $oldarticle->getContent());
         }
     }
     if ($nt->getNamespace() == NS_MEDIAWIKI) {
         $newarticle = new Article($nt);
         MessageCache::singleton()->replace($nt->getDBkey(), $newarticle->getContent());
     }
     global $wgUser;
     wfRunHooks('TitleMoveComplete', array(&$this, &$nt, &$wgUser, $pageid, $redirid));
     return true;
 }
Example #8
0
 function __construct($title, $from = '', $until = '', $query = array())
 {
     global $wgCategoryPagingLimit;
     $this->title = $title;
     $this->from = $from;
     $this->until = $until;
     $this->limit = $wgCategoryPagingLimit;
     $this->cat = Category::newFromTitle($title);
     $this->query = $query;
     $this->collation = Collation::singleton();
     unset($this->query['title']);
 }
    }
    ?>
					</td>
					<td>
						<?php 
    echo $table->getRowCount();
    ?>
					</td>
					<td>
						<?php 
    echo $table->ENGINE;
    ?>
					</td>
					<td>
						<dfn title="<?php 
    echo Collation::getDefinition($table->TABLE_COLLATION);
    ?>
"><?php 
    echo $table->TABLE_COLLATION;
    ?>
</dfn>
					</td>
					<td style="text-align: right">
						<?php 
    echo Formatter::fileSize($table->DATA_LENGTH + $table->INDEX_LENGTH);
    ?>
					</td>
					<td style="text-align: right">
						<?php 
    echo Formatter::fileSize($table->DATA_FREE);
    ?>
Example #10
0
 /**
  * Update a schema.
  *
  * @todo(mburtscher): Renaming. Requires copying the whole schema.
  */
 public function actionUpdate()
 {
     $isSubmitted = false;
     $sql = null;
     $schema = $this->loadSchema();
     if (isset($_POST['Schema'])) {
         $schema->attributes = $_POST['Schema'];
         if ($sql = $schema->save()) {
             $isSubmitted = true;
         }
     }
     $collations = Collation::model()->findAll(array('order' => 'COLLATION_NAME', 'select' => 'COLLATION_NAME, CHARACTER_SET_NAME AS collationGroup'));
     $this->render('form', array('schema' => $schema, 'collations' => $collations, 'isSubmitted' => $isSubmitted, 'sql' => $sql));
 }
Example #11
0
 public function execute()
 {
     global $wgCategoryCollation;
     $dbw = $this->getDB(DB_MASTER);
     $dbr = $this->getDB(DB_SLAVE);
     $force = $this->getOption('force');
     $dryRun = $this->getOption('dry-run');
     $verboseStats = $this->getOption('verbose-stats');
     if ($this->hasOption('target-collation')) {
         $collationName = $this->getOption('target-collation');
         $collation = Collation::factory($collationName);
     } else {
         $collationName = $wgCategoryCollation;
         $collation = Collation::singleton();
     }
     // Collation sanity check: in some cases the constructor will work,
     // but this will raise an exception, breaking all category pages
     $collation->getFirstLetter('MediaWiki');
     // Locally at least, (my local is a rather old version of mysql)
     // mysql seems to filesort if there is both an equality
     // (but not for an inequality) condition on cl_collation in the
     // WHERE and it is also the first item in the ORDER BY.
     if ($this->hasOption('previous-collation')) {
         $orderBy = 'cl_to, cl_type, cl_from';
     } else {
         $orderBy = 'cl_collation, cl_to, cl_type, cl_from';
     }
     $options = ['LIMIT' => self::BATCH_SIZE, 'ORDER BY' => $orderBy, 'STRAIGHT_JOIN'];
     if ($force || $dryRun) {
         $collationConds = [];
     } else {
         if ($this->hasOption('previous-collation')) {
             $collationConds['cl_collation'] = $this->getOption('previous-collation');
         } else {
             $collationConds = [0 => 'cl_collation != ' . $dbw->addQuotes($collationName)];
         }
         $count = $dbr->estimateRowCount('categorylinks', '*', $collationConds, __METHOD__);
         // Improve estimate if feasible
         if ($count < 1000000) {
             $count = $dbr->selectField('categorylinks', 'COUNT(*)', $collationConds, __METHOD__);
         }
         if ($count == 0) {
             $this->output("Collations up-to-date.\n");
             return;
         }
         $this->output("Fixing collation for {$count} rows.\n");
         wfWaitForSlaves();
     }
     $count = 0;
     $batchCount = 0;
     $batchConds = [];
     do {
         $this->output("Selecting next " . self::BATCH_SIZE . " rows...");
         // cl_type must be selected as a number for proper paging because
         // enums suck.
         if ($dbw->getType() === 'mysql') {
             $clType = 'cl_type+0 AS "cl_type_numeric"';
         } else {
             $clType = 'cl_type';
         }
         $res = $dbw->select(['categorylinks', 'page'], ['cl_from', 'cl_to', 'cl_sortkey_prefix', 'cl_collation', 'cl_sortkey', $clType, 'page_namespace', 'page_title'], array_merge($collationConds, $batchConds, ['cl_from = page_id']), __METHOD__, $options);
         $this->output(" processing...");
         if (!$dryRun) {
             $this->beginTransaction($dbw, __METHOD__);
         }
         foreach ($res as $row) {
             $title = Title::newFromRow($row);
             if (!$row->cl_collation) {
                 # This is an old-style row, so the sortkey needs to be
                 # converted.
                 if ($row->cl_sortkey == $title->getText() || $row->cl_sortkey == $title->getPrefixedText()) {
                     $prefix = '';
                 } else {
                     # Custom sortkey, use it as a prefix
                     $prefix = $row->cl_sortkey;
                 }
             } else {
                 $prefix = $row->cl_sortkey_prefix;
             }
             # cl_type will be wrong for lots of pages if cl_collation is 0,
             # so let's update it while we're here.
             if ($title->getNamespace() == NS_CATEGORY) {
                 $type = 'subcat';
             } elseif ($title->getNamespace() == NS_FILE) {
                 $type = 'file';
             } else {
                 $type = 'page';
             }
             $newSortKey = $collation->getSortKey($title->getCategorySortkey($prefix));
             if ($verboseStats) {
                 $this->updateSortKeySizeHistogram($newSortKey);
             }
             if (!$dryRun) {
                 $dbw->update('categorylinks', ['cl_sortkey' => $newSortKey, 'cl_sortkey_prefix' => $prefix, 'cl_collation' => $collationName, 'cl_type' => $type, 'cl_timestamp = cl_timestamp'], ['cl_from' => $row->cl_from, 'cl_to' => $row->cl_to], __METHOD__);
             }
             if ($row) {
                 $batchConds = [$this->getBatchCondition($row, $dbw)];
             }
         }
         if (!$dryRun) {
             $this->commitTransaction($dbw, __METHOD__);
         }
         $count += $res->numRows();
         $this->output("{$count} done.\n");
         if (!$dryRun && ++$batchCount % self::SYNC_INTERVAL == 0) {
             $this->output("Waiting for slaves ... ");
             wfWaitForSlaves();
             $this->output("done\n");
         }
     } while ($res->numRows() == self::BATCH_SIZE);
     $this->output("{$count} rows processed\n");
     if ($verboseStats) {
         $this->output("\n");
         $this->showSortKeySizeHistogram();
     }
 }
Example #12
0
 public function getColumnDefinition()
 {
     if (DataType::check($this->DATA_TYPE, DataType::SUPPORTS_COLLATION)) {
         $collate = ' CHARACTER SET ' . Collation::getCharacterSet($this->COLLATION_NAME) . ' COLLATE ' . $this->COLLATION_NAME;
     } else {
         $collate = '';
     }
     if ($this->attribute) {
         if ($this->attribute == 'unsigned' && DataType::check($this->DATA_TYPE, DataType::SUPPORTS_UNSIGNED) || $this->attribute == 'unsigned zerofill' && DataType::check($this->DATA_TYPE, DataType::SUPPORTS_UNSIGNED_ZEROFILL) || $this->attribute == 'on update current_timestamp' && DataType::check($this->DATA_TYPE, DataType::SUPPORTS_ON_UPDATE_CURRENT_TIMESTAMP)) {
             $attribute = ' ' . $this->attribute;
         } else {
             $attribute = '';
         }
     } else {
         $attribute = '';
     }
     if (strlen($this->COLUMN_DEFAULT) > 0 && $this->EXTRA != 'auto_increment') {
         if ($this->DATA_TYPE == 'timestamp' && strtolower($this->COLUMN_DEFAULT) == 'current_timestamp') {
             $defaultValue = 'CURRENT_TIMESTAMP';
         } elseif ($this->DATA_TYPE == 'bit') {
             if (preg_match('/b\'[01]+\'/', $this->COLUMN_DEFAULT)) {
                 $defaultValue = $this->COLUMN_DEFAULT;
             } else {
                 $defaultValue = 'b' . self::$db->quoteValue($this->COLUMN_DEFAULT);
             }
         } else {
             $defaultValue = self::$db->quoteValue($this->COLUMN_DEFAULT);
         }
         $default = ' DEFAULT ' . $defaultValue;
     } else {
         if ($this->getIsNullable() && $this->EXTRA != 'auto_increment') {
             $default = ' DEFAULT NULL';
         } else {
             $default = '';
         }
     }
     return trim(self::$db->quoteColumnName($this->COLUMN_NAME) . ' ' . $this->getColumnType() . $attribute . $collate . ($this->getIsNullable() ? ' NULL' : ' NOT NULL') . $default . ($this->EXTRA == 'auto_increment' ? ' AUTO_INCREMENT' : '') . ($this->createPrimaryKey ? ' PRIMARY KEY' : '') . ($this->createUniqueKey ? ' UNIQUE KEY' : '') . (strlen($this->COLUMN_COMMENT) ? ' COMMENT ' . self::$db->quoteValue($this->COLUMN_COMMENT) : ''));
 }
Example #13
0
 public function actionUpdate()
 {
     $isSubmitted = false;
     $sql = false;
     $column = Column::model()->findByPk(array('TABLE_SCHEMA' => $this->schema, 'TABLE_NAME' => $this->table, 'COLUMN_NAME' => $this->column));
     if (isset($_POST['Column'])) {
         $column->attributes = $_POST['Column'];
         $sql = $column->save();
         if ($sql) {
             $isSubmitted = true;
         }
     }
     $collations = Collation::model()->findAll(array('order' => 'COLLATION_NAME', 'select' => 'COLLATION_NAME, CHARACTER_SET_NAME AS collationGroup'));
     CHtml::generateRandomIdPrefix();
     $data = array('column' => $column, 'collations' => $collations, 'isSubmitted' => $isSubmitted, 'sql' => $sql);
     $data['formBody'] = $this->renderPartial('formBody', $data, true);
     $this->render('form', $data);
 }
Example #14
0
    echo $charset['Description'];
    ?>
</th>
				</tr>
			</thead>
			<tbody>
				<?php 
    foreach ($charset['collations'] as $collation) {
        ?>
					<tr>
						<td><?php 
        echo $collation['Collation'];
        ?>
</td>
						<td><?php 
        echo Collation::getDefinition($collation['Collation'], false);
        ?>
</td>
					</tr>
				<?php 
    }
    ?>
			</tbody>
		</table>
	</div>
<?php 
}
?>

<script type="text/javascript">
breadCrumb.set([
 /**
  * @param ApiPageSet $resultPageSet
  * @return void
  */
 private function run($resultPageSet = null)
 {
     $params = $this->extractRequestParams();
     $categoryTitle = $this->getTitleOrPageId($params)->getTitle();
     if ($categoryTitle->getNamespace() != NS_CATEGORY) {
         $this->dieUsage('The category name you entered is not valid', 'invalidcategory');
     }
     $prop = array_flip($params['prop']);
     $fld_ids = isset($prop['ids']);
     $fld_title = isset($prop['title']);
     $fld_sortkey = isset($prop['sortkey']);
     $fld_sortkeyprefix = isset($prop['sortkeyprefix']);
     $fld_timestamp = isset($prop['timestamp']);
     $fld_type = isset($prop['type']);
     if (is_null($resultPageSet)) {
         $this->addFields(array('cl_from', 'cl_sortkey', 'cl_type', 'page_namespace', 'page_title'));
         $this->addFieldsIf('page_id', $fld_ids);
         $this->addFieldsIf('cl_sortkey_prefix', $fld_sortkeyprefix);
     } else {
         $this->addFields($resultPageSet->getPageTableFields());
         // will include page_ id, ns, title
         $this->addFields(array('cl_from', 'cl_sortkey', 'cl_type'));
     }
     $this->addFieldsIf('cl_timestamp', $fld_timestamp || $params['sort'] == 'timestamp');
     $this->addTables(array('page', 'categorylinks'));
     // must be in this order for 'USE INDEX'
     $this->addWhereFld('cl_to', $categoryTitle->getDBkey());
     $queryTypes = $params['type'];
     $contWhere = false;
     // Scanning large datasets for rare categories sucks, and I already told
     // how to have efficient subcategory access :-) ~~~~ (oh well, domas)
     $miser_ns = array();
     if ($this->getConfig()->get('MiserMode')) {
         $miser_ns = $params['namespace'];
     } else {
         $this->addWhereFld('page_namespace', $params['namespace']);
     }
     $dir = in_array($params['dir'], array('asc', 'ascending', 'newer')) ? 'newer' : 'older';
     if ($params['sort'] == 'timestamp') {
         $this->addTimestampWhereRange('cl_timestamp', $dir, $params['start'], $params['end']);
         // Include in ORDER BY for uniqueness
         $this->addWhereRange('cl_from', $dir, null, null);
         if (!is_null($params['continue'])) {
             $cont = explode('|', $params['continue']);
             $this->dieContinueUsageIf(count($cont) != 2);
             $op = $dir === 'newer' ? '>' : '<';
             $db = $this->getDB();
             $continueTimestamp = $db->addQuotes($db->timestamp($cont[0]));
             $continueFrom = (int) $cont[1];
             $this->dieContinueUsageIf($continueFrom != $cont[1]);
             $this->addWhere("cl_timestamp {$op} {$continueTimestamp} OR " . "(cl_timestamp = {$continueTimestamp} AND " . "cl_from {$op}= {$continueFrom})");
         }
         $this->addOption('USE INDEX', 'cl_timestamp');
     } else {
         if ($params['continue']) {
             $cont = explode('|', $params['continue'], 3);
             $this->dieContinueUsageIf(count($cont) != 3);
             // Remove the types to skip from $queryTypes
             $contTypeIndex = array_search($cont[0], $queryTypes);
             $queryTypes = array_slice($queryTypes, $contTypeIndex);
             // Add a WHERE clause for sortkey and from
             $this->dieContinueUsageIf(!$this->validateHexSortkey($cont[1]));
             // pack( "H*", $foo ) is used to convert hex back to binary
             $escSortkey = $this->getDB()->addQuotes(pack('H*', $cont[1]));
             $from = intval($cont[2]);
             $op = $dir == 'newer' ? '>' : '<';
             // $contWhere is used further down
             $contWhere = "cl_sortkey {$op} {$escSortkey} OR " . "(cl_sortkey = {$escSortkey} AND " . "cl_from {$op}= {$from})";
             // The below produces ORDER BY cl_sortkey, cl_from, possibly with DESC added to each of them
             $this->addWhereRange('cl_sortkey', $dir, null, null);
             $this->addWhereRange('cl_from', $dir, null, null);
         } else {
             if ($params['startsortkeyprefix'] !== null) {
                 $startsortkey = Collation::singleton()->getSortkey($params['startsortkeyprefix']);
             } elseif ($params['starthexsortkey'] !== null) {
                 if (!$this->validateHexSortkey($params['starthexsortkey'])) {
                     $this->dieUsage('The starthexsortkey provided is not valid', 'bad_starthexsortkey');
                 }
                 $startsortkey = pack('H*', $params['starthexsortkey']);
             } else {
                 if ($params['startsortkey'] !== null) {
                     $this->logFeatureUsage('list=categorymembers&cmstartsortkey');
                 }
                 $startsortkey = $params['startsortkey'];
             }
             if ($params['endsortkeyprefix'] !== null) {
                 $endsortkey = Collation::singleton()->getSortkey($params['endsortkeyprefix']);
             } elseif ($params['endhexsortkey'] !== null) {
                 if (!$this->validateHexSortkey($params['endhexsortkey'])) {
                     $this->dieUsage('The endhexsortkey provided is not valid', 'bad_endhexsortkey');
                 }
                 $endsortkey = pack('H*', $params['endhexsortkey']);
             } else {
                 if ($params['endsortkey'] !== null) {
                     $this->logFeatureUsage('list=categorymembers&cmendsortkey');
                 }
                 $endsortkey = $params['endsortkey'];
             }
             // The below produces ORDER BY cl_sortkey, cl_from, possibly with DESC added to each of them
             $this->addWhereRange('cl_sortkey', $dir, $startsortkey, $endsortkey);
             $this->addWhereRange('cl_from', $dir, null, null);
         }
         $this->addOption('USE INDEX', 'cl_sortkey');
     }
     $this->addWhere('cl_from=page_id');
     $limit = $params['limit'];
     $this->addOption('LIMIT', $limit + 1);
     if ($params['sort'] == 'sortkey') {
         // Run a separate SELECT query for each value of cl_type.
         // This is needed because cl_type is an enum, and MySQL has
         // inconsistencies between ORDER BY cl_type and
         // WHERE cl_type >= 'foo' making proper paging impossible
         // and unindexed.
         $rows = array();
         $first = true;
         foreach ($queryTypes as $type) {
             $extraConds = array('cl_type' => $type);
             if ($first && $contWhere) {
                 // Continuation condition. Only added to the
                 // first query, otherwise we'll skip things
                 $extraConds[] = $contWhere;
             }
             $res = $this->select(__METHOD__, array('where' => $extraConds));
             $rows = array_merge($rows, iterator_to_array($res));
             if (count($rows) >= $limit + 1) {
                 break;
             }
             $first = false;
         }
     } else {
         // Sorting by timestamp
         // No need to worry about per-type queries because we
         // aren't sorting or filtering by type anyway
         $res = $this->select(__METHOD__);
         $rows = iterator_to_array($res);
     }
     $result = $this->getResult();
     $count = 0;
     foreach ($rows as $row) {
         if (++$count > $limit) {
             // We've reached the one extra which shows that there are
             // additional pages to be had. Stop here...
             // @todo Security issue - if the user has no right to view next
             // title, it will still be shown
             if ($params['sort'] == 'timestamp') {
                 $this->setContinueEnumParameter('continue', "{$row->cl_timestamp}|{$row->cl_from}");
             } else {
                 $sortkey = bin2hex($row->cl_sortkey);
                 $this->setContinueEnumParameter('continue', "{$row->cl_type}|{$sortkey}|{$row->cl_from}");
             }
             break;
         }
         // Since domas won't tell anyone what he told long ago, apply
         // cmnamespace here. This means the query may return 0 actual
         // results, but on the other hand it could save returning 5000
         // useless results to the client. ~~~~
         if (count($miser_ns) && !in_array($row->page_namespace, $miser_ns)) {
             continue;
         }
         if (is_null($resultPageSet)) {
             $vals = array(ApiResult::META_TYPE => 'assoc');
             if ($fld_ids) {
                 $vals['pageid'] = intval($row->page_id);
             }
             if ($fld_title) {
                 $title = Title::makeTitle($row->page_namespace, $row->page_title);
                 ApiQueryBase::addTitleInfo($vals, $title);
             }
             if ($fld_sortkey) {
                 $vals['sortkey'] = bin2hex($row->cl_sortkey);
             }
             if ($fld_sortkeyprefix) {
                 $vals['sortkeyprefix'] = $row->cl_sortkey_prefix;
             }
             if ($fld_type) {
                 $vals['type'] = $row->cl_type;
             }
             if ($fld_timestamp) {
                 $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $row->cl_timestamp);
             }
             $fit = $result->addValue(array('query', $this->getModuleName()), null, $vals);
             if (!$fit) {
                 if ($params['sort'] == 'timestamp') {
                     $this->setContinueEnumParameter('continue', "{$row->cl_timestamp}|{$row->cl_from}");
                 } else {
                     $sortkey = bin2hex($row->cl_sortkey);
                     $this->setContinueEnumParameter('continue', "{$row->cl_type}|{$sortkey}|{$row->cl_from}");
                 }
                 break;
             }
         } else {
             $resultPageSet->processDbRow($row);
         }
     }
     if (is_null($resultPageSet)) {
         $result->addIndexedTagName(array('query', $this->getModuleName()), 'cm');
     }
 }
Example #16
0
File: list.php Project: cebe/chive
    ?>
" />
					</td>
					<td>
						<?php 
    echo CHtml::link(CHtml::encode($model->SCHEMA_NAME), Yii::app()->createUrl('schema/' . urlencode($model->SCHEMA_NAME)));
    ?>
					</td>
					<td class="count">
						<?php 
    echo $model->tableCount;
    ?>
					</td>
					<td>
						<dfn class="collation" title="<?php 
    echo Collation::getDefinition($model->DEFAULT_COLLATION_NAME);
    ?>
">
							<?php 
    echo $model->DEFAULT_COLLATION_NAME;
    ?>
						</dfn>
					</td>
					<td>
						<?php 
    echo Html::icon('privileges', 16, true, 'core.privileges');
    ?>
					</td>
					<td>
						<?php 
    if (Yii::app()->user->privileges->checkSchema($model->SCHEMA_NAME, 'ALTER')) {
 /**
  * Move a title to a new location
  *
  * @param Title $nt The new title
  * @param bool $auth Indicates whether $wgUser's permissions
  *  should be checked
  * @param string $reason The reason for the move
  * @param bool $createRedirect Whether to create a redirect from the old title to the new title.
  *  Ignored if the user doesn't have the suppressredirect right.
  * @return array|bool True on success, getUserPermissionsErrors()-like array on failure
  */
 public function moveTo(&$nt, $auth = true, $reason = '', $createRedirect = true)
 {
     global $wgUser;
     $err = $this->isValidMoveOperation($nt, $auth, $reason);
     if (is_array($err)) {
         // Auto-block user's IP if the account was "hard" blocked
         $wgUser->spreadAnyEditBlock();
         return $err;
     }
     // Check suppressredirect permission
     if ($auth && !$wgUser->isAllowed('suppressredirect')) {
         $createRedirect = true;
     }
     wfRunHooks('TitleMove', array($this, $nt, $wgUser));
     // If it is a file, move it first.
     // It is done before all other moving stuff is done because it's hard to revert.
     $dbw = wfGetDB(DB_MASTER);
     if ($this->getNamespace() == NS_FILE) {
         $file = wfLocalFile($this);
         if ($file->exists()) {
             $status = $file->move($nt);
             if (!$status->isOk()) {
                 return $status->getErrorsArray();
             }
         }
         // Clear RepoGroup process cache
         RepoGroup::singleton()->clearCache($this);
         RepoGroup::singleton()->clearCache($nt);
         # clear false negative cache
     }
     $dbw->begin(__METHOD__);
     # If $file was a LocalFile, its transaction would have closed our own.
     $pageid = $this->getArticleID(self::GAID_FOR_UPDATE);
     $protected = $this->isProtected();
     // Do the actual move
     $this->moveToInternal($nt, $reason, $createRedirect);
     // Refresh the sortkey for this row.  Be careful to avoid resetting
     // cl_timestamp, which may disturb time-based lists on some sites.
     $prefixes = $dbw->select('categorylinks', array('cl_sortkey_prefix', 'cl_to'), array('cl_from' => $pageid), __METHOD__);
     foreach ($prefixes as $prefixRow) {
         $prefix = $prefixRow->cl_sortkey_prefix;
         $catTo = $prefixRow->cl_to;
         $dbw->update('categorylinks', array('cl_sortkey' => Collation::singleton()->getSortKey($nt->getCategorySortkey($prefix)), 'cl_timestamp=cl_timestamp'), array('cl_from' => $pageid, 'cl_to' => $catTo), __METHOD__);
     }
     $redirid = $this->getArticleID();
     if ($protected) {
         # Protect the redirect title as the title used to be...
         $dbw->insertSelect('page_restrictions', 'page_restrictions', array('pr_page' => $redirid, 'pr_type' => 'pr_type', 'pr_level' => 'pr_level', 'pr_cascade' => 'pr_cascade', 'pr_user' => 'pr_user', 'pr_expiry' => 'pr_expiry'), array('pr_page' => $pageid), __METHOD__, array('IGNORE'));
         # Update the protection log
         $log = new LogPage('protect');
         $comment = wfMessage('prot_1movedto2', $this->getPrefixedText(), $nt->getPrefixedText())->inContentLanguage()->text();
         if ($reason) {
             $comment .= wfMessage('colon-separator')->inContentLanguage()->text() . $reason;
         }
         // @todo FIXME: $params?
         $logId = $log->addEntry('move_prot', $nt, $comment, array($this->getPrefixedText()), $wgUser);
         // reread inserted pr_ids for log relation
         $insertedPrIds = $dbw->select('page_restrictions', 'pr_id', array('pr_page' => $redirid), __METHOD__);
         $logRelationsValues = array();
         foreach ($insertedPrIds as $prid) {
             $logRelationsValues[] = $prid->pr_id;
         }
         $log->addRelations('pr_id', $logRelationsValues, $logId);
     }
     // Update *_from_namespace fields as needed
     if ($this->getNamespace() != $nt->getNamespace()) {
         $dbw->update('pagelinks', array('pl_from_namespace' => $nt->getNamespace()), array('pl_from' => $pageid), __METHOD__);
         $dbw->update('templatelinks', array('tl_from_namespace' => $nt->getNamespace()), array('tl_from' => $pageid), __METHOD__);
         $dbw->update('imagelinks', array('il_from_namespace' => $nt->getNamespace()), array('il_from' => $pageid), __METHOD__);
     }
     # Update watchlists
     $oldtitle = $this->getDBkey();
     $newtitle = $nt->getDBkey();
     $oldsnamespace = MWNamespace::getSubject($this->getNamespace());
     $newsnamespace = MWNamespace::getSubject($nt->getNamespace());
     if ($oldsnamespace != $newsnamespace || $oldtitle != $newtitle) {
         WatchedItem::duplicateEntries($this, $nt);
     }
     $dbw->commit(__METHOD__);
     wfRunHooks('TitleMoveComplete', array(&$this, &$nt, &$wgUser, $pageid, $redirid, $reason));
     return true;
 }
Example #18
0
					<td>
						<?php 
    echo $column->COLUMN_NAME;
    ?>
					</td>
					<td>
						<?php 
    echo $column->COLUMN_TYPE;
    ?>
					</td>
					<td>
						<?php 
    if (!is_null($column->COLLATION_NAME)) {
        ?>
							<dfn class="collation" title="<?php 
        echo Collation::getDefinition($column->COLLATION_NAME);
        ?>
">
								<?php 
        echo $column->COLLATION_NAME;
        ?>
							</dfn>
						<?php 
    }
    ?>
					</td>
					<td>
						<?php 
    echo Yii::t('core', strtolower($column->IS_NULLABLE));
    ?>
					</td>
Example #19
0
File: Table.php Project: cebe/chive
 /**
  * Returns the query string for all options which need to be saved.
  *
  * @return	string
  */
 private function getSaveDefinition()
 {
     $sql = '';
     $comma = '';
     if ($this->TABLE_NAME !== @$this->originalAttributes['TABLE_NAME'] && !$this->getIsNewRecord()) {
         //@todo(mburtscher): Privileges are not copied automatically!!!
         $sql .= "\n\t" . 'RENAME ' . self::$db->quoteTableName($this->TABLE_NAME);
         $comma = ',';
     }
     if ($this->TABLE_COLLATION !== @$this->originalAttributes['TABLE_COLLATION']) {
         $sql .= $comma . "\n\t" . 'CHARACTER SET ' . Collation::getCharacterSet($this->TABLE_COLLATION) . ' COLLATE ' . $this->TABLE_COLLATION;
         $comma = ',';
     }
     if ($this->comment !== @$this->originalAttributes['comment']) {
         $sql .= $comma . "\n\t" . 'COMMENT ' . self::$db->quoteValue($this->comment);
         $comma = ',';
     }
     if ($this->ENGINE !== @$this->originalAttributes['ENGINE']) {
         $sql .= $comma . "\n\t" . 'ENGINE ' . $this->ENGINE;
         $comma = ',';
     }
     if ($this->optionChecksum !== $this->originalOptionChecksum) {
         $sql .= $comma . "\n\t" . 'CHECKSUM ' . $this->optionChecksum;
         $comma = ',';
     }
     if ($this->optionPackKeys !== $this->originalOptionPackKeys) {
         $sql .= $comma . "\n\t" . 'PACK_KEYS ' . $this->optionPackKeys;
         $comma = ',';
     }
     if ($this->optionDelayKeyWrite !== $this->originalOptionDelayKeyWrite) {
         $sql .= $comma . "\n\t" . 'DELAY_KEY_WRITE ' . $this->optionDelayKeyWrite;
     }
     return $sql;
 }
Example #20
0
	public function execute() {
		global $wgCategoryCollation;

		$dbw = $this->getDB( DB_MASTER );
		$force = $this->getOption( 'force' );
		$dryRun = $this->getOption( 'dry-run' );
		$verboseStats = $this->getOption( 'verbose-stats' );
		if ( $this->hasOption( 'target-collation' ) ) {
			$collationName = $this->getOption( 'target-collation' );
			$collation = Collation::factory( $collationName );
		} else {
			$collationName = $wgCategoryCollation;
			$collation = Collation::singleton();
		}

		// Collation sanity check: in some cases the constructor will work,
		// but this will raise an exception, breaking all category pages
		$collation->getFirstLetter( 'MediaWiki' );

		$options = array(
			'LIMIT' => self::BATCH_SIZE,
			'ORDER BY' => 'cl_to, cl_type, cl_from',
			'STRAIGHT_JOIN',
		);

		if ( $force || $dryRun ) {
			$collationConds = array();
		} else {
			if ( $this->hasOption( 'previous-collation' ) ) {
				$collationConds['cl_collation'] = $this->getOption( 'previous-collation' );
			} else {
				$collationConds = array( 0 =>
					'cl_collation != ' . $dbw->addQuotes( $collationName )
				);
			}

			$count = $dbw->estimateRowCount(
				'categorylinks',
				'*',
				$collationConds,
				__METHOD__
			);
			// Improve estimate if feasible
			if ( $count < 1000000 ) {
				$count = $dbw->selectField(
					'categorylinks',
					'COUNT(*)',
					$collationConds,
					__METHOD__
				);
			}
			if ( $count == 0 ) {
				$this->output( "Collations up-to-date.\n" );
				return;
			}
			$this->output( "Fixing collation for $count rows.\n" );
		}

		$count = 0;
		$batchCount = 0;
		$batchConds = array();
		do {
			$this->output( "Selecting next " . self::BATCH_SIZE . " rows..." );
			$res = $dbw->select(
				array( 'categorylinks', 'page' ),
				array( 'cl_from', 'cl_to', 'cl_sortkey_prefix', 'cl_collation',
					'cl_sortkey', 'cl_type', 'page_namespace', 'page_title'
				),
				array_merge( $collationConds, $batchConds, array( 'cl_from = page_id' ) ),
				__METHOD__,
				$options
			);
			$this->output( " processing..." );

			if ( !$dryRun ) {
				$dbw->begin( __METHOD__ );
			}
			foreach ( $res as $row ) {
				$title = Title::newFromRow( $row );
				if ( !$row->cl_collation ) {
					# This is an old-style row, so the sortkey needs to be
					# converted.
					if ( $row->cl_sortkey == $title->getText()
						|| $row->cl_sortkey == $title->getPrefixedText() ) {
						$prefix = '';
					} else {
						# Custom sortkey, use it as a prefix
						$prefix = $row->cl_sortkey;
					}
				} else {
					$prefix = $row->cl_sortkey_prefix;
				}
				# cl_type will be wrong for lots of pages if cl_collation is 0,
				# so let's update it while we're here.
				if ( $title->getNamespace() == NS_CATEGORY ) {
					$type = 'subcat';
				} elseif ( $title->getNamespace() == NS_FILE ) {
					$type = 'file';
				} else {
					$type = 'page';
				}
				$newSortKey = $collation->getSortKey(
					$title->getCategorySortkey( $prefix ) );
				if ( $verboseStats ) {
					$this->updateSortKeySizeHistogram( $newSortKey );
				}

				if ( !$dryRun ) {
					$dbw->update(
						'categorylinks',
						array(
							'cl_sortkey' => $newSortKey,
							'cl_sortkey_prefix' => $prefix,
							'cl_collation' => $collationName,
							'cl_type' => $type,
							'cl_timestamp = cl_timestamp',
						),
						array( 'cl_from' => $row->cl_from, 'cl_to' => $row->cl_to ),
						__METHOD__
					);
				}
			}
			if ( !$dryRun ) {
				$dbw->commit( __METHOD__ );
			}

			if ( $row ) {
				$batchConds = array( $this->getBatchCondition( $row ) );
			}

			$count += $res->numRows();
			$this->output( "$count done.\n" );

			if ( !$dryRun && ++$batchCount % self::SYNC_INTERVAL == 0 ) {
				$this->output( "Waiting for slaves ... " );
				wfWaitForSlaves();
				$this->output( "done\n" );
			}
		} while ( $res->numRows() == self::BATCH_SIZE );

		$this->output( "$count rows processed\n" );

		if ( $verboseStats ) {
			$this->output( "\n" );
			$this->showSortKeySizeHistogram();
		}
	}
Example #21
0
 /**
  * Updates a table.
  */
 public function actionUpdate()
 {
     $this->layout = false;
     $isSubmitted = false;
     $sql = false;
     $table = Table::model()->findByPk(array('TABLE_SCHEMA' => $this->schema, 'TABLE_NAME' => $this->table));
     if (isset($_POST['Table'])) {
         $table->attributes = $_POST['Table'];
         $sql = $table->save();
         if ($sql) {
             $isSubmitted = true;
         }
     }
     $collations = Collation::model()->findAll(array('order' => 'COLLATION_NAME', 'select' => 'COLLATION_NAME, CHARACTER_SET_NAME AS collationGroup'));
     CHtml::generateRandomIdPrefix();
     $this->render('form', array('table' => $table, 'collations' => $collations, 'storageEngines' => StorageEngine::getSupportedEngines(), 'isSubmitted' => $isSubmitted, 'sql' => $sql));
 }
Example #22
0
 /**
  * @param User $user
  * @param string $reason
  * @param bool $createRedirect
  * @return Status
  */
 public function move(User $user, $reason, $createRedirect)
 {
     global $wgCategoryCollation;
     Hooks::run('TitleMove', array($this->oldTitle, $this->newTitle, $user));
     // If it is a file, move it first.
     // It is done before all other moving stuff is done because it's hard to revert.
     $dbw = wfGetDB(DB_MASTER);
     if ($this->oldTitle->getNamespace() == NS_FILE) {
         $file = wfLocalFile($this->oldTitle);
         $file->load(File::READ_LATEST);
         if ($file->exists()) {
             $status = $file->move($this->newTitle);
             if (!$status->isOk()) {
                 return $status;
             }
         }
         // Clear RepoGroup process cache
         RepoGroup::singleton()->clearCache($this->oldTitle);
         RepoGroup::singleton()->clearCache($this->newTitle);
         # clear false negative cache
     }
     $dbw->begin(__METHOD__);
     # If $file was a LocalFile, its transaction would have closed our own.
     $pageid = $this->oldTitle->getArticleID(Title::GAID_FOR_UPDATE);
     $protected = $this->oldTitle->isProtected();
     // Do the actual move
     $this->moveToInternal($user, $this->newTitle, $reason, $createRedirect);
     // Refresh the sortkey for this row.  Be careful to avoid resetting
     // cl_timestamp, which may disturb time-based lists on some sites.
     // @todo This block should be killed, it's duplicating code
     // from LinksUpdate::getCategoryInsertions() and friends.
     $prefixes = $dbw->select('categorylinks', array('cl_sortkey_prefix', 'cl_to'), array('cl_from' => $pageid), __METHOD__);
     if ($this->newTitle->getNamespace() == NS_CATEGORY) {
         $type = 'subcat';
     } elseif ($this->newTitle->getNamespace() == NS_FILE) {
         $type = 'file';
     } else {
         $type = 'page';
     }
     foreach ($prefixes as $prefixRow) {
         $prefix = $prefixRow->cl_sortkey_prefix;
         $catTo = $prefixRow->cl_to;
         $dbw->update('categorylinks', array('cl_sortkey' => Collation::singleton()->getSortKey($this->newTitle->getCategorySortkey($prefix)), 'cl_collation' => $wgCategoryCollation, 'cl_type' => $type, 'cl_timestamp=cl_timestamp'), array('cl_from' => $pageid, 'cl_to' => $catTo), __METHOD__);
     }
     $redirid = $this->oldTitle->getArticleID();
     if ($protected) {
         # Protect the redirect title as the title used to be...
         $dbw->insertSelect('page_restrictions', 'page_restrictions', array('pr_page' => $redirid, 'pr_type' => 'pr_type', 'pr_level' => 'pr_level', 'pr_cascade' => 'pr_cascade', 'pr_user' => 'pr_user', 'pr_expiry' => 'pr_expiry'), array('pr_page' => $pageid), __METHOD__, array('IGNORE'));
         // Build comment for log
         $comment = wfMessage('prot_1movedto2', $this->oldTitle->getPrefixedText(), $this->newTitle->getPrefixedText())->inContentLanguage()->text();
         if ($reason) {
             $comment .= wfMessage('colon-separator')->inContentLanguage()->text() . $reason;
         }
         // reread inserted pr_ids for log relation
         $insertedPrIds = $dbw->select('page_restrictions', 'pr_id', array('pr_page' => $redirid), __METHOD__);
         $logRelationsValues = array();
         foreach ($insertedPrIds as $prid) {
             $logRelationsValues[] = $prid->pr_id;
         }
         // Update the protection log
         $logEntry = new ManualLogEntry('protect', 'move_prot');
         $logEntry->setTarget($this->newTitle);
         $logEntry->setComment($comment);
         $logEntry->setPerformer($user);
         $logEntry->setParameters(array('4::oldtitle' => $this->oldTitle->getPrefixedText()));
         $logEntry->setRelations(array('pr_id' => $logRelationsValues));
         $logId = $logEntry->insert();
         $logEntry->publish($logId);
     }
     // Update *_from_namespace fields as needed
     if ($this->oldTitle->getNamespace() != $this->newTitle->getNamespace()) {
         $dbw->update('pagelinks', array('pl_from_namespace' => $this->newTitle->getNamespace()), array('pl_from' => $pageid), __METHOD__);
         $dbw->update('templatelinks', array('tl_from_namespace' => $this->newTitle->getNamespace()), array('tl_from' => $pageid), __METHOD__);
         $dbw->update('imagelinks', array('il_from_namespace' => $this->newTitle->getNamespace()), array('il_from' => $pageid), __METHOD__);
     }
     # Update watchlists
     $oldtitle = $this->oldTitle->getDBkey();
     $newtitle = $this->newTitle->getDBkey();
     $oldsnamespace = MWNamespace::getSubject($this->oldTitle->getNamespace());
     $newsnamespace = MWNamespace::getSubject($this->newTitle->getNamespace());
     if ($oldsnamespace != $newsnamespace || $oldtitle != $newtitle) {
         WatchedItem::duplicateEntries($this->oldTitle, $this->newTitle);
     }
     $dbw->commit(__METHOD__);
     Hooks::run('TitleMoveComplete', array(&$this->oldTitle, &$this->newTitle, &$user, $pageid, $redirid, $reason));
     return Status::newGood();
 }
Example #23
0
 /**
  * Test correct first letter is fetched.
  *
  * @param $collation String Collation name (aka uca-en)
  * @param $string String String to get first letter of
  * @param $firstLetter String Expected first letter.
  *
  * @dataProvider firstLetterProvider
  */
 function testGetFirstLetter($collation, $string, $firstLetter)
 {
     $col = Collation::factory($collation);
     $this->assertEquals($firstLetter, $col->getFirstLetter($string));
 }
Example #24
0
 /**
  * Tests to get character set name from collation name.
  */
 public function testGetCharset()
 {
     // Get Charset for utf8_unicode_ci
     $this->assertEquals('utf8', Collation::getCharacterSet('utf8_unicode_ci'));
 }
Example #25
0
 /**
  * Get an array of category insertions
  *
  * @param array $existing Mapping existing category names to sort keys. If both
  * match a link in $this, the link will be omitted from the output
  *
  * @return array
  */
 private function getCategoryInsertions($existing = array())
 {
     global $wgContLang, $wgCategoryCollation;
     $diffs = array_diff_assoc($this->mCategories, $existing);
     $arr = array();
     foreach ($diffs as $name => $prefix) {
         $nt = Title::makeTitleSafe(NS_CATEGORY, $name);
         $wgContLang->findVariantLink($name, $nt, true);
         if ($this->mTitle->getNamespace() == NS_CATEGORY) {
             $type = 'subcat';
         } elseif ($this->mTitle->getNamespace() == NS_FILE) {
             $type = 'file';
         } else {
             $type = 'page';
         }
         # Treat custom sortkeys as a prefix, so that if multiple
         # things are forced to sort as '*' or something, they'll
         # sort properly in the category rather than in page_id
         # order or such.
         $sortkey = Collation::singleton()->getSortKey($this->mTitle->getCategorySortkey($prefix));
         $arr[] = array('cl_from' => $this->mId, 'cl_to' => $name, 'cl_sortkey' => $sortkey, 'cl_timestamp' => $this->mDb->timestamp(), 'cl_sortkey_prefix' => $prefix, 'cl_collation' => $wgCategoryCollation, 'cl_type' => $type);
     }
     return $arr;
 }
Example #26
0
File: form.php Project: cebe/chive
<?php

CHtml::generateRandomIdPrefix();
if (!$schema->isNewRecord && $isSubmitted) {
    ?>
	<script type="text/javascript">
	var idPrefix = '<?php 
    echo CHtml::$idPrefix;
    ?>
';
	var row = $('#' + idPrefix).closest("tr").prev();
	row.find("td dfn.collation").html("<?php 
    echo $schema->DEFAULT_COLLATION_NAME;
    ?>
").attr("title", "<?php 
    echo Collation::getDefinition($schema->DEFAULT_COLLATION_NAME);
    ?>
");
	$('#' + idPrefix).parent().slideUp(500, function() {
		$('#' + idPrefix).parents("tr").remove();
	});
	Notification.add('success', '<?php 
    echo Yii::t('core', 'successEditSchema', array('{schema}' => $schema->SCHEMA_NAME));
    ?>
', null, <?php 
    echo CJSON::encode($sql);
    ?>
);
	</script>
<?php 
}