Tweak commands
This commit is contained in:
@ -22,7 +22,7 @@
|
|||||||
"repositories": {
|
"repositories": {
|
||||||
"slotdb-client": {
|
"slotdb-client": {
|
||||||
"type": "vcs",
|
"type": "vcs",
|
||||||
"url": "../slotdb-client-php"
|
"url": "git@dev.noccylabs.info:slotdb/slotdb-client-php.git"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"bin": [
|
"bin": [
|
||||||
|
8
composer.lock
generated
8
composer.lock
generated
@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "9dc3a3ca30d0b0d1698b2e4e26577e67",
|
"content-hash": "8140c4572894cc393ef74de8ad3fe56c",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "guzzlehttp/guzzle",
|
"name": "guzzlehttp/guzzle",
|
||||||
@ -593,8 +593,8 @@
|
|||||||
"version": "dev-master",
|
"version": "dev-master",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "../slotdb-client-php",
|
"url": "git@dev.noccylabs.info:slotdb/slotdb-client-php.git",
|
||||||
"reference": "4734ca5fe4ed02da5bc3e0df3c9ecbabc3474af3"
|
"reference": "e6e1e980eaa9500fc38bfd22dfdc23ca13258ad3"
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"psr/http-client": "^1.0"
|
"psr/http-client": "^1.0"
|
||||||
@ -620,7 +620,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "SlotDB PHP Client",
|
"description": "SlotDB PHP Client",
|
||||||
"time": "2025-03-14T14:34:28+00:00"
|
"time": "2025-03-15T13:25:21+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/console",
|
"name": "symfony/console",
|
||||||
|
@ -16,8 +16,8 @@ class Application extends \Symfony\Component\Console\Application
|
|||||||
$psr = new Client();
|
$psr = new Client();
|
||||||
$client = new SlotDbClient($psr, $baseUrl);
|
$client = new SlotDbClient($psr, $baseUrl);
|
||||||
|
|
||||||
$this->add(new Command\ImportCommand());
|
$this->add(new Command\ImportCommand($client));
|
||||||
$this->add(new Command\ExportCommand());
|
$this->add(new Command\ExportCommand($client));
|
||||||
|
|
||||||
$this->add(new Command\Slot\SlotCreateCommand($client));
|
$this->add(new Command\Slot\SlotCreateCommand($client));
|
||||||
$this->add(new Command\Slot\SlotQueryCommand($client));
|
$this->add(new Command\Slot\SlotQueryCommand($client));
|
||||||
|
@ -2,10 +2,73 @@
|
|||||||
|
|
||||||
namespace SlotDb\Cli\Command;
|
namespace SlotDb\Cli\Command;
|
||||||
|
|
||||||
|
use SlotDb\Client\SlotDbClient;
|
||||||
use Symfony\Component\Console\Attribute\AsCommand;
|
use Symfony\Component\Console\Attribute\AsCommand;
|
||||||
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
use Symfony\Component\Console\Input\InputOption;
|
||||||
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
|
||||||
#[AsCommand(name:"export", description:"Export the database to a file")]
|
#[AsCommand(name:"export", description:"Export the database to a file")]
|
||||||
class ExportCommand extends BaseCommand
|
class ExportCommand extends BaseCommand
|
||||||
{
|
{
|
||||||
|
public function __construct(
|
||||||
|
private readonly SlotDbClient $client
|
||||||
|
)
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function configure()
|
||||||
|
{
|
||||||
|
$this->addOption("all-props", "A", InputOption::VALUE_NONE, "Include all slot properties. If not specified, properties that match the group property will be stripped.");
|
||||||
|
$this->addOption("output", "o", InputOption::VALUE_REQUIRED, "Write to file instead of standard output");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||||
|
{
|
||||||
|
// TODO implement paging
|
||||||
|
|
||||||
|
$groups = $this->client->findGroups();
|
||||||
|
$indexedGroups = array_combine(
|
||||||
|
array_map(fn($group) => $group['_group'], $groups),
|
||||||
|
array_values($groups)
|
||||||
|
);
|
||||||
|
|
||||||
|
$slots = $this->client->findSlots();
|
||||||
|
if (!$input->getOption("all-props")) {
|
||||||
|
foreach ($slots as &$slot) {
|
||||||
|
if ($slot['_group'] && isset($indexedGroups[$slot['_group']])) {
|
||||||
|
$group = $indexedGroups[$slot['_group']];
|
||||||
|
foreach ($slot as $k=>$v) {
|
||||||
|
if (str_starts_with($k,"_")) continue;
|
||||||
|
if (isset($group[$k]) && $group[$k] == $v) {
|
||||||
|
unset($slot[$k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$export = json_encode([
|
||||||
|
'comment' => "This is an exported SlotDB database.",
|
||||||
|
'timestamp' => date('Y-m-d H:i:s P'),
|
||||||
|
'generator' => "SlotCLI v".APP_VERSION." (".APP_BUILT.")",
|
||||||
|
'export' => [
|
||||||
|
'schemas' => [],
|
||||||
|
'hooks' => [],
|
||||||
|
'groups' => $groups,
|
||||||
|
'slots' => $slots,
|
||||||
|
],
|
||||||
|
], JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
|
||||||
|
|
||||||
|
if ($input->getOption("output")) {
|
||||||
|
$file = $input->getOption("output");
|
||||||
|
file_put_contents($file, $export."\n");
|
||||||
|
} else {
|
||||||
|
$output->writeln($export);
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -42,8 +42,14 @@ class GroupFindCommand extends Command
|
|||||||
foreach ($groups as $group) {
|
foreach ($groups as $group) {
|
||||||
$row = [];
|
$row = [];
|
||||||
foreach ($keys as $key) {
|
foreach ($keys as $key) {
|
||||||
$row[] = isset($group[$key]) ? json_encode($group[$key]) : null;
|
$row[] = isset($group[$key]) ? $group[$key] : null;
|
||||||
}
|
}
|
||||||
|
$row = array_map(fn($v) => match(true) {
|
||||||
|
is_bool($v) => "<fg=magenta>".($v?"true":"false")."</>",
|
||||||
|
is_int($v) => "<fg=cyan>{$v}</>",
|
||||||
|
is_string($v) => "<fg=yellow>{$v}</>",
|
||||||
|
default => $v,
|
||||||
|
}, $row);
|
||||||
$table->addRow($row);
|
$table->addRow($row);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ class GroupQueryCommand extends Command
|
|||||||
try {
|
try {
|
||||||
$group = $this->client->queryGroup($groupId);
|
$group = $this->client->queryGroup($groupId);
|
||||||
} catch (\RuntimeException $e) {
|
} catch (\RuntimeException $e) {
|
||||||
$output->writeln("<error>Invalid group id: {$slotId}</>");
|
$output->writeln("<error>Invalid group id: {$groupId}</>");
|
||||||
return self::INVALID;
|
return self::INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,10 +2,68 @@
|
|||||||
|
|
||||||
namespace SlotDb\Cli\Command;
|
namespace SlotDb\Cli\Command;
|
||||||
|
|
||||||
|
use SlotDb\Client\SlotDbClient;
|
||||||
use Symfony\Component\Console\Attribute\AsCommand;
|
use Symfony\Component\Console\Attribute\AsCommand;
|
||||||
|
use Symfony\Component\Console\Input\InputArgument;
|
||||||
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
use Symfony\Component\Console\Input\InputOption;
|
||||||
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||||
|
|
||||||
#[AsCommand(name:"import", description:"Import database from file")]
|
#[AsCommand(name:"import", description:"Import database from file")]
|
||||||
class ImportCommand extends BaseCommand
|
class ImportCommand extends BaseCommand
|
||||||
{
|
{
|
||||||
|
public function __construct(
|
||||||
|
private readonly SlotDbClient $client
|
||||||
|
)
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function configure()
|
||||||
|
{
|
||||||
|
$this->addOption("hard-reset", "R", InputOption::VALUE_NONE, "Completely wipe the database before importing the new data.");
|
||||||
|
$this->addArgument("filename", InputArgument::OPTIONAL, "Filename to read from, if omitted read standard input.");
|
||||||
|
$this->addOption("assume-yes", "y", InputOption::VALUE_NONE, "Assume yes on all questions.");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||||
|
{
|
||||||
|
if ($input->getArgument("filename")) {
|
||||||
|
$file = $input->getArgument("filename");
|
||||||
|
$json = file_get_contents($file);
|
||||||
|
} else {
|
||||||
|
$json = stream_get_contents(STDIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
$export = json_decode($json);
|
||||||
|
|
||||||
|
$output->writeln("File was generated <fg=yellow>{$export->timestamp}</>");
|
||||||
|
$output->writeln("Generated using <fg=yellow>{$export->generator}</>");
|
||||||
|
$output->writeln("");
|
||||||
|
if (!$input->getOption("assume-yes")) {
|
||||||
|
$confirm = (new SymfonyStyle($input, $output))->confirm("Do you want to continue", false);
|
||||||
|
if (!$confirm) {
|
||||||
|
return self::FAILURE;
|
||||||
|
}
|
||||||
|
$output->writeln("");
|
||||||
|
}
|
||||||
|
|
||||||
|
$output->writeln("+ <options=bold>Importing schemas...</>");
|
||||||
|
|
||||||
|
$output->writeln("+ <options=bold>Importing hooks...</>");
|
||||||
|
|
||||||
|
$output->writeln("+ <options=bold>Importing groups...</>");
|
||||||
|
foreach ($export->export->groups as $group) {
|
||||||
|
$output->writeln(" - <fg=green>".$group->_group."</>");
|
||||||
|
}
|
||||||
|
|
||||||
|
$output->writeln("+ <options=bold>Importing slots...</>");
|
||||||
|
foreach ($export->export->slots as $slot) {
|
||||||
|
$output->writeln(" - <fg=green>".$slot->_slot."</>");
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ class SlotCreateCommand extends Command
|
|||||||
protected function configure()
|
protected function configure()
|
||||||
{
|
{
|
||||||
$this
|
$this
|
||||||
->addOption("name", "n", InputOption::VALUE_REQUIRED, "Set slot name")
|
->addOption("name", "N", InputOption::VALUE_REQUIRED, "Set slot name")
|
||||||
->addArgument("slot", InputArgument::REQUIRED, "Slot ID")
|
->addArgument("slot", InputArgument::REQUIRED, "Slot ID")
|
||||||
->addArgument("properties", InputArgument::IS_ARRAY, "Properties to assign to the slot")
|
->addArgument("properties", InputArgument::IS_ARRAY, "Properties to assign to the slot")
|
||||||
;
|
;
|
||||||
@ -32,8 +32,25 @@ class SlotCreateCommand extends Command
|
|||||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||||
{
|
{
|
||||||
|
|
||||||
// $slotId = $input->getArgument("slot");
|
$slotId = $input->getArgument("slot");
|
||||||
// $slot = $this->client->querySlot($slotId);
|
$slotName = $input->getOption("name") ?? $slotId;
|
||||||
|
|
||||||
|
$props = [];
|
||||||
|
foreach ($input->getArgument("properties") as $prop) {
|
||||||
|
if (!str_contains($prop, '=')) {
|
||||||
|
$output->writeln("<error>Invalid property \"{$prop}\", should be in the form of key=value.</>");
|
||||||
|
return self::INVALID;
|
||||||
|
}
|
||||||
|
[$k, $v] = explode("=", $prop, 2);
|
||||||
|
$props[$k] = match ($v) {
|
||||||
|
'true','false','null' => json_decode($v),
|
||||||
|
default => json_decode($v) ?? $v,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
$slot = $this->client->createSlot($slotId, $slotName, $props);
|
||||||
|
|
||||||
|
var_dump($slot);
|
||||||
|
|
||||||
return self::SUCCESS;
|
return self::SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -55,8 +55,14 @@ class SlotFindCommand extends Command
|
|||||||
foreach ($slots as $slot) {
|
foreach ($slots as $slot) {
|
||||||
$row = [];
|
$row = [];
|
||||||
foreach ($keys as $key) {
|
foreach ($keys as $key) {
|
||||||
$row[] = isset($slot[$key]) ? json_encode($slot[$key]) : null;
|
$row[] = isset($slot[$key]) ? $slot[$key] : null;
|
||||||
}
|
}
|
||||||
|
$row = array_map(fn($v) => match(true) {
|
||||||
|
is_bool($v) => "<fg=magenta>".($v?"true":"false")."</>",
|
||||||
|
is_int($v) => "<fg=cyan>{$v}</>",
|
||||||
|
is_string($v) => "<fg=yellow>{$v}</>",
|
||||||
|
default => $v,
|
||||||
|
}, $row);
|
||||||
$table->addRow($row);
|
$table->addRow($row);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,12 @@
|
|||||||
|
|
||||||
require_once __DIR__."/../vendor/autoload.php";
|
require_once __DIR__."/../vendor/autoload.php";
|
||||||
|
|
||||||
|
$buildInfo = (file_exists(__DIR__."/build.php"))
|
||||||
|
? include __DIR__."/build.php"
|
||||||
|
: [ 'version' => '0.0.0', 'builddate' => 'never' ];
|
||||||
|
define("APP_VERSION", $buildInfo['version']);
|
||||||
|
define("APP_BUILT", $buildInfo['builddate']);
|
||||||
|
|
||||||
$app = new SlotDb\Cli\Application();
|
$app = new SlotDb\Cli\Application();
|
||||||
|
|
||||||
$app->run();
|
$app->run();
|
||||||
|
Reference in New Issue
Block a user