ray / query-module
外部媒体访问框架
Requires
- php: ^7.3 || ^8.0
- ext-json: *
- ext-pdo: *
- aura/sql: ^3.0 | ^4.0 | ^5.0
- bear/resource: ^1.15
- doctrine/annotations: ^1.12
- guzzlehttp/guzzle: ^6.3 || ^7.0
- koriym/query-locator: ^1.4
- nikic/php-parser: ^v4.13
- ray/aop: ^2.10.3
- ray/aura-sql-module: ^1.10.0
- ray/di: ^2.11
Requires (Dev)
- bamarni/composer-bin-plugin: ^1.4
- phpunit/phpunit: ^9.5
This package is auto-updated.
Last update: 2024-09-13 02:49:29 UTC
README
概述
Ray.QueryModule
使用一个注入的函数对象对数据库或 Web API 等外部媒体进行查询。
SqlQueryModule
用于数据库。将 SQL 文件转换为执行该 SQL 的简单函数对象。WebQueryModule
用于 Web API。将 URI 和方法集转换为执行 Web 请求的简单函数对象。PhpQueryModule
是一个通用模块。它提供存储访问,这是 PHP 函数对象无法通过静态转换提供的。
动机
- 在代码中,您可以清楚地在领域层(使用代码)和基础设施层(注入的函数)之间划分界限。
- 执行对象会自动生成,因此您不需要编写执行过程代码。
- 由于使用代码对外部媒体的实际状态不关心,因此以后可以更改存储。便于并行开发和并行攻击。
安装
Composer 安装
$ composer require ray/query-module
模块安装
use Ray\Di\AbstractModule; use Ray\Query\SqlQueryModule; class AppModule extends AbstractModule { protected function configure() { // SqlQueryModule install $this->install(new SqlQueryModule($sqlDir)); // WebQueryModule install $webQueryConfig = [ 'post_todo' => ['POST', 'https://httpbin.org/todo'], // bind-name => [method, uri] 'get_todo' => ['GET', 'https://httpbin.org/todo'] ]; $guzzleConfig = []; // @see http://docs.guzzlephp.org/en/stable/request-options.html $this->install(new WebQueryModule($webQueryConfig, $guzzleConfig)); } }
SQL 文件
$sqlDir/todo_insert.sql
INSERT INTO todo (id, title) VALUES (:id, :title)
$sqlDir/todo_item_by_id.sql
SELECT * FROM todo WHERE id = :id
将 SQL 转换为 SQL 调用对象
注入到构造函数中的可调用对象。这些对象是在指定的 SQL 中使用 @Named
绑定创建的。
class Todo { /** * @var callable */ private $createTodo; /** * @var callable */ private $todo; /** * @Named("createTodo=todo_insert, todo=todo_item_by_id") */ public function __construct( callable $createTodo, callable $todo ){ $this->createTodo = $createTodo; $this->todo = $todo; } public function get(string $uuid) { return ($this->todo)(['id' => $uuid]); } public function create(string $uuid, string $title) { ($this->createTodo)([ 'id' => $uuid, 'title' => $title ]); } }
行或行列表
您可以使用 RowInterface
或 RowListInterface
指定期望的返回值类型为 Row
或 RowList
。 RowInterface
用于指定返回单行的 SQL。
use Ray\Query\RowInterface; class Todo { /** * @Named("todo_item_by_id") */ public function __construct(RowInterface $todo) { $this->todo = $todo; } public function get(string $uuid) { $todo = ($this->todo)(['id' => $uuid]); // single row data } }
use Ray\Query\RowListInterface; class Todos { /** * @Named("todos") */ public function __construct(RowListInterface $todos) { $this->todos = $todos; } public function get(string $uuid) { $todos = ($this->todos)(); // multiple row data } }
使用可调用对象覆盖方法
可以使用指定了 @Query
的可调用对象覆盖整个方法调用。
class Foo { /** * @Query(id="todo_item_by_id") */ public function get(string $id) { } }
当参数名与方法和查询对象参数不同时,可以使用 uri_template 样式表达式解决这个问题。
class FooTempalted { /** * @Query(id="todo_item_by_id?id={a}", templated=true) */ public function get(string $a) { } }
当期望返回单行结果时,指定 type='row'
。
class FooRow { /** * @Query(id="ticket_item_by_id", type="row") */ public function onGet(string $id) : ResourceObject { } }
如果没有 SELECT 结果,则返回 404 Not Found
。
将 URI 转换为 Web 请求对象
使用 WebQueryModule
,它将配置中绑定的 URI 转换为 Web 访问的调用对象并注入它。在以下示例中,将向 https://httpbin.org/todo
发送 POST
请求的 $createTodo
调用对象注入为 $createTodo
。
use Ray\Di\AbstractModule; use Ray\Query\SqlQueryModule; class AppModule extends AbstractModule { protected function configure() { // WebQueryModuleインストール $webQueryConfig = [ 'todo_post' => ['POST', 'https://httpbin.org/todo'], 'todo_get' => ['GET', 'https://httpbin.org/todo'] ]; $guzzleConfig = []; $this->install(new WebQueryModule($webQueryConfig, $guzzleConfig)); } }
使用代码与 SqlQueryModule
相同。
/** * @Named("createTodo=todo_post, todo=todo_get") */ public function __construct( callable $createTodo, callable $todo ){ $this->createTodo = $createTodo; $this->todo = $todo; }
// POST ($this->createTodo)([ 'id' => $uuid, 'title' => $title ]); // GET ($this->todo)(['id' => $uuid]);
@Query
的使用代码也没有改变。
绑定到 PHP 类
如果需要其他依赖项,我们将其绑定到 PHP 类,并使用依赖项作为服务。
class CreateTodo implements QueryInterface { private $pdo; private $builder; public function __construct(PdoInterface $pdo, QueryBuilderInferface $builder) { $this->pdo = $pdo; $this->builder = $builder; } public function __invoke(array $query) { // Query execution using $pdo and $builder return $result; } }
绑定到 callable
。
$this->bind('')->annotatedWith('cretate_todo')->to(CreateTodo::class); // callableはインターフェイスなし
使用代码相同。使用 @Query
的使用代码也没有改变。
ISO8601 日期时间模块
将指定的列名值转换为 ISO8601 格式。在 PHP 中,这是由 DateTime::ATOM 常量定义的格式。将日期列名作为数组安装,并将其作为参数传递给 Iso8601FormatModule
。
$this->install(new Iso8601FormatModule(['created_at', 'updated_at']));
SQL 文件名日志
可以将 SQL 文件名附加到 SQL 语句作为注释。这对于查询日志非常有用。
use Ray\Query\SqlFileName; use Ray\Query\SqlQueryModule; $this->install(new SqlQueryModule(__DIR__ . '/Fake/sql', null, new SqlFileName()));
执行 SQL
/* todo_item_by_id.sql */ SELECT * FROM todo WHERE id = :id
演示
php demo/run.php