déplacer yaml dans nur/ser74
This commit is contained in:
		
							parent
							
								
									2d4801e135
								
							
						
					
					
						commit
						9a6acf912b
					
				@ -9,7 +9,6 @@
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	],
 | 
						],
 | 
				
			||||||
	"require": {
 | 
						"require": {
 | 
				
			||||||
		"symfony/yaml": "^5.0",
 | 
					 | 
				
			||||||
		"php": ">=7.4"
 | 
							"php": ">=7.4"
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	"require-dev": {
 | 
						"require-dev": {
 | 
				
			||||||
@ -59,15 +58,8 @@
 | 
				
			|||||||
	"bin": [
 | 
						"bin": [
 | 
				
			||||||
		"nur_bin/compctl.php",
 | 
							"nur_bin/compctl.php",
 | 
				
			||||||
		"nur_bin/compdep.php",
 | 
							"nur_bin/compdep.php",
 | 
				
			||||||
		"nur_bin/cachectl.php",
 | 
					 | 
				
			||||||
		"nur_bin/dumpser.php",
 | 
					 | 
				
			||||||
		"nur_bin/datectl.php",
 | 
							"nur_bin/datectl.php",
 | 
				
			||||||
		"nur_bin/fsvdiff.php",
 | 
							"nur_bin/fsvdiff.php"
 | 
				
			||||||
		"nur_bin/ldap-delete.php",
 | 
					 | 
				
			||||||
		"nur_bin/ldap-get-infos.php",
 | 
					 | 
				
			||||||
		"nur_bin/ldap-search.php",
 | 
					 | 
				
			||||||
		"nur_bin/sqlite-storage.php",
 | 
					 | 
				
			||||||
		"nur_bin/mysql-storage.php"
 | 
					 | 
				
			||||||
	],
 | 
						],
 | 
				
			||||||
	"scripts": {
 | 
						"scripts": {
 | 
				
			||||||
		"uc": "@php sbin/update_classes.php"
 | 
							"uc": "@php sbin/update_classes.php"
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										1025
									
								
								composer.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1025
									
								
								composer.lock
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -1,119 +0,0 @@
 | 
				
			|||||||
#!/usr/bin/php
 | 
					 | 
				
			||||||
<?php
 | 
					 | 
				
			||||||
require $_composer_autoload_path?? __DIR__.'/../vendor/autoload.php';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use nur\b\io\CacheFile;
 | 
					 | 
				
			||||||
use nur\cli\Application;
 | 
					 | 
				
			||||||
use nur\msg;
 | 
					 | 
				
			||||||
use nur\path;
 | 
					 | 
				
			||||||
use nur\yaml;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Application::run(new class extends Application {
 | 
					 | 
				
			||||||
  const ACTION_READ = 10, ACTION_INFOS = 20, ACTION_CLEAN = 30;
 | 
					 | 
				
			||||||
  const ACTION_UPDATE = 40, ACTION_UPDATE_ADD = 41, ACTION_UPDATE_SUB = 42, ACTION_UPDATE_SET = 43;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const ARGS = [
 | 
					 | 
				
			||||||
    "merge" => parent::ARGS,
 | 
					 | 
				
			||||||
    "purpose" => "gestion de fichiers cache",
 | 
					 | 
				
			||||||
    ["-r", "--read", "name" => "action", "value" => self::ACTION_READ,
 | 
					 | 
				
			||||||
      "help" => "Afficher le contenu d'un fichier cache",
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    ["-i", "--infos", "name" => "action", "value" => self::ACTION_INFOS,
 | 
					 | 
				
			||||||
      "help" => "Afficher des informations sur le fichier cache",
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    ["-k", "--clean", "name" => "action", "value" => self::ACTION_CLEAN,
 | 
					 | 
				
			||||||
      "help" => "Supprimer le fichier cache s'il a expiré",
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    ["-a", "--add-duration", "args" => 1,
 | 
					 | 
				
			||||||
      "action" => [null, "->setActionUpdate", self::ACTION_UPDATE_ADD],
 | 
					 | 
				
			||||||
      "help" => "Ajouter le nombre de secondes spécifié à la durée du cache",
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    ["-b", "--sub-duration", "args" => 1,
 | 
					 | 
				
			||||||
      "action" => [null, "->setActionUpdate", self::ACTION_UPDATE_SUB],
 | 
					 | 
				
			||||||
      "help" => "Enlever le nombre de secondes spécifié à la durée du cache",
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    ["-s", "--set-duration", "args" => 1,
 | 
					 | 
				
			||||||
      "action" => [null, "->setActionUpdate", self::ACTION_UPDATE_SET],
 | 
					 | 
				
			||||||
      "help" => "Mettre à jour la durée du cache à la valeur spécifiée",
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
  ];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  protected $action = self::ACTION_READ;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  protected $updateAction, $updateDuration;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  protected $args;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function setActionUpdate(int $action, $updateDuration): void {
 | 
					 | 
				
			||||||
    $this->action = self::ACTION_UPDATE;
 | 
					 | 
				
			||||||
    switch ($action) {
 | 
					 | 
				
			||||||
    case self::ACTION_UPDATE_SUB: $this->updateAction = -1; break;
 | 
					 | 
				
			||||||
    case self::ACTION_UPDATE_SET: $this->updateAction = 0; break;
 | 
					 | 
				
			||||||
    case self::ACTION_UPDATE_ADD: $this->updateAction = 1; break;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    $this->updateDuration = $updateDuration;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  protected function findCaches(string $dir, ?array &$files): void {
 | 
					 | 
				
			||||||
    foreach (glob("$dir/*") as $file) {
 | 
					 | 
				
			||||||
      if (is_dir($file)) {
 | 
					 | 
				
			||||||
        $this->findCaches($file, $files);
 | 
					 | 
				
			||||||
      } elseif (is_file($file) && fnmatch("*.cache", $file)) {
 | 
					 | 
				
			||||||
        $files[] = $file;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function main() {
 | 
					 | 
				
			||||||
    $files = [];
 | 
					 | 
				
			||||||
    foreach ($this->args as $arg) {
 | 
					 | 
				
			||||||
      if (is_dir($arg)) {
 | 
					 | 
				
			||||||
        $this->findCaches($arg, $files);
 | 
					 | 
				
			||||||
      } elseif (is_file($arg)) {
 | 
					 | 
				
			||||||
        $files[] = $arg;
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        msg::warning("$arg: fichier invalide ou introuvable");
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    $showSection = count($files) > 1;
 | 
					 | 
				
			||||||
    foreach ($files as $file) {
 | 
					 | 
				
			||||||
      switch ($this->action) {
 | 
					 | 
				
			||||||
      case self::ACTION_READ:
 | 
					 | 
				
			||||||
        if ($showSection) msg::section($file);
 | 
					 | 
				
			||||||
        $cache = new CacheFile($file, [
 | 
					 | 
				
			||||||
          "duration" => "INF",
 | 
					 | 
				
			||||||
          "override_duration" => true,
 | 
					 | 
				
			||||||
        ]);
 | 
					 | 
				
			||||||
        yaml::dump($cache->get());
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
      case self::ACTION_INFOS:
 | 
					 | 
				
			||||||
        if ($showSection) msg::section($file);
 | 
					 | 
				
			||||||
        $cache = new CacheFile($file);
 | 
					 | 
				
			||||||
        yaml::dump($cache->getInfos());
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
      case self::ACTION_CLEAN:
 | 
					 | 
				
			||||||
        msg::action(path::ppath($file));
 | 
					 | 
				
			||||||
        $cache = new CacheFile($file);
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
          if ($cache->deleteExpired()) msg::asuccess("fichier supprimé");
 | 
					 | 
				
			||||||
          else msg::astep("fichier non expiré");
 | 
					 | 
				
			||||||
        } catch (Exception $e) {
 | 
					 | 
				
			||||||
          msg::afailure(null, $e);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
      case self::ACTION_UPDATE:
 | 
					 | 
				
			||||||
        msg::action(path::ppath($file));
 | 
					 | 
				
			||||||
        $cache = new CacheFile($file);
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
          $cache->updateDuration($this->updateDuration, $this->updateAction);
 | 
					 | 
				
			||||||
          msg::asuccess("fichier mis à jour");
 | 
					 | 
				
			||||||
        } catch (Exception $e) {
 | 
					 | 
				
			||||||
          msg::afailure(null, $e);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
      default:
 | 
					 | 
				
			||||||
        self::die("$this->action: action non implémentée");
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
@ -1,36 +0,0 @@
 | 
				
			|||||||
#!/usr/bin/php
 | 
					 | 
				
			||||||
<?php
 | 
					 | 
				
			||||||
require $_composer_autoload_path?? __DIR__.'/../vendor/autoload.php';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use nur\b\io\CacheFile;
 | 
					 | 
				
			||||||
use nur\b\io\SharedFile;
 | 
					 | 
				
			||||||
use nur\cli\Application;
 | 
					 | 
				
			||||||
use nur\msg;
 | 
					 | 
				
			||||||
use nur\path;
 | 
					 | 
				
			||||||
use nur\yaml;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Application::run(new class extends Application {
 | 
					 | 
				
			||||||
  const ARGS = [
 | 
					 | 
				
			||||||
    "merge" => parent::ARGS,
 | 
					 | 
				
			||||||
    "purpose" => "afficher des données sérialisées",
 | 
					 | 
				
			||||||
  ];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  protected $args;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function main() {
 | 
					 | 
				
			||||||
    $files = [];
 | 
					 | 
				
			||||||
    foreach ($this->args as $arg) {
 | 
					 | 
				
			||||||
      if (is_file($arg)) {
 | 
					 | 
				
			||||||
        $files[] = $arg;
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        msg::warning("$arg: fichier invalide ou introuvable");
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    $showSection = count($files) > 1;
 | 
					 | 
				
			||||||
    foreach ($files as $file) {
 | 
					 | 
				
			||||||
      if ($showSection) msg::section($file);
 | 
					 | 
				
			||||||
      $sfile = new SharedFile($file);
 | 
					 | 
				
			||||||
      yaml::dump($sfile->unserialize());
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
@ -1,127 +0,0 @@
 | 
				
			|||||||
#!/usr/bin/php
 | 
					 | 
				
			||||||
<?php
 | 
					 | 
				
			||||||
require $_composer_autoload_path?? __DIR__.'/../vendor/autoload.php';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use nur\b\io\CacheFile;
 | 
					 | 
				
			||||||
use nur\cli\Application;
 | 
					 | 
				
			||||||
use nur\config;
 | 
					 | 
				
			||||||
use nur\msg;
 | 
					 | 
				
			||||||
use nur\path;
 | 
					 | 
				
			||||||
use nur\sery\db\Capacitor;
 | 
					 | 
				
			||||||
use nur\sery\db\CapacitorChannel;
 | 
					 | 
				
			||||||
use nur\sery\db\mysql\MysqlStorage;
 | 
					 | 
				
			||||||
use nur\sery\db\sqlite\SqliteStorage;
 | 
					 | 
				
			||||||
use nur\sery\file\Stream;
 | 
					 | 
				
			||||||
use nur\yaml;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Application::run(new class extends Application {
 | 
					 | 
				
			||||||
  const ACTION_QUERY = 0, ACTION_SQL = 1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const ARGS = [
 | 
					 | 
				
			||||||
    "merge" => parent::ARGS,
 | 
					 | 
				
			||||||
    "purpose" => "gestion d'un capacitor mysql",
 | 
					 | 
				
			||||||
    "usage" => [
 | 
					 | 
				
			||||||
      "-d DBCONN -c CHANNEL [--query] key=value...",
 | 
					 | 
				
			||||||
      "-d DBCONN -c CHANNEL --sql-create",
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    ["-d", "--dbconn", "args" => 1,
 | 
					 | 
				
			||||||
      "help" => "nom de la connexion à 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 $dbconn = 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() {
 | 
					 | 
				
			||||||
    $dbconn = $this->dbconn;
 | 
					 | 
				
			||||||
    if ($dbconn === null) self::die("Vous devez spécifier la base de données");
 | 
					 | 
				
			||||||
    $tmp = config::db($dbconn);
 | 
					 | 
				
			||||||
    if ($tmp === null) self::die("$dbconn: base de données invalide");
 | 
					 | 
				
			||||||
    $dbconn = $tmp;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if ($this->channelClass !== null) {
 | 
					 | 
				
			||||||
      $channelClass = str_replace("/", "\\", $this->channelClass);
 | 
					 | 
				
			||||||
      $channel = new $channelClass;
 | 
					 | 
				
			||||||
    } elseif ($this->tableName !== null) {
 | 
					 | 
				
			||||||
      $channel = new class($this->tableName) extends CapacitorChannel {
 | 
					 | 
				
			||||||
        function __construct(?string $name=null) {
 | 
					 | 
				
			||||||
          parent::__construct($name);
 | 
					 | 
				
			||||||
          $this->tableName = $name;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      };
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      self::die("Vous devez spécifier le canal de données");
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $storage = new MysqlStorage($dbconn);
 | 
					 | 
				
			||||||
    $capacitor = new Capacitor($storage, $channel);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    switch ($this->action) {
 | 
					 | 
				
			||||||
    case self::ACTION_QUERY:
 | 
					 | 
				
			||||||
      $args = $this->args;
 | 
					 | 
				
			||||||
      if (!$args) {
 | 
					 | 
				
			||||||
        # lister les id
 | 
					 | 
				
			||||||
        $out = new Stream(STDOUT);
 | 
					 | 
				
			||||||
        $primaryKeys = $storage->getPrimaryKeys($channel);
 | 
					 | 
				
			||||||
        $rows = $storage->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;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
@ -1,156 +0,0 @@
 | 
				
			|||||||
#!/usr/bin/php
 | 
					 | 
				
			||||||
<?php
 | 
					 | 
				
			||||||
require $_composer_autoload_path?? __DIR__.'/../vendor/autoload.php';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use nur\b\io\CacheFile;
 | 
					 | 
				
			||||||
use nur\cli\Application;
 | 
					 | 
				
			||||||
use nur\msg;
 | 
					 | 
				
			||||||
use nur\path;
 | 
					 | 
				
			||||||
use nur\sery\db\Capacitor;
 | 
					 | 
				
			||||||
use nur\sery\db\CapacitorChannel;
 | 
					 | 
				
			||||||
use nur\sery\db\sqlite\SqliteStorage;
 | 
					 | 
				
			||||||
use nur\sery\file\Stream;
 | 
					 | 
				
			||||||
use nur\yaml;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Application::run(new class extends Application {
 | 
					 | 
				
			||||||
  const ACTION_QUERY = 0, ACTION_SQL = 1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const ARGS = [
 | 
					 | 
				
			||||||
    "merge" => 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");
 | 
					 | 
				
			||||||
      else self::exit();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    $capacitor = new Capacitor($storage, $channel);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    switch ($this->action) {
 | 
					 | 
				
			||||||
    case self::ACTION_QUERY:
 | 
					 | 
				
			||||||
      $args = $this->args;
 | 
					 | 
				
			||||||
      if (!$args) {
 | 
					 | 
				
			||||||
        # lister les id
 | 
					 | 
				
			||||||
        $out = new Stream(STDOUT);
 | 
					 | 
				
			||||||
        $primaryKeys = $storage->getPrimaryKeys($channel);
 | 
					 | 
				
			||||||
        $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;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
@ -1,37 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
namespace nur;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use nur\b\io\IOException;
 | 
					 | 
				
			||||||
use nur\b\io\IReader;
 | 
					 | 
				
			||||||
use nur\b\ValueException;
 | 
					 | 
				
			||||||
use Symfony\Component\Yaml\Exception\ParseException;
 | 
					 | 
				
			||||||
use Symfony\Component\Yaml\Yaml as SymfonyYaml;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Class yaml: lecture de données yaml
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
class yaml {
 | 
					 | 
				
			||||||
  /**
 | 
					 | 
				
			||||||
   * @throws ValueException si $input n'est pas un string ni une instance de
 | 
					 | 
				
			||||||
   * {@link IReader}
 | 
					 | 
				
			||||||
   * @throws IOException si une erreur de lecture s'est produite
 | 
					 | 
				
			||||||
   */
 | 
					 | 
				
			||||||
  static final function load($input): array {
 | 
					 | 
				
			||||||
    $contents = reader::get_contents($input);
 | 
					 | 
				
			||||||
    try {
 | 
					 | 
				
			||||||
      return A::with(SymfonyYaml::parse($contents));
 | 
					 | 
				
			||||||
    } catch (ParseException $e) {
 | 
					 | 
				
			||||||
      $message = "parse error";
 | 
					 | 
				
			||||||
      if (is_string($input)) $message .= " while loading $input";
 | 
					 | 
				
			||||||
      throw new IOException($message, 0, $e);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  static final function with($data, int $indent=2, int $flags=0): string {
 | 
					 | 
				
			||||||
    return SymfonyYaml::dump($data, PHP_INT_MAX, $indent, $flags);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  static final function dump($data, $output=null, int $indent=2, int $flags=0): void {
 | 
					 | 
				
			||||||
    writer::with($output)->write(self::with($data, $indent, $flags))->close();
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,35 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
namespace nur\sery\ext;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use nur\sery\cl;
 | 
					 | 
				
			||||||
use nur\sery\file;
 | 
					 | 
				
			||||||
use nur\sery\os\IOException;
 | 
					 | 
				
			||||||
use Symfony\Component\Yaml\Exception\ParseException;
 | 
					 | 
				
			||||||
use Symfony\Component\Yaml\Yaml as SymfonyYaml;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Class yaml: lecture de données yaml
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
class yaml {
 | 
					 | 
				
			||||||
  /**
 | 
					 | 
				
			||||||
   * @throws IOException si une erreur de lecture s'est produite
 | 
					 | 
				
			||||||
   */
 | 
					 | 
				
			||||||
  static final function load($input): array {
 | 
					 | 
				
			||||||
    $contents = file::reader($input)->getContents();
 | 
					 | 
				
			||||||
    try {
 | 
					 | 
				
			||||||
      return cl::with(SymfonyYaml::parse($contents));
 | 
					 | 
				
			||||||
    } catch (ParseException $e) {
 | 
					 | 
				
			||||||
      $message = "parse error";
 | 
					 | 
				
			||||||
      if (is_string($input)) $message .= " while loading $input";
 | 
					 | 
				
			||||||
      throw new IOException($message, 0, $e);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  static final function with($data, int $indent=2, int $flags=0): string {
 | 
					 | 
				
			||||||
    return SymfonyYaml::dump($data, PHP_INT_MAX, $indent, $flags);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  static final function dump($data, $output=null, int $indent=2, int $flags=0): void {
 | 
					 | 
				
			||||||
    file::writer($output)->putContents(self::with($data, $indent, $flags));
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user