r23955 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r23954‎ | r23955 | r23956 >
Date:13:55, 10 July 2007
Author:mkroetzsch
Status:old
Tags:
Comment:
More verbose setup procedure for semantic store. Better (i.e. faster) SQL queries.
Modified paths:
  • /trunk/extensions/SemanticMediaWiki/includes/storage/SMW_SQLStore.php (modified) (history)
  • /trunk/extensions/SemanticMediaWiki/includes/storage/SMW_Store.php (modified) (history)
  • /trunk/extensions/SemanticMediaWiki/specials/SMWAdmin/SMW_SpecialSMWAdmin.php (modified) (history)

Diff [purge]

Index: trunk/extensions/SemanticMediaWiki/specials/SMWAdmin/SMW_SpecialSMWAdmin.php
@@ -32,32 +32,33 @@
3333 return;
3434 }
3535
 36+ $wgOut->setPageTitle(wfMsg('smwadmin'));
 37+
3638 /**** Execute actions if any ****/
3739
3840 $action = $wgRequest->getText( 'action' );
39 - $message='';
4041 if ( $action=='updatetables' ) {
4142 $sure = $wgRequest->getText( 'udsure' );
4243 if ($sure == 'yes') {
43 - $message = smwfGetStore()->setup();
44 - if ($message === true) {
45 - $message = 'The database was set up successfully.';
 44+ $wgOut->disable(); // raw output
 45+ ob_start();
 46+ print "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\" dir=\"ltr\">\n<head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" /><title>Setting up Storage for Semantic MediaWiki</title></head><body><p style=\"font-family: courier, fixed, monospace; \">";
 47+ header( "Content-type: application/rdf+xml; charset=UTF-8" );
 48+ $result = smwfGetStore()->setup();
 49+ print '</p>';
 50+ if ($result === true) {
 51+ print '<p><b>The storage engine was set up successfully.</b></p>';
4652 }
 53+ print '<p> Return to <a href="' . $wgServer . $wgScript . '/Special:SMWAdmin">Special:SMWAdmin</a></p>';
 54+ print '</body></html>';
 55+ ob_flush();
 56+ flush();
 57+ return;
4758 }
4859 }
4960
50 - /**** Output ****/
 61+ /**** Normal output ****/
5162
52 - $wgOut->setPageTitle(wfMsg('smwadmin'));
53 -
54 - // only report success/failure after an action
55 - if ( $message!='' ) {
56 - $html = $message;
57 - $html .= '<p> Return to <a href="' . $wgServer . $wgScript . '/Special:SMWAdmin">Special:SMWAdmin</p>';
58 - $wgOut->addHTML($html);
59 - return true;
60 - }
61 -
6263 $html = '<p>This special page helps you during installation and upgrade of
6364 Semantic MediaWiki. Remember to backup valuable data before
6465 executing administrative functions.</p>' . "\n";
Index: trunk/extensions/SemanticMediaWiki/includes/storage/SMW_SQLStore.php
@@ -625,6 +625,15 @@
626626 foreach ($query->getErrors() as $error) {
627627 $result .= $error . '<br />';
628628 }
 629+ $result .= '<br /><b>Auxilliary tables used (possibly in multiple copies)</b><br />';
 630+ foreach (SMWSQLStore::$m_categorytables as $tablename) {
 631+ $result .= $tablename . ': ';
 632+ $res = $db->select( $tablename, 'cat_name', '', 'SMW::getQueryResult:DEBUG');
 633+ while ( $row = $db->fetchObject($res) ) {
 634+ $result .= $row->cat_name . ', ';
 635+ }
 636+ $result .= '<br />';
 637+ }
629638 $result .= '</div>';
630639 /// TODO: report query errors!
631640 return $result;
@@ -676,18 +685,27 @@
677686
678687 ///// Setup store /////
679688
680 - function setup() {
 689+ function setup($verbose = true) {
681690 global $wgDBname;
 691+ $this->reportProgress('Setting up standard database configuration for SMW ...<br /><br />',$verbose);
682692
683693 $fname = 'SMW::setupDatabase';
684694 $db =& wfGetDB( DB_MASTER );
685695
686696 extract( $db->tableNames('smw_relations','smw_attributes','smw_longstrings','smw_specialprops') );
687697
 698+/// DEBUG
 699+// $this->setupTable('smw_test',
 700+// array('subject_id' => 'INT(8) UNSIGNED NOT NULL',
 701+// 'subject_namespace' => 'INT(11) NOT NULL',
 702+// 'subject_title' => 'VARCHAR(255) NOT NULL',
 703+// 'nullvalue' => 'VARCHAR(255)',
 704+// 'value_unit' => 'VARCHAR(63)'), $db, $verbose);
 705+
688706 // create relation table
689 - if ($db->tableExists('smw_relations') === false) {
 707+ if ($db->tableExists($smw_relations) === false) {
690708 $sql = 'CREATE TABLE ' . $wgDBname . '.' . $smw_relations . '
691 - ( subject_id INT(8) UNSIGNED NOT NULL,
 709+ ( subject_id INT(8) UNSIGNED NOT NULL,
692710 subject_namespace INT(11) NOT NULL,
693711 subject_title VARCHAR(255) NOT NULL,
694712 relation_title VARCHAR(255) NOT NULL,
@@ -695,12 +713,15 @@
696714 object_title VARCHAR(255) NOT NULL
697715 ) TYPE=innodb';
698716 $res = $db->query( $sql, $fname );
 717+ } else {
 718+
699719 }
700720
701721 $this->setupIndex($smw_relations, array('subject_id','relation_title','object_title,object_namespace'), $db);
 722+ $this->reportProgress('Relation table set up successfully.<br />',$verbose);
702723
703724 // create attribute table
704 - if ($db->tableExists('smw_attributes') === false) {
 725+ if ($db->tableExists($smw_attributes) === false) {
705726 $sql = 'CREATE TABLE ' . $wgDBname . '.' . $smw_attributes . '
706727 ( subject_id INT(8) UNSIGNED NOT NULL,
707728 subject_namespace INT(11) NOT NULL,
@@ -715,9 +736,10 @@
716737 }
717738
718739 $this->setupIndex($smw_attributes, array('subject_id','attribute_title','value_num','value_xsd'), $db);
 740+ $this->reportProgress('Attribute table set up successfully.<br />',$verbose);
719741
720742 // create table for long string attributes
721 - if ($db->tableExists('smw_longstrings') === false) {
 743+ if ($db->tableExists($smw_longstrings) === false) {
722744 $sql = 'CREATE TABLE ' . $wgDBname . '.' . $smw_longstrings . '
723745 ( subject_id INT(8) UNSIGNED NOT NULL,
724746 subject_namespace INT(11) NOT NULL,
@@ -729,9 +751,10 @@
730752 }
731753
732754 $this->setupIndex($smw_longstrings, array('subject_id','attribute_title'), $db);
 755+ $this->reportProgress('Table for long string values (Type:Text) set up successfully.<br />',$verbose);
733756
734757 // create table for special properties
735 - if ($db->tableExists('smw_specialprops') === false) {
 758+ if ($db->tableExists($smw_specialprops) === false) {
736759 $sql = 'CREATE TABLE ' . $wgDBname . '.' . $smw_specialprops . '
737760 ( subject_id INT(8) UNSIGNED NOT NULL,
738761 subject_namespace INT(11) NOT NULL,
@@ -741,9 +764,10 @@
742765 ) TYPE=innodb'; /// TODO: remove subject_namespace and subject_title columns completely
743766 $res = $db->query( $sql, $fname );
744767 }
745 -
746768 $this->setupIndex($smw_specialprops, array('subject_id', 'property_id'), $db);
747 -
 769+ $this->reportProgress('Table for special properties set up successfully.<br />',$verbose);
 770+
 771+ $this->reportProgress('Database initialised successfully.<br />',$verbose);
748772 return true;
749773 }
750774
@@ -921,14 +945,13 @@
922946 if ($this->addInnerJoin('PAGE', $from, $db, $curtables)) { // try to add PAGE
923947 $curtables['CATS'] = 'cl' . SMWSQLStore::$m_tablenum++;
924948 $cond = $curtables['CATS'] . '.cl_from=' . $curtables['PAGE'] . '.page_id';
925 -// if ($smwgIQRedirectNormalization) {
926 -// $this->addInnerJoin('REDIPAGE', $from, $db, $curtables);
927 -// $cond = '((' . $cond . ') OR (' .
928 -// $curtables['PAGE'] . '.page_id=' . $curtables['REDIRECT'] . '.rd_from AND ' .
929 -// $curtables['REDIRECT'] . '.rd_title=' . $curtables['REDIPAGE'] . '.page_title AND ' .
930 -// $curtables['REDIRECT'] . '.rd_namespace=' . $curtables['REDIPAGE'] . '.page_namespace AND ' .
931 -// $curtables['REDIPAGE'] . '.page_id=' . $curtables['CATS'] . '.cl_from))';
932 -// }
 949+ /// TODO: slow, introduce another parameter to activate this
 950+ if ($smwgIQRedirectNormalization && (array_key_exists('PREVREL', $curtables))) {
 951+ // only do this at inner queries (PREVREL set)
 952+ $this->addInnerJoin('REDIPAGE', $from, $db, $curtables);
 953+ $cond = '((' . $cond . ') OR (' .
 954+ $curtables['REDIPAGE'] . '.page_id=' . $curtables['CATS'] . '.cl_from))';
 955+ }
933956 $from .= ' INNER JOIN ' . $db->tableName('categorylinks') . ' AS ' . $curtables['CATS'] . ' ON ' . $cond;
934957 return true;
935958 }
@@ -936,20 +959,32 @@
937960 if ($this->addInnerJoin('PAGE', $from, $db, $curtables)) { // try to add PAGE
938961 $curtables['RELS'] = 'rel' . SMWSQLStore::$m_tablenum++;
939962 $cond = $curtables['RELS'] . '.subject_id=' . $curtables['PAGE'] . '.page_id';
940 -// if ($smwgIQRedirectNormalization) {
941 -// $this->addInnerJoin('REDIRECT', $from, $db, $curtables);
942 -// $cond = '((' . $cond . ') OR (' .
943 -// $curtables['PAGE'] . '.page_id=' . $curtables['REDIRECT'] . '.rd_from AND ' .
944 -// $curtables['REDIRECT'] . '.rd_title=' . $curtables['RELS'] . '.subject_title AND ' .
945 -// $curtables['REDIRECT'] . '.rd_namespace=' . $curtables['RELS'] . '.subject_namespace))';
946 -// }
 963+ /// TODO: slow, introduce another parameter to activate this
 964+ if ($smwgIQRedirectNormalization && (array_key_exists('PREVREL', $curtables))) {
 965+ // only do this at inner queries (PREVREL set)
 966+ $this->addInnerJoin('REDIRECT', $from, $db, $curtables);
 967+ $cond = '((' . $cond . ') OR (' .
 968+ //$curtables['PAGE'] . '.page_id=' . $curtables['REDIRECT'] . '.rd_from AND ' .
 969+ $curtables['REDIRECT'] . '.rd_title=' . $curtables['RELS'] . '.subject_title AND ' .
 970+ $curtables['REDIRECT'] . '.rd_namespace=' . $curtables['RELS'] . '.subject_namespace))';
 971+ }
947972 $from .= ' INNER JOIN ' . $db->tableName('smw_relations') . ' AS ' . $curtables['RELS'] . ' ON ' . $cond;
948973 return true;
949974 }
950975 } elseif ($tablename == 'ATTS') {
951976 if ($this->addInnerJoin('PAGE', $from, $db, $curtables)) { // try to add PAGE
952977 $curtables['ATTS'] = 'att' . SMWSQLStore::$m_tablenum++;
953 - $from .= ' INNER JOIN ' . $db->tableName('smw_attributes') . ' AS ' . $curtables['ATTS'] . ' ON ' . $curtables['ATTS'] . '.subject_id=' . $curtables['PAGE'] . '.page_id';
 978+ $cond = $curtables['ATTS'] . '.subject_id=' . $curtables['PAGE'] . '.page_id';
 979+ /// TODO: slow, introduce another parameter to activate this
 980+ if ($smwgIQRedirectNormalization && (array_key_exists('PREVREL', $curtables))) {
 981+ // only do this at inner queries (PREVREL set)
 982+ $this->addInnerJoin('REDIRECT', $from, $db, $curtables);
 983+ $cond = '((' . $cond . ') OR (' .
 984+ //$curtables['PAGE'] . '.page_id=' . $curtables['REDIRECT'] . '.rd_from AND ' .
 985+ $curtables['REDIRECT'] . '.rd_title=' . $curtables['ATTS'] . '.subject_title AND ' .
 986+ $curtables['REDIRECT'] . '.rd_namespace=' . $curtables['ATTS'] . '.subject_namespace))';
 987+ }
 988+ $from .= ' INNER JOIN ' . $db->tableName('smw_attributes') . ' AS ' . $curtables['ATTS'] . ' ON ' . $cond;
954989 return true;
955990 }
956991 } elseif ($tablename == 'TEXT') {
@@ -961,13 +996,16 @@
962997 } elseif ($tablename == 'REDIRECT') {
963998 if ($this->addInnerJoin('PAGE', $from, $db, $curtables)) { // try to add PAGE
964999 $curtables['REDIRECT'] = 'rd' . SMWSQLStore::$m_tablenum++;
965 - $from .= ' INNER JOIN ' . $db->tableName('redirect') . ' AS ' . $curtables['REDIRECT'];
 1000+ $from .= ' LEFT JOIN ' . $db->tableName('redirect') . ' AS ' . $curtables['REDIRECT'] . ' ON ' . $curtables['REDIRECT'] . '.rd_from=' . $curtables['PAGE'] . '.page_id';
9661001 return true;
9671002 }
9681003 } elseif ($tablename == 'REDIPAGE') { // add another copy of page for getting ids of redirect targets
9691004 if ($this->addInnerJoin('REDIRECT', $from, $db, $curtables)) {
9701005 $curtables['REDIPAGE'] = 'rp' . SMWSQLStore::$m_tablenum++;
971 - $from .= ' INNER JOIN ' . $db->tableName('page') . ' AS ' . $curtables['REDIPAGE'];
 1006+ $from .= ' INNER JOIN ' . $db->tableName('page') . ' AS ' . $curtables['REDIPAGE'] . ' ON (' .
 1007+ $curtables['REDIRECT'] . '.rd_title=' . $curtables['REDIPAGE'] . '.page_title AND ' .
 1008+ $curtables['REDIRECT'] . '.rd_namespace=' . $curtables['REDIPAGE'] . '.page_namespace)';
 1009+
9721010 return true;
9731011 }
9741012 }
@@ -1036,8 +1074,8 @@
10371075 $page->getNamespace();
10381076 if ( $smwgIQRedirectNormalization && ($this->addInnerJoin('REDIRECT', $from, $db, $curtables)) ) {
10391077 $cond = '(' . $cond . ') OR (' .
1040 - $curtables['REDIRECT'] . '.rd_from=' .
1041 - $curtables['PAGE'] . '.page_id AND ' .
 1078+// $curtables['REDIRECT'] . '.rd_from=' .
 1079+// $curtables['PAGE'] . '.page_id AND ' .
10421080 $curtables['REDIRECT'] . '.rd_title=' .
10431081 $db->addQuotes($page->getDBKey()) . ' AND ' .
10441082 $curtables['REDIRECT'] . '.rd_namespace=' .
@@ -1149,6 +1187,48 @@
11501188 }
11511189 }
11521190 }
 1191+
 1192+ /**
 1193+ * Make sure the table of the given name has the given fields, provided
 1194+ * as an array with entries fieldname => typeparams. typeparams should be
 1195+ * in a normalised form and order to match to existing values.
 1196+ */
 1197+ protected function setupTable($table, $fields, $db, $verbose) {
 1198+ global $wgDBname;
 1199+ if ($db->tableExists($table) === false) { // create new table
 1200+ $sql = 'CREATE TABLE ' . $wgDBname . '.' . $table . ' (';
 1201+ $first = true;
 1202+ foreach ($fields as $name => $type) {
 1203+ if ($first) {
 1204+ $first = false;
 1205+ } else {
 1206+ $sql .= ',';
 1207+ }
 1208+ $sql .= $name . ' ' . $type;
 1209+ }
 1210+ $sql .= ') TYPE=innodb';
 1211+ $db->query( $sql, 'SMWSQLStore::setupTable' );
 1212+ } else { // check table signature
 1213+ $res = $db->query( 'DESCRIBE ' . $table, 'SMWSQLStore::setupTable' );
 1214+ $curfields = array();
 1215+ while ($row = $db->fetchObject($res)) {
 1216+ $type = strtoupper($row->Type);
 1217+ if ($row->Null != 'YES') {
 1218+ $type .= ' NOT NULL';
 1219+ }
 1220+ $curfields[$row->Field] = $type;
 1221+ }
 1222+ foreach ($fields as $name => $type) {
 1223+ if ( !array_key_exists($name,$curfields) ) {
 1224+ $this->reportProgress("Field $name not existing yet.<br />",$verbose);
 1225+ } elseif ($curfields[$name] != $type) {
 1226+ $this->reportProgress("Field $name has wrong type (should be '$type', but is '$curfields[$name]').<br />",$verbose);
 1227+ } else {
 1228+ $this->reportProgress("Field $name is fine.<br />",$verbose);
 1229+ }
 1230+ }
 1231+ }
 1232+ }
11531233
11541234 /**
11551235 * Make sure that each of the column descriptions in the given array is indexed by *one* index
@@ -1184,6 +1264,19 @@
11851265 return true;
11861266 }
11871267
 1268+ /**
 1269+ * Print some output to indicate progress. The output message is given by
 1270+ * $msg, while $verbose indicates whether or not output is desired at all.
 1271+ */
 1272+ protected function reportProgress($msg, $verbose) {
 1273+ if (!$verbose) {
 1274+ return;
 1275+ }
 1276+ print $msg;
 1277+ ob_flush();
 1278+ flush();
 1279+ }
 1280+
11881281 }
11891282
11901283
Index: trunk/extensions/SemanticMediaWiki/includes/storage/SMW_Store.php
@@ -227,8 +227,13 @@
228228 * creation of database tables. It is called upon installation as well as on upgrade: hence it
229229 * must be able to upgrade existing storage structures if needed. It should return "true" if
230230 * successful and return a meaningful string error message otherwise.
 231+ *
 232+ * The parameter $verbose determines whether the procedure is allowed to report on its progress.
 233+ * This is doen by just using print and possibly ob_flush/flush. This is also relevant for preventing
 234+ * timeouts during long operations. All output must be valid XHTML, but should preferrably be plain
 235+ * text, possibly with some linebreaks and weak markup.
231236 */
232 - abstract function setup();
 237+ abstract function setup($verbose = true);
233238
234239 }
235240

Status & tagging log