#!/usr/bin/php parent::ARGS, "purpose" => "gestion d'un capacitor sqlite", "usage" => [ "-f DBFILE -n CHANNEL [--query] key=value...", "-f DBFILE -n CHANNEL --sql-create", ], ["-f", "--dbfile", "args" => 1, "help" => "chemin vers la base de données", ], ["-n", "--name", "args" => 1, "help" => "nom du canal de données. table-name et channel-class sont chargés depuis la base de données", ], ["-t", "--table-name", "args" => 1, "help" => "nom de la table porteuse du canal de données", ], ["-c", "--channel-class", "args" => 1, "help" => "nom de la classe dérivée de CapacitorChannel", ], ["--query", "name" => "action", "value" => self::ACTION_QUERY, "help" => "lister les lignes correspondant aux valeurs spécifiées. c'est l'action par défaut", ], ["-s", "--sql-create", "name" => "action", "value" => self::ACTION_SQL, "help" => "afficher la requête pour créer la table", ], ]; protected ?string $dbfile = null; protected ?string $name = null; protected ?string $tableName = null; protected ?string $channelClass = null; protected int $action = self::ACTION_QUERY; protected ?array $args = null; protected static function isa_cond(string $arg, ?array &$ms=null): bool { return preg_match('/^(.+?)\s*(=|<>|<|>|<=|>=|(?:is\s+)?null|(?:is\s+)?not\s+null)\s*(.*)$/', $arg, $ms); } function main() { $dbfile = $this->dbfile; if ($dbfile === null) self::die("Vous devez spécifier la base de données"); if (!file_exists($dbfile)) self::die("$dbfile: fichier introuvable"); $storage = new SqliteStorage($dbfile); $db = $storage->db(); $haveChannels = $storage->tableExists("_channels"); $name = $this->name; $channelClass = $this->channelClass; $tableName = $this->tableName; if ($name !== null) { $row = null; if ($haveChannels) { $row = $db->one([ "select from _channels", "where" => ["name" => $name], ]); } if ($row === null) self::die("$name: nom de canal de données introuvable"); if ($row["class"] !== "class@anonymous") $channelClass = $row["class"]; else $tableName = $row["table_name"]; } if ($channelClass !== null) { $channelClass = str_replace("/", "\\", $channelClass); $channel = new $channelClass; } elseif ($tableName !== null) { $channel = new class($tableName) extends CapacitorChannel { function __construct(?string $name=null) { parent::__construct($name); $this->tableName = $name; } }; } else { $found = false; if ($haveChannels) { $rows = $db->all([ "select from _channels", ]); foreach ($rows as $row) { msg::print($row["name"]); $found = true; } } if (!$found) self::die("Vous devez spécifier le canal de données"); } $capacitor = new Capacitor($storage, $channel); switch ($this->action) { case self::ACTION_QUERY: $args = $this->args; var_export($args); #XXX if (!$args) { # lister les id $out = new Stream(STDOUT); $primaryKeys = $storage->getPrimaryKeys($channel); var_export($primaryKeys); #XXX $rows = $db->all([ "select", "cols" => $primaryKeys, "from" => $channel->getTableName(), ]); $out->fputcsv($primaryKeys); foreach ($rows as $row) { $rowIds = $storage->getRowIds($channel, $row); $out->fputcsv($rowIds); } } else { # afficher les lignes correspondantes if (count($args) == 1 && !self::isa_cond($args[0])) { $filter = $args[0]; } else { $filter = []; $ms = null; foreach ($args as $arg) { if (self::isa_cond($arg, $ms)) { $filter[$ms[1]] = [$ms[2], $ms[3]]; } else { $filter[$arg] = ["not null"]; } } } $first = true; $capacitor->each($filter, function ($item, $row) use (&$first) { if ($first) $first = false; else echo "---\n"; yaml::dump($row); }); } break; case self::ACTION_SQL: echo $capacitor->getCreateSql()."\n"; break; } } });