Updated PDO shell plugin

* Added .save and .show commands to PDO shell plugin
This commit is contained in:
Chris 2021-12-17 01:48:57 +01:00
parent 0c7fc0196a
commit 1eab339347
2 changed files with 105 additions and 0 deletions

View File

@ -0,0 +1,39 @@
# PDO Shell Plugin
This is a plugin to interactively work with PDO.
## Usage
The simplest use is invoking the shell directly:
$ spark pdo:shell
PDO[db]>
You are presented with a prompt containing the string "PDO", follwed by the currently
selected resource in brackets. Commands start with a period (`.`) and you can get a
list of the valid commands with `.help`.
To run a query, you can either run it directly:
PDO[db]> SELECT id FROM users WHERE username='bob'
Or let the shell do the escaping for you:
PDO[db]> .query "SELECT id FROM users WHERE username=?" bob
You can also read the commands from a file and have them executed as if they were
entered into the shell:
$ spark pdo:shell -r sparkrc
### Selecting the resource
This can be done from the command line:
$ spark pdo:shell --db otherdb
Or from within the shell:
PDO[db]> .select otherdb
PDO[otherdb]>

View File

@ -25,6 +25,8 @@ class PdoShell {
private array $options = []; private array $options = [];
private ?array $lastQuery = null;
private array $defaultOptions = [ private array $defaultOptions = [
'output' => 'table', 'output' => 'table',
'table.maxwidth' => 40, 'table.maxwidth' => 40,
@ -98,6 +100,12 @@ class PdoShell {
{ {
switch ($command) { switch ($command) {
case '.save':
$this->doSaveCommand($args);
break;
case '.show':
$this->doShowCommand($args);
break;
case '.select': case '.select':
$this->doSelectCommand($args); $this->doSelectCommand($args);
break; break;
@ -127,7 +135,9 @@ class PdoShell {
{ {
$cmds = [ $cmds = [
'.help' => "Show this help", '.help' => "Show this help",
'.save FILE' => "Save the last query and result to a .json file",
'.select RES' => "Select the database resource to query", '.select RES' => "Select the database resource to query",
'.show [FILE]' => "Show the last query, or one saved to file",
'.set [KEY [VALUE]]' => "Set a configuration value", '.set [KEY [VALUE]]' => "Set a configuration value",
'.var [NAME [VALUE]]' => "Set a variable, or show variable value", '.var [NAME [VALUE]]' => "Set a variable, or show variable value",
'.exit|.quit' => "Exit the shell", '.exit|.quit' => "Exit the shell",
@ -139,6 +149,54 @@ class PdoShell {
} }
} }
private function doSaveCommand(array $args)
{
if (empty($this->lastQuery)) {
$this->output->writeln("<error>No last query to save!</>");
return;
}
$filename = array_shift($args);
if (empty($filename)) {
for($n=0;$n<999;$n++) {
$filename = sprintf("query.%03d.json", $n);
if (!file_exists($filename)) break;
}
}
file_put_contents($filename, json_encode($this->lastQuery, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES));
$this->output->writeln("<info>Wrote {$filename}</>");
}
private function doShowCommand(array $args)
{
$file = array_shift($args);
if ($file) {
if (!file_exists($file)) {
$this->output->writeln("<error>File not found: {$file}</>");
return;
}
$json = json_decode(file_get_contents($file), true);
$query = $json['query']??'?';
$res = $json['result']??[];
} else {
$query = $this->lastQuery['query'];
$res = $this->lastQuery['result'];
}
$this->output->writeln("<comment>{$query}</>");
switch ($this->options['output']) {
case 'table':
$this->dumpQueryTable($res);
break;
case 'vertical':
$this->dumpQueryVertical($res);
break;
default:
print_r($res);
}
}
private function doSetCommand(array $args) private function doSetCommand(array $args)
{ {
$varname = array_shift($args); $varname = array_shift($args);
@ -221,6 +279,14 @@ class PdoShell {
return; return;
} }
$this->lastQuery = [
'timestamp' => microtime(true),
'resource' => $this->resource,
'query' => $query,
'params' => $params,
'result' => $res
];
switch ($this->options['output']) { switch ($this->options['output']) {
case 'table': case 'table':
$this->dumpQueryTable($res); $this->dumpQueryTable($res);