earc/query-language

eArc - 显式架构框架 - 查询语言组件

0.1 2021-03-19 17:11 UTC

This package is auto-updated.

Last update: 2024-09-20 00:56:26 UTC


README

这是eArc框架轻量级的独立(无依赖)find/select查询语言组件。

它全面支持类型提示,以及类似于SQL的语法,使其易于学习和使用。

您可以将此组件绑定到任何支持某种类型分类(例如,表)并能解析以下关系的数据库或索引

  • =
  • !=
  • <
  • <=
  • >
  • >=
  • IN
  • NOT IN

您可以只使用关系子集或仅使用一个单一分类。

安装

使用composer安装earc依赖注入库。

$ composer require earc/query-language

绑定

要将语言绑定到您的数据库/索引,实现ResolverInterface。如果您使用AbstractResolver,则只需实现三个方法:findAll()queryRelation()sort()

use eArc\QueryLanguage\AbstractResolver;

class MyResolver extends AbstractResolver
{
    public function findAll(string $dataCategory) : iterable
    {
        // ...
    }

    protected function queryRelation(string $dataCategory, string $dataProperty, string $cmp, $value, ?iterable $allowedDataIdentifiers = null) : iterable
    {
        // ...
    }

    public function sort(string $dataCategory, string $sort, iterable $dataPropertyNames, ?iterable $dataIdentifiers, ?iterable $allowedDataIdentifiers = null, int $limit = 0, int $offset = 0) : iterable
    {
        // ... You may skip this and throw an exception if you do not want to sort your results via query.
    }
}

返回的可迭代对象必须使用唯一数据标识符字符串作为键,以及作为值的数据项。

提示:唯一数据标识符必须包含一个非整数字符,否则PHP会将字符串键转换为整数。

您可以在项目中使用多个不同的绑定。因此,解析器必须绑定到您的查询工厂。只需扩展AbstractQueryFactory并实现getQueryResolver()方法。

use eArc\QueryLanguage\AbstractQueryFactory;
use eArc\QueryLanguage\Interfaces\ResolverInterface;

class MyFinder extends AbstractQueryFactory
{
    protected function getQueryResolver() : ResolverInterface
    {
        // ...
    }
}

要注入您的解析器,您可以使用传统的构造函数注入或使用更复杂的工具,如earc/di

使用方法

简单使用

简单使用受到了doctrine repositories的findBy()方法灵感的启发。

$qFactory = new MyFinder();
$result = $qFactory->findBy('SomeCategory', []);

这给出了数据分类SomeCategory的所有数据条目。

$qFactory = new MyFinder();
$result = $qFactory->findBy('Wallpaper', ['color' => 'green', 'available' => true]);

这给出了具有属性color值为green和属性available值为true的数据分类Wallpaper的所有数据条目。

内部这解析为查询...

(new QueryInitializer($qFactory->getQueryResolver()))
    ->from('Wallpaper')
    ->where('color')->equals('green')
    ->andWhere('available')->equals(true)
    ->eval();

基于查询的使用

您可以直接使用查询语言,通过使用find()代替findBy()find()会返回一个QueryInitializer,您可以从中构建查询。

$qFactory = new MyFinder();
$result = $qFactory->find()
    ->from('SomeCategory')

第一个查询部分总是from。在这里,您指定数据分类。

您可以在第二个查询部分指定一个可选的limit

    ->limit($limit, $offset)

$limit是一个int,指定返回的数据项的最大数量。 $offset也是一个int,指定第一个项目的位置。limit对于所有类型的分页特别有用。

第三个查询部分也是可选的。它指定返回数据项的排序。当然,在排序后应用limit

    ->sortAsc('color', 'price')
    // or
    ->sortDesc('color', 'price')

您可以通过传递任意多的属性。数据项将按照第一个属性进行排序;如果某些项相同,则按第二个属性排序,依此类推。

提示:排序必须在解析器中实现。其实施可能与这里解释的行为不同。

之后,总是有一个evalwhere表达式。eval会在这一点返回由from指定的数据分类的所有数据项(仅受可选的limitsort影响)。而where则引入一个关系,这可能会缩小结果数据项。

    ->where('price')

where表达式必须与以下关系之一链接

    ->equals($value)
    ->notEqual($value)
    ->lt($value)
    ->leq($value)
    ->gt($value)
    ->geq($value)
    ->in($iterable)
    ->notIn($iterable)

该表达式可以通过eval()进行评估,或者通过一个后置的where和一个逻辑连接词前缀进行链式调用。

    ->andWhere('property')
    // or
    ->orWhere('property')

随后是一个关系,将通过eval()进行评估,或者通过另一个andWhere()orWhere进行链式调用,依此类推。

如果解析器使用AbstractResolver,则andWhere()连接词将先于orWhere()连接词进行评估。

如果您需要其他行为,可以使用BRACKETS()方法而不是where(),使用AND()而不是andWhere(),以及使用OR()而不是orWhere()。它们接受一个查询表达式作为参数,首先对该表达式进行评估,然后在AND()OR()的情况下应用于左表达式的结果。

use eArc\QueryLanguage\Collector\QueryPart;

    ->BRACKETS((new QueryPart())->where('property')...)
    ->AND((new QueryPart())->where('property')...)
    ->OR((new QueryPart())->where('property')...)

您可以为所有括号表达式使用相同的QueryPart实例。(它是一个没有属性的纯对象。)

结果

如果解析器使用AbstractResolver,则eval()返回一个QueryResult。要检索数据项,您必须遍历它。

限制结果

Both find()findBy()的最后一个参数是一个iterable $allowedDataIdentifiers,它将返回的结果限制为指向允许的数据标识符的数据项。

发布

发布0.1

  • 支持php ^8.0 || ^7.2

发布0.0

  • 支持php ^7.2
  • 第一个官方版本