summaryrefslogtreecommitdiff
path: root/www/wiki/extensions/SemanticMediaWiki/src/SQLStore/PropertyTableDefinitionBuilder.php
diff options
context:
space:
mode:
Diffstat (limited to 'www/wiki/extensions/SemanticMediaWiki/src/SQLStore/PropertyTableDefinitionBuilder.php')
-rw-r--r--www/wiki/extensions/SemanticMediaWiki/src/SQLStore/PropertyTableDefinitionBuilder.php247
1 files changed, 247 insertions, 0 deletions
diff --git a/www/wiki/extensions/SemanticMediaWiki/src/SQLStore/PropertyTableDefinitionBuilder.php b/www/wiki/extensions/SemanticMediaWiki/src/SQLStore/PropertyTableDefinitionBuilder.php
new file mode 100644
index 00000000..49812cc4
--- /dev/null
+++ b/www/wiki/extensions/SemanticMediaWiki/src/SQLStore/PropertyTableDefinitionBuilder.php
@@ -0,0 +1,247 @@
+<?php
+
+namespace SMW\SQLStore;
+
+use Hooks;
+use SMW\DataTypeRegistry;
+use SMW\DIProperty;
+use SMW\PropertyRegistry;
+
+/**
+ * @private
+ *
+ * @license GNU GPL v2+
+ * @since 1.9
+ *
+ * @author mwjames
+ */
+class PropertyTableDefinitionBuilder {
+
+ /**
+ * Fixed property table prefix
+ */
+ const PROPERTY_TABLE_PREFIX = 'smw_fpt';
+
+ /**
+ * @var PropertyTypeFinder
+ */
+ private $propertyTypeFinder;
+
+ /**
+ * @var TableDefinition[]
+ */
+ protected $propertyTables = [];
+
+ /**
+ * @var array
+ */
+ protected $fixedPropertyTableIds = [];
+
+ /**
+ * @since 1.9
+ *
+ * @param PropertyTypeFinder $propertyTypeFinder
+ */
+ public function __construct( PropertyTypeFinder $propertyTypeFinder ) {
+ $this->propertyTypeFinder = $propertyTypeFinder;
+ }
+
+ /**
+ * @since 1.9
+ *
+ * @param array $diType
+ * @param array $specialProperties
+ * @param array $userDefinedFixedProperties
+ */
+ public function doBuild( $diTypes, $specialProperties, $userDefinedFixedProperties ) {
+
+ $this->addTableDefinitionForDiTypes( $diTypes );
+
+ $this->addTableDefinitionForFixedProperties(
+ $specialProperties
+ );
+
+ $customFixedProperties = [];
+ $fixedPropertyTablePrefix = [];
+
+ // Allow to alter the prefix by an extension
+ Hooks::run( 'SMW::SQLStore::AddCustomFixedPropertyTables', [ &$customFixedProperties, &$fixedPropertyTablePrefix ] );
+
+ $this->addTableDefinitionForFixedProperties(
+ $customFixedProperties,
+ $fixedPropertyTablePrefix
+ );
+
+ $this->addRedirectTableDefinition();
+
+ $this->addTableDefinitionForUserDefinedFixedProperties(
+ $userDefinedFixedProperties
+ );
+
+ Hooks::run( 'SMW::SQLStore::updatePropertyTableDefinitions', [ &$this->propertyTables ] );
+
+ $this->createFixedPropertyTableIdIndex();
+ }
+
+ /**
+ * Returns table prefix
+ *
+ * @since 1.9
+ *
+ * @return string
+ */
+ public function getTablePrefix() {
+ return self::PROPERTY_TABLE_PREFIX;
+ }
+
+ /**
+ * Returns fixed properties table Ids
+ *
+ * @since 1.9
+ *
+ * @return array|null
+ */
+ public function getFixedPropertyTableIds() {
+ return $this->fixedPropertyTableIds;
+ }
+
+ /**
+ * Returns property table definitions
+ *
+ * @since 1.9
+ *
+ * @return TableDefinition[]
+ */
+ public function getTableDefinitions() {
+ return $this->propertyTables;
+ }
+
+ /**
+ * Returns new table definition
+ *
+ * @since 1.9
+ *
+ * @param $diType
+ * @param $tableName
+ * @param $fixedProperty
+ *
+ * @return TableDefinition
+ */
+ public function newTableDefinition( $diType, $tableName, $fixedProperty = false ) {
+ return new TableDefinition( $diType, $tableName, $fixedProperty );
+ }
+
+ /**
+ * @since 2.5
+ *
+ * @param string $tableName
+ *
+ * @return string
+ */
+ public function createTableNameFrom( $tableName ) {
+ return self::PROPERTY_TABLE_PREFIX . strtolower( $tableName );
+ }
+
+ /**
+ * @see http://stackoverflow.com/questions/3763728/shorter-php-cipher-than-md5
+ * @since 2.5
+ *
+ * @param string $tableName
+ *
+ * @return string
+ */
+ public function createHashedTableNameFrom( $tableName ) {
+ return self::PROPERTY_TABLE_PREFIX . '_' . substr( base_convert( md5( $tableName ), 16, 32 ), 0, 12 );
+ }
+
+ /**
+ * Add property table definition
+ *
+ * @since 1.9
+ *
+ * @param $diType
+ * @param $tableName
+ * @param $fixedProperty
+ */
+ protected function addPropertyTable( $diType, $tableName, $fixedProperty = false ) {
+ $this->propertyTables[$tableName] = $this->newTableDefinition( $diType, $tableName, $fixedProperty );
+ }
+
+ /**
+ * @param array $diTypes
+ */
+ private function addTableDefinitionForDiTypes( array $diTypes ) {
+ foreach( $diTypes as $tableDIType => $tableName ) {
+ $this->addPropertyTable( $tableDIType, $tableName );
+ }
+ }
+
+ private function addTableDefinitionForFixedProperties( array $properties, array $fixedPropertyTablePrefix = [] ) {
+ foreach( $properties as $propertyKey => $propertyTableSuffix ) {
+
+ $tablePrefix = isset( $fixedPropertyTablePrefix[$propertyKey] ) ? $fixedPropertyTablePrefix[$propertyKey] : self::PROPERTY_TABLE_PREFIX;
+
+ // Either as plain index array containing the property key or as associated
+ // array with property key => tableSuffix
+ $propertyKey = is_int( $propertyKey ) ? $propertyTableSuffix : $propertyKey;
+
+ $this->addPropertyTable(
+ DataTypeRegistry::getInstance()->getDataItemByType( PropertyRegistry::getInstance()->getPropertyValueTypeById( $propertyKey ) ),
+ $tablePrefix . strtolower( $propertyTableSuffix ),
+ $propertyKey
+ );
+ }
+ }
+
+ private function addRedirectTableDefinition() {
+ // Redirect table uses another subject scheme for historic reasons
+ // TODO This should be changed if possible
+ $redirectTableName = $this->createTableNameFrom( '_REDI' );
+
+ if ( isset( $this->propertyTables[$redirectTableName]) ) {
+ $this->propertyTables[$redirectTableName]->setUsesIdSubject( false );
+ }
+ }
+
+ /**
+ * Get all the tables for the properties that are declared as fixed
+ * (overly used and thus having separate tables)
+ *
+ * @param array $fixedProperties
+ */
+ private function addTableDefinitionForUserDefinedFixedProperties( array $fixedProperties ) {
+
+ $this->propertyTypeFinder->setTypeTableName(
+ $this->createTableNameFrom( '_TYPE' )
+ );
+
+ foreach( $fixedProperties as $propertyKey ) {
+
+ // Normalize the key to be independent from a possible MW setting
+ // (has area == Has_area <> Has_Area)
+ $propertyKey = str_replace( ' ', '_', ucfirst( $propertyKey ) );
+ $property = new DIProperty( $propertyKey );
+
+ $this->addPropertyTable(
+ DataTypeRegistry::getInstance()->getDataItemByType( $this->propertyTypeFinder->findTypeID( $property ) ),
+ $this->createHashedTableNameFrom( $propertyKey ),
+ $propertyKey
+ );
+ }
+ }
+
+ private function createFixedPropertyTableIdIndex() {
+
+ foreach ( $this->propertyTables as $tid => $propTable ) {
+ if ( $propTable->isFixedPropertyTable() ) {
+ $this->fixedPropertyTableIds[$propTable->getFixedProperty()] = $tid;
+ }
+ }
+
+ // Specifically set properties that must not be stored in any
+ // property table to null here. Any function that hits this
+ // null unprepared is doing something wrong anyway.
+ $this->fixedPropertyTableIds['_SKEY'] = null;
+ }
+
+}