Index: trunk/extensions/SemanticMediaWiki/includes/storage/SMW_SQLStore2_Queries.php |
— | — | @@ -4,6 +4,8 @@ |
5 | 5 | * for avoiding twice the amount of code being required on every use of a simple storage function. |
6 | 6 | * |
7 | 7 | * @author Markus Krötzsch |
| 8 | + * @author Jeroen De Dauw |
| 9 | + * |
8 | 10 | * @file |
9 | 11 | * @ingroup SMWStore |
10 | 12 | */ |
— | — | @@ -88,15 +90,19 @@ |
89 | 91 | */ |
90 | 92 | public function refreshConceptCache( $concept ) { |
91 | 93 | global $smwgQMaxLimit, $smwgQConceptFeatures, $wgDBtype; |
| 94 | + |
92 | 95 | $cid = $this->m_store->getSMWPageID( $concept->getDBkey(), SMW_NS_CONCEPT, '' ); |
93 | 96 | $cid_c = $this->m_store->getSMWPageID( $concept->getDBkey(), SMW_NS_CONCEPT, '', false ); |
| 97 | + |
94 | 98 | if ( $cid != $cid_c ) { |
95 | 99 | $this->m_errors[] = "Skipping redirect concept."; |
96 | 100 | return $this->m_errors; |
97 | 101 | } |
| 102 | + |
98 | 103 | $dv = end( $this->m_store->getPropertyValues( $concept, SMWPropertyValue::makeProperty( '_CONC' ) ) ); |
99 | 104 | $desctxt = ( $dv !== false ) ? $dv->getWikiValue():false; |
100 | 105 | $this->m_errors = array(); |
| 106 | + |
101 | 107 | if ( $desctxt ) { // concept found |
102 | 108 | $this->m_qmode = SMWQuery::MODE_INSTANCES; |
103 | 109 | $this->m_queries = array(); |
— | — | @@ -109,13 +115,17 @@ |
110 | 116 | $qp = new SMWQueryParser( $smwgQConceptFeatures ); |
111 | 117 | $desc = $qp->getQueryDescription( $desctxt ); |
112 | 118 | $qid = $this->compileQueries( $desc ); |
| 119 | + |
113 | 120 | $this->executeQueries( $this->m_queries[$qid] ); // execute query tree, resolve all dependencies |
114 | 121 | $qobj = $this->m_queries[$qid]; |
| 122 | + |
115 | 123 | if ( $qobj->joinfield === '' ) { |
116 | 124 | return; |
117 | 125 | } |
| 126 | + |
118 | 127 | // Update database: |
119 | 128 | $this->m_dbs->delete( 'smw_conccache', array( 'o_id' => $cid ), 'SMW::refreshConceptCache' ); |
| 129 | + |
120 | 130 | if ( $wgDBtype == 'postgres' ) { // PostgresQL: no INSERT IGNORE, check for duplicates explicitly |
121 | 131 | $where = $qobj->where . ( $qobj->where ? ' AND ':'' ) . |
122 | 132 | 'NOT EXISTS (SELECT NULL FROM ' . $this->m_dbs->tableName( 'smw_conccache' ) . |
— | — | @@ -124,18 +134,22 @@ |
125 | 135 | } else { // MySQL just uses INSERT IGNORE, no extra conditions |
126 | 136 | $where = $qobj->where; |
127 | 137 | } |
| 138 | + |
128 | 139 | $this->m_dbs->query( "INSERT " . ( ( $wgDBtype == 'postgres' ) ? "":"IGNORE " ) . "INTO " . $this->m_dbs->tableName( 'smw_conccache' ) . |
129 | 140 | " SELECT DISTINCT $qobj->joinfield AS s_id, $cid AS o_id FROM " . |
130 | 141 | $this->m_dbs->tableName( $qobj->jointable ) . " AS $qobj->alias" . $qobj->from . |
131 | 142 | ( $where ? " WHERE ":'' ) . $where . " LIMIT $smwgQMaxLimit", |
132 | 143 | 'SMW::refreshConceptCache' ); |
| 144 | + |
133 | 145 | $this->m_dbs->update( 'smw_conc2', array( 'cache_date' => strtotime( "now" ), 'cache_count' => $this->m_dbs->affectedRows() ), array( 's_id' => $cid ), 'SMW::refreshConceptCache' ); |
134 | 146 | } else { // just delete old data if there is any |
135 | 147 | $this->m_dbs->delete( 'smw_conccache', array( 'o_id' => $cid ), 'SMW::refreshConceptCache' ); |
136 | 148 | $this->m_dbs->update( 'smw_conc2', array( 'cache_date' => null, 'cache_count' => null ), array( 's_id' => $cid ), 'SMW::refreshConceptCache' ); |
137 | 149 | $this->m_errors[] = "No concept description found."; |
138 | 150 | } |
| 151 | + |
139 | 152 | $this->cleanUp(); |
| 153 | + |
140 | 154 | return $this->m_errors; |
141 | 155 | } |
142 | 156 | |
— | — | @@ -315,17 +329,22 @@ |
316 | 330 | */ |
317 | 331 | protected function getCountQueryResult( SMWQuery $query, $rootid ) { |
318 | 332 | wfProfileIn( 'SMWSQLStore2Queries::getCountQueryResult (SMW)' ); |
| 333 | + |
319 | 334 | $qobj = $this->m_queries[$rootid]; |
| 335 | + |
320 | 336 | if ( $qobj->joinfield === '' ) { // empty result, no query needed |
321 | 337 | wfProfileOut( 'SMWSQLStore2Queries::getCountQueryResult (SMW)' ); |
322 | 338 | return 0; |
323 | 339 | } |
| 340 | + |
324 | 341 | $sql_options = array( 'LIMIT' => $query->getLimit() + 1, 'OFFSET' => $query->getOffset() ); |
325 | 342 | $res = $this->m_dbs->select( $this->m_dbs->tableName( $qobj->jointable ) . " AS $qobj->alias" . $qobj->from, "COUNT(DISTINCT $qobj->alias.smw_id) AS count", $qobj->where, 'SMW::getQueryResult', $sql_options ); |
326 | 343 | $row = $this->m_dbs->fetchObject( $res ); |
327 | 344 | $count = $row->count; |
328 | 345 | $this->m_dbs->freeResult( $res ); |
| 346 | + |
329 | 347 | wfProfileOut( 'SMWSQLStore2Queries::getCountQueryResult (SMW)' ); |
| 348 | + |
330 | 349 | return $count; |
331 | 350 | } |
332 | 351 | |
— | — | @@ -502,12 +521,14 @@ |
503 | 522 | if ( $row->cache_date && |
504 | 523 | ( ( $row->cache_date > ( strtotime( "now" ) - $smwgQConceptCacheLifetime * 60 ) ) || |
505 | 524 | !$may_be_computed ) ) { // Cached concept, use cache unless it is dead and can be revived. |
| 525 | + |
506 | 526 | $query->jointable = 'smw_conccache'; |
507 | 527 | $query->joinfield = "$query->alias.s_id"; |
508 | 528 | $query->where = "$query->alias.o_id=" . $this->m_dbs->addQuotes( $cid ); |
509 | 529 | } elseif ( $row->concept_txt ) { // Parse description and process it recursively. |
510 | 530 | if ( $may_be_computed ) { |
511 | 531 | $qp = new SMWQueryParser(); |
| 532 | + |
512 | 533 | //No defaultnamespaces here; If any, these are already in the concept. |
513 | 534 | $desc = $qp->getQueryDescription( $row->concept_txt ); |
514 | 535 | $qid = $this->compileQueries( $desc ); |
— | — | @@ -524,6 +545,7 @@ |
525 | 546 | |
526 | 547 | if ( $qid >= 0 ) { // Success, keep query object, propagate sortkeys from subqueries. |
527 | 548 | $this->m_queries[$qid] = $query; |
| 549 | + |
528 | 550 | if ( $query->type != SMW_SQL2_DISJUNCTION ) { // Sortkeys are killed by disjunctions (not all parts may have them), |
529 | 551 | // NOTE: preprocessing might try to push disjunctions downwards to safe sortkey, but this seems to be minor |
530 | 552 | foreach ( $query->components as $cid => $field ) { |
— | — | @@ -1094,6 +1116,7 @@ |
1095 | 1117 | */ |
1096 | 1118 | protected function getCreateTempIDTableSQL( $tablename ) { |
1097 | 1119 | global $wgDBtype; |
| 1120 | + |
1098 | 1121 | if ( $wgDBtype == 'postgres' ) { // PostgreSQL: no memory tables, use RULE to emulate INSERT IGNORE |
1099 | 1122 | return "CREATE OR REPLACE FUNCTION create_" . $tablename . "() RETURNS void AS " |
1100 | 1123 | . "$$ " |