在 MediaWiki 扩展中创建新 SQL table 的正确方法
Proper way to create new SQL table in a MediaWiki Extension
我正在创建一个需要自己的 mediawiki 扩展 SQL table。在扩展中创建它的正确方法是什么,我是否需要像 OATHAuth extension 那样为我想要支持的每个数据库创建单独的 SQL 代码?这似乎不是正确的方法。
(OATHAuth 挂钩 onLoadExtensionSchemaUpdates
)
对于扩展的架构更改,LoadExtensionSchemaUpdates hook page 是正确的查找位置。
LoadExtensionSchemaUpdates 挂钩是
fired when MediaWiki is updated (php maintenance/update.php) to allow extensions to update the database
如果你看一下 ArticleFeedbackv5.sql file, that's basically what the sql file 应该看起来像
CREATE TABLE IF NOT EXISTS /*_*/aft_feedback (
-- id is no auto-increment, but a in PHP generated unique value
aft_id binary(32) NOT NULL PRIMARY KEY,
aft_page integer unsigned NOT NULL,
...
) /*$wgDBTableOptions*/;
-- sort indexes (central feedback page; lots of data - more details indexes for most popular actions)
CREATE INDEX /*i*/relevance ON /*_*/aft_feedback (aft_relevance_score, aft_id, aft_has_comment, aft_oversight, aft_archive, aft_hide);
CREATE INDEX /*i*/age ON /*_*/aft_feedback (aft_timestamp, aft_id, aft_has_comment, aft_oversight, aft_archive, aft_hide);
CREATE INDEX /*i*/helpful ON /*_*/aft_feedback (aft_net_helpful, aft_id, aft_has_comment, aft_oversight, aft_archive, aft_hide);
-- page-specific
CREATE INDEX /*i*/relevance_page ON /*_*/aft_feedback (aft_page, aft_relevance_score);
CREATE INDEX /*i*/age_page ON /*_*/aft_feedback (aft_page, aft_timestamp);
CREATE INDEX /*i*/helpful_page ON /*_*/aft_feedback (aft_page, aft_net_helpful);
-- index for archive-job
CREATE INDEX /*i*/archive_queue ON /*_*/aft_feedback (aft_archive, aft_archive_date);
-- index for mycontribs data
CREATE INDEX /*i*/contribs ON /*_*/aft_feedback (aft_user, aft_timestamp);
CREATE INDEX /*i*/contribs_anon ON /*_*/aft_feedback (aft_user, aft_user_text, aft_timestamp);
然后你在钩子文件hook中引用这个文件
public static function loadExtensionSchemaUpdates( $updater = null ) {
// that's for adding a table
$updater->addExtensionTable(
'aft_feedback',
dirname( __FILE__ ) . '/sql/ArticleFeedbackv5.sql' //that's the previous sql file
);
...
}
不要忘记在 extension.json
文件的挂钩部分添加挂钩。 table 将在您 运行 update.php
文件时创建。
关于您关于为每个数据库引擎创建文件的问题,我们不能为每个数据库引擎使用相同的文件,因为查询可能存在一些差异。看看
如果您还没有,请查看 hook file。
protected function execute() {
switch ( $this->updater->getDB()->getType() ) {
case 'mysql':
case 'sqlite':
$this->updater->addExtensionTable( 'oathauth_users', "{$this->base}/sql/mysql/tables.sql" );
$this->updater->addExtensionUpdate( [ [ $this, 'schemaUpdateOldUsersFromInstaller' ] ] );
$this->updater->dropExtensionField(
'oathauth_users',
'secret_reset',
"{$this->base}/sql/mysql/patch-remove_reset.sql"
);
$this->updater->addExtensionField(
'oathauth_users',
'module',
"{$this->base}/sql/mysql/patch-add_generic_fields.sql"
);
$this->updater->addExtensionUpdate(
[ [ __CLASS__, 'schemaUpdateSubstituteForGenericFields' ] ]
);
$this->updater->dropExtensionField(
'oathauth_users',
'secret',
"{$this->base}/sql/mysql/patch-remove_module_specific_fields.sql"
);
/*$this->updaterAddExtensionUpdate(
[ [ __CLASS__, 'schemaUpdateTOTPToMultipleKeys' ] ]
);*/
break;
case 'oracle':
$this->updater->addExtensionTable( 'oathauth_users', "{$this->base}/sql/oracle/tables.sql" );
break;
case 'postgres':
$this->updater->addExtensionTable( 'oathauth_users', "{$this->base}/sql/postgres/tables.sql" );
break;
}
return true;
}
是的,您确实需要为每个支持的数据库引擎准备一个补丁文件。理论上它可以是同一个补丁文件,但实际上通常存在细微的语法差异,需要单独的文件。有一些 planned changes 用抽象模式更改替换当前模式更新程序系统,这样扩展开发人员就不必处理数据库引擎差异,但这需要一段时间才能实现。
实际上,大多数扩展通过仅支持 MySQL 和可能的 Postgres 来解决这个问题。