--- a/Command/SyncDocumentsCommand.php Fri Nov 18 17:54:30 2011 +0100
+++ b/Command/SyncDocumentsCommand.php Fri Nov 25 18:55:42 2011 +0100
@@ -13,13 +13,29 @@
use IRI\Bundle\WikiTagBundle\Event\WikiTagEvents;
use IRI\Bundle\WikiTagBundle\Event\DocumentTagEvent;
use Doctrine\ORM\Query;
-use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
-class SyncDocumentsCommand extends ContainerAwareCommand
+/**
+ *
+ * This class implement a command to synchronize the wikita document table and index to the host application documents.
+ * options :
+ * - tags: Synchronize the tag string of the wikitag documents, otherwise, synchronize the document themselves (default not set).
+ * The tags string is the concatenation (with comma) of all tag's label of a wikita document. It allows the indexation of the tags.
+ * - clear: Clear the wikitag documents. (default not set)
+ * - all: if set, process all objects, if not process only those that need it. (default not set)
+ * - --tags not set : if --all is set, recreate a wikitag document for all host document (you may have to run the commant with the clear option first),
+ * otherwise create only the missing wikitag document.
+ * - --tags set: if --all is set, recalculate the tags string for all document, otherwise, only calculate the tag string wher it is null.
+ * - --clear: if --all is set, delete all wikitag documents, otherwise clear only those not linked to a host document.
+ * - force: force document deletion (default not set)
+ *
+ * @author ymh
+ *
+ */
+class SyncDocumentsCommand extends ProgressContainerAwareCommand
{
protected function configure()
{
@@ -28,88 +44,127 @@
$this
->setName('wikitag:sync-doc')
->setDescription('Synchronize and index document class')
- ->addOption('missing', 'm', InputOption::VALUE_NONE, "process missing")
+ ->addOption('force', 'f', InputOption::VALUE_NONE, "Force document deletion")
->addOption('tags', 't', InputOption::VALUE_NONE, "update tags")
- ->addOption('clear', 'c', InputOption::VALUE_NONE, "clear all docs");
+ ->addOption('clear', 'c', InputOption::VALUE_NONE, "Clear documents")
+ ->addOption('all', 'a', InputOption::VALUE_NONE, "clear all docs");
+
}
-
- protected function execute(InputInterface $input, OutputInterface $output)
+
+ private function execute_tags(InputInterface $input, OutputInterface $output)
{
- $class = $this->getContainer()->getParameter('wiki_tag.document_class');
- $clear = $input->getOption('clear');
- $missing = $input->getOption('missing');
-
-
$doctrine = $this->getContainer()->get('doctrine');
$docrep = $doctrine->getRepository('WikiTagBundle:Document');
- $rep = $doctrine->getRepository($class);
+ $all = $input->getOption('all');
- if(is_null($rep)) {
- //TODO : translate
- $output->writeln("$class does not have a repository : exiting.");
- return ;
+ if($all)
+ {
+ $docquery = $doctrine->getEntityManager()->createQuery("SELECT doc from WikiTagBundle:Document doc");
+ $doccountquery = $doctrine->getEntityManager()->createQuery("SELECT COUNT(doc.id) from WikiTagBundle:Document doc");
+ }
+ else
+ {
+ $docquery = $doctrine->getEntityManager()->createQuery("SELECT doc from WikiTagBundle:Document doc WHERE doc.tagsStr IS NULL");
+ $doccountquery = $doctrine->getEntityManager()->createQuery("SELECT COUNT(doc.id) from WikiTagBundle:Document doc WHERE doc.tagsStr IS NULL");
}
- if($input->getOption('tags'))
- {
- if(!$missing)
+
+ $total = $doccountquery->getSingleScalarResult();
+ $done = 0;
+ $iterable = $docquery->iterate();
+ $todetach = array();
+ while (($row = $iterable->next()) !== false) {
+ $done++;
+ $memory = ((($done%10)==0)?" - mem: ".strval(memory_get_usage(true)):"");
+ $doc = $row[0];
+ $todetach[] = $doc;
+
+ $this->showProgress($output, $done, $total, "id : ".$doc->getId()."%$memory", 50);
+ $docrep->updateTagsStr($doc);
+ //dispatch event
+ $event_dispatcher = $this->getContainer()->get('event_dispatcher');
+ $event = new DocumentTagEvent($doc);
+ $event_dispatcher->dispatch(WikiTagEvents::onTagChanged, $event);
+
+ if($done%10 == 0)
{
- $docquery = $doctrine->getEntityManager()->createQuery("SELECT doc from WikiTagBundle:Document doc");
- $doccountquery = $doctrine->getEntityManager()->createQuery("SELECT COUNT(doc.id) from WikiTagBundle:Document doc");
- }
- else
- {
- $docquery = $doctrine->getEntityManager()->createQuery("SELECT doc from WikiTagBundle:Document doc WHERE doc.tagsStr IS NULL");
- $doccountquery = $doctrine->getEntityManager()->createQuery("SELECT COUNT(doc.id) from WikiTagBundle:Document doc WHERE doc.tagsStr IS NULL");
+ $doctrine->getEntityManager()->flush();
+ foreach($todetach as $obj)
+ {
+ $doctrine->getEntityManager()->detach($obj);
+ }
+ $todetach = array();
}
-
-
- $total = $doccountquery->getSingleScalarResult();
- $done = 0;
- $iterable = $docquery->iterate();
- $todetach = array();
- while (($row = $iterable->next()) !== false) {
- $done++;
- $memory = ((($done%10)==0)?" - mem: ".strval(memory_get_usage(true)):"");
- $doc = $row[0];
- $todetach[] = $doc;
- $output->writeln("Process doc id ".$doc->getId()." $done/$total ".strval(intval(floatval($done)/floatval($total)*100.0))."%$memory");
- $docrep->updateTagsStr($doc);
- //dispatch event
- $event_dispatcher = $this->getContainer()->get('event_dispatcher');
- $event = new DocumentTagEvent($doc);
- $event_dispatcher->dispatch(WikiTagEvents::onTagChanged, $event);
-
- if($done%10 == 0)
- {
- $doctrine->getEntityManager()->flush();
- foreach($todetach as $obj)
- {
- $doctrine->getEntityManager()->detach($obj);
- }
- $todetach = array();
- }
- }
- $doctrine->getEntityManager()->flush();
-
- return;
-
+ }
+ $doctrine->getEntityManager()->flush();
+ $doctrine->getEntityManager()->clear();
+ }
+
+ private function execute_clear(InputInterface $input, OutputInterface $output)
+ {
+ $class = $this->getContainer()->getParameter('wiki_tag.document_class');
+ $doctrine = $this->getContainer()->get('doctrine');
+ $all = $input->getOption('all');
+ $force = $input->getOption('force');
+
+
+ if($all)
+ {
+ // delete all documents
+ $query_str = "DELETE WikiTagBundle:Document wtdoc";
+ $count_query_str = "SELECT COUNT(wtdoc.id) FROM WikiTagBundle:Document wtdoc";
+ }
+ else
+ {
+ // delete only wikitag document that have no conterpart
+ $query_str = "DELETE WikiTagBundle:Document wtdoc WHERE wtdoc.externalId IS NULL OR wtdoc.externalId NOT IN (SELECT doc FROM $class doc)";
+ $count_query_str = "SELECT COUNT(wtdoc.id) FROM WikiTagBundle:Document wtdoc WHERE wtdoc.externalId IS NULL OR wtdoc.externalId NOT IN (SELECT doc FROM $class doc)";
}
- //TODO : check class to implement DocumentInterface
- //TODO : write progress
- if($missing)
+ $count_query = $doctrine->getEntityManager()->createQuery($count_query_str);
+ $total = $count_query->getSingleScalarResult();
+
+ if($total === 0)
+ {
+ $output->writeln("No wikitag document to delete. Exit.");
+ return;
+ }
+
+ $output->writeln("$total wikitag document(s) to delete.");
+ if(!$force && $input->isInteractive())
+ {
+ $dialog = $this->getHelper('dialog');
+ if (!$dialog->askConfirmation($output, '<question>Confirm deletion? (y/N) : </question>', false)) {
+ return;
+ }
+ }
+
+ $req = $doctrine->getEntityManager()->createQuery($query_str);
+
+ $nb_deleted = $req->getResult();
+
+ $output->writeln("$nb_deleted wikitag document(s) deleted.");
+
+ $doctrine->getEntityManager()->flush();
+
+ }
+
+ private function execute_docs(InputInterface $input, OutputInterface $output)
+ {
+ $all = $input->getOption('all');
+ $doctrine = $this->getContainer()->get('doctrine');
+ $docrep = $doctrine->getRepository('WikiTagBundle:Document');
+
+ if($all)
+ {
+ $docquery = $doctrine->getEntityManager()->createQuery("SELECT doc FROM $class doc");
+ $doccountquery = $doctrine->getEntityManager()->createQuery("SELECT count(doc.id) FROM $class doc");
+ }
+ else
{
$docquery = $doctrine->getEntityManager()->createQuery("SELECT doc FROM $class doc WHERE doc.id not in (SELECT wtdoc FROM WikiTagBundle:Document wtdoc)");
$doccountquery = $doctrine->getEntityManager()->createQuery("SELECT count(doc.id) FROM $class doc WHERE doc.id not in (SELECT wtdoc FROM WikiTagBundle:Document wtdoc)");
- //$doclist = $doctrine->getEntityManager()->createQuery("SELECT doc FROM $class doc WHERE doc.id not in (SELECT wtdoc FROM WikiTagBundle:Document wtdoc)")->getResult();
- }
- else
- {
- $docquery = $doctrine->getEntityManager()->createQuery("SELECT doc FROM $class doc");
- $doccountquery = $doctrine->getEntityManager()->createQuery("SELECT count(doc.id) FROM $class doc");
- //$doclist = $rep->findAll();
}
$total = $doccountquery->getSingleScalarResult();
$done = 0;
@@ -118,7 +173,7 @@
$done++;
$doc = $row[0];
$memory = ((($done%10)==0)?" - mem: ".strval(memory_get_usage(true)):"");
- $output->writeln("Process doc id ".$doc->getId()." $done/$total ".strval(intval(floatval($done)/floatval($total)*100.0))."%$memory");
+ $this->showProgress($output, $done, $total, "id : ".$doc->getId()."%$memory", 50);
$docrep->writeDocument($doc, $this->getContainer()->getParameter('wiki_tag.document_id_column'), $this->getContainer()->getParameter('wiki_tag.fields'));
if($done%10 == 0)
{
@@ -127,14 +182,39 @@
}
}
$doctrine->getEntityManager()->flush();
+ $doctrine->getEntityManager()->clear();
- if($clear) {
-
- $req = $doctrine->getEntityManager()->createQuery("DELETE WikiTagBundle:Document wtdoc WHERE wtdoc.externalId NOT IN (SELECT doc FROM $class doc)");
- $req->getResult();
- $doctrine->getEntityManager()->flush();
+ }
+
+
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $clear = $input->getOption('clear');
+ $tags = $input->getOption('tags');
+
+
+ $class = $this->getContainer()->getParameter('wiki_tag.document_class');
+ $doctrine = $this->getContainer()->get('doctrine');
+ $rep = $doctrine->getRepository($class);
+
+ if(is_null($rep))
+ {
+ $output->writeln("$class does not have a repository : exiting.");
+ return ;
+ }
+
+ if($tags)
+ {
+ $this->execute_tags($input, $output);
+ }
+ elseif($clear)
+ {
+ $this->execute_clear($input, $output);
+ }
+ else
+ {
+ $this->execute_docs($input, $output);
}
- $output->writeln(strval(count($doclist)) ." documents imported.");
}
}
\ No newline at end of file