[ Index ] |
PHP Cross Reference of Phabricator |
[Summary view] [Print] [Text view]
1 <?php 2 3 final class PhabricatorSearchEngineMySQL extends PhabricatorSearchEngine { 4 5 public function reindexAbstractDocument( 6 PhabricatorSearchAbstractDocument $doc) { 7 8 $phid = $doc->getPHID(); 9 if (!$phid) { 10 throw new Exception('Document has no PHID!'); 11 } 12 13 $store = new PhabricatorSearchDocument(); 14 $store->setPHID($doc->getPHID()); 15 $store->setDocumentType($doc->getDocumentType()); 16 $store->setDocumentTitle($doc->getDocumentTitle()); 17 $store->setDocumentCreated($doc->getDocumentCreated()); 18 $store->setDocumentModified($doc->getDocumentModified()); 19 $store->replace(); 20 21 $conn_w = $store->establishConnection('w'); 22 23 $field_dao = new PhabricatorSearchDocumentField(); 24 queryfx( 25 $conn_w, 26 'DELETE FROM %T WHERE phid = %s', 27 $field_dao->getTableName(), 28 $phid); 29 foreach ($doc->getFieldData() as $field) { 30 list($ftype, $corpus, $aux_phid) = $field; 31 queryfx( 32 $conn_w, 33 'INSERT INTO %T (phid, phidType, field, auxPHID, corpus) '. 34 ' VALUES (%s, %s, %s, %ns, %s)', 35 $field_dao->getTableName(), 36 $phid, 37 $doc->getDocumentType(), 38 $ftype, 39 $aux_phid, 40 $corpus); 41 } 42 43 44 $sql = array(); 45 foreach ($doc->getRelationshipData() as $relationship) { 46 list($rtype, $to_phid, $to_type, $time) = $relationship; 47 $sql[] = qsprintf( 48 $conn_w, 49 '(%s, %s, %s, %s, %d)', 50 $phid, 51 $to_phid, 52 $rtype, 53 $to_type, 54 $time); 55 } 56 57 $rship_dao = new PhabricatorSearchDocumentRelationship(); 58 queryfx( 59 $conn_w, 60 'DELETE FROM %T WHERE phid = %s', 61 $rship_dao->getTableName(), 62 $phid); 63 if ($sql) { 64 queryfx( 65 $conn_w, 66 'INSERT INTO %T'. 67 ' (phid, relatedPHID, relation, relatedType, relatedTime) '. 68 ' VALUES %Q', 69 $rship_dao->getTableName(), 70 implode(', ', $sql)); 71 } 72 73 } 74 75 /** 76 * Rebuild the PhabricatorSearchAbstractDocument that was used to index 77 * an object out of the index itself. This is primarily useful for debugging, 78 * as it allows you to inspect the search index representation of a 79 * document. 80 * 81 * @param phid PHID of a document which exists in the search index. 82 * @return null|PhabricatorSearchAbstractDocument Abstract document object 83 * which corresponds to the original abstract document used to 84 * build the document index. 85 */ 86 public function reconstructDocument($phid) { 87 $dao_doc = new PhabricatorSearchDocument(); 88 $dao_field = new PhabricatorSearchDocumentField(); 89 $dao_relationship = new PhabricatorSearchDocumentRelationship(); 90 91 $t_doc = $dao_doc->getTableName(); 92 $t_field = $dao_field->getTableName(); 93 $t_relationship = $dao_relationship->getTableName(); 94 95 $doc = queryfx_one( 96 $dao_doc->establishConnection('r'), 97 'SELECT * FROM %T WHERE phid = %s', 98 $t_doc, 99 $phid); 100 101 if (!$doc) { 102 return null; 103 } 104 105 $fields = queryfx_all( 106 $dao_field->establishConnection('r'), 107 'SELECT * FROM %T WHERE phid = %s', 108 $t_field, 109 $phid); 110 111 $relationships = queryfx_all( 112 $dao_relationship->establishConnection('r'), 113 'SELECT * FROM %T WHERE phid = %s', 114 $t_relationship, 115 $phid); 116 117 $adoc = id(new PhabricatorSearchAbstractDocument()) 118 ->setPHID($phid) 119 ->setDocumentType($doc['documentType']) 120 ->setDocumentTitle($doc['documentTitle']) 121 ->setDocumentCreated($doc['documentCreated']) 122 ->setDocumentModified($doc['documentModified']); 123 124 foreach ($fields as $field) { 125 $adoc->addField( 126 $field['field'], 127 $field['corpus'], 128 $field['auxPHID']); 129 } 130 131 foreach ($relationships as $relationship) { 132 $adoc->addRelationship( 133 $relationship['relation'], 134 $relationship['relatedPHID'], 135 $relationship['relatedType'], 136 $relationship['relatedTime']); 137 } 138 139 return $adoc; 140 } 141 142 public function executeSearch(PhabricatorSavedQuery $query) { 143 $where = array(); 144 $join = array(); 145 $order = 'ORDER BY documentCreated DESC'; 146 147 $dao_doc = new PhabricatorSearchDocument(); 148 $dao_field = new PhabricatorSearchDocumentField(); 149 150 $t_doc = $dao_doc->getTableName(); 151 $t_field = $dao_field->getTableName(); 152 153 $conn_r = $dao_doc->establishConnection('r'); 154 155 $q = $query->getParameter('query'); 156 157 if (strlen($q)) { 158 $join[] = qsprintf( 159 $conn_r, 160 '%T field ON field.phid = document.phid', 161 $t_field); 162 $where[] = qsprintf( 163 $conn_r, 164 'MATCH(corpus) AGAINST (%s IN BOOLEAN MODE)', 165 $q); 166 167 // When searching for a string, promote user listings above other 168 // listings. 169 $order = qsprintf( 170 $conn_r, 171 'ORDER BY 172 IF(documentType = %s, 0, 1) ASC, 173 MAX(MATCH(corpus) AGAINST (%s)) DESC', 174 'USER', 175 $q); 176 177 $field = $query->getParameter('field'); 178 if ($field) { 179 $where[] = qsprintf( 180 $conn_r, 181 'field.field = %s', 182 $field); 183 } 184 } 185 186 $exclude = $query->getParameter('exclude'); 187 if ($exclude) { 188 $where[] = qsprintf($conn_r, 'document.phid != %s', $exclude); 189 } 190 191 $types = $query->getParameter('types'); 192 if ($types) { 193 if (strlen($q)) { 194 $where[] = qsprintf( 195 $conn_r, 196 'field.phidType IN (%Ls)', 197 $types); 198 } 199 $where[] = qsprintf( 200 $conn_r, 201 'document.documentType IN (%Ls)', 202 $types); 203 } 204 205 $join[] = $this->joinRelationship( 206 $conn_r, 207 $query, 208 'authorPHIDs', 209 PhabricatorSearchRelationship::RELATIONSHIP_AUTHOR); 210 211 $statuses = $query->getParameter('statuses', array()); 212 $statuses = array_fuse($statuses); 213 $open_rel = PhabricatorSearchRelationship::RELATIONSHIP_OPEN; 214 $closed_rel = PhabricatorSearchRelationship::RELATIONSHIP_CLOSED; 215 $include_open = !empty($statuses[$open_rel]); 216 $include_closed = !empty($statuses[$closed_rel]); 217 218 if ($include_open && !$include_closed) { 219 $join[] = $this->joinRelationship( 220 $conn_r, 221 $query, 222 'statuses', 223 $open_rel, 224 true); 225 } else if ($include_closed && !$include_open) { 226 $join[] = $this->joinRelationship( 227 $conn_r, 228 $query, 229 'statuses', 230 $closed_rel, 231 true); 232 } 233 234 if ($query->getParameter('withUnowned')) { 235 $join[] = $this->joinRelationship( 236 $conn_r, 237 $query, 238 'withUnowned', 239 PhabricatorSearchRelationship::RELATIONSHIP_UNOWNED, 240 true); 241 } else { 242 $join[] = $this->joinRelationship( 243 $conn_r, 244 $query, 245 'ownerPHIDs', 246 PhabricatorSearchRelationship::RELATIONSHIP_OWNER); 247 } 248 249 $join[] = $this->joinRelationship( 250 $conn_r, 251 $query, 252 'subscriberPHIDs', 253 PhabricatorSearchRelationship::RELATIONSHIP_SUBSCRIBER); 254 255 $join[] = $this->joinRelationship( 256 $conn_r, 257 $query, 258 'projectPHIDs', 259 PhabricatorSearchRelationship::RELATIONSHIP_PROJECT); 260 261 $join[] = $this->joinRelationship( 262 $conn_r, 263 $query, 264 'repository', 265 PhabricatorSearchRelationship::RELATIONSHIP_REPOSITORY); 266 267 $join = array_filter($join); 268 269 foreach ($join as $key => $clause) { 270 $join[$key] = ' JOIN '.$clause; 271 } 272 $join = implode(' ', $join); 273 274 if ($where) { 275 $where = 'WHERE '.implode(' AND ', $where); 276 } else { 277 $where = ''; 278 } 279 280 $offset = (int)$query->getParameter('offset', 0); 281 $limit = (int)$query->getParameter('limit', 25); 282 283 $hits = queryfx_all( 284 $conn_r, 285 'SELECT 286 document.phid 287 FROM %T document 288 %Q 289 %Q 290 GROUP BY document.phid 291 %Q 292 LIMIT %d, %d', 293 $t_doc, 294 $join, 295 $where, 296 $order, 297 $offset, 298 $limit); 299 300 return ipull($hits, 'phid'); 301 } 302 303 protected function joinRelationship( 304 AphrontDatabaseConnection $conn, 305 PhabricatorSavedQuery $query, 306 $field, 307 $type, 308 $is_existence = false) { 309 310 $sql = qsprintf( 311 $conn, 312 '%T AS %C ON %C.phid = document.phid AND %C.relation = %s', 313 id(new PhabricatorSearchDocumentRelationship())->getTableName(), 314 $field, 315 $field, 316 $field, 317 $type); 318 319 if (!$is_existence) { 320 $phids = $query->getParameter($field, array()); 321 if (!$phids) { 322 return null; 323 } 324 $sql .= qsprintf( 325 $conn, 326 ' AND %C.relatedPHID in (%Ls)', 327 $field, 328 $phids); 329 } 330 331 return $sql; 332 } 333 334 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sun Nov 30 09:20:46 2014 | Cross-referenced by PHPXref 0.7.1 |