Compare commits
11 Commits
Author | SHA1 | Date | |
---|---|---|---|
990533a906 | |||
0b8c39a35c | |||
5e01a69572 | |||
cb8e0f1ec0 | |||
1c7961d356 | |||
e221300ba4 | |||
aaa99825f0 | |||
ec82ea80ee | |||
afaa816eff | |||
9fc0464c3d | |||
9387949937 |
@ -5,12 +5,12 @@ composer:
|
||||
dev:
|
||||
link: true
|
||||
require-dev:
|
||||
nulib/base: ^8.2-dev
|
||||
nulib/spout: ^8.2-dev
|
||||
nulib/phpss: ^8.2-dev
|
||||
nulib/base: ^7.4-dev
|
||||
nulib/spout: ^7.4-dev
|
||||
nulib/phpss: ^7.4-dev
|
||||
dist:
|
||||
link: false
|
||||
require-dev:
|
||||
nulib/base: ^0.6.0p82
|
||||
nulib/spout: ^0.6.0p82
|
||||
nulib/phpss: ^0.6.0p82
|
||||
nulib/base: ^0.6.0p74
|
||||
nulib/spout: ^0.6.0p74
|
||||
nulib/phpss: ^0.6.0p74
|
||||
|
1
.idea/php.xml
generated
1
.idea/php.xml
generated
@ -70,6 +70,7 @@
|
||||
<path value="$PROJECT_DIR$/vendor/nulib/spout" />
|
||||
<path value="$PROJECT_DIR$/vendor/nulib/php" />
|
||||
<path value="$PROJECT_DIR$/vendor/nulib/spout" />
|
||||
<path value="$PROJECT_DIR$/vendor/nulib/base" />
|
||||
</include_path>
|
||||
</component>
|
||||
<component name="PhpProjectSharedConfiguration" php_language_level="7.4" />
|
||||
|
14
.pman.conf
14
.pman.conf
@ -1,13 +1,13 @@
|
||||
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
|
||||
|
||||
UPSTREAM=dev74
|
||||
DEVELOP=dev82
|
||||
FEATURE=wip82/
|
||||
RELEASE=rel82-
|
||||
MAIN=dist82
|
||||
UPSTREAM=
|
||||
DEVELOP=dev74
|
||||
FEATURE=wip74/
|
||||
RELEASE=rel74-
|
||||
MAIN=dist74
|
||||
TAG_PREFIX=
|
||||
TAG_SUFFIX=p82
|
||||
HOTFIX=hotf82-
|
||||
TAG_SUFFIX=p74
|
||||
HOTFIX=hotf74-
|
||||
DIST=
|
||||
NOAUTO=
|
||||
|
||||
|
@ -4,5 +4,5 @@
|
||||
RUNPHP=
|
||||
|
||||
# Si RUNPHP n'est pas défini, les variables suivantes peuvent être définies
|
||||
DIST=d12
|
||||
DIST=d11
|
||||
#REGISTRY=pubdocker.univ-reunion.fr/dist
|
||||
|
14
TODO.md
14
TODO.md
@ -7,5 +7,19 @@
|
||||
## Vrac
|
||||
|
||||
* classe de base `profile_manager` qui permet de gérer des profils
|
||||
* class Tool permettant d'appliquer un traitement à une valeur scalaire
|
||||
* ArrayTool permet d'appliquer les traitement à tous les éléments du tableau
|
||||
* les traitements sont une suite d'opérations à faire, ou de filtres à
|
||||
appliquer, qui ne sont appliqués que lors du parcours effectif de la liste
|
||||
* exemple
|
||||
```php
|
||||
$result = ArrayTool::with($source)
|
||||
->filterKey("key")
|
||||
->filter("value")
|
||||
->add("value", "key")
|
||||
->addAll($iterable)
|
||||
->all();
|
||||
```
|
||||
déterminer le genre de traitements que l'on peut offrir
|
||||
|
||||
-*- coding: utf-8 mode: markdown -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8:noeol:binary
|
@ -2,6 +2,6 @@
|
||||
<?php
|
||||
require $_composer_autoload_path?? __DIR__.'/../vendor/autoload.php';
|
||||
|
||||
use nulib\tools\Csv2xlsxApp;
|
||||
use nulib\cli\Csv2xlsxApp;
|
||||
|
||||
Csv2xlsxApp::run();
|
||||
|
@ -2,6 +2,6 @@
|
||||
<?php
|
||||
require $_composer_autoload_path?? __DIR__.'/../vendor/autoload.php';
|
||||
|
||||
use nulib\tools\DumpserApp;
|
||||
use nulib\cli\DumpserApp;
|
||||
|
||||
DumpserApp::run();
|
||||
|
@ -2,6 +2,6 @@
|
||||
<?php
|
||||
require $_composer_autoload_path?? __DIR__.'/../vendor/autoload.php';
|
||||
|
||||
use nulib\tools\Json2yamlApp;
|
||||
use nulib\cli\Json2yamlApp;
|
||||
|
||||
Json2yamlApp::run();
|
||||
|
@ -2,6 +2,6 @@
|
||||
<?php
|
||||
require $_composer_autoload_path?? __DIR__.'/../vendor/autoload.php';
|
||||
|
||||
use nulib\tools\SteamTrainApp;
|
||||
use nulib\cli\MysqlStorageApp;
|
||||
|
||||
SteamTrainApp::run();
|
||||
MysqlStorageApp::run();
|
@ -2,6 +2,6 @@
|
||||
<?php
|
||||
require $_composer_autoload_path?? __DIR__.'/../vendor/autoload.php';
|
||||
|
||||
use nulib\tools\NucacheApp;
|
||||
use nulib\cli\NucacheApp;
|
||||
|
||||
NucacheApp::run();
|
7
bin/pgsql.storage.php
Executable file
7
bin/pgsql.storage.php
Executable file
@ -0,0 +1,7 @@
|
||||
#!/usr/bin/php
|
||||
<?php
|
||||
require $_composer_autoload_path?? __DIR__.'/../vendor/autoload.php';
|
||||
|
||||
use nulib\cli\PgsqlStorageApp;
|
||||
|
||||
PgsqlStorageApp::run();
|
7
bin/sqlite.storage.php
Executable file
7
bin/sqlite.storage.php
Executable file
@ -0,0 +1,7 @@
|
||||
#!/usr/bin/php
|
||||
<?php
|
||||
require $_composer_autoload_path?? __DIR__.'/../vendor/autoload.php';
|
||||
|
||||
use nulib\cli\SqliteStorageApp;
|
||||
|
||||
SqliteStorageApp::run();
|
@ -2,6 +2,6 @@
|
||||
<?php
|
||||
require $_composer_autoload_path?? __DIR__.'/../vendor/autoload.php';
|
||||
|
||||
use nulib\tools\Yaml2jsonApp;
|
||||
use nulib\cli\Yaml2jsonApp;
|
||||
|
||||
Yaml2jsonApp::run();
|
||||
|
@ -3,6 +3,18 @@
|
||||
"type": "library",
|
||||
"description": "espace de maturation pour les librairies",
|
||||
"repositories": [
|
||||
{
|
||||
"type": "path",
|
||||
"url": "../nulib-base"
|
||||
},
|
||||
{
|
||||
"type": "path",
|
||||
"url": "../nulib-spout"
|
||||
},
|
||||
{
|
||||
"type": "path",
|
||||
"url": "../nulib-phpss"
|
||||
},
|
||||
{
|
||||
"type": "composer",
|
||||
"url": "https://repos.univ-reunion.fr/composer"
|
||||
@ -15,13 +27,13 @@
|
||||
}
|
||||
},
|
||||
"require": {
|
||||
"php": "^8.2"
|
||||
"php": "^7.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"nulib/base": "^0.6.0p82",
|
||||
"nulib/spout": "^0.6.0p82",
|
||||
"nulib/phpss": "^0.6.0p82",
|
||||
"nulib/tests": "^8.2",
|
||||
"nulib/base": "^7.4-dev",
|
||||
"nulib/spout": "^7.4-dev",
|
||||
"nulib/phpss": "^7.4-dev",
|
||||
"nulib/tests": "^7.4",
|
||||
"ext-posix": "*",
|
||||
"ext-pcntl": "*",
|
||||
"ext-fileinfo": "*",
|
||||
@ -67,9 +79,13 @@
|
||||
},
|
||||
"bin": [
|
||||
"bin/dumpser.php",
|
||||
"bin/nucache.php",
|
||||
"bin/csv2xlsx.php",
|
||||
"bin/json2yml.php",
|
||||
"bin/yml2json.php",
|
||||
"bin/sqlite.storage.php",
|
||||
"bin/mysql.storage.php",
|
||||
"bin/pgsql.storage.php",
|
||||
"nur_bin/compctl.php",
|
||||
"nur_bin/compdep.php",
|
||||
"nur_bin/datectl.php",
|
||||
@ -77,9 +93,7 @@
|
||||
"nur_bin/cachectl.php",
|
||||
"nur_bin/ldap-delete.php",
|
||||
"nur_bin/ldap-get-infos.php",
|
||||
"nur_bin/ldap-search.php",
|
||||
"nur_bin/storage.sqlite.php",
|
||||
"nur_bin/storage.mysql.php"
|
||||
"nur_bin/ldap-search.php"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
|
1028
composer.lock
generated
1028
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@ -1,123 +0,0 @@
|
||||
#!/usr/bin/php
|
||||
<?php
|
||||
require $_composer_autoload_path?? __DIR__.'/../vendor/autoload.php';
|
||||
|
||||
use nulib\db\Capacitor;
|
||||
use nulib\db\CapacitorChannel;
|
||||
use nulib\db\mysql\MysqlStorage;
|
||||
use nulib\file\Stream;
|
||||
use nur\cli\Application;
|
||||
use nur\config;
|
||||
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;
|
||||
}
|
||||
}
|
||||
});
|
@ -8,6 +8,7 @@ use nur\b\ExitError;
|
||||
use nur\co;
|
||||
use nur\config;
|
||||
use nur\func;
|
||||
use nur\json;
|
||||
use nur\v\html5\Html5BasicErrorPage;
|
||||
use nur\v\model\IChildComponent;
|
||||
use nur\v\model\IComponent;
|
||||
@ -19,6 +20,7 @@ use nur\v\page;
|
||||
use nur\v\prefix;
|
||||
use nur\v\vo;
|
||||
use Throwable;
|
||||
use Traversable;
|
||||
|
||||
abstract class AbstractPageContainer implements IPageContainer {
|
||||
protected static function ensure_preparec(IComponent $c, bool $afterPrepare=false): bool {
|
||||
@ -41,10 +43,10 @@ abstract class AbstractPageContainer implements IPageContainer {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected static function ensure_setupc(IComponent $c, bool $afterSetup=false): bool {
|
||||
protected static function ensure_setupc(IComponent $c, bool $afterSetup=false, &$output=null): bool {
|
||||
if (!$c->didSetup()) {
|
||||
$c->beforeSetup();
|
||||
$c->setup();
|
||||
$output = $c->setup();
|
||||
if ($afterSetup) $c->afterSetup();
|
||||
return true;
|
||||
}
|
||||
@ -248,6 +250,7 @@ abstract class AbstractPageContainer implements IPageContainer {
|
||||
function print(): void {
|
||||
$page = $this->page;
|
||||
page::set_current_page($page);
|
||||
$output = null;
|
||||
|
||||
try {
|
||||
$this->phase = self::PREPARE_PHASE;
|
||||
@ -265,14 +268,43 @@ abstract class AbstractPageContainer implements IPageContainer {
|
||||
config::configure($this->config["configure_options"]);
|
||||
|
||||
$this->phase = self::SETUP_PHASE;
|
||||
if (self::ensure_setupc($page)) {
|
||||
if (self::ensure_setupc($page, false, $output)) {
|
||||
$this->overrideSetup($page);
|
||||
$page->afterSetup();
|
||||
}
|
||||
|
||||
$this->phase = self::PRINT_PHASE;
|
||||
if ($output instanceof IComponent) {
|
||||
self::ensure_phasec($output);
|
||||
if ($this->beforePrint($output)) {
|
||||
$this->haveOutput = true;
|
||||
co::_print([$output]);
|
||||
}
|
||||
} elseif (is_callable($output)) {
|
||||
if ($this->beforePrint(null)) {
|
||||
$this->haveOutput = true;
|
||||
$output();
|
||||
}
|
||||
} elseif ($output !== null) {
|
||||
if ($this->beforePrint(null)) {
|
||||
$this->haveOutput = true;
|
||||
if (is_iterable($output)) {
|
||||
header("Content-Type: application/json");
|
||||
echo "[";
|
||||
$sep = "";
|
||||
foreach ($output as $data) {
|
||||
$line = json::encode($data);
|
||||
echo "$sep$line\n";
|
||||
$sep = ",";
|
||||
}
|
||||
echo "]";
|
||||
} else {
|
||||
co::_print([strval($output)]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->overridePrint($page);
|
||||
|
||||
}
|
||||
} catch (Throwable $e) {
|
||||
if ($e instanceof ExitError && !$e->isError()) {
|
||||
# NOP
|
||||
@ -293,6 +325,9 @@ abstract class AbstractPageContainer implements IPageContainer {
|
||||
}
|
||||
if ($page->didSetup()) {
|
||||
$this->phase = self::TEARDOWN_PHASE;
|
||||
if ($output instanceof IComponent) {
|
||||
self::ensure_teardownc($output);
|
||||
}
|
||||
if (self::ensure_teardownc($page)) {
|
||||
$this->overrideTeardown($page);
|
||||
$page->afterTeardown();
|
||||
@ -310,12 +345,15 @@ abstract class AbstractPageContainer implements IPageContainer {
|
||||
protected function overrideSetup(IPage $page): void {
|
||||
}
|
||||
|
||||
protected function beforePrint(?IComponent $component): bool {
|
||||
return $component === null || $component->haveContent();
|
||||
}
|
||||
|
||||
protected function overridePrint(IPage $page): void {
|
||||
if ($page->haveContent()) {
|
||||
if (!$this->beforePrint($page)) return;
|
||||
$this->haveOutput = true;
|
||||
co::_print([$page]);
|
||||
}
|
||||
}
|
||||
|
||||
protected function overrideTeardown(IPage $page): void {
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ trait TComponent {
|
||||
|
||||
protected $setupDone = false;
|
||||
function beforeSetup(): void {}
|
||||
function setup(): void {}
|
||||
function setup() {}
|
||||
function afterSetup(): void { $this->setupDone = true; }
|
||||
function didSetup(): bool { return $this->setupDone; }
|
||||
|
||||
|
@ -11,6 +11,7 @@ class Bs3IconManager implements IIconManager {
|
||||
"warning" => "exclamation-sign",
|
||||
"error" => "remove-sign",
|
||||
|
||||
"pending" => "hourglass",
|
||||
"refresh",
|
||||
"config" => "cog",
|
||||
"save" => "floppy-disk",
|
||||
@ -83,6 +84,7 @@ EOT;
|
||||
'success' => 'ok-sign',
|
||||
'warning' => 'exclamation-sign',
|
||||
'error' => 'remove-sign',
|
||||
'pending' => 'hourglass',
|
||||
'refresh' => 'refresh',
|
||||
'config' => 'cog',
|
||||
'save' => 'floppy-disk',
|
||||
@ -139,6 +141,7 @@ EOT;
|
||||
'<span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>',
|
||||
];
|
||||
const ERROR = /*autogen*/['<span class="glyphicon glyphicon-remove-sign" aria-hidden="true"></span>'];
|
||||
const PENDING = /*autogen*/['<span class="glyphicon glyphicon-hourglass" aria-hidden="true"></span>'];
|
||||
const REFRESH = /*autogen*/['<span class="glyphicon glyphicon-refresh" aria-hidden="true"></span>'];
|
||||
const CONFIG = /*autogen*/['<span class="glyphicon glyphicon-cog" aria-hidden="true"></span>'];
|
||||
const SAVE = /*autogen*/['<span class="glyphicon glyphicon-floppy-disk" aria-hidden="true"></span>'];
|
||||
|
@ -6,6 +6,7 @@ use nur\co;
|
||||
use nur\session;
|
||||
use nur\v\ly;
|
||||
use nur\v\model\IBasicPage;
|
||||
use nur\v\model\IComponent;
|
||||
use nur\v\model\IPage;
|
||||
|
||||
class Html5BasicPageContainer extends Html5VanillaPageContainer {
|
||||
@ -23,10 +24,14 @@ class Html5BasicPageContainer extends Html5VanillaPageContainer {
|
||||
|
||||
function isAutocloseSession(): bool { return $this->config["autoclose_session"]; }
|
||||
|
||||
protected function overridePrint(IPage $page): void {
|
||||
protected function beforePrint(?IComponent $component): bool {
|
||||
if ($this->isAutocloseSession()) session::close();
|
||||
return parent::beforePrint($component);
|
||||
}
|
||||
|
||||
protected function overridePrint(IPage $page): void {
|
||||
if (!$this->beforePrint($page)) return;
|
||||
if ($page instanceof IBasicPage) {
|
||||
if ($page->haveContent()) {
|
||||
$this->doResolveConfig();
|
||||
$this->haveOutput = true;
|
||||
$this->printStartHtml();
|
||||
@ -40,13 +45,10 @@ class Html5BasicPageContainer extends Html5VanillaPageContainer {
|
||||
$this->printContent();
|
||||
$this->printEndBody();
|
||||
$this->printEndHtml();
|
||||
}
|
||||
} else {
|
||||
# si ce n'est pas une instance de IBasicPage, l'imprimer tel quel
|
||||
if ($page->haveContent()) {
|
||||
$this->haveOutput = true;
|
||||
co::_write([$this->page]);
|
||||
}
|
||||
co::_write([$page]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,9 +12,8 @@ use nur\v\v;
|
||||
|
||||
class Html5NavigablePageContainer extends Html5BasicPageContainer {
|
||||
protected function overridePrint(IPage $page): void {
|
||||
if ($this->isAutocloseSession()) session::close();
|
||||
if (!$this->beforePrint($page)) return;
|
||||
if ($page instanceof IBasicPage) {
|
||||
if ($page->haveContent()) {
|
||||
$this->doResolveConfig();
|
||||
$this->haveOutput = true;
|
||||
$this->printStartHtml();
|
||||
@ -68,15 +67,12 @@ class Html5NavigablePageContainer extends Html5BasicPageContainer {
|
||||
}
|
||||
$this->printEndBody();
|
||||
$this->printEndHtml();
|
||||
}
|
||||
} else {
|
||||
# si ce n'est pas une instance de IBasicPage, l'imprimer tel quel
|
||||
if ($page->haveContent()) {
|
||||
$this->haveOutput = true;
|
||||
co::_write([$this->page]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function printStartNavigation(?array $options): void {
|
||||
navbar::start($options);
|
||||
|
@ -12,6 +12,7 @@ use nur\v\base\AbstractPageContainer;
|
||||
use nur\v\base\MenuManager;
|
||||
use nur\v\fo;
|
||||
use nur\v\ly;
|
||||
use nur\v\model\IBasicPage;
|
||||
use nur\v\model\IComponent;
|
||||
use nur\v\model\IPage;
|
||||
use nur\v\model\IPlugin;
|
||||
@ -46,7 +47,8 @@ class Html5VanillaPageContainer extends AbstractPageContainer {
|
||||
}
|
||||
|
||||
protected function overridePrint(IPage $page): void {
|
||||
if ($page->haveContent()) {
|
||||
if (!$this->beforePrint($page)) return;
|
||||
if ($page instanceof IPage) {
|
||||
$this->doResolveConfig();
|
||||
$this->haveOutput = true;
|
||||
$this->printStartHtml();
|
||||
@ -62,6 +64,10 @@ class Html5VanillaPageContainer extends AbstractPageContainer {
|
||||
$this->printContent();
|
||||
$this->printEndBody();
|
||||
$this->printEndHtml();
|
||||
} else {
|
||||
# si ce n'est pas une instance de IPage, l'imprimer tel quel
|
||||
$this->haveOutput = true;
|
||||
co::_write([$page]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,57 +47,58 @@ class icon {
|
||||
|
||||
#############################################################################
|
||||
|
||||
static final function info(?string $suffix=null, ?string $alt="INFO: "): array { return self::manager()->getIcon("info", $suffix, $alt); }
|
||||
static final function success(?string $suffix=null, ?string $alt="SUCCESS: "): array { return self::manager()->getIcon("success", $suffix, $alt); }
|
||||
static final function warning(?string $suffix=null, ?string $alt="WARNING: "): array { return self::manager()->getIcon("warning", $suffix, $alt); }
|
||||
static final function error(?string $suffix=null, ?string $alt="ERROR: "): array { return self::manager()->getIcon("error", $suffix, $alt); }
|
||||
static final function info($suffix=null, ?string $alt="INFO: "): array { return self::manager()->getIcon("info", $suffix, $alt); }
|
||||
static final function success($suffix=null, ?string $alt="SUCCESS: "): array { return self::manager()->getIcon("success", $suffix, $alt); }
|
||||
static final function warning($suffix=null, ?string $alt="WARNING: "): array { return self::manager()->getIcon("warning", $suffix, $alt); }
|
||||
static final function error($suffix=null, ?string $alt="ERROR: "): array { return self::manager()->getIcon("error", $suffix, $alt); }
|
||||
|
||||
static final function refresh(?string $suffix=null, ?string $alt=null): array { return self::manager()->getIcon("refresh", $suffix, $alt); }
|
||||
static final function config(?string $suffix=null, ?string $alt=null): array { return self::manager()->getIcon("config", $suffix, $alt); }
|
||||
static final function save(?string $suffix=null, ?string $alt=null): array { return self::manager()->getIcon("save", $suffix, $alt); }
|
||||
static final function download(?string $suffix=null, ?string $alt=null): array { return self::manager()->getIcon("download", $suffix, $alt); }
|
||||
static final function upload(?string $suffix=null, ?string $alt=null): array { return self::manager()->getIcon("upload", $suffix, $alt); }
|
||||
static final function bin(?string $suffix=null, ?string $alt=null): array { return self::manager()->getIcon("bin", $suffix, $alt); }
|
||||
static final function mail(?string $suffix=null, ?string $alt=null): array { return self::manager()->getIcon("mail", $suffix, $alt); }
|
||||
static final function search(?string $suffix=null, ?string $alt=null): array { return self::manager()->getIcon("search", $suffix, $alt); }
|
||||
static final function user(?string $suffix=null, ?string $alt=null): array { return self::manager()->getIcon("user", $suffix, $alt); }
|
||||
static final function login(?string $suffix=null, ?string $alt=null): array { return self::manager()->getIcon("login", $suffix, $alt); }
|
||||
static final function logout(?string $suffix=null, ?string $alt=null): array { return self::manager()->getIcon("logout", $suffix, $alt); }
|
||||
static final function new_window(?string $suffix=null, ?string $alt=null): array { return self::manager()->getIcon("new_window", $suffix, $alt); }
|
||||
static final function pending($suffix=null, ?string $alt=null): array { return self::manager()->getIcon("hourglass", $suffix, $alt); }
|
||||
static final function refresh($suffix=null, ?string $alt=null): array { return self::manager()->getIcon("refresh", $suffix, $alt); }
|
||||
static final function config($suffix=null, ?string $alt=null): array { return self::manager()->getIcon("config", $suffix, $alt); }
|
||||
static final function save($suffix=null, ?string $alt=null): array { return self::manager()->getIcon("save", $suffix, $alt); }
|
||||
static final function download($suffix=null, ?string $alt=null): array { return self::manager()->getIcon("download", $suffix, $alt); }
|
||||
static final function upload($suffix=null, ?string $alt=null): array { return self::manager()->getIcon("upload", $suffix, $alt); }
|
||||
static final function bin($suffix=null, ?string $alt=null): array { return self::manager()->getIcon("bin", $suffix, $alt); }
|
||||
static final function mail($suffix=null, ?string $alt=null): array { return self::manager()->getIcon("mail", $suffix, $alt); }
|
||||
static final function search($suffix=null, ?string $alt=null): array { return self::manager()->getIcon("search", $suffix, $alt); }
|
||||
static final function user($suffix=null, ?string $alt=null): array { return self::manager()->getIcon("user", $suffix, $alt); }
|
||||
static final function login($suffix=null, ?string $alt=null): array { return self::manager()->getIcon("login", $suffix, $alt); }
|
||||
static final function logout($suffix=null, ?string $alt=null): array { return self::manager()->getIcon("logout", $suffix, $alt); }
|
||||
static final function new_window($suffix=null, ?string $alt=null): array { return self::manager()->getIcon("new_window", $suffix, $alt); }
|
||||
|
||||
static final function ignore(?string $suffix=null, ?string $alt=null): array { return self::manager()->getIcon("fast-forward", $suffix, $alt); }
|
||||
static final function replace(?string $suffix=null, ?string $alt=null): array { return self::manager()->getIcon("erase", $suffix, $alt); }
|
||||
static final function delete(?string $suffix=null, ?string $alt=null): array { return self::manager()->getIcon("remove", $suffix, $alt); }
|
||||
static final function ignore($suffix=null, ?string $alt=null): array { return self::manager()->getIcon("fast-forward", $suffix, $alt); }
|
||||
static final function replace($suffix=null, ?string $alt=null): array { return self::manager()->getIcon("erase", $suffix, $alt); }
|
||||
static final function delete($suffix=null, ?string $alt=null): array { return self::manager()->getIcon("remove", $suffix, $alt); }
|
||||
|
||||
static final function arrow_up(?string $suffix=null, ?string $alt=null): array { return self::manager()->getIcon("arrow_up", $suffix, $alt); }
|
||||
static final function arrow_down(?string $suffix=null, ?string $alt=null): array { return self::manager()->getIcon("arrow_down", $suffix, $alt); }
|
||||
static final function arrow_left(?string $suffix=null, ?string $alt=null): array { return self::manager()->getIcon("arrow_left", $suffix, $alt); }
|
||||
static final function arrow_right(?string $suffix=null, ?string $alt=null): array { return self::manager()->getIcon("arrow_right", $suffix, $alt); }
|
||||
static final function chevron_up(?string $suffix=null, ?string $alt=null): array { return self::manager()->getIcon("chevron_up", $suffix, $alt); }
|
||||
static final function chevron_down(?string $suffix=null, ?string $alt=null): array { return self::manager()->getIcon("chevron_down", $suffix, $alt); }
|
||||
static final function chevron_left(?string $suffix=null, ?string $alt=null): array { return self::manager()->getIcon("chevron_left", $suffix, $alt); }
|
||||
static final function chevron_right(?string $suffix=null, ?string $alt=null): array { return self::manager()->getIcon("chevron_right", $suffix, $alt); }
|
||||
static final function hand_up(?string $suffix=null, ?string $alt=null): array { return self::manager()->getIcon("hand_up", $suffix, $alt); }
|
||||
static final function hand_down(?string $suffix=null, ?string $alt=null): array { return self::manager()->getIcon("hand_down", $suffix, $alt); }
|
||||
static final function hand_left(?string $suffix=null, ?string $alt=null): array { return self::manager()->getIcon("hand_left", $suffix, $alt); }
|
||||
static final function hand_right(?string $suffix=null, ?string $alt=null): array { return self::manager()->getIcon("hand_right", $suffix, $alt); }
|
||||
static final function menu_up(?string $suffix=null, ?string $alt=null): array { return self::manager()->getIcon("menu_up", $suffix, $alt); }
|
||||
static final function menu_down(?string $suffix=null, ?string $alt=null): array { return self::manager()->getIcon("menu_down", $suffix, $alt); }
|
||||
static final function menu_left(?string $suffix=null, ?string $alt=null): array { return self::manager()->getIcon("menu_left", $suffix, $alt); }
|
||||
static final function menu_right(?string $suffix=null, ?string $alt=null): array { return self::manager()->getIcon("menu_right", $suffix, $alt); }
|
||||
static final function triangle_up(?string $suffix=null, ?string $alt=null): array { return self::manager()->getIcon("triangle_up", $suffix, $alt); }
|
||||
static final function triangle_down(?string $suffix=null, ?string $alt=null): array { return self::manager()->getIcon("triangle_down", $suffix, $alt); }
|
||||
static final function triangle_left(?string $suffix=null, ?string $alt=null): array { return self::manager()->getIcon("triangle_left", $suffix, $alt); }
|
||||
static final function triangle_right(?string $suffix=null, ?string $alt=null): array { return self::manager()->getIcon("triangle_right", $suffix, $alt); }
|
||||
static final function arrow_up($suffix=null, ?string $alt=null): array { return self::manager()->getIcon("arrow_up", $suffix, $alt); }
|
||||
static final function arrow_down($suffix=null, ?string $alt=null): array { return self::manager()->getIcon("arrow_down", $suffix, $alt); }
|
||||
static final function arrow_left($suffix=null, ?string $alt=null): array { return self::manager()->getIcon("arrow_left", $suffix, $alt); }
|
||||
static final function arrow_right($suffix=null, ?string $alt=null): array { return self::manager()->getIcon("arrow_right", $suffix, $alt); }
|
||||
static final function chevron_up($suffix=null, ?string $alt=null): array { return self::manager()->getIcon("chevron_up", $suffix, $alt); }
|
||||
static final function chevron_down($suffix=null, ?string $alt=null): array { return self::manager()->getIcon("chevron_down", $suffix, $alt); }
|
||||
static final function chevron_left($suffix=null, ?string $alt=null): array { return self::manager()->getIcon("chevron_left", $suffix, $alt); }
|
||||
static final function chevron_right($suffix=null, ?string $alt=null): array { return self::manager()->getIcon("chevron_right", $suffix, $alt); }
|
||||
static final function hand_up($suffix=null, ?string $alt=null): array { return self::manager()->getIcon("hand_up", $suffix, $alt); }
|
||||
static final function hand_down($suffix=null, ?string $alt=null): array { return self::manager()->getIcon("hand_down", $suffix, $alt); }
|
||||
static final function hand_left($suffix=null, ?string $alt=null): array { return self::manager()->getIcon("hand_left", $suffix, $alt); }
|
||||
static final function hand_right($suffix=null, ?string $alt=null): array { return self::manager()->getIcon("hand_right", $suffix, $alt); }
|
||||
static final function menu_up($suffix=null, ?string $alt=null): array { return self::manager()->getIcon("menu_up", $suffix, $alt); }
|
||||
static final function menu_down($suffix=null, ?string $alt=null): array { return self::manager()->getIcon("menu_down", $suffix, $alt); }
|
||||
static final function menu_left($suffix=null, ?string $alt=null): array { return self::manager()->getIcon("menu_left", $suffix, $alt); }
|
||||
static final function menu_right($suffix=null, ?string $alt=null): array { return self::manager()->getIcon("menu_right", $suffix, $alt); }
|
||||
static final function triangle_up($suffix=null, ?string $alt=null): array { return self::manager()->getIcon("triangle_up", $suffix, $alt); }
|
||||
static final function triangle_down($suffix=null, ?string $alt=null): array { return self::manager()->getIcon("triangle_down", $suffix, $alt); }
|
||||
static final function triangle_left($suffix=null, ?string $alt=null): array { return self::manager()->getIcon("triangle_left", $suffix, $alt); }
|
||||
static final function triangle_right($suffix=null, ?string $alt=null): array { return self::manager()->getIcon("triangle_right", $suffix, $alt); }
|
||||
|
||||
static final function star(?string $suffix=null, ?string $alt=null): array { return self::manager()->getIcon("star", $suffix, $alt); }
|
||||
static final function star_empty(?string $suffix=null, ?string $alt=null): array { return self::manager()->getIcon("star_empty", $suffix, $alt); }
|
||||
static final function heart(?string $suffix=null, ?string $alt=null): array { return self::manager()->getIcon("heart", $suffix, $alt); }
|
||||
static final function heart_empty(?string $suffix=null, ?string $alt=null): array { return self::manager()->getIcon("heart_empty", $suffix, $alt); }
|
||||
static final function star($suffix=null, ?string $alt=null): array { return self::manager()->getIcon("star", $suffix, $alt); }
|
||||
static final function star_empty($suffix=null, ?string $alt=null): array { return self::manager()->getIcon("star_empty", $suffix, $alt); }
|
||||
static final function heart($suffix=null, ?string $alt=null): array { return self::manager()->getIcon("heart", $suffix, $alt); }
|
||||
static final function heart_empty($suffix=null, ?string $alt=null): array { return self::manager()->getIcon("heart_empty", $suffix, $alt); }
|
||||
|
||||
static final function plus(?string $suffix=null, ?string $alt=null): array { return self::manager()->getIcon("plus", $suffix, $alt); }
|
||||
static final function minus(?string $suffix=null, ?string $alt=null): array { return self::manager()->getIcon("minus", $suffix, $alt); }
|
||||
static final function plus($suffix=null, ?string $alt=null): array { return self::manager()->getIcon("plus", $suffix, $alt); }
|
||||
static final function minus($suffix=null, ?string $alt=null): array { return self::manager()->getIcon("minus", $suffix, $alt); }
|
||||
|
||||
# template:
|
||||
#static final function xxx(?string $suffix=null, ?string $alt=null): array { return self::manager()->getIcon("xxx", $suffix, $alt); }
|
||||
#static final function xxx($suffix=null, ?string $alt=null): array { return self::manager()->getIcon("xxx", $suffix, $alt); }
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ interface IComponent extends IPlugin {
|
||||
function beforeSetup(): void;
|
||||
|
||||
/** initialiser le composant */
|
||||
function setup(): void;
|
||||
function setup();
|
||||
|
||||
/** marquer le composant comme initialisé */
|
||||
function afterSetup(): void;
|
||||
|
@ -23,7 +23,7 @@ class AppCasauthPage extends AbstractPage {
|
||||
/** @var string nom de l'utilisateur connecté */
|
||||
private $user;
|
||||
|
||||
function setup(): void {
|
||||
function setup() {
|
||||
$destUrl = $retUrl = null;
|
||||
$user = false;
|
||||
if ($user === false) $user = A::get($_SERVER, "REMOTE_USER", false);
|
||||
|
@ -9,7 +9,7 @@ class AppDevauthPage extends AInitPage {
|
||||
/** @var string nom de l'utilisateur connecté */
|
||||
private $user;
|
||||
|
||||
function setup(): void {
|
||||
function setup() {
|
||||
if (!$this->isDevauthAllowed()) {
|
||||
page::redirect($this->getLoginUrl());
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ class AppExtauthPage extends AbstractPage {
|
||||
/** @var string nom de l'utilisateur connecté */
|
||||
private $user;
|
||||
|
||||
function setup(): void {
|
||||
function setup() {
|
||||
$destUrl = null;
|
||||
$user = false;
|
||||
if ($user === false) $user = A::get($_SERVER, "REMOTE_USER", false);
|
||||
|
@ -16,7 +16,7 @@ class AppLogoutPage extends AInitPage {
|
||||
return static::DEBUG || F::get("d");
|
||||
}
|
||||
|
||||
function setup(): void {
|
||||
function setup() {
|
||||
cookie::set("MOD_AUTH_CAS", false);
|
||||
cookie::set("MOD_AUTH_CAS_S", false);
|
||||
authz::manager()->resetSession(authz::DISCONNECTED);
|
||||
|
8
src/cache/CacheChannel.php
vendored
8
src/cache/CacheChannel.php
vendored
@ -63,7 +63,7 @@ class CacheChannel extends CapacitorChannel {
|
||||
]);
|
||||
}
|
||||
|
||||
function onCreate($item, array $values, ?array $alwaysNull, ?string $duration=null): ?array {
|
||||
function onCreate($item, array $row, ?array $alwaysNull, ?string $duration=null): ?array {
|
||||
$now = new DateTime();
|
||||
$duration ??= $this->duration;
|
||||
return [
|
||||
@ -72,7 +72,7 @@ class CacheChannel extends CapacitorChannel {
|
||||
];
|
||||
}
|
||||
|
||||
function onUpdate($item, array $values, array $pvalues, ?string $duration=null): ?array {
|
||||
function onUpdate($item, array $row, array $prow, ?string $duration=null): ?array {
|
||||
$now = new DateTime();
|
||||
$duration ??= $this->duration;
|
||||
return [
|
||||
@ -97,9 +97,9 @@ class CacheChannel extends CapacitorChannel {
|
||||
$found = false;
|
||||
$expired = false;
|
||||
$this->each($cacheIds,
|
||||
function($item, $values) use (&$found, &$expired) {
|
||||
function($row) use (&$found, &$expired) {
|
||||
$found = true;
|
||||
$expired = $values["duration"]->isElapsed();
|
||||
$expired = $row["duration"]->isElapsed();
|
||||
});
|
||||
return !$found || $expired;
|
||||
}
|
||||
|
69
nur_bin/storage.sqlite.php → src/cli/AbstractStorageApp.php
Executable file → Normal file
69
nur_bin/storage.sqlite.php → src/cli/AbstractStorageApp.php
Executable file → Normal file
@ -1,48 +1,17 @@
|
||||
#!/usr/bin/php
|
||||
<?php
|
||||
require $_composer_autoload_path?? __DIR__.'/../vendor/autoload.php';
|
||||
namespace nulib\cli;
|
||||
|
||||
use nulib\A;
|
||||
use nulib\app\cli\Application;
|
||||
use nulib\db\Capacitor;
|
||||
use nulib\db\CapacitorChannel;
|
||||
use nulib\db\sqlite\SqliteStorage;
|
||||
use nulib\db\CapacitorStorage;
|
||||
use nulib\ext\yaml;
|
||||
use nulib\file\Stream;
|
||||
use nur\cli\Application;
|
||||
use nur\msg;
|
||||
use nur\yaml;
|
||||
use nulib\output\msg;
|
||||
|
||||
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;
|
||||
abstract class AbstractStorageApp extends Application {
|
||||
const ACTION_RESET = 0, ACTION_QUERY = 1, ACTION_SQL = 2;
|
||||
|
||||
protected ?string $tableName = null;
|
||||
|
||||
@ -50,22 +19,21 @@ Application::run(new class extends Application {
|
||||
|
||||
protected int $action = self::ACTION_QUERY;
|
||||
|
||||
protected bool $recreate = true;
|
||||
|
||||
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();
|
||||
protected function storageCtl(CapacitorStorage $storage): void {
|
||||
$args = $this->args;
|
||||
|
||||
$name = $this->name;
|
||||
$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");
|
||||
@ -73,6 +41,7 @@ Application::run(new class extends Application {
|
||||
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;
|
||||
@ -95,13 +64,15 @@ Application::run(new class extends Application {
|
||||
$capacitor = new Capacitor($storage, $channel);
|
||||
|
||||
switch ($this->action) {
|
||||
case self::ACTION_RESET:
|
||||
$capacitor->reset($this->recreate);
|
||||
break;
|
||||
case self::ACTION_QUERY:
|
||||
$args = $this->args;
|
||||
if (!$args) {
|
||||
# lister les id
|
||||
$out = new Stream(STDOUT);
|
||||
$primaryKeys = $storage->getPrimaryKeys($channel);
|
||||
$rows = $db->all([
|
||||
$rows = $storage->db()->all([
|
||||
"select",
|
||||
"cols" => $primaryKeys,
|
||||
"from" => $channel->getTableName(),
|
||||
@ -139,4 +110,4 @@ Application::run(new class extends Application {
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
124
src/cli/BgLauncherApp.php
Normal file
124
src/cli/BgLauncherApp.php
Normal file
@ -0,0 +1,124 @@
|
||||
<?php
|
||||
namespace nulib\cli;
|
||||
|
||||
use nulib\app;
|
||||
use nulib\app\cli\Application;
|
||||
use nulib\app\RunFile;
|
||||
use nulib\ExitError;
|
||||
use nulib\ext\yaml;
|
||||
use nulib\os\path;
|
||||
use nulib\os\proc\Cmd;
|
||||
use nulib\os\sh;
|
||||
use nulib\output\msg;
|
||||
|
||||
class BgLauncherApp extends Application {
|
||||
const ACTION_INFOS = 0, ACTION_START = 1, ACTION_STOP = 2;
|
||||
const ARGS = [
|
||||
"purpose" => "lancer un script en tâche de fond",
|
||||
"usage" => "ApplicationClass args...",
|
||||
|
||||
"sections" => [
|
||||
parent::VERBOSITY_SECTION,
|
||||
],
|
||||
|
||||
["-i", "--infos", "name" => "action", "value" => self::ACTION_INFOS,
|
||||
"help" => "Afficher des informations sur la tâche",
|
||||
],
|
||||
["-s", "--start", "name" => "action", "value" => self::ACTION_START,
|
||||
"help" => "Démarrer la tâche",
|
||||
],
|
||||
["-k", "--stop", "name" => "action", "value" => self::ACTION_STOP,
|
||||
"help" => "Arrêter la tâche",
|
||||
],
|
||||
];
|
||||
|
||||
protected int $action = self::ACTION_START;
|
||||
|
||||
protected ?array $args = null;
|
||||
|
||||
static function show_infos(RunFile $runfile, ?int $level=null): void {
|
||||
msg::print($runfile->getDesc(), $level);
|
||||
msg::print(yaml::with(["data" => $runfile->read()]), ($level ?? 0) - 1);
|
||||
}
|
||||
|
||||
function main() {
|
||||
$args = $this->args;
|
||||
|
||||
$appClass = $args[0] ?? null;
|
||||
if ($appClass === null) {
|
||||
self::die("Vous devez spécifier la classe de l'application");
|
||||
}
|
||||
$appClass = $args[0] = str_replace("/", "\\", $appClass);
|
||||
if (!class_exists($appClass)) {
|
||||
self::die("$appClass: classe non trouvée");
|
||||
}
|
||||
|
||||
$useRunfile = constant("$appClass::USE_RUNFILE");
|
||||
if (!$useRunfile) {
|
||||
self::die("Cette application ne supporte le lancement en tâche de fond");
|
||||
}
|
||||
|
||||
$runfile = app::with($appClass)->getRunfile();
|
||||
switch ($this->action) {
|
||||
case self::ACTION_START:
|
||||
$argc = count($args);
|
||||
$appClass::_manage_runfile($argc, $args, $runfile);
|
||||
if ($runfile->warnIfLocked()) self::exit(app::EC_LOCKED);
|
||||
array_splice($args, 0, 0, [
|
||||
PHP_BINARY,
|
||||
path::abspath(NULIB_APP_app_launcher),
|
||||
]);
|
||||
app::params_putenv();
|
||||
self::_start($args, $runfile);
|
||||
break;
|
||||
case self::ACTION_STOP:
|
||||
self::_stop($runfile);
|
||||
self::show_infos($runfile, -1);
|
||||
break;
|
||||
case self::ACTION_INFOS:
|
||||
self::show_infos($runfile);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public static function _start(array $args, Runfile $runfile): void {
|
||||
$pid = pcntl_fork();
|
||||
if ($pid == -1) {
|
||||
# parent, impossible de forker
|
||||
throw new ExitError(app::EC_FORK_PARENT, "Unable to fork");
|
||||
} elseif (!$pid) {
|
||||
# child, fork ok
|
||||
$runfile->wfPrepare($pid);
|
||||
$outfile = $runfile->getOutfile() ?? "/tmp/NULIB_APP_app_console.out";
|
||||
$exitcode = app::EC_FORK_CHILD;
|
||||
try {
|
||||
# rediriger STDIN, STDOUT et STDERR
|
||||
fclose(fopen($outfile, "wb")); // vider le fichier
|
||||
fclose(STDIN); $in = fopen("/dev/null", "rb");
|
||||
fclose(STDOUT); $out = fopen($outfile, "ab");
|
||||
fclose(STDERR); $err = fopen($outfile, "ab");
|
||||
# puis lancer la commande
|
||||
$cmd = new Cmd($args);
|
||||
$cmd->addSource("/g/init.env");
|
||||
$cmd->addRedir("both", $outfile, true);
|
||||
$cmd->fork_exec($exitcode, false);
|
||||
sh::_waitpid(-$pid, $exitcode);
|
||||
} finally {
|
||||
$runfile->wfReaped($exitcode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function _stop(Runfile $runfile): bool {
|
||||
$data = $runfile->read();
|
||||
$pid = $runfile->_getCid($data);
|
||||
msg::action("stop $pid");
|
||||
if ($runfile->wfKill($reason)) {
|
||||
msg::asuccess();
|
||||
return true;
|
||||
} else {
|
||||
msg::afailure($reason);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
<?php
|
||||
namespace nulib\tools;
|
||||
namespace nulib\cli;
|
||||
|
||||
use nulib\app\cli\Application;
|
||||
use nulib\ext\tab\SsBuilder;
|
@ -1,5 +1,5 @@
|
||||
<?php
|
||||
namespace nulib\tools;
|
||||
namespace nulib\cli;
|
||||
|
||||
use nulib\app\cli\Application;
|
||||
use nulib\ext\yaml;
|
@ -1,5 +1,5 @@
|
||||
<?php
|
||||
namespace nulib\tools;
|
||||
namespace nulib\cli;
|
||||
|
||||
use nulib\app\cli\Application;
|
||||
use nulib\ext\json;
|
45
src/cli/MysqlStorageApp.php
Normal file
45
src/cli/MysqlStorageApp.php
Normal file
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
namespace nulib\cli;
|
||||
|
||||
use nulib\A;
|
||||
use nulib\db\mysql\MysqlStorage;
|
||||
use nur\config;
|
||||
|
||||
class MysqlStorageApp extends AbstractStorageApp {
|
||||
const ARGS = [
|
||||
"merge" => parent::ARGS,
|
||||
"purpose" => "gestion d'un capacitor mysql",
|
||||
"usage" => [
|
||||
"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",
|
||||
],
|
||||
["-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",
|
||||
],
|
||||
["-n", "--no-recreate", "name" => "recreate", "value" => false,
|
||||
"help" => "ne pas recréer la table correspondant au 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",
|
||||
],
|
||||
["-s", "--sql-create", "name" => "action", "value" => self::ACTION_SQL,
|
||||
"help" => "afficher la requête pour créer la table",
|
||||
],
|
||||
];
|
||||
|
||||
function main() {
|
||||
$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");
|
||||
$storage = new MysqlStorage($tmp);
|
||||
|
||||
$this->storageCtl($storage);
|
||||
}
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
<?php
|
||||
namespace nulib\tools;
|
||||
namespace nulib\cli;
|
||||
|
||||
use Exception;
|
||||
use nulib\app\cli\Application;
|
||||
use nulib\ext\yaml;
|
||||
use nulib\cache\CacheFile;
|
||||
use nulib\ext\yaml;
|
||||
use nulib\os\path;
|
||||
use nulib\output\msg;
|
||||
|
45
src/cli/PgsqlStorageApp.php
Normal file
45
src/cli/PgsqlStorageApp.php
Normal file
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
namespace nulib\cli;
|
||||
|
||||
use nulib\A;
|
||||
use nulib\db\pgsql\PgsqlStorage;
|
||||
use nur\config;
|
||||
|
||||
class PgsqlStorageApp extends AbstractStorageApp {
|
||||
const ARGS = [
|
||||
"merge" => parent::ARGS,
|
||||
"purpose" => "gestion d'un capacitor pgsql",
|
||||
"usage" => [
|
||||
"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",
|
||||
],
|
||||
["-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",
|
||||
],
|
||||
["-n", "--no-recreate", "name" => "recreate", "value" => false,
|
||||
"help" => "ne pas recréer la table correspondant au 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",
|
||||
],
|
||||
["-s", "--sql-create", "name" => "action", "value" => self::ACTION_SQL,
|
||||
"help" => "afficher la requête pour créer la table",
|
||||
],
|
||||
];
|
||||
|
||||
function main() {
|
||||
$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");
|
||||
$storage = new PgsqlStorage($tmp);
|
||||
|
||||
$this->storageCtl($storage);
|
||||
}
|
||||
}
|
43
src/cli/SqliteStorageApp.php
Normal file
43
src/cli/SqliteStorageApp.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
namespace nulib\cli;
|
||||
|
||||
use nulib\A;
|
||||
use nulib\db\sqlite\SqliteStorage;
|
||||
|
||||
class SqliteStorageApp extends AbstractStorageApp {
|
||||
const ARGS = [
|
||||
"merge" => parent::ARGS,
|
||||
"purpose" => "gestion d'un capacitor sqlite",
|
||||
"usage" => [
|
||||
"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",
|
||||
],
|
||||
["-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",
|
||||
],
|
||||
["-n", "--no-recreate", "name" => "recreate", "value" => false,
|
||||
"help" => "ne pas recréer la table correspondant au 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",
|
||||
],
|
||||
["-s", "--sql-create", "name" => "action", "value" => self::ACTION_SQL,
|
||||
"help" => "afficher la requête pour créer la table",
|
||||
],
|
||||
];
|
||||
|
||||
function main() {
|
||||
$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);
|
||||
|
||||
$this->storageCtl($storage);
|
||||
}
|
||||
}
|
53
src/cli/SteamTrainApp.php
Normal file
53
src/cli/SteamTrainApp.php
Normal file
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
namespace nulib\cli;
|
||||
|
||||
use nulib\app;
|
||||
use nulib\app\cli\Application;
|
||||
use nulib\output\msg;
|
||||
use nulib\php\time\DateTime;
|
||||
use nulib\text\words;
|
||||
|
||||
class SteamTrainApp extends Application {
|
||||
const PROJDIR = __DIR__.'/../..';
|
||||
const TITLE = "Train à vapeur";
|
||||
const USE_LOGFILE = true;
|
||||
const USE_RUNFILE = true;
|
||||
const USE_RUNLOCK = true;
|
||||
|
||||
const ARGS = [
|
||||
"purpose" => self::TITLE,
|
||||
"description" => <<<EOT
|
||||
Cette application peut être utilisée pour tester le lancement des tâches de fond
|
||||
EOT,
|
||||
|
||||
["-c", "--count", "args" => 1,
|
||||
"help" => "spécifier le nombre d'étapes",
|
||||
],
|
||||
["-f", "--force-enabled", "value" => true,
|
||||
"help" => "lancer la commande même si les tâches planifiées sont désactivées",
|
||||
],
|
||||
["-n", "--no-install-signal-handler", "value" => false,
|
||||
"help" => "ne pas installer le gestionnaire de signaux",
|
||||
],
|
||||
];
|
||||
|
||||
protected $count = 100;
|
||||
|
||||
protected bool $forceEnabled = false;
|
||||
|
||||
protected bool $installSignalHandler = true;
|
||||
|
||||
function main() {
|
||||
app::check_bgapplication_enabled($this->forceEnabled);
|
||||
if ($this->installSignalHandler) app::install_signal_handler();
|
||||
$count = intval($this->count);
|
||||
msg::info("Starting train for ".words::q($count, "step#s"));
|
||||
app::action("Running train...", $count);
|
||||
for ($i = 1; $i <= $count; $i++) {
|
||||
msg::print("Tchou-tchou! x $i");
|
||||
app::step();
|
||||
sleep(1);
|
||||
}
|
||||
msg::info("Stopping train at ".new DateTime());
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
<?php
|
||||
namespace nulib\tools;
|
||||
namespace nulib\cli;
|
||||
|
||||
use nulib\app\cli\Application;
|
||||
use nulib\ext\json;
|
@ -3,20 +3,23 @@
|
||||
* rajouter l'attribut "size" pour spécifier la taille maximale des valeurs
|
||||
* cela pourrait servir pour générer automatiquement des tables SQL
|
||||
* ou pour modéliser un schéma FSV
|
||||
* support `max_size`, qui diffère de `size` en ce qu'on ne spécifie qu'une
|
||||
taille maximum. sinon, faire `size` à la place de `max_size` et `fixed_size`
|
||||
à la plage de `size`
|
||||
|
||||
* support allowed_values
|
||||
* support `allowed_values`
|
||||
|
||||
* valeurs composite/computed
|
||||
* analyse / vérification de la valeur complète après calcul du résultat, si
|
||||
tous les résultats sont bons
|
||||
* calcul des valeurs composites/computed par une fonction avant/après l'analyse
|
||||
globale si résultat ok
|
||||
* fonction getter_func, setter_func, deleter_func pour les propriétés de type
|
||||
* fonction `getter_func`, `setter_func`, `deleter_func` pour les propriétés de type
|
||||
computed
|
||||
* tdate et tdatetime. qu'en est-il des autres classes (delay, etc.)
|
||||
* parse_format pour spécifier le format d'analyse au lieu de l'auto-détecter
|
||||
* `parse_format` pour spécifier le format d'analyse au lieu de l'auto-détecter
|
||||
|
||||
* ScalarSchema::from_property()
|
||||
* `ScalarSchema::from_property()`
|
||||
|
||||
* l'argument $format de AssocWrapper::format() est un tableau associatif
|
||||
`[$key => $format]`
|
||||
@ -68,7 +71,7 @@
|
||||
la définition de ces "circonstances" est encore à faire: soit un paramètre
|
||||
lors de la définition du schéma, soit un truc magique du genre "toutes les
|
||||
valeurs séquentielles sont des clés du schéma", soit un mode automatique
|
||||
activé par un paramètre où une valeur "val" devient "val"=>true si la clé
|
||||
activé par un paramètre où une valeur `"val"` devient `"val"=>true` si la clé
|
||||
"val" existe dans le schéma
|
||||
|
||||
-*- coding: utf-8 mode: markdown -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8:noeol:binary
|
Loading…
x
Reference in New Issue
Block a user