From f85c510ed49be031145f6b35e815ce890cd4f9aa Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Thu, 2 Jun 2022 08:41:08 +0200 Subject: New search engine (#4378) * New possibility to invoke user queries from a search expression From the search field: `S:"My query"`. Can be combined with other filters such as `S:"My query" date:P3d` as long as the user queries do not contain `OR`. A use-case is to have an RSS filter with a stable address or an external API call with the ability to update the user query. * Draft of parenthesis logic * More draft * Working parenthesis (a OR b) (c OR d) * Working (A) OR (B) * Support nested parentheses + unit tests + documentation * search:MySearch and S:3 --- tests/app/Models/SearchTest.php | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'tests/app/Models') diff --git a/tests/app/Models/SearchTest.php b/tests/app/Models/SearchTest.php index b43834147..74c1596f6 100644 --- a/tests/app/Models/SearchTest.php +++ b/tests/app/Models/SearchTest.php @@ -297,4 +297,39 @@ class SearchTest extends PHPUnit\Framework\TestCase { ), ); } + + /** + * @dataProvider provideParentheses + * @param array $values + */ + public function test__construct_parentheses(string $input, string $sql, $values) { + list($filterValues, $filterSearch) = FreshRSS_EntryDAOPGSQL::sqlBooleanSearch('e.', new FreshRSS_BooleanSearch($input)); + $this->assertEquals($sql, $filterSearch); + $this->assertEquals($values, $filterValues); + } + + public function provideParentheses() { + return [ + [ + 'f:1 (f:2 OR f:3 OR f:4) (f:5 OR (f:6 OR f:7))', + ' ((e.id_feed IN (?) )) AND ((e.id_feed IN (?) ) OR (e.id_feed IN (?) ) OR (e.id_feed IN (?) )) AND' . + ' (((e.id_feed IN (?) )) OR ((e.id_feed IN (?) ) OR (e.id_feed IN (?) ))) ', + ['1', '2', '3', '4', '5', '6', '7'] + ], + [ + '#tag Hello OR (author:Alice inurl:example) OR (f:3 intitle:World) OR L:12', + ' ((e.tags LIKE ? AND e.title||e.content LIKE ? )) OR ((e.author LIKE ? AND e.link||e.guid LIKE ? )) OR' . + ' ((e.id_feed IN (?) AND e.title LIKE ? )) OR ((e.id IN (SELECT et.id_entry FROM `_entrytag` et WHERE et.id_tag IN (?)) )) ', + ['%tag%','%Hello%','%Alice%','%example%','3','%World%', '12'] + ], + [ + '#tag Hello (author:Alice inurl:example) (f:3 intitle:World) label:Bleu', + ' ((e.tags LIKE ? AND e.title||e.content LIKE ? )) AND' . + ' ((e.author LIKE ? AND e.link||e.guid LIKE ? )) AND' . + ' ((e.id_feed IN (?) AND e.title LIKE ? )) AND' . + ' ((e.id IN (SELECT et.id_entry FROM `_entrytag` et, `_tag` t WHERE et.id_tag = t.id AND t.name IN (?)) )) ', + ['%tag%','%Hello%','%Alice%','%example%','3','%World%', 'Bleu'] + ], + ]; + } } -- cgit v1.2.3