factoriser
This commit is contained in:
		
							parent
							
								
									afaa816eff
								
							
						
					
					
						commit
						ec82ea80ee
					
				
							
								
								
									
										111
									
								
								src/cli/AbstractStorageApp.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								src/cli/AbstractStorageApp.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,111 @@ | ||||
| <?php | ||||
| namespace nulib\cli; | ||||
| 
 | ||||
| use nulib\A; | ||||
| use nulib\app\cli\Application; | ||||
| use nulib\db\Capacitor; | ||||
| use nulib\db\CapacitorChannel; | ||||
| use nulib\db\CapacitorStorage; | ||||
| use nulib\ext\yaml; | ||||
| use nulib\file\Stream; | ||||
| use nulib\output\msg; | ||||
| 
 | ||||
| abstract class AbstractStorageApp extends Application { | ||||
|   const ACTION_RESET = 0, ACTION_QUERY = 1, ACTION_SQL = 2; | ||||
| 
 | ||||
|   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); | ||||
|   } | ||||
| 
 | ||||
|   protected function storageCtl(CapacitorStorage $storage): void { | ||||
|     $args = $this->args; | ||||
| 
 | ||||
|     $channelClass = $this->channelClass; | ||||
|     $tableName = $this->tableName; | ||||
|     if ($channelClass === null && $tableName === null) { | ||||
|       $name = A::shift($args); | ||||
|       if ($name !== null) { | ||||
|         if (!$storage->channelExists($name, $row)) { | ||||
|           self::die("$name: nom de canal de données introuvable"); | ||||
|         } | ||||
|         if ($row["class_name"] !== "class@anonymous") $channelClass = $row["class_name"]; | ||||
|         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; | ||||
|       foreach ($storage->getChannels() as $row) { | ||||
|         msg::print($row["name"]); | ||||
|         $found = true; | ||||
|       } | ||||
|       if ($found) self::exit(); | ||||
|       self::die("Vous devez spécifier le canal de données"); | ||||
|     } | ||||
|     $capacitor = new Capacitor($storage, $channel); | ||||
| 
 | ||||
|     switch ($this->action) { | ||||
|     case self::ACTION_RESET: | ||||
|       $capacitor->reset(true); | ||||
|       break; | ||||
|     case self::ACTION_QUERY: | ||||
|       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,26 +1,23 @@ | ||||
| <?php | ||||
| namespace nulib\cli; | ||||
| 
 | ||||
| use nulib\A; | ||||
| use nulib\app\cli\Application; | ||||
| use nulib\db\Capacitor; | ||||
| use nulib\db\CapacitorChannel; | ||||
| use nulib\db\mysql\MysqlStorage; | ||||
| use nulib\ext\yaml; | ||||
| use nulib\file\Stream; | ||||
| use nulib\output\msg; | ||||
| use nur\config; | ||||
| 
 | ||||
| class StorageMysqlApp extends Application { | ||||
|   const ACTION_QUERY = 0, ACTION_SQL = 1; | ||||
| 
 | ||||
| class StorageMysqlApp extends AbstractStorageApp { | ||||
|   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", | ||||
|       "DBCONN [CHANNEL_NAME | -t TABLE | -c CHANNEL_CLASS] [--query] key=value...", | ||||
|       "DBCONN [CHANNEL_NAME | -t TABLE | -c CHANNEL_CLASS] --sql-create", | ||||
|     ], | ||||
|     ["-t", "--table-name", "args" => 1, | ||||
|       "help" => "nom de la table porteuse du canal de données", | ||||
| @ -28,6 +25,9 @@ class StorageMysqlApp extends Application { | ||||
|     ["-c", "--channel-class", "args" => 1, | ||||
|       "help" => "nom de la classe dérivée de CapacitorChannel", | ||||
|     ], | ||||
|     ["-z", "--reset", "name" => "action", "value" => self::ACTION_RESET, | ||||
|       "help" => "réinitialiser le canal", | ||||
|     ], | ||||
|     ["--query", "name" => "action", "value" => self::ACTION_QUERY, | ||||
|       "help" => "lister les lignes correspondant aux valeurs spécifiées. c'est l'action par défaut", | ||||
|     ], | ||||
| @ -35,88 +35,13 @@ class StorageMysqlApp extends Application { | ||||
|       "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; | ||||
|     $dbconn = A::shift($this->args); | ||||
|     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; | ||||
|     $storage = new MysqlStorage($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; | ||||
|     } | ||||
|     $this->storageCtl($storage); | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -1,29 +1,16 @@ | ||||
| <?php | ||||
| namespace nulib\cli; | ||||
| 
 | ||||
| use nulib\app\cli\Application; | ||||
| use nulib\db\Capacitor; | ||||
| use nulib\db\CapacitorChannel; | ||||
| use nulib\A; | ||||
| use nulib\db\sqlite\SqliteStorage; | ||||
| use nulib\ext\yaml; | ||||
| use nulib\file\Stream; | ||||
| use nulib\output\msg; | ||||
| 
 | ||||
| class StorageSqliteApp extends Application { | ||||
|   const ACTION_QUERY = 0, ACTION_SQL = 1; | ||||
| 
 | ||||
| class StorageSqliteApp extends AbstractStorageApp { | ||||
|   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", | ||||
|       "DBFILE [CHANNEL_NAME | -t TABLE | -c CHANNEL_CLASS] [--query] key=value...", | ||||
|       "DBFILE [CHANNEL_NAME | -t TABLE | -c CHANNEL_CLASS] --sql-create", | ||||
|     ], | ||||
|     ["-t", "--table-name", "args" => 1, | ||||
|       "help" => "nom de la table porteuse du canal de données", | ||||
| @ -31,6 +18,9 @@ class StorageSqliteApp extends Application { | ||||
|     ["-c", "--channel-class", "args" => 1, | ||||
|       "help" => "nom de la classe dérivée de CapacitorChannel", | ||||
|     ], | ||||
|     ["-z", "--reset", "name" => "action", "value" => self::ACTION_RESET, | ||||
|       "help" => "réinitialiser le canal", | ||||
|     ], | ||||
|     ["--query", "name" => "action", "value" => self::ACTION_QUERY, | ||||
|       "help" => "lister les lignes correspondant aux valeurs spécifiées. c'est l'action par défaut", | ||||
|     ], | ||||
| @ -39,103 +29,12 @@ class StorageSqliteApp extends Application { | ||||
|     ], | ||||
|   ]; | ||||
| 
 | ||||
|   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; | ||||
|     $dbfile = A::shift($this->args); | ||||
|     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(); | ||||
| 
 | ||||
|     $name = $this->name; | ||||
|     $channelClass = $this->channelClass; | ||||
|     $tableName = $this->tableName; | ||||
|     if ($name !== null) { | ||||
|       if (!$storage->channelExists($name, $row)) { | ||||
|         self::die("$name: nom de canal de données introuvable"); | ||||
|       } | ||||
|       if ($row["class_name"] !== "class@anonymous") $channelClass = $row["class_name"]; | ||||
|       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; | ||||
|       foreach ($storage->getChannels() as $row) { | ||||
|         msg::print($row["name"]); | ||||
|         $found = true; | ||||
|       } | ||||
|       if ($found) self::exit(); | ||||
|       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; | ||||
|       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; | ||||
|     } | ||||
|     $this->storageCtl($storage); | ||||
|   } | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user