Skip to content

Commit

Permalink
Merge pull request #9 from IdanHaim/RavenDB-6452
Browse files Browse the repository at this point in the history
RavenDB-6452
  • Loading branch information
IdanHaim authored Feb 28, 2017
2 parents 167d428 + d8eff8b commit 474938d
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 8 deletions.
35 changes: 30 additions & 5 deletions pyravendb/store/session_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@
from datetime import timedelta
import sys
import time
import re


class EscapeQueryOptions(Enum):
EscapeAll = 0
AllowPostfixWildcard = 1
AllowAllWildcards = 2
RawQuery = 3


class Query(object):
Expand Down Expand Up @@ -56,7 +64,20 @@ def select(self, *args):
self.fetch = args
return self

def _lucene_builder(self, value, action=None):
def _lucene_builder(self, value, action=None, escape_query_options=EscapeQueryOptions.EscapeAll):

if isinstance(value, str):
if escape_query_options == EscapeQueryOptions.EscapeAll:
value = Utils.escape(value, False, False)

elif escape_query_options == EscapeQueryOptions.AllowPostfixWildcard:
value = Utils.escape(value, False, False)
elif escape_query_options == EscapeQueryOptions.AllowAllWildcards:
value = Utils.escape(value, False, False)
value = re.sub(r'"\\\*(\s|$)"', "*${1}", value)
elif escape_query_options == EscapeQueryOptions.RawQuery:
value = Utils.escape(value, False, False).replace("\\*", "*")

lucene_text = Utils.to_lucene(value, action=action)

if len(self.query_builder) > 0 and not self.query_builder.endswith(' '):
Expand All @@ -70,13 +91,15 @@ def _lucene_builder(self, value, action=None):
def __iter__(self):
return self._execute_query().__iter__()

def where_equals(self, field_name, value):
def where_equals(self, field_name, value, escape_query_options=EscapeQueryOptions.EscapeAll):
"""
To get all the document that equal to the value in the given field_name
@param field_name:The field name in the index you want to query.
:type str
@param value: The value will be the fields value you want to query
@param escape_query_options: the way we should escape special characters
:type EscapeQueryOptions
"""
if field_name is None:
raise ValueError("None field_name is invalid")
Expand All @@ -89,7 +112,7 @@ def where_equals(self, field_name, value):
sort_hint = self.session.conventions.get_default_sort_option("long")
self._sort_hints.add("SortHint-{0}={1}".format(field_name, sort_hint))

lucene_text = self._lucene_builder(value, action="equal")
lucene_text = self._lucene_builder(value, action="equal", escape_query_options=escape_query_options)
self.query_builder += "{0}:{1}".format(field_name, lucene_text)
return self

Expand All @@ -108,17 +131,19 @@ def where(self, **kwargs):
self.where_equals(field_name, kwargs[field_name])
return self

def search(self, field_name, search_terms):
def search(self, field_name, search_terms, escape_query_options=EscapeQueryOptions.RawQuery):
"""
for more complex text searching
@param field_name:The field name in the index you want to query.
:type str
@param search_terms: the terms you want to query
:type str
@param escape_query_options: the way we should escape special characters
:type EscapeQueryOptions
"""
search_terms = Utils.quote_key(str(search_terms))
search_terms = self._lucene_builder(search_terms, "search")
search_terms = self._lucene_builder(search_terms, "search", escape_query_options)
self.query_builder += "{0}:{1}".format(field_name, search_terms)
return self

Expand Down
40 changes: 38 additions & 2 deletions pyravendb/tools/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,6 @@ def make_initialize_dict(document, entity_init):
@staticmethod
def to_lucene(value, action):
query_text = ""
if isinstance(value, str):
value = re.escape(value).replace('\*', '*')
if action == "in":
if not value or len(value) == 0:
return None
Expand Down Expand Up @@ -281,3 +279,41 @@ def timedelta_to_str(timedelta_obj):
if microseconds > 0:
timedelta_str += ".{0}".format(microseconds)
return timedelta_str

@staticmethod
def escape(term, allow_wild_cards, make_phrase):
wild_cards = ['-', '&', '|', '!', '(', ')', '{', '}', '[', ']', '^', '"', '~', ':', '\\']
if not term:
return "\"\""
start = 0
length = len(term)
builder = ""
if length >= 2 and term[0] == '/' and term[1] == '/':
builder += "//"
start = 2
i = start
while i < length:
ch = term[i]
if ch == '*' or ch == '?':
if allow_wild_cards:
i += 1
continue

if ch in wild_cards:
if i > start:
builder += term[start:i - start]

builder += '\\{0}'.format(ch)
start = i + 1
i += 1
continue

if ch == ' ' or ch == '\t':
if make_phrase:
return "\"{0}\"".format(Utils.escape(term, allow_wild_cards, False))

i += 1
if length > start:
builder += term[start: length]

return builder
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
setup(
name='pyravendb',
packages=find_packages(),
version='1.3.1.2',
version='1.3.1.3',
description='This is the official python client for RavenDB document database',
author='Idan Haim Shalom',
author_email='[email protected]',
Expand Down

0 comments on commit 474938d

Please sign in to comment.