public static function reindexAbstractDocument(PhabricatorSearchAbstractDocument $doc)
 {
     $phid = $doc->getPHID();
     if (!$phid) {
         throw new Exception("Document has no PHID!");
     }
     $store = new PhabricatorSearchDocument();
     $store->setPHID($doc->getPHID());
     $store->setDocumentType($doc->getDocumentType());
     $store->setDocumentTitle($doc->getDocumentTitle());
     $store->setDocumentCreated($doc->getDocumentCreated());
     $store->setDocumentModified($doc->getDocumentModified());
     $store->replace();
     $conn_w = $store->establishConnection('w');
     $field_dao = new PhabricatorSearchDocumentField();
     queryfx($conn_w, 'DELETE FROM %T WHERE phid = %s', $field_dao->getTableName(), $phid);
     foreach ($doc->getFieldData() as $field) {
         list($ftype, $corpus, $aux_phid) = $field;
         queryfx($conn_w, 'INSERT INTO %T (phid, phidType, field, auxPHID, corpus) ' . ' VALUES (%s, %s, %s, %ns, %s)', $field_dao->getTableName(), $phid, $doc->getDocumentType(), $ftype, $aux_phid, $corpus);
     }
     $sql = array();
     foreach ($doc->getRelationshipData() as $relationship) {
         list($rtype, $to_phid, $to_type, $time) = $relationship;
         $sql[] = qsprintf($conn_w, '(%s, %s, %s, %s, %d)', $phid, $to_phid, $rtype, $to_type, $time);
     }
     $rship_dao = new PhabricatorSearchDocumentRelationship();
     queryfx($conn_w, 'DELETE FROM %T WHERE phid = %s', $rship_dao->getTableName(), $phid);
     if ($sql) {
         queryfx($conn_w, 'INSERT INTO %T' . ' (phid, relatedPHID, relation, relatedType, relatedTime) ' . ' VALUES %Q', $rship_dao->getTableName(), implode(', ', $sql));
     }
 }
 /**
  * Rebuild the PhabricatorSearchAbstractDocument that was used to index
  * an object out of the index itself. This is primarily useful for debugging,
  * as it allows you to inspect the search index representation of a
  * document.
  *
  * @param  phid PHID of a document which exists in the search index.
  * @return null|PhabricatorSearchAbstractDocument Abstract document object
  *           which corresponds to the original abstract document used to
  *           build the document index.
  */
 public function reconstructDocument($phid)
 {
     $dao_doc = new PhabricatorSearchDocument();
     $dao_field = new PhabricatorSearchDocumentField();
     $dao_relationship = new PhabricatorSearchDocumentRelationship();
     $t_doc = $dao_doc->getTableName();
     $t_field = $dao_field->getTableName();
     $t_relationship = $dao_relationship->getTableName();
     $doc = queryfx_one($dao_doc->establishConnection('r'), 'SELECT * FROM %T WHERE phid = %s', $t_doc, $phid);
     if (!$doc) {
         return null;
     }
     $fields = queryfx_all($dao_field->establishConnection('r'), 'SELECT * FROM %T WHERE phid = %s', $t_field, $phid);
     $relationships = queryfx_all($dao_relationship->establishConnection('r'), 'SELECT * FROM %T WHERE phid = %s', $t_relationship, $phid);
     $adoc = id(new PhabricatorSearchAbstractDocument())->setPHID($phid)->setDocumentType($doc['documentType'])->setDocumentTitle($doc['documentTitle'])->setDocumentCreated($doc['documentCreated'])->setDocumentModified($doc['documentModified']);
     foreach ($fields as $field) {
         $adoc->addField($field['field'], $field['corpus'], $field['auxPHID']);
     }
     foreach ($relationships as $relationship) {
         $adoc->addRelationship($relationship['relation'], $relationship['relatedPHID'], $relationship['relatedType'], $relationship['relatedTime']);
     }
     return $adoc;
 }