Fz-29 has uploaded a new change for review. (
https://gerrit.wikimedia.org/r/359793 )
Change subject: Add Hierarchy Structure Table creation for hierarchy field
......................................................................
Add Hierarchy Structure Table creation for hierarchy field
This commit adds the functionality to create hierarchy structure table with
columns (_value, _left, _right) and also populated from the hierarchical
enumeration provided using "*".
Change-Id: Idad419eb4dc78c70eb2efc69cccc77a1f3a5ba4b
---
M Cargo.php
M CargoFieldDescription.php
A CargoHierarchy.php
M CargoUtils.php
M extension.json
M parserfunctions/CargoDeclare.php
6 files changed, 147 insertions(+), 28 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Cargo
refs/changes/93/359793/1
diff --git a/Cargo.php b/Cargo.php
index 02249f3..301ae1b 100644
--- a/Cargo.php
+++ b/Cargo.php
@@ -82,6 +82,7 @@
$wgAutoloadClasses['CargoUtils'] = $dir . '/CargoUtils.php';
$wgAutoloadClasses['CargoFieldDescription'] = $dir .
'/CargoFieldDescription.php';
$wgAutoloadClasses['CargoTableSchema'] = $dir . '/CargoTableSchema.php';
+$wgAutoloadClasses['CargoHierarchy'] = $dir . '/CargoHierarchy.php';
$wgAutoloadClasses['CargoDeclare'] = $dir .
'/parserfunctions/CargoDeclare.php';
$wgAutoloadClasses['CargoAttach'] = $dir . '/parserfunctions/CargoAttach.php';
$wgAutoloadClasses['CargoStore'] = $dir . '/parserfunctions/CargoStore.php';
diff --git a/CargoFieldDescription.php b/CargoFieldDescription.php
index 2cc3202..727136c 100644
--- a/CargoFieldDescription.php
+++ b/CargoFieldDescription.php
@@ -50,7 +50,7 @@
if ( count( $extraParamParts ) == 1 ) {
$paramKey = trim( $extraParamParts[0] );
if ( $paramKey == 'hierarchy' ) {
- $mIsHierarchy = true;
+ $fieldDescription->mIsHierarchy
= true;
}
$fieldDescription->mOtherParams[$paramKey] = true;
} else {
diff --git a/CargoHierarchy.php b/CargoHierarchy.php
new file mode 100644
index 0000000..9b23bcf
--- /dev/null
+++ b/CargoHierarchy.php
@@ -0,0 +1,90 @@
+<?php
+/**
+ * CargoHierarchy - holds the tree for hierarchy inorder to implement Nested
Set model for
+ * efficient storage and query of hierarchy fields.
+ *
+ * @author Feroz Ahmad
+ * @ingroup Cargo
+ */
+
+class CargoHierarchy {
+ public $mTitle;
+ public $mChildren;
+ public $mLeft = 0;
+ public $mRight = 0;
+
+ function __construct( $curTitle ) {
+ $this->mTitle = $curTitle;
+ $this->mChildren = array();
+ }
+
+ function addChild( $child ) {
+ $this->mChildren[] = $child;
+ }
+
+ /**
+ * Turn a manually-created "structure", defined as a bulleted list
+ * in wikitext, into a tree. This code has been borrowed from PFTree
class
+ * of PageForms Extension
+ */
+ public static function newFromWikiText( $wikitext ) {
+ // __psuedo_root__ node is added so that multiple nodes can be added
in the first level
+ $fullTree = new CargoHierarchy( '__psuedo_root__' );
+ $lines = explode( "\n", $wikitext );
+ foreach ( $lines as $line ) {
+ $numBullets = 0;
+ for ( $i = 0; $i < strlen( $line ) && $line[$i] == '*';
$i++ ) {
+ $numBullets++;
+ }
+ if ( $numBullets == 0 ) continue;
+ $lineText = trim( substr( $line, $numBullets ) );
+ $curParentNode = $fullTree->getLastNodeForLevel(
$numBullets );
+ $curParentNode->addChild( new CargoHierarchy( $lineText
) );
+ }
+ return $fullTree;
+ }
+
+ function getLastNodeForLevel( $level ) {
+ if ( $level <= 1 || count( $this->mChildren ) == 0 ) {
+ return $this;
+ }
+ $lastNodeOnCurLevel = end( $this->mChildren );
+ return $lastNodeOnCurLevel->getLastNodeForLevel( $level - 1 );
+ }
+
+ function generateHierarchyStructureTableData() {
+ $tableData = array();
+ $this->computeLeftRight();
+ //Preorder traversal using Stack data structure
+ $stack = new SplStack();
+ $stack->push( $this );
+ while( !$stack->isEmpty() ) {
+ $node = $stack->pop();
+ $row = array();
+ $row['_value'] = $node->mTitle;
+ $row['_left'] = $node->mLeft;
+ $row['_right'] = $node->mRight;
+ $tableData[] = $row;
+ foreach( array_reverse( $node->mChildren ) as $child ) {
+ $stack->push( $child );
+ }
+ }
+ return $tableData;
+ }
+
+ private function __computeLeftRight( &$counter ) {
+ $this->mLeft = $counter;
+ $counter += 1;
+ //visit mChildren
+ foreach( $this->mChildren as $child ) {
+ $child->__computeLeftRight( $counter );
+ }
+ $this->mRight = $counter;
+ $counter += 1;
+ }
+
+ function computeLeftRight() {
+ $counter = 1;
+ $this->__computeLeftRight( $counter );
+ }
+}
\ No newline at end of file
diff --git a/CargoUtils.php b/CargoUtils.php
index 438e3a6..ece6c06 100644
--- a/CargoUtils.php
+++ b/CargoUtils.php
@@ -686,34 +686,58 @@
// if there are any.
$fieldTableNames = array();
foreach ( $tableSchema->mFieldDescriptions as $fieldName =>
$fieldDescription ) {
- if ( !$fieldDescription->mIsList ) {
- continue;
+ if ( $fieldDescription->mIsList ) {
+ // The double underscore in this table name
should
+ // prevent anyone from giving this name to a
"real"
+ // table.
+ $fieldTableName = $tableName . '__' .
$fieldName;
+ $cdb->dropTable( $fieldTableName );
+ $fieldType = $fieldDescription->mType;
+ $createSQL = "CREATE TABLE " .
+ $cdb->tableName( $fieldTableName ) . '
( ' .
+ $cdb->addIdentifierQuotes( '_rowID' ) .
" $intTypeString, ";
+ if ( $fieldType == 'Coordinates' ) {
+ $floatTypeString =
self::fieldTypeToSQLType( 'Float', $dbType );
+ $createSQL .=
$cdb->addIdentifierQuotes( '_value' ) . " $floatTypeString, ";
+ $createSQL .=
$cdb->addIdentifierQuotes( '_lat' ) . " $floatTypeString, ";
+ $createSQL .=
$cdb->addIdentifierQuotes( '_lon' ) . " $floatTypeString";
+ } else {
+ $createSQL .=
$cdb->addIdentifierQuotes( '_value' ) . ' ' . self::fieldTypeToSQLType(
$fieldType, $dbType, $size );
+ }
+ $createSQL .= ' )';
+ $cdb->query( $createSQL );
+ $createIndexSQL = 'CREATE INDEX ' .
+ $cdb->addIdentifierQuotes(
"row_id_$fieldTableName" ) . ' ON ' .
+ $cdb->tableName( $fieldTableName ) .
+ ' (' . $cdb->addIdentifierQuotes(
'_rowID' ) . ')';
+ $cdb->query( $createIndexSQL );
+ $fieldTableNames[] = $tableName . '__' .
$fieldName;
}
- // The double underscore in this table name should
- // prevent anyone from giving this name to a "real"
- // table.
- $fieldTableName = $tableName . '__' . $fieldName;
- $cdb->dropTable( $fieldTableName );
- $fieldType = $fieldDescription->mType;
- $createSQL = "CREATE TABLE " .
- $cdb->tableName( $fieldTableName ) . ' ( ' .
- $cdb->addIdentifierQuotes( '_rowID' ) . "
$intTypeString, ";
- if ( $fieldType == 'Coordinates' ) {
- $floatTypeString = self::fieldTypeToSQLType(
'Float', $dbType );
- $createSQL .= $cdb->addIdentifierQuotes(
'_value' ) . " $floatTypeString, ";
- $createSQL .= $cdb->addIdentifierQuotes( '_lat'
) . " $floatTypeString, ";
- $createSQL .= $cdb->addIdentifierQuotes( '_lon'
) . " $floatTypeString";
- } else {
- $createSQL .= $cdb->addIdentifierQuotes(
'_value' ) . ' ' . self::fieldTypeToSQLType( $fieldType, $dbType, $size );
+ if ( $fieldDescription->mIsHierarchy ) {
+ $fieldTableName = $tableName . '__' .
$fieldName . '__hierarchy';
+ $cdb->dropTable( $fieldTableName );
+ $fieldType = $fieldDescription->mType;
+ $createSQL = "CREATE TABLE " . $cdb->tableName(
$fieldTableName ) . ' ( ' ;
+ $createSQL .= $cdb->addIdentifierQuotes(
'_value' ) . ' ' . self::fieldTypeToSQLType( $fieldType, $dbType, $size ) . ",
";
+ $createSQL .= $cdb->addIdentifierQuotes(
'_left' ) . " $intTypeString, ";
+ $createSQL .= $cdb->addIdentifierQuotes(
'_right' ) . " $intTypeString ";
+ $createSQL .= ' )';
+ $cdb->query( $createSQL );
+ $createIndexSQL = 'CREATE INDEX ' .
$cdb->addIdentifierQuotes( "nested_set_$fieldTableName" ) . ' ON ' ;
+ $createIndexSQL .= $cdb->tableName(
$fieldTableName ) . ' (' ;
+ $createIndexSQL .= $cdb->addIdentifierQuotes(
'_value' ) . ', ';
+ $createIndexSQL .= $cdb->addIdentifierQuotes(
'_left' ) . ', ';
+ $createIndexSQL .= $cdb->addIdentifierQuotes(
'_right' ) . ')';
+ $cdb->query( $createIndexSQL );
+ $fieldTableNames[] = $fieldTableName;
+ //Insert Hierarchy Structure
+ $allowedValuesWikitext =
$fieldDescription->mAllowedValues[0];
+ $hierarchyTree =
CargoHierarchy::newFromWikiText( $allowedValuesWikitext );
+ $hierarchyStructureData =
$hierarchyTree->generateHierarchyStructureTableData();
+ foreach( $hierarchyStructureData as $entry ) {
+ $cdb->insert( $fieldTableName, $entry );
+ }
}
- $createSQL .= ' )';
- $cdb->query( $createSQL );
- $createIndexSQL = 'CREATE INDEX ' .
- $cdb->addIdentifierQuotes(
'row_id_$fieldTableName' ) . ' ON ' .
- $cdb->tableName( $fieldTableName ) .
- ' (' . $cdb->addIdentifierQuotes( '_rowID' ) .
')';
- $cdb->query( $createIndexSQL );
- $fieldTableNames[] = $tableName . '__' . $fieldName;
}
// And create a helper table holding all the files stored in
@@ -741,7 +765,7 @@
'main_table' => $tableName,
'field_tables' => serialize( $fieldTableNames ),
'table_schema' => $tableSchemaString
- ) );
+ ) );
}
public static function fullTextMatchSQL( $cdb, $tableName, $fieldName,
$searchTerm ) {
diff --git a/extension.json b/extension.json
index 2d3240a..bb9ec75 100755
--- a/extension.json
+++ b/extension.json
@@ -45,6 +45,7 @@
"CargoUtils": "CargoUtils.php",
"CargoFieldDescription": "CargoFieldDescription.php",
"CargoTableSchema": "CargoTableSchema.php",
+ "CargoHierarchy": "CargoHierarchy.php",
"CargoDeclare": "parserfunctions/CargoDeclare.php",
"CargoAttach": "parserfunctions/CargoAttach.php",
"CargoStore": "parserfunctions/CargoStore.php",
diff --git a/parserfunctions/CargoDeclare.php b/parserfunctions/CargoDeclare.php
index ecbcb30..9f3eea5 100644
--- a/parserfunctions/CargoDeclare.php
+++ b/parserfunctions/CargoDeclare.php
@@ -73,6 +73,9 @@
if ( $fieldDescription == null ) {
return CargoUtils::formatError( "Error:
could not parse type for field \"$fieldName\"." );
}
+ if ( $fieldDescription->mIsHierarchy == true &&
$fieldDescription->mType == 'Coordinates' ) {
+ return CargoUtils::formatError( "Error:
Hierarchy enumeration field cannot be created for $fieldDescription->mType
type." );
+ }
$tableSchema->mFieldDescriptions[$fieldName] =
$fieldDescription;
}
}
--
To view, visit https://gerrit.wikimedia.org/r/359793
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Idad419eb4dc78c70eb2efc69cccc77a1f3a5ba4b
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Cargo
Gerrit-Branch: master
Gerrit-Owner: Fz-29 <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits