2017 © Pedro Peláez
 

library search-query

image

railken/search-query

  • Sunday, July 1, 2018
  • by railken
  • Repository
  • 2 Watchers
  • 0 Stars
  • 2,502 Installations
  • PHP
  • 3 Dependents
  • 0 Suggesters
  • 0 Forks
  • 0 Open issues
  • 23 Versions
  • 300 % Grown

The README.md

Search Query

Actions Status, (*1)

Converts a simple expression (e.g. 'x eq 1 or y gt 2') into a tree object. This can be pretty usefull when building the API endpoint for a search., (*2)

Requirements

PHP 7.1 or later., (*3)

Composer

You can install it via Composer by typing the following command:, (*4)

composer require railken/search-query

Demo

demo, (*5)

Usage

A simple usage looks like this:, (*6)

   use Railken\SQ\QueryParser;
   use Railken\SQ\Resolvers as Resolvers;

   $parser = new QueryParser();
   $parser->addResolvers([
      new Resolvers\ValueResolver(),
      new Resolvers\KeyResolver(),
      new Resolvers\GroupingResolver(),
      new Resolvers\NotEqResolver(),
      new Resolvers\EqResolver(),
      new Resolvers\LteResolver(),
      new Resolvers\LtResolver(),
      new Resolvers\GteResolver(),
      new Resolvers\GtResolver(),
      new Resolvers\CtResolver(),
      new Resolvers\SwResolver(),
      new Resolvers\NotInResolver(),
      new Resolvers\InResolver(),
      new Resolvers\EwResolver(),
      new Resolvers\NotNullResolver(),
      new Resolvers\NullResolver(),
      new Resolvers\AndResolver(),
      new Resolvers\OrResolver(),
      new Resolvers\TextResolver(),
   ]);
   $result = $query->parse('x eq 1 or y > 1');

The result formatted in json of $result:, (*7)

{
  "type": "Railken\\SQ\\Nodes\\OrNode",
  "value": "OR",
  "childs": [
    {
      "type": "Railken\\SQ\\Nodes\\EqNode",
      "value": "EQ",
      "childs": [
        {
          "type": "Railken\\SQ\\Nodes\\KeyNode",
          "value": "x"
        },
        {
          "type": "Railken\\SQ\\Nodes\\ValueNode",
          "value": "1"
        }
      ]
    },
    {
      "type": "Railken\\SQ\\Nodes\\GtNode",
      "value": "GT",
      "childs": [
        {
          "type": "Railken\\SQ\\Nodes\\KeyNode",
          "value": "y"
        },
        {
          "type": "Railken\\SQ\\Nodes\\ValueNode",
          "value": "1"
        }
      ]
    }
  ]
}

Nodes

Key node

All alphanumeric (starting with alphabetic character) are converted as KeyNode. Other characters allowed: _, (*8)

Examples:, (*9)

created_at

Value node

All numbers and strings are converted as ValueNode. The delimiter of strings can be either ' or ", (*10)

Examples:, (*11)

"An apple"
30.20

Group node

All round parenthesis create a group node ( ... ). Of course a nested group can be made. If a parenthesis is missing an exception will be thrown, (*12)

Examples:, (*13)

(x or y) and z
((x > 10 and w) or (y > 5 and f)) and z

AND, OR

This operators requires a Node before and after, otherwise an exception will be thrown., (*14)

Can be expressed as literals (and, or) or as symbols (&&, ||), (*15)

Important: If a parent group is defined and the LogicNode is the only child, the LogicNode will take the place of the GroupNode., (*16)

Examples:, (*17)

x or y || z
x and y && z

EQ, NOT_EQ, GT, GTE, LT, LTE

All these operators requires KeyNode or a ValueNode before and afters. Can be expressed as literals (eq, not eq, gt, gte, lt, lte) or as symbols (=, !=, >, >=, < <=), (*18)

Examples:, (*19)

x eq 1
x = 1
x gt 1
x > 1
x gte 1
x >= 1
x lt 1
x < 1
x lte 1
x <= 1

Comparison can be also made between two keys, (*20)

Examples:, (*21)

x eq y

CT, SW, EW

These operators will handle comparison with strings: contains, start with and end with., (*22)

Examples:, (*23)

description ct "a random phrase"
description sw "the text must start with this"
description ew "the text must end with this"

NULL, NOT NULL

These operators don't require a node after the operator., (*24)

deleted_at is null
deleted_at is not null

Custom resolver

As you already saw, in order to parse the query you have to add the resolvers. So you are free to add any resolvers you want, but pay attention to the order: KeyValue and NodeValue are the foundation for all the resolvers, so be carefull., (*25)

Here's an example of custom resolver and node, (*26)

CustomResolver.php, (*27)

<?php
namespace App\SQ\Resolvers;

use Railken\SQ\Resolvers\ComparisonOperatorResolver;
use App\SQ\Nodes\CustomNode;

class CustomResolver extends ComparisonOperatorResolver
{
    /**
     * Node resolved
     *
     * @var string
     */
    public $node = CustomNode::class;

    /**
     * Regex token
     *
     * @var string
     */
    public $regex = [
        '/(?<![^\s])custom(?![^\s])/i',
    ];
}

CustomNode.php, (*28)

<?php
namespace App\SQ\Nodes;

use Railken\SQ\Nodes\ComparisonOperatorNode;

class CustomNode extends ComparisonOperatorNode
{
    /**
     * Value
     *
     * @var string
     */
    public $value = 'CUSTOM';
}

Remember to add the resolver when you're creating the instance of the parser, (*29)

<?php
$parser->addResolvers([
   new \App\SQ\Resolvers\CustomResolver(),
});

If you have a more complicated node to resolve simply add the method resolve to the CustomResolver., (*30)

<?php
namespace App\SQ\Resolvers;

use Railken\SQ\Contracts\ResolverContract;
use Railken\SQ\Contracts\NodeContract;

class CustomResolver implements ResolverContract
{

   /**
     * Resolve node
     *
     * @param NodeContract $node
     *
     * @return NodeContract
     */
    public function resolve(NodeContract $node)
    {
        return $node;
    }

}

Railken\SQ\Languages\BoomTree\Resolvers\CustomResolver

There is also a CustomResolver that works and cycle with all children and it's configurabile through a Closure, it's Railken\SQ\Languages\BoomTree\Resolvers\CustomResolver. For istance you could attach a prefix to all KeyNode doing this:, (*31)

use Railken\SQ\Languages\BoomTree\Resolvers;
use Railken\SQ\Languages\BoomTree\Nodes;

$parser->addResolvers([
    new Resolvers\CustomResolver(function ($node) {
        if($node instanceof Nodes\KeyNode) {
            $node->setValue("myCustomPrefix.".$node->getValue());
        }
    }),
]);

License

Open-source software licensed under the MIT license., (*32)

The Versions

01/07 2018
16/03 2018
11/03 2018

v2.1.5

2.1.5.0

  Sources   Download

MIT

The Requires

 

The Development Requires

api

05/03 2018

v2.1.4

2.1.4.0

  Sources   Download

MIT

The Requires

 

The Development Requires

api

04/01 2018

v2.1.3

2.1.3.0

  Sources   Download

MIT

The Requires

 

The Development Requires

api

18/12 2017

v2.1.2

2.1.2.0

  Sources   Download

MIT

The Requires

 

The Development Requires

api

18/12 2017

v2.1.1

2.1.1.0

  Sources   Download

MIT

The Requires

 

The Development Requires

api

09/12 2017

v2.1.0

2.1.0.0

  Sources   Download

MIT

The Requires

 

The Development Requires

api

20/11 2017

v2.0.0

2.0.0.0

  Sources   Download

MIT

The Requires

 

The Development Requires

api

25/10 2017

v1.0.5

1.0.5.0

  Sources   Download

MIT

The Requires

 

The Development Requires

api

24/10 2017

v1.0.4

1.0.4.0

  Sources   Download

MIT

The Requires

 

The Development Requires

api

15/10 2017

v1.0.3

1.0.3.0

  Sources   Download

MIT

The Requires

 

The Development Requires

api

15/10 2017

v1.0.2

1.0.2.0

  Sources   Download

MIT

The Requires

 

The Development Requires

api

15/10 2017

v1.0.1

1.0.1.0

  Sources   Download

MIT

The Requires

 

The Development Requires

api

15/10 2017

v1.0.0

1.0.0.0

  Sources   Download

MIT

The Requires

 

The Development Requires

api