1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
<?php
namespace Micropoly\Search;
class LogicOp implements SearchExpr
{
public const OP_AND = "and";
public const OP_OR = "or";
private const SQLOPS = [
self::OP_AND => "AND",
self::OP_OR => "OR",
];
private string $op;
private SearchExpr $a;
private SearchExpr $b;
public function __construct(string $op, SearchExpr $a, SearchExpr $b)
{
if (!self::checkOp($op))
throw new \DomainException("{$op} is not a valid operator");
$this->op = $op;
$this->a = $a;
$this->b = $b;
}
public static function build(string $op, SearchExpr $a, SearchExpr $b): SearchExpr
{
return $a instanceof AbstractFTSExpr && $b instanceof AbstractFTSExpr
? new FTSLogicOp($op, $a, $b)
: new self($op, $a, $b);
}
/**
* @param string $op
* @return bool
*/
public static function checkOp(string $op): bool
{
return in_array($op, [
self::OP_AND,
self::OP_OR,
]);
}
public function getA(): SearchExpr { return $this->a; }
public function getB(): SearchExpr { return $this->b; }
public function getOp(): string { return $this->op; }
public function toString(): string
{
return "({$this->a->toString()}) {$this->op} ({$this->b->toString()})";
}
public function toSQL($bindPrefix, bool $singleFTS): SQLSearchExpr
{
$sqlex = new SQLSearchExpr();
$a = $this->a->toSQL("a_$bindPrefix", $singleFTS);
$b = $this->b->toSQL("b_$bindPrefix", $singleFTS);
assert(isset(self::SQLOPS[$this->op]));
$sqlop = self::SQLOPS[$this->op];
$sqlex->sql = "(({$a->sql}) {$sqlop} ({$b->sql}))";
$sqlex->bindings = array_merge($a->bindings, $b->bindings);
return $sqlex;
}
public function countFTSQueries(): int
{
return $this->a->countFTSQueries() + $this->b->countFTSQueries();
}
}
|