Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
erp5
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Laurent S
erp5
Commits
d7cc8581
Commit
d7cc8581
authored
Oct 28, 2014
by
Kazuhiko Shiozaki
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
full text: move special query generation logic from SearchKey to ComparisonOperator.
parent
6d4c6e39
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
68 additions
and
76 deletions
+68
-76
product/ZSQLCatalog/Operator/ComparisonOperator.py
product/ZSQLCatalog/Operator/ComparisonOperator.py
+65
-3
product/ZSQLCatalog/SearchKey/MroongaBooleanFullTextKey.py
product/ZSQLCatalog/SearchKey/MroongaBooleanFullTextKey.py
+1
-1
product/ZSQLCatalog/SearchKey/MroongaFullTextKey.py
product/ZSQLCatalog/SearchKey/MroongaFullTextKey.py
+2
-72
No files found.
product/ZSQLCatalog/Operator/ComparisonOperator.py
View file @
d7cc8581
...
...
@@ -33,6 +33,7 @@ from Products.ZSQLCatalog.SQLExpression import SQLExpression
from
Products.ZSQLCatalog.interfaces.operator
import
IOperator
from
zope.interface.verify
import
verifyClass
from
Products.ZSQLCatalog.SQLCatalog
import
list_type_list
import
re
class
ComparisonOperatorBase
(
OperatorBase
):
def
asSQLExpression
(
self
,
column
,
value_list
,
only_group_columns
):
...
...
@@ -98,16 +99,19 @@ verifyClass(IOperator, MultivaluedComparisonOperator)
class
MatchComparisonOperator
(
MonovaluedComparisonOperator
):
def
__init__
(
self
,
operator
,
mode
=
''
):
MonovaluedComparisonOperator
.
__init__
(
self
,
operator
,
''
)
self
.
where_expression_format_string
=
'MATCH (%%(column)s) AGAINST (%%(value_list)s%s)'
%
(
mode
,
)
self
.
mode
=
mode
self
.
where_expression_format_string
=
'MATCH (%(column)s) AGAINST (%(value_list)s%(mode)s)'
def
asSQLExpression
(
self
,
column
,
value_list
,
only_group_columns
):
"""
This operator can emit a select expression, so it overrides
asSQLExpression inseatd of just defining a render method.
"""
value_list
=
self
.
renderValue
(
value_list
)
match_string
=
self
.
where_expression_format_string
%
{
'column'
:
column
,
'value_list'
:
self
.
renderValue
(
value_list
),
'value_list'
:
value_list
,
'mode'
:
self
.
mode
,
}
select_dict
=
{}
if
not
only_group_columns
:
...
...
@@ -127,6 +131,63 @@ class MatchComparisonOperator(MonovaluedComparisonOperator):
verifyClass
(
IOperator
,
MatchComparisonOperator
)
class
MroongaComparisonOperator
(
MatchComparisonOperator
):
fulltext_boolean_splitter
=
re
.
compile
(
r'(\
s|
\(.+?\
)|
".+?")'
)
fulltext_boolean_detector
=
re
.
compile
(
r'(^[+-]|^.+\
*$|^[
"(].+[")]$)'
)
def
renderValue
(
self
,
value_list
):
"""
Special Query renderer for MroongaFullText queries:
* by default 'AND' search by using '*D+' pragma.
* similarity search for non-boolean queries by using '*S"..."' operator.
"""
if
isinstance
(
value_list
,
list_type_list
):
try
:
value_list
,
=
value_list
except
ValueError
:
raise
ValueError
,
'%r: value_list must not contain more than one item. Got %r'
%
(
self
,
value_list
)
if
self
.
mode
==
' IN BOOLEAN MODE'
:
fulltext_query
=
'*D+ %s'
%
value_list
return
self
.
_renderValue
(
fulltext_query
)
else
:
match_query_list
=
[]
match_boolean_query_list
=
[]
for
token
in
self
.
fulltext_boolean_splitter
.
split
(
value_list
):
token
=
token
.
strip
()
if
not
token
:
continue
elif
self
.
fulltext_boolean_detector
.
match
(
token
):
match_boolean_query_list
.
append
(
token
)
else
:
match_query_list
.
append
(
token
)
fulltext_query
=
'*D+'
if
match_query_list
:
fulltext_query
+=
' *S"%s"'
%
' '
.
join
(
x
.
replace
(
'"'
,
'
\
\
"'
)
for
x
in
match_query_list
)
if
match_boolean_query_list
:
fulltext_query
+=
' %s'
%
' '
.
join
(
match_boolean_query_list
)
self
.
mode
=
' IN BOOLEAN MODE'
return
self
.
_renderValue
(
fulltext_query
)
verifyClass
(
IOperator
,
MroongaComparisonOperator
)
class
MroongaBooleanComparisonOperator
(
MroongaComparisonOperator
):
def
renderValue
(
self
,
value_list
):
"""
value_list must either be a non-list or a single-value list.
"""
if
isinstance
(
value_list
,
list_type_list
):
try
:
value_list
,
=
value_list
except
ValueError
:
raise
ValueError
,
'%r: value_list must not contain more than one item. Got %r'
%
(
self
,
value_list
)
fulltext_query
=
'*D+ %s'
%
value_list
print
self
.
_renderValue
(
fulltext_query
)
return
self
.
_renderValue
(
fulltext_query
)
verifyClass
(
IOperator
,
MatchComparisonOperator
)
class
SphinxSEComparisonOperator
(
MonovaluedComparisonOperator
):
def
__init__
(
self
,
operator
,
mode
=
''
):
MonovaluedComparisonOperator
.
__init__
(
self
,
operator
,
''
)
...
...
@@ -173,9 +234,10 @@ operator_dict = {
'match'
:
MatchComparisonOperator
(
'match'
),
'match_boolean'
:
MatchComparisonOperator
(
'match_boolean'
,
mode
=
' IN BOOLEAN MODE'
),
'match_expansion'
:
MatchComparisonOperator
(
'match_expansion'
,
mode
=
' WITH QUERY EXPANSION'
),
'mroonga'
:
MroongaComparisonOperator
(
'mroonga'
),
'mroonga_boolean'
:
MroongaComparisonOperator
(
'mroonga_boolean'
,
mode
=
' IN BOOLEAN MODE'
),
'sphinxse'
:
SphinxSEComparisonOperator
(
'sphinxse'
),
'in'
:
MultivaluedComparisonOperator
(
'in'
),
'is'
:
MonovaluedComparisonOperator
(
'is'
),
'is not'
:
MonovaluedComparisonOperator
(
'is not'
,
'!='
),
}
product/ZSQLCatalog/SearchKey/MroongaBooleanFullTextKey.py
View file @
d7cc8581
...
...
@@ -35,6 +35,6 @@ class MroongaBooleanFullTextKey(MroongaFullTextKey):
This SearchKey generates SQL fulltext comparisons for Mroonga whose
default comparison operator is match_boolean.
"""
default_comparison_operator
=
'm
atch
_boolean'
default_comparison_operator
=
'm
roonga
_boolean'
verifyClass
(
ISearchKey
,
MroongaBooleanFullTextKey
)
product/ZSQLCatalog/SearchKey/MroongaFullTextKey.py
View file @
d7cc8581
...
...
@@ -27,80 +27,10 @@
##############################################################################
from
DefaultKey
import
DefaultKey
from
FullTextKey
import
FullTextKey
from
Products.ZSQLCatalog.Query.SimpleQuery
import
SimpleQuery
from
Products.ZSQLCatalog.interfaces.search_key
import
ISearchKey
from
SearchKey
import
SearchKey
from
zope.interface.verify
import
verifyClass
import
re
class
MroongaFullTextKey
(
FullTextKey
):
"""
This SearchKey generates SQL fulltext comparisons for Mroonga.
"""
default_comparison_operator
=
'match'
fulltext_boolean_splitter
=
re
.
compile
(
r'(\
s|
\(.+?\
)|
".+?")'
)
fulltext_boolean_detector
=
re
.
compile
(
r'(^[+-]|^.+\
*$|^[
"(].+[")]$)'
)
def
_processSearchValue
(
self
,
search_value
,
logical_operator
,
comparison_operator
):
"""
Special SearchValue processor for MroongaFullText queries:
if a searched token from 'match' operator group contains an
operator recognised in boolean mode, make the operator for
that value be 'match_boolean'.
"""
operator_value_dict
,
logical_operator
,
parsed
=
\
SearchKey
.
_processSearchValue
(
self
,
search_value
,
logical_operator
,
comparison_operator
)
new_value_list
=
[]
append
=
new_value_list
.
append
for
value
in
operator_value_dict
.
pop
(
'match'
,
[]):
if
isinstance
(
value
,
basestring
):
# special case for empty string.
if
value
==
''
:
operator_value_dict
.
setdefault
(
'='
,
[]).
append
(
value
)
continue
for
token
in
self
.
fulltext_boolean_splitter
.
split
(
value
):
token
=
token
.
strip
()
if
not
token
:
continue
elif
self
.
fulltext_boolean_detector
.
match
(
token
):
operator_value_dict
.
setdefault
(
'match_boolean'
,
[]).
append
(
token
)
else
:
append
(
token
)
else
:
append
(
value
)
operator_value_dict
[
'match'
]
=
new_value_list
return
operator_value_dict
,
logical_operator
,
parsed
def
_buildQuery
(
self
,
operator_value_dict
,
logical_operator
,
parsed
,
group
):
"""
Special Query builder for MroongaFullText queries:
* by default 'AND' search by using '*D+' pragma.
* similarity search for non-boolean queries by using '*S"..."' operator.
"""
column
=
self
.
getColumn
()
query_list
=
[]
append
=
query_list
.
append
match_query
=
operator_value_dict
.
pop
(
'match'
,
[])
match_boolean_query
=
operator_value_dict
.
pop
(
'match_boolean'
,
[])
fulltext_query
=
'*D+'
if
match_query
:
fulltext_query
+=
' *S"%s"'
%
' '
.
join
(
x
.
replace
(
'"'
,
'
\
\
"'
)
for
x
in
match_query
)
if
match_boolean_query
:
if
len
(
match_boolean_query
)
>
1
and
logical_operator
==
'or'
:
fulltext_query
+=
' %s'
%
' OR '
.
join
(
'(%s)'
%
x
for
x
in
match_boolean_query
)
else
:
fulltext_query
+=
' %s'
%
' '
.
join
(
match_boolean_query
)
if
match_query
or
match_boolean_query
:
append
(
SimpleQuery
(
search_key
=
self
,
comparison_operator
=
'match_boolean'
,
group
=
group
,
**
{
column
:
fulltext_query
}))
# other comparison operators are handled by DefaultKey.
if
operator_value_dict
:
query_list
+=
DefaultKey
.
_buildQuery
(
self
,
operator_value_dict
,
logical_operator
,
parsed
,
group
)
return
query_list
class
MroongaFullTextKey
(
DefaultKey
):
default_comparison_operator
=
'mroonga'
verifyClass
(
ISearchKey
,
MroongaFullTextKey
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment