chevere/sql2p

MySQL模式参数

1.0.0 2024-01-16 13:07 UTC

This package is auto-updated.

Last update: 2024-09-20 12:05:20 UTC


README

🔔 订阅通讯,不错过Chevere的任何更新。

Chevere

Build Code size Apache-2.0 PHPStan Mutation testing badge

Quality Gate Status Maintainability Rating Reliability Rating Security Rating Coverage Technical Debt CodeFactor

摘要

SQL2P为MySQL模式生成参数。它使用Parameter包来表示数据库表及其列。

安装

SQL2P通过包管理器提供,仓库源代码在chevere/sql2p

composer require chevere/sql2p

它做什么?

从一个类似的CREATE TABLE语句。

CREATE TABLE `invoice` (
  `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
  `client_id` INT UNSIGNED NOT NULL,
  `datetime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `details` LONGTEXT NULL,
  `quantity` INT UNSIGNED NOT NULL,
  `rate` DECIMAL(10,2) NOT NULL,
  `total` DECIMAL(19,4) GENERATED ALWAYS AS (quantity*rate),
  PRIMARY KEY (`id`)
) ENGINE = InnoDB;

SQL2P生成以下PHP代码。

use Chevere\Parameter\Interfaces\ArrayParameterInterface;
use function Chevere\Parameter\arrayp;
use function Chevere\Parameter\datetime;
use function Chevere\Parameter\float;
use function Chevere\Parameter\int;
use function Chevere\Parameter\null;
use function Chevere\Parameter\string;
use function Chevere\Parameter\union;

function invoiceTable(): ArrayParameterInterface
{
    return arrayp(
        id: int(min: 0),
        client_id: int(min: 0),
        datetime: datetime(),
        details: union(
            null(),
            string()
        ),
        quantity: int(min: 0),
        rate: float(),
        total: float()
    );
}

invoiceTable()函数使用数组 Parameter返回PHP代码中的表invoice模式,其中每个列都由另一个Parameter表示。

您可以从生成的代码中添加自己的验证规则。

例如,您可以通过添加maxmin参数将quantity限制在100, 200范围内。向details添加正则表达式以验证字符串形状。

details: union(
    null(),
-    string()
+    string('/^(?!\s*$)./')
),
-quantity: int(min: 0),
+quantity: int(max: 200, min: 100),

此函数返回的Array Parameter对象也可以用于动态与一个或多个这些列进行交互。有关更多信息,请参阅数组组合

创建SQL2P

通过传递SQL和Writer实例来创建SQL2P实例。在实例创建时,解析SQL并使用writer写入生成的代码。

use Chevere\SQL2P\SQL2P;
use Chevere\Writer\StreamWriter;
use function Chevere\Filesystem\fileForPath;
use function Chevere\Writer\streamFor;

$schema = __DIR__ . '/schema.sql';
$output = __DIR__ . '/sql2p.php';
$header = <<<PHP
namespace MyNamespace;
PHP;
$sql = file_get_contents($schema);
file_put_contents($output, '');
$stream = streamFor($output, 'w');
$writer = new StreamWriter($stream);
$sql2p = new SQL2P($sql, $writer, $header);
$count = count($sql2p);
echo <<<PLAIN
[{$count} tables] {$output->path()}

PLAIN;

数据验证

使用SQL2P验证数据与表Parameter模式。

例如,对于单个获取结果,您可能获得以下数组作为数据库行的结果。

SELECT * FROM invoice WHERE id = 1
$fetch = [
    'id' => 1,
    'client_id' => 1234,
    'datetime' => '2023-10-22 19:58:44',
    'details' => null,
    'quantity' => 100,
    'rate' => 16.5,
    'total' => 1650,
];

可以使用invoiceTable()函数通过调用它来验证$fetch

$table = invoiceTable();
$table($fetch); // validation

使用arrayFrom函数创建一个仅包含您需要的列的数组。

SELECT id, total FROM invoice WHERE id = 1
use function Chevere\Parameter\arrayFrom;

$fetch = [
    'id' => 1,
    'total' => 1650,
];
$table = arrayFrom(invoiceTable(), 'id', 'total');
$table($fetch);

使用arguments函数以类型化方式访问获取的数组成员。

use function Chevere\Parameter\arguments;

$invoice = arguments($table, $fetch);
$total = $invoice->required('total')->int(); // 1650

在获取多行时,将Array表包裹在iterable函数中。

SELECT id, total FROM invoice WHERE id > 0
$fetchAll = [
    0 => [
        'id' => 1,
        'total' => 1650,
    ],
    1 => [
        'id' => 2,
        'total' => 1820,
    ],
];
$iterable = iterable($table);
$iterable($fetchAll);

注意,arguments函数支持iterable。

$invoices = arguments($iterable, $fetchAll);
$secondRow = $invoices->required('1')->array();

数组组合

Parameter提供了一套工具来处理数组,允许动态添加、删除或修改值。它还可以从其他数组组合数组。

例如,要向invoiceTable()添加一个虚拟列total_usd

SELECT
    id,
    total,
    total/100 total_usd
FROM invoice WHERE id = 1
$fetch = [
    'id' => 1,
    'total' => 1650,
    'total_usd' => 16.5,
];
$table = arrayFrom(invoiceTable(), 'id', 'total');
$table = $table
    ->withRequired(
        total_usd: float(),
    );
$table($fetch);

当联合表时,您可能希望根据联合的表来选择列。使用takeFrom函数创建一个包含column => parameter对的iterable。

SELECT
    invoice.id,
    invoice.total,
    client.name,
    client.email
FROM invoice
JOIN client ON client.id = invoice.client_id
WHERE invoice.id = 1
$fetch = [
    'id' => 1,
    'total' => 1650,
    'name' => 'Rodolfo',
    'email' => 'rodolfo@chevere.org'
];
$invoice = arrayFrom(invoiceTable(), 'id', 'total');
$client = takeFrom(clientTable(), 'name', 'email');
$table = $invoice->withRequired(...$client);
$table($fetch);

对于此代码,$client被分配为一个包含从clientTable()中获取的nameemail列对的iterable。然后通过在$invoice上调用withRequired,它通过展开获取这些列。

文档

文档可在chevere.org找到。

许可证

版权所有 Rodolfo Berrios A.

Chevere采用Apache许可证,版本2.0。有关完整的许可证文本,请参阅LICENSE

除非适用法律要求或书面同意,否则在许可证下分发的软件按照“现状”基础分发,不提供任何形式的保证或条件,无论是明示的还是默示的。请参阅许可证以了解具体的管理权限和限制的语言。