| @@ -149,12 +149,12 @@ class _QueryParser(object): | |||||
| ## TODO: balance tree | ## TODO: balance tree | ||||
| ## -------------------------------------------------------------------- | ## -------------------------------------------------------------------- | ||||
| def SCAN_FOR_MARKER(string, markers): | |||||
| def SCAN_FOR_MARKERS(string, markers): | |||||
| best_marker, best_index = None, maxsize | best_marker, best_index = None, maxsize | ||||
| for marker in markers: | for marker in markers: | ||||
| index = string.find(marker) | index = string.find(marker) | ||||
| if index > 0 and string[index - 1] == "\\" and (index == 1 or string[index - 2] != "\\"): | if index > 0 and string[index - 1] == "\\" and (index == 1 or string[index - 2] != "\\"): | ||||
| _, new_index = SCAN_FOR_MARKER(string[index + 1:], marker) | |||||
| _, new_index = SCAN_FOR_MARKERS(string[index + 1:], marker) | |||||
| index += new_index + 1 | index += new_index + 1 | ||||
| if index >= 0 and index < best_index: | if index >= 0 and index < best_index: | ||||
| best_marker, best_index = marker, index | best_marker, best_index = marker, index | ||||
| @@ -164,35 +164,43 @@ class _QueryParser(object): | |||||
| string = string.lstrip() | string = string.lstrip() | ||||
| if not string: | if not string: | ||||
| return [] | return [] | ||||
| marker, index = SCAN_FOR_MARKER(string, " \"'()") | |||||
| marker, index = SCAN_FOR_MARKERS(string, " \"'()") | |||||
| if not marker: | if not marker: | ||||
| return [string] | return [string] | ||||
| before = [string[:index]] if index > 0 else [] | |||||
| nest = [string[:index]] if index > 0 else [] | |||||
| after = string[index + 1:] | after = string[index + 1:] | ||||
| if marker == " ": | if marker == " ": | ||||
| return before + SPLIT_QUERY_STRING(after, parens) | |||||
| nest += SPLIT_QUERY_STRING(after, parens) | |||||
| elif marker in ('"', "'"): | elif marker in ('"', "'"): | ||||
| close_marker, close_index = SCAN_FOR_MARKER(after, marker) | |||||
| if not close_marker: | |||||
| return before + [after] | |||||
| quoted, after = after[:close_index], after[close_index + 1:] | |||||
| return before + [quoted] + SPLIT_QUERY_STRING(after, parens) | |||||
| close_marker, close_index = SCAN_FOR_MARKERS(after, marker) | |||||
| if close_marker: | |||||
| if close_index > 0: | |||||
| nest.append(after[:close_index]) | |||||
| after = after[close_index + 1:] | |||||
| nest += SPLIT_QUERY_STRING(after, parens) | |||||
| elif after: | |||||
| nest.append(after) | |||||
| elif marker == "(": | elif marker == "(": | ||||
| inner = SPLIT_QUERY_STRING(after, True) | |||||
| inner, after = SPLIT_QUERY_STRING(after, True), [] | |||||
| if inner and isinstance(inner[-1], tuple): | if inner and isinstance(inner[-1], tuple): | ||||
| after, inner = inner.pop()[0], [inner] if inner else [] | |||||
| return before + inner + SPLIT_QUERY_STRING(after, parens) | |||||
| return before + [inner] | |||||
| after = SPLIT_QUERY_STRING(inner.pop()[0], parens) | |||||
| if inner: | |||||
| nest.append(inner) | |||||
| if after: | |||||
| nest += after | |||||
| elif marker == ")": | elif marker == ")": | ||||
| if parens: | if parens: | ||||
| return before + [(after,)] | |||||
| return before + SPLIT_QUERY_STRING(after) | |||||
| nest.append((after,)) | |||||
| else: | |||||
| nest += SPLIT_QUERY_STRING(after) | |||||
| return nest | |||||
| nest = SPLIT_QUERY_STRING(query.rstrip()) | nest = SPLIT_QUERY_STRING(query.rstrip()) | ||||
| if not nest: | if not nest: | ||||