Index: trunk/extensions/Wikidata/OmegaWiki/OmegaWikiRecordSets.php |
— | — | @@ -754,8 +754,10 @@ |
755 | 755 | |
756 | 756 | if (count($objectIds) > 0) { |
757 | 757 | for ($i = 0; $i < count($objectIds); $i++) { |
758 | | - $record = new ArrayRecord($objectAttributesRecordStructure); |
759 | | - $objectAttributesRecords[$objectIds[$i]] = $record; |
| 758 | + if (isset($objectIds[$i])) { |
| 759 | + $record = new ArrayRecord($objectAttributesRecordStructure); |
| 760 | + $objectAttributesRecords[$objectIds[$i]] = $record; |
| 761 | + } |
760 | 762 | } |
761 | 763 | |
762 | 764 | // Text attributes |
Index: trunk/extensions/Wikidata/OmegaWiki/WikiDataTables.php |
— | — | @@ -1,5 +1,20 @@ |
2 | 2 | <?php |
3 | 3 | |
| 4 | +/** |
| 5 | + * This unit is meant to provide a database abstraction layer. The main purposes of this layer are: |
| 6 | + * 1) To centralize table identifiers and table column identifiers |
| 7 | + * 2) To provide meta data on the wikidata tables we use in the (MySQL) database (possibly for creating the tables through CREATE TABLE) |
| 8 | + * 3) To ease querying of the wikidata tables making use of the meta data |
| 9 | + * 4) To ease querying of the wikidata tables by using PHP functions and types instead of plain SQL |
| 10 | + * 5) To hide some frequently used constructions in queries like getting the latest version of a record (remove_transaction_id IS NULL) |
| 11 | + * 6) To provide a starting point for a generic structure that queries these tables into Records and RecordSets |
| 12 | + * |
| 13 | + * The basic components of this abstraction Layer are: |
| 14 | + * 1) DatabaseExpression: a general interface that can turn PHP data into an SQL expression |
| 15 | + * 2) TableColumn: represents a specific column in a specific table |
| 16 | + * 3) Table: represents a specific table in the database, meant as a base class for specific tables |
| 17 | + */ |
| 18 | + |
4 | 19 | require_once("Wikidata.php"); |
5 | 20 | |
6 | 21 | interface DatabaseExpression { |
— | — | @@ -79,21 +94,56 @@ |
80 | 95 | } |
81 | 96 | } |
82 | 97 | |
| 98 | +class TransactionsTable extends Table { |
| 99 | + public $transactionId; |
| 100 | + public $userId; |
| 101 | + public $userIp; |
| 102 | + public $timestamp; |
| 103 | + public $comment; |
| 104 | + |
| 105 | + public function __construct($identifier) { |
| 106 | + parent::__construct($identifier, false, array("transaction_id")); |
| 107 | + |
| 108 | + $this->transactionId = $this->createColumn("transaction_id"); |
| 109 | + $this->userId = $this->createColumn("user_id"); |
| 110 | + $this->userIp = $this->createColumn("user_ip"); |
| 111 | + $this->timestamp = $this->createColumn("timestamp"); |
| 112 | + $this->comment = $this->createColumn("comment"); |
| 113 | + } |
| 114 | +} |
| 115 | + |
83 | 116 | class DefinedMeaningTable extends VersionedTable { |
84 | 117 | public $definedMeaningId; |
85 | 118 | public $expressionId; |
| 119 | + public $meaningTextTcid; |
86 | 120 | |
87 | 121 | public function __construct($identifier) { |
88 | 122 | parent::__construct($identifier, array("defined_meaning_id")); |
89 | 123 | |
90 | 124 | $this->definedMeaningId = $this->createColumn("defined_meaning_id"); |
91 | 125 | $this->expressionId = $this->createColumn("expression_id"); |
| 126 | + $this->meaningTextTcid = $this->createColumn("meaning_text_tcid"); |
92 | 127 | } |
93 | 128 | } |
94 | 129 | |
| 130 | +class AlternativeDefinitionsTable extends VersionedTable { |
| 131 | + public $meaningMid; |
| 132 | + public $meaningTextTcid; |
| 133 | + public $sourceId; |
| 134 | + |
| 135 | + public function __construct($identifier) { |
| 136 | + parent::__construct($identifier, array("meaning_mid", "meaning_text_tcid")); |
| 137 | + |
| 138 | + $this->meaningMid = $this->createColumn("meaning_mid"); |
| 139 | + $this->meaningTextTcid = $this->createColumn("meaning_text_tcid"); |
| 140 | + $this->sourceId = $this->createColumn("source_id"); |
| 141 | + } |
| 142 | +} |
| 143 | + |
95 | 144 | class ExpressionTable extends VersionedTable { |
96 | 145 | public $expressionId; |
97 | 146 | public $spelling; |
| 147 | + public $hyphenation; |
98 | 148 | public $languageId; |
99 | 149 | |
100 | 150 | public function __construct($name) { |
— | — | @@ -101,10 +151,191 @@ |
102 | 152 | |
103 | 153 | $this->expressionId = $this->createColumn("expression_id"); |
104 | 154 | $this->spelling = $this->createColumn("spelling"); |
| 155 | + $this->hyphenation = $this->createColumn("hyphenation"); |
105 | 156 | $this->languageId = $this->createColumn("language_id"); |
106 | 157 | } |
107 | 158 | } |
108 | 159 | |
| 160 | +class ClassAttributesTable extends VersionedTable { |
| 161 | + public $objectId; |
| 162 | + public $classMid; |
| 163 | + public $levelMid; |
| 164 | + public $attributeMid; |
| 165 | + public $attributeType; |
| 166 | + |
| 167 | + public function __construct($name) { |
| 168 | + parent::__construct($name, array("object_id")); |
| 169 | + |
| 170 | + $this->objectId = $this->createColumn("object_id"); |
| 171 | + $this->classMid = $this->createColumn("class_mid"); |
| 172 | + $this->levelMid = $this->createColumn("level_mid"); |
| 173 | + $this->attributeMid = $this->createColumn("attribute_mid"); |
| 174 | + $this->attributeType = $this->createColumn("attribute_type"); |
| 175 | + } |
| 176 | +} |
| 177 | + |
| 178 | +class ClassMembershipsTable extends VersionedTable { |
| 179 | + public $classMembershipId; |
| 180 | + public $classMid; |
| 181 | + public $classMemberMid; |
| 182 | + |
| 183 | + public function __construct($name) { |
| 184 | + parent::__construct($name, array("class_membership_id")); |
| 185 | + |
| 186 | + $this->classMembershipId = $this->createColumn("class_membership_id"); |
| 187 | + $this->classMid = $this->createColumn("class_mid"); |
| 188 | + $this->classMemberMid = $this->createColumn("class_member_mid"); |
| 189 | + } |
| 190 | +} |
| 191 | + |
| 192 | +class CollectionMembershipsTable extends VersionedTable { |
| 193 | + public $collectionId; |
| 194 | + public $memberMid; |
| 195 | + public $internalMemberId; |
| 196 | + public $applicableLanguageId; |
| 197 | + |
| 198 | + public function __construct($name) { |
| 199 | + parent::__construct($name, array('collection_id', 'member_mid')); |
| 200 | + |
| 201 | + $this->collectionId = $this->createColumn("collection_id"); |
| 202 | + $this->memberMid = $this->createColumn("member_mid"); |
| 203 | + $this->internalMemberId = $this->createColumn("internal_member_id"); |
| 204 | + $this->applicableLanguageId = $this->createColumn("applicable_language_id"); |
| 205 | + } |
| 206 | +} |
| 207 | + |
| 208 | +class MeaningRelationsTable extends VersionedTable { |
| 209 | + public $relationId; |
| 210 | + public $meaning1Mid; |
| 211 | + public $meaning2Mid; |
| 212 | + public $relationTypeMid; |
| 213 | + |
| 214 | + public function __construct($name) { |
| 215 | + parent::__construct($name, array("relation_id")); |
| 216 | + |
| 217 | + $this->relationId = $this->createColumn("relation_id"); |
| 218 | + $this->meaning1Mid = $this->createColumn("meaning1_mid"); |
| 219 | + $this->meaning2Mid = $this->createColumn("meaning2_mid"); |
| 220 | + $this->relationTypeMid = $this->createColumn("relationtype_mid"); |
| 221 | + } |
| 222 | +} |
| 223 | + |
| 224 | +class SyntransTable extends VersionedTable { |
| 225 | + public $syntransSid; |
| 226 | + public $definedMeaningId; |
| 227 | + public $expressionId; |
| 228 | + public $firstUse; |
| 229 | + public $identicalMeaning; |
| 230 | + |
| 231 | + public function __construct($name) { |
| 232 | + parent::__construct($name, array("syntrans_sid")); |
| 233 | + |
| 234 | + $this->syntransSid = $this->createColumn("syntrans_sid"); |
| 235 | + $this->definedMeaningId = $this->createColumn("defined_meaning_id"); |
| 236 | + $this->expressionId = $this->createColumn("expression_id"); |
| 237 | + $this->firstUse = $this->createColumn("firstuse"); |
| 238 | + $this->identicalMeaning = $this->createColumn("identical_meaning"); |
| 239 | + } |
| 240 | +} |
| 241 | + |
| 242 | +class TextAttributeValuesTable extends VersionedTable { |
| 243 | + public $valueId; |
| 244 | + public $objectId; |
| 245 | + public $attributeMid; |
| 246 | + public $text; |
| 247 | + |
| 248 | + public function __construct($name) { |
| 249 | + parent::__construct($name, array("value_id")); |
| 250 | + |
| 251 | + $this->valueId = $this->createColumn("value_id"); |
| 252 | + $this->objectId = $this->createColumn("object_id"); |
| 253 | + $this->attributeMid = $this->createColumn("attribute_mid"); |
| 254 | + $this->text = $this->createColumn("text"); |
| 255 | + } |
| 256 | +} |
| 257 | + |
| 258 | +class TranslatedContentAttributeValuesTable extends VersionedTable { |
| 259 | + public $valueId; |
| 260 | + public $objectId; |
| 261 | + public $attributeMid; |
| 262 | + public $valueTcid; |
| 263 | + |
| 264 | + public function __construct($name) { |
| 265 | + parent::__construct($name, array("value_id")); |
| 266 | + |
| 267 | + $this->valueId = $this->createColumn("value_id"); |
| 268 | + $this->objectId = $this->createColumn("object_id"); |
| 269 | + $this->attributeMid = $this->createColumn("attribute_mid"); |
| 270 | + $this->valueTcid = $this->createColumn("value_tcid"); |
| 271 | + } |
| 272 | +} |
| 273 | + |
| 274 | +class TranslatedContentTable extends VersionedTable { |
| 275 | + public $translatedContentId; |
| 276 | + public $languageId; |
| 277 | + public $shortTextId; |
| 278 | + public $textId; |
| 279 | + public $originalLanguageId; |
| 280 | + |
| 281 | + public function __construct($name) { |
| 282 | + parent::__construct($name, array("translated_content_id", "language_id")); |
| 283 | + |
| 284 | + $this->translatedContentId = $this->createColumn("translated_content_id"); |
| 285 | + $this->languageId = $this->createColumn("language_id"); |
| 286 | + $this->shortTextId = $this->createColumn("shorttext_id"); |
| 287 | + $this->textId = $this->createColumn("text_id"); |
| 288 | + $this->originalLanguageId = $this->createColumn("original_language_id"); |
| 289 | + } |
| 290 | +} |
| 291 | + |
| 292 | +class OptionAttributeOptionsTable extends VersionedTable { |
| 293 | + public $optionId; |
| 294 | + public $attributeId; |
| 295 | + public $optionMid; |
| 296 | + public $languageId; |
| 297 | + |
| 298 | + public function __construct($name) { |
| 299 | + parent::__construct($name, array("attribute_id", "option_mid")); |
| 300 | + |
| 301 | + $this->optionId = $this->createColumn("option_id"); |
| 302 | + $this->attributeId = $this->createColumn("attribute_id"); |
| 303 | + $this->optionMid = $this->createColumn("option_mid"); |
| 304 | + $this->languageId = $this->createColumn("language_id"); |
| 305 | + } |
| 306 | +} |
| 307 | + |
| 308 | +class OptionAttributeValuesTable extends VersionedTable { |
| 309 | + public $valueId; |
| 310 | + public $objectId; |
| 311 | + public $optionId; |
| 312 | + |
| 313 | + public function __construct($name) { |
| 314 | + parent::__construct($name, array("value_id")); |
| 315 | + |
| 316 | + $this->valueId = $this->createColumn("value_id"); |
| 317 | + $this->objectId = $this->createColumn("object_id"); |
| 318 | + $this->optionId = $this->createColumn("option_id"); |
| 319 | + } |
| 320 | +} |
| 321 | + |
| 322 | +class URLAttributeValuesTable extends VersionedTable { |
| 323 | + public $valueId; |
| 324 | + public $objectId; |
| 325 | + public $attributeMid; |
| 326 | + public $url; |
| 327 | + public $label; |
| 328 | + |
| 329 | + public function __construct($name) { |
| 330 | + parent::__construct($name, array("value_id")); |
| 331 | + |
| 332 | + $this->valueId = $this->createColumn("value_id"); |
| 333 | + $this->objectId = $this->createColumn("object_id"); |
| 334 | + $this->attributeMid = $this->createColumn("attribute_mid"); |
| 335 | + $this->url = $this->createColumn("url"); |
| 336 | + $this->label = $this->createColumn("label"); |
| 337 | + } |
| 338 | +} |
| 339 | + |
109 | 340 | global |
110 | 341 | $tables, |
111 | 342 | |
— | — | @@ -126,24 +357,24 @@ |
127 | 358 | $urlAttributeValuesTable; |
128 | 359 | |
129 | 360 | $dc=wdGetDataSetContext(); |
130 | | -$alternativeDefinitionsTable = new Table("alt_meaningtexts", true, array('meaning_mid', 'meaning_text_tcid')); |
| 361 | +$alternativeDefinitionsTable = new AlternativeDefinitionsTable("alt_meaningtexts"); |
131 | 362 | $bootstrappedDefinedMeaningsTable = new BootstrappedDefinedMeaningsTable("bootstrapped_defined_meanings"); |
132 | | -$classAttributesTable = new Table("class_attributes", true, array('object_id')); |
133 | | -$classMembershipsTable = new Table("class_membership", true, array('class_membership_id')); |
134 | | -$collectionMembershipsTable = new Table("collection_contents", true, array('collection_id', 'member_mid')); |
| 363 | +$classAttributesTable = new ClassAttributesTable("class_attributes"); |
| 364 | +$classMembershipsTable = new ClassMembershipsTable("class_membership"); |
| 365 | +$collectionMembershipsTable = new CollectionMembershipsTable("collection_contents"); |
135 | 366 | $definedMeaningTable = new DefinedMeaningTable("defined_meaning"); |
136 | 367 | $expressionTable = new ExpressionTable("expression_ns"); |
137 | | -$meaningRelationsTable = new Table("meaning_relations", true, array('relation_id')); |
138 | | -$syntransTable = new Table("syntrans", true, array('syntrans_sid')); |
139 | | -$textAttributeValuesTable = new Table("text_attribute_values", true, array('value_id')); |
| 368 | +$meaningRelationsTable = new MeaningRelationsTable("meaning_relations"); |
| 369 | +$syntransTable = new SyntransTable("syntrans"); |
| 370 | +$textAttributeValuesTable = new TextAttributeValuesTable("text_attribute_values"); |
140 | 371 | $transactionsTable = new Table("transactions", false, array('transaction_id')); |
141 | | -$translatedContentAttributeValuesTable = new Table("translated_content_attribute_values", true, array('value_id')); |
142 | | -$translatedContentTable = new Table("translated_content", true, array('translated_content_id', 'language_id')); |
143 | | -$optionAttributeOptionsTable = new Table("option_attribute_options", true, array('attribute_id', 'option_mid')); |
144 | | -$optionAttributeValuesTable = new Table("option_attribute_values", true, array('value_id')); |
145 | | -$urlAttributeValuesTable = new Table("url_attribute_values", true, array('value_id')); |
| 372 | +$translatedContentAttributeValuesTable = new TranslatedContentAttributeValuesTable("translated_content_attribute_values"); |
| 373 | +$translatedContentTable = new TranslatedContentTable("translated_content"); |
| 374 | +$optionAttributeOptionsTable = new OptionAttributeOptionsTable("option_attribute_options"); |
| 375 | +$optionAttributeValuesTable = new OptionAttributeValuesTable("option_attribute_values"); |
| 376 | +$urlAttributeValuesTable = new URLAttributeValuesTable("url_attribute_values"); |
146 | 377 | |
147 | | -function select($expressions, $tables, $restrictions) { |
| 378 | +function select(array $expressions, array $tables, array $restrictions) { |
148 | 379 | $result = "SELECT " . $expressions[0]->toExpression(); |
149 | 380 | |
150 | 381 | for ($i = 1; $i < count($expressions); $i++) |
— | — | @@ -166,7 +397,7 @@ |
167 | 398 | return $result; |
168 | 399 | } |
169 | 400 | |
170 | | -function selectLatest($expressions, $tables, $restrictions) { |
| 401 | +function selectLatest(array $expressions, array $tables, array $restrictions) { |
171 | 402 | foreach($tables as $table) |
172 | 403 | if ($table->isVersioned) |
173 | 404 | $restrictions[] = $table->removeTransactionId->toExpression() . " IS NULL"; |