PHRAS-1055 #time 2h

- change lone argument (databox) to option "--databox" (mandatory)
- add option "--missing_only" to create missing subdefs after structure change.
- add option "--garbage_collect" to remove orphan subdefs left by structure change.
This commit is contained in:
Jean-Yves Gaulier
2016-03-31 19:30:11 +02:00
parent 81b636d4de
commit 4e37af6386
3 changed files with 76 additions and 17 deletions

View File

@@ -42,6 +42,9 @@ class BuildSubdefs extends Command
var $recmax; var $recmax;
var $substitutedOnly; var $substitutedOnly;
var $withSubstituted; var $withSubstituted;
var $missingOnly;
var $garbageCollect;
var $subdefsNameByType; var $subdefsNameByType;
/** @var int */ /** @var int */
@@ -57,13 +60,15 @@ class BuildSubdefs extends Command
parent::__construct($name); parent::__construct($name);
$this->setDescription('Build subviews for given subview names and record types'); $this->setDescription('Build subviews for given subview names and record types');
$this->addArgument('databox', InputArgument::REQUIRED, 'The id (or dbname or viewname) of the databox'); $this->addOption('databox', null, InputOption::VALUE_REQUIRED, 'Mandatory : The id (or dbname or viewname) of the databox');
$this->addOption('record_type', null, InputOption::VALUE_REQUIRED|InputOption::VALUE_IS_ARRAY, 'Type(s) of records(s) to (re)build ex. "image,video", dafault=ALL'); $this->addOption('record_type', null, InputOption::VALUE_REQUIRED|InputOption::VALUE_IS_ARRAY, 'Type(s) of records(s) to (re)build ex. "image,video", dafault=ALL');
$this->addOption('name', null, InputOption::VALUE_REQUIRED|InputOption::VALUE_IS_ARRAY, 'Name(s) of sub-definition(s) to (re)build, ex. "thumbnail,preview", default=ALL'); $this->addOption('name', null, InputOption::VALUE_REQUIRED|InputOption::VALUE_IS_ARRAY, 'Name(s) of sub-definition(s) to (re)build, ex. "thumbnail,preview", default=ALL');
$this->addOption('min_record', null, InputOption::VALUE_OPTIONAL, 'Min record id'); $this->addOption('min_record', null, InputOption::VALUE_OPTIONAL, 'Min record id');
$this->addOption('max_record', null, InputOption::VALUE_OPTIONAL, 'Max record id'); $this->addOption('max_record', null, InputOption::VALUE_OPTIONAL, 'Max record id');
$this->addOption('with_substituted', null, InputOption::VALUE_NONE, 'Regenerate subdefs for substituted records as well'); $this->addOption('with_substituted', null, InputOption::VALUE_NONE, 'Regenerate subdefs for substituted records as well');
$this->addOption('substituted_only', null, InputOption::VALUE_NONE, 'Regenerate subdefs for substituted records only'); $this->addOption('substituted_only', null, InputOption::VALUE_NONE, 'Regenerate subdefs for substituted records only');
$this->addOption('missing_only', null, InputOption::VALUE_NONE, 'Regenerate only missing subdefs');
$this->addOption('garbage_collect', null, InputOption::VALUE_NONE, 'Delete subdefs not in structure anymore');
$this->addOption('partition', null, InputOption::VALUE_REQUIRED, 'n/N : work only on records belonging to partition \'n\''); $this->addOption('partition', null, InputOption::VALUE_REQUIRED, 'n/N : work only on records belonging to partition \'n\'');
$this->addOption('dry', null, InputOption::VALUE_NONE, 'dry run, list but don\'t act'); $this->addOption('dry', null, InputOption::VALUE_NONE, 'dry run, list but don\'t act');
} }
@@ -114,16 +119,22 @@ class BuildSubdefs extends Command
// find the databox / collection by id or by name // find the databox / collection by id or by name
$this->databox = null; $this->databox = null;
$d = trim($input->getArgument('databox')); if(($d = $input->getOption('databox')) !== null) {
foreach ($this->container->getDataboxes() as $db) { $d = trim($d);
if ($db->get_sbas_id() == (int)$d || $db->get_viewname() == $d || $db->get_dbname() == $d) { foreach ($this->container->getDataboxes() as $db) {
$this->databox = $db; if ($db->get_sbas_id() == (int)$d || $db->get_viewname() == $d || $db->get_dbname() == $d) {
$this->connection = $db->get_connection(); $this->databox = $db;
break; $this->connection = $db->get_connection();
break;
}
}
if ($this->databox == null) {
$output->writeln(sprintf("<error>Unknown databox \"%s\"</error>", $input->getOption('databox')));
$this->argsOK = false;
} }
} }
if ($this->databox == null) { else {
$output->writeln(sprintf("<error>Unknown databox \"%s\"</error>", $input->getArgument('databox'))); $output->writeln(sprintf("<error>Missing mandatory options --databox</error>"));
$this->argsOK = false; $this->argsOK = false;
} }
@@ -133,17 +144,24 @@ class BuildSubdefs extends Command
$this->recmax = $input->getOption('max_record'); $this->recmax = $input->getOption('max_record');
$this->substitutedOnly = $input->getOption('substituted_only') ? true : false; $this->substitutedOnly = $input->getOption('substituted_only') ? true : false;
$this->withSubstituted = $input->getOption('with_substituted') ? true : false; $this->withSubstituted = $input->getOption('with_substituted') ? true : false;
$this->missingOnly = $input->getOption('missing_only') ? true : false;
$this->garbageCollect = $input->getOption('garbage_collect') ? true : false;
$types = $this->getOptionAsArray($input, 'record_type', self::OPTION_DISTINT_VALUES);
$names = $this->getOptionAsArray($input, 'name', self::OPTION_DISTINT_VALUES);
if ($this->withSubstituted && $this->substitutedOnly) { if ($this->withSubstituted && $this->substitutedOnly) {
$output->writeln("<error>--substituted_only and --with_substituted are mutually exclusive<error>"); $output->writeln("<error>--substituted_only and --with_substituted are mutually exclusive<error>");
$this->argsOK = false; $this->argsOK = false;
} }
if($this->garbageCollect && !empty($names)) {
$output->writeln("<error>--garbage_collect and --name are mutually exclusive<error>");
$this->argsOK = false;
}
// validate types and subdefs // validate types and subdefs
$this->subdefsNameByType = []; $this->subdefsNameByType = [];
if($this->databox !== null) { if($this->databox !== null) {
$types = $this->getOptionAsArray($input, 'record_type', self::OPTION_DISTINT_VALUES);
$names = $this->getOptionAsArray($input, 'name', self::OPTION_DISTINT_VALUES);
/** @var SubdefGroup $sg */ /** @var SubdefGroup $sg */
foreach ($this->databox->get_subdef_structure() as $sg) { foreach ($this->databox->get_subdef_structure() as $sg) {
@@ -222,18 +240,33 @@ class BuildSubdefs extends Command
/** @var media_subdef $subdef */ /** @var media_subdef $subdef */
foreach ($record->get_subdefs() as $subdef) { foreach ($record->get_subdefs() as $subdef) {
if(!in_array($subdef->get_name(), $this->subdefsNameByType[$type])) { $name = $subdef->get_name();
if($name == "document") {
continue;
}
if(!in_array($name, $this->subdefsNameByType[$type])) {
// this existing subdef is unknown in structure
if($this->garbageCollect) {
if(!$this->dry) {
$subdef->delete();
}
$this->verbose(sprintf(" \"%s\" deleted,", $name));
}
continue;
}
if($this->missingOnly) {
unset($subdefNamesToDo[$name]);
continue; continue;
} }
if($subdef->is_substituted()) { if($subdef->is_substituted()) {
if(!$this->withSubstituted && !$this->substitutedOnly) { if(!$this->withSubstituted && !$this->substitutedOnly) {
unset($subdefNamesToDo[$subdef->get_name()]); unset($subdefNamesToDo[$name]);
continue; continue;
} }
} }
else { else {
if($this->substitutedOnly) { if($this->substitutedOnly) {
unset($subdefNamesToDo[$subdef->get_name()]); unset($subdefNamesToDo[$name]);
continue; continue;
} }
} }
@@ -252,10 +285,10 @@ class BuildSubdefs extends Command
$subdefGenerator->generateSubdefs($record, $subdefNamesToDo); $subdefGenerator->generateSubdefs($record, $subdefNamesToDo);
} }
$this->verbose(sprintf(" subdefs[%s] done\n", join(',', $subdefNamesToDo))); $this->verbose(sprintf(" subdefs[%s] built\n", join(',', $subdefNamesToDo)));
} }
else { else {
$this->verbose(" nothing to do\n"); $this->verbose(" nothing to build\n");
} }
} }
catch(\Exception $e) { catch(\Exception $e) {

View File

@@ -235,6 +235,32 @@ class media_subdef extends media_abstract implements cache_cacheableInterface
return $this; return $this;
} }
/**
* delete this subdef
*
* @throws \Doctrine\DBAL\DBALException
*/
public function delete()
{
$subdef_id = $this->subdef_id;
$this->remove_file();
$connbas = $this->record->getDatabox()->get_connection();
$sql = "DELETE FROM subdef WHERE subdef_id = :subdef_id";
$stmt = $connbas->prepare($sql);
$stmt->execute(['subdef_id'=>$subdef_id]);
$stmt->closeCursor();
$sql = "DELETE FROM permalinks WHERE subdef_id = :subdef_id";
$stmt = $connbas->prepare($sql);
$stmt->execute(['subdef_id'=>$subdef_id]);
$stmt->closeCursor();
$this->delete_data_from_cache();
$this->record->delete_data_from_cache(record_adapter::CACHE_SUBDEFS);
}
/** /**
* Find a substitution file for a subdef * Find a substitution file for a subdef
* *

View File

@@ -691,7 +691,7 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
} }
$rs = $this->getDataboxConnection()->fetchAll( $rs = $this->getDataboxConnection()->fetchAll(
'SELECT name FROM subdef s LEFT JOIN record r ON s.record_id = r.record_id WHERE r.record_id = :record_id', 'SELECT name FROM subdef WHERE record_id = :record_id',
['record_id' => $this->getRecordId()] ['record_id' => $this->getRecordId()]
); );