Multiple fixes

* PDO shell improvements: .query command, -r and --db on command
  line to read commands from file or preselect database.
* Updated build scripts and readme
This commit is contained in:
2021-12-16 16:01:17 +01:00
parent 16753e1892
commit 0c7fc0196a
8 changed files with 126 additions and 59 deletions

View File

@ -15,12 +15,29 @@ class PdoShellCommand extends Command {
protected function configure() {
$this->setName("pdo:shell");
$this->setDescription("Launch an interactive PDO shell");
$this->addOption("db", null, InputOption::VALUE_REQUIRED, "Select database resource", "db");
$this->addOption("read", "r", InputOption::VALUE_REQUIRED, "Read commands to execute from file");
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$shell = new Shell\PdoShell($output);
$shell->run();
$db = $input->getOption("db");
$read = $input->getOption("read");
if ($read) {
if (!file_exists($read)) {
$output->writeln("<error>File not found: {$read}</>");
return Command::FAILURE;
}
$file = file($read, FILE_IGNORE_NEW_LINES);
$shell->runCommands($file);
} else {
$shell->runCommands([ ".select {$db}" ]);
$shell->run();
}
return Command::SUCCESS;
}

View File

@ -28,6 +28,7 @@ class PdoShell {
private array $defaultOptions = [
'output' => 'table',
'table.maxwidth' => 40,
'table.style' => 'box',
];
public function __construct(OutputInterface $output)
@ -38,7 +39,7 @@ class PdoShell {
private function promptForCommand()
{
$prompt = sprintf("PDO:[%s%s]> ", $this->resource, $this->db?"":"*");
$prompt = sprintf("PDO:[%s%s]> ", $this->resource, $this->db?"":"?");
$input = readline($prompt);
return $input;
@ -81,6 +82,18 @@ class PdoShell {
}
}
public function runCommands(array $commands)
{
foreach ($commands as $input) {
if (str_starts_with($input, ".")) {
[$cmd,$args] = $this->parseCommand($input);
$this->handleCommand($cmd, $args);
} else {
$this->doQuery($input, []);
}
}
}
private function handleCommand(string $command, array $args)
{
@ -94,9 +107,14 @@ class PdoShell {
case '.var':
$this->doVarCommand($args);
break;
case '.query':
$this->doQueryCommand($args);
break;
case '.help':
$this->doHelpCommand($args);
break;
case '.quit':
case '.exit':
$this->running = false;
break;;
@ -112,8 +130,9 @@ class PdoShell {
'.select RES' => "Select the database resource to query",
'.set [KEY [VALUE]]' => "Set a configuration value",
'.var [NAME [VALUE]]' => "Set a variable, or show variable value",
'.exit' => "Exit the shell",
'.exit|.quit' => "Exit the shell",
'SQL' => "Run SQL against the database",
'.query SQL [PARAM..]' => "Escape and run a query using ? as placeholder",
];
foreach ($cmds as $cmd=>$info) {
$this->output->writeln(" <options=bold>{$cmd}</> - <info>{$info}</>");
@ -150,7 +169,7 @@ class PdoShell {
if ($res instanceof PdoResource) {
$this->db = $res;
$this->resource = $name;
$this->output->writeln("<fg=green>Seleced {$name}</>");
$this->output->writeln("<fg=green>** Selected {$name}</>");
} else {
$this->output->writeln("<error>Invalid resource {$name}</>");
}
@ -176,8 +195,17 @@ class PdoShell {
}
}
private function doQueryCommand(array $args)
{
$query = array_shift($args);
$this->doQuery($query, $args);
}
private function doQuery(string $query, array $params=[])
{
if (!$query) {
return;
}
if (!$this->db) {
$this->output->writeln("<error>No database resource selected</>");
return;
@ -210,7 +238,7 @@ class PdoShell {
if (count($res) == 0) return;
$table = new Table($this->output);
$table->setHeaders(array_keys(reset($res)));
$table->setStyle($this->options['table.style']);
$max = $this->options['table.maxwidth'];
foreach ($res as $row) {