From b6bc0075905af278be9f8bcf602ee4601782d210 Mon Sep 17 00:00:00 2001 From: Aldarien Date: Tue, 13 Apr 2021 21:02:23 -0400 Subject: [PATCH] Migrate once when loaded --- app/common/Controller/Update.php | 75 ++------------------------ app/common/Middleware/Migrate.php | 31 +++++++++++ app/common/Service/Update.php | 90 +++++++++++++++++++++++++++++++ app/composer.json | 2 +- app/phinx.php | 26 ++++----- app/setup/api/middleware.php | 2 + app/setup/api/settings.php | 8 ++- app/setup/api/setups.php | 18 +++++++ 8 files changed, 165 insertions(+), 87 deletions(-) create mode 100644 app/common/Middleware/Migrate.php create mode 100644 app/common/Service/Update.php create mode 100644 app/setup/api/middleware.php diff --git a/app/common/Controller/Update.php b/app/common/Controller/Update.php index d6d663e..0b90c04 100644 --- a/app/common/Controller/Update.php +++ b/app/common/Controller/Update.php @@ -4,83 +4,14 @@ namespace ProVM\Money\Common\Controller; use Psr\Container\ContainerInterface as Container; use Psr\Http\Message\ServerRequestInterface as Request; use Psr\Http\Message\ResponseInterface as Response; -use GuzzleHttp\ClientInterface as Client; -use Carbon\Carbon; use ProVM\Common\Define\Controller\Json; -use ProVM\Common\Factory\Model as ModelFactory; -use ProVM\Money\Currency; -use ProVM\Money\Source; -use ProVM\Money\Value; +use ProVM\Money\Common\Service\Update as Updater; class Update { use Json; - protected function get(Client $client, string $url, bool $exception = true) { - $res = $client->get($url); - if ($res->getStatusCode() < 200 or $res->getStatusCode() >= 300) { - if ($exception) { - throw new \Exception('Url ' . $url . ' not connected.'); - } - return false; - } - return json_decode($res->getBody()); - } - - protected function baseMap($unit) { - $map = [ - 'Dólar' => 'US Dollar', - 'Pesos' => 'Peso Chileno' - ]; - return $map[$unit] ?? $unit; - } - - public function __invoke(Request $request, Response $response, Client $client, ModelFactory $factory, Container $container): Response { - ini_set('max_execution_time', 300); - - $sources = $factory->find(Source::class)->many(); - $date = Carbon::now(); - $output = ['count' => 0, 'values' => []]; - foreach ($sources as $source) { - $url = str_replace([ - '{year}', - '{month}', - '{day}', - '{hour}', - '{minute}', - '{second}' - ], [ - $date->year, - $date->month, - $date->day, - $date->hour, - $date->minute, - $date->second - ], $source->url); - $b = $this->get($client, $url, false); - if ($b === false) { - continue; - } - $base = $factory->find(Currency::class)->where([ - ['name', '%' . $this->baseMap($b->unidad_medida) . '%', 'like'] - ])->one(); - if (!$base) { - continue; - } - foreach ($b->serie as $info) { - $f = Carbon::parse($info->fecha); - $data = [ - 'currency_id' => $source->currency()->id, - 'date_time' => $f->format('Y-m-d H:i:s'), - 'value' => $info->valor, - 'base_id' => $base->id - ]; - $result = Value::add($factory, $data); - $output['values'] []= $result; - if ($result->created === true) { - $output['count'] ++; - } - } - } + public function __invoke(Request $request, Response $response, Updater $updater): Response { + $output = $updater->update(); return $this->withJson($response, $output); } } diff --git a/app/common/Middleware/Migrate.php b/app/common/Middleware/Migrate.php new file mode 100644 index 0000000..6ae2392 --- /dev/null +++ b/app/common/Middleware/Migrate.php @@ -0,0 +1,31 @@ +phinx = $phinx; + $this->updater = $updater; + } + + public function __invoke(Request $request, Handler $handler): Response { + $query = "SHOW TABLES"; + $st = \ORM::get_db()->query($query); + $r = $st->fetchAll(\PDO::FETCH_ASSOC); + if (count($r) == 0) { + $this->phinx->getMigrate(); + $this->phinx->getSeed(); + $this->updater->update(); + } + + return $handler->handle($request); + } +} diff --git a/app/common/Service/Update.php b/app/common/Service/Update.php new file mode 100644 index 0000000..fc6e3ea --- /dev/null +++ b/app/common/Service/Update.php @@ -0,0 +1,90 @@ +factory = $factory; + $this->client = $client; + } + + protected function get(Client $client, string $url, bool $exception = true) { + $res = $client->get($url); + if ($res->getStatusCode() < 200 or $res->getStatusCode() >= 300) { + if ($exception) { + throw new \Exception('Url ' . $url . ' not connected.'); + } + return false; + } + return json_decode($res->getBody()); + } + + protected function baseMap($unit) { + $map = [ + 'Dólar' => 'US Dollar', + 'Pesos' => 'Peso Chileno' + ]; + return $map[$unit] ?? $unit; + } + protected function buildUrl(Source $source) { + $date = Carbon::now(); + return str_replace([ + '{year}', + '{month}', + '{day}', + '{hour}', + '{minute}', + '{second}' + ], [ + $date->year, + $date->month, + $date->day, + $date->hour, + $date->minute, + $date->second + ], $source->url); + } + + public function update() { + ini_set('max_execution_time', 300); + + $sources = $this->factory->find(Source::class)->many(); + $output = ['count' => 0, 'values' => []]; + foreach ($sources as $source) { + $url = $this->buildUrl($source); + $b = $this->get($this->client, $url, false); + if ($b === false) { + continue; + } + $base = $this->factory->find(Currency::class)->where([ + ['name', '%' . $this->baseMap($b->unidad_medida) . '%', 'like'] + ])->one(); + if ($base === false) { + continue; + } + foreach ($b->serie as $info) { + $f = Carbon::parse($info->fecha); + $data = [ + 'currency_id' => $source->currency()->id, + 'date_time' => $f->format('Y-m-d H:i:s'), + 'value' => $info->valor, + 'base_id' => $base->id + ]; + $result = Value::add($this->factory, $data); + $output['values'] []= $result; + if ($result->created === true) { + $output['count'] ++; + } + } + } + return $output; + } +} diff --git a/app/composer.json b/app/composer.json index cabfd3f..28f9906 100644 --- a/app/composer.json +++ b/app/composer.json @@ -11,6 +11,7 @@ "provm/controller": "dev-master", "vlucas/phpdotenv": "^5.3", "guzzlehttp/guzzle": "^7.3", + "robmorgan/phinx": "^0.12.5", "nesbot/carbon": "^2.46" }, "license": "MIT", @@ -22,7 +23,6 @@ ], "require-dev": { "phpunit/phpunit": "^8.5", - "robmorgan/phinx": "^0.12.5", "odan/phinx-migrations-generator": "^5.4" }, "autoload": { diff --git a/app/phinx.php b/app/phinx.php index da7ec82..104f7c9 100644 --- a/app/phinx.php +++ b/app/phinx.php @@ -12,28 +12,28 @@ return 'default_environment' => 'development', 'production' => [ 'adapter' => 'mysql', - 'host' => 'localhost', - 'name' => 'production_db', - 'user' => 'root', - 'pass' => '', + 'host' => $_ENV['DB_HOST'], + 'name' => $_ENV['DB_NAME'], + 'user' => $_ENV['DB_USER'], + 'pass' => $_ENV['DB_PASSWORD'], 'port' => '3306', 'charset' => 'utf8', ], 'development' => [ 'adapter' => 'mysql', - 'host' => 'localhost', - 'name' => 'money_dev', - 'user' => 'money', - 'pass' => 'money_pass', - 'port' => '3307', + 'host' => $_ENV['DB_HOST'], + 'name' => $_ENV['DB_NAME'], + 'user' => $_ENV['DB_USER'], + 'pass' => $_ENV['DB_PASSWORD'], + 'port' => '3306', 'charset' => 'utf8', ], 'testing' => [ 'adapter' => 'mysql', - 'host' => 'localhost', - 'name' => 'testing_db', - 'user' => 'root', - 'pass' => '', + 'host' => $_ENV['DB_HOST'], + 'name' => $_ENV['DB_NAME'], + 'user' => $_ENV['DB_USER'], + 'pass' => $_ENV['DB_PASSWORD'], 'port' => '3306', 'charset' => 'utf8', ] diff --git a/app/setup/api/middleware.php b/app/setup/api/middleware.php new file mode 100644 index 0000000..d670df8 --- /dev/null +++ b/app/setup/api/middleware.php @@ -0,0 +1,2 @@ +add($app->getContainer()->get(ProVM\Money\Common\Middleware\Migrate::class)); diff --git a/app/setup/api/settings.php b/app/setup/api/settings.php index ab9de6d..ecaaf2e 100644 --- a/app/setup/api/settings.php +++ b/app/setup/api/settings.php @@ -22,5 +22,11 @@ return [ 'routes' ]); return (object) $arr; - }) + }), + 'phinx' => function(Container $c) { + return implode(DIRECTORY_SEPARATOR, [ + $c->get('locations')->base, + 'phinx.php' + ]); + } ]; diff --git a/app/setup/api/setups.php b/app/setup/api/setups.php index e342d27..29fe819 100644 --- a/app/setup/api/setups.php +++ b/app/setup/api/setups.php @@ -4,5 +4,23 @@ use Psr\Container\ContainerInterface as Container; return [ GuzzleHttp\ClientInterface::class => function(Container $c) { return new GuzzleHttp\Client(); + }, + ProVM\Common\Factory\Model::class => function(Container $c) { + return new ProVM\Common\Factory\Model(); + }, + ProVM\Money\Common\Service\Update::class => function(Container $c) { + return new ProVM\Money\Common\Service\Update($c->get(ProVM\Common\Factory\Model::class), $c->get(GuzzleHttp\ClientInterface::class)); + }, + ProVM\Money\Common\Middleware\Migrate::class => function(Container $c) { + return new ProVM\Money\Common\Middleware\Migrate($c->get(Phinx\Wrapper\TextWrapper::class), $c->get(ProVM\Money\Common\Service\Update::class)); + }, + Phinx\Console\PhinxApplication::class => function(Container $c) { + return new Phinx\Console\PhinxApplication(); + }, + Phinx\Wrapper\TextWrapper::class => function(Container $c) { + $options = [ + 'configuration' => $c->get('phinx') + ]; + return new Phinx\Wrapper\TextWrapper($c->get(Phinx\Console\PhinxApplication::class), $options); } ];