-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathQueryManager.py
143 lines (125 loc) · 4.02 KB
/
QueryManager.py
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# coding=utf-8
__author__ = 'kasper'
from Index import Index
import Tree
import re
class QueryManager:
def __init__(self, db, cdb):
self.cacheIndex = Index()
self.cacheIndex.createFromCursor(cdb.findAll())
self.db = db
def toArray(self, query):
strArr = []
tmpStr = ''
j = 0
level = 0
for i in range(len(query)):
if query[i] == '(' and i < len(query):
if tmpStr != '':
strArr.append(tmpStr)
tmpStr = ''
strArr.append('(')
elif query[i] == ')' and i < len(query):
if tmpStr != '':
strArr.append(tmpStr)
tmpStr = ''
strArr.append(')')
elif query[i] == ' ':
if tmpStr != '':
strArr.append(tmpStr)
tmpStr = ''
else:
tmpStr += query[i]
if tmpStr != '':
strArr.append(tmpStr)
return strArr
def andQ(self, A, B):
# A ke e zbor ili lista
# Ako ne e lista ke zejme lista od kes ili baza
lstA = A
lstB = B
if not A or not B:
raise Exception('Грешка.' )
return None
if not isinstance(A, list):
lstA = self.cacheIndex.find(A)
if not lstA:
lstA = self.db.find(A)
if not lstA:
raise Exception('Зборот "' + A + '" не постои.' )
return None
if not isinstance(B, list):
lstB = self.cacheIndex.find(B)
if not lstB:
lstB = self.db.find(B)
if not lstB:
raise Exception('Зборот "' + B + '" не постои.' )
return None
result = []
i = 0
j = 0
lstA.append(None)
lstB.append(None)
while lstA[i] is not None and lstB[j] is not None:
if lstA[i] == lstB[j]:
result.append(lstA[i])
j += 1
i += 1
elif lstA[i] < lstB[j]:
i += 1
elif lstA[i] > lstB[j]:
j += 1
return result
def orQ(self, A, B):
lstA = A
lstB = B
if not isinstance(A, list):
lstA = self.cacheIndex.find(A)
if not lstA:
lstA = self.db.find(A)
if not lstA:
raise Exception('Зборот "' + A + '" не постои.')
return None
if not isinstance(B, list):
lstB = self.cacheIndex.find(B)
if not lstB:
lstB = self.db.find(B)
if not lstB:
raise Exception('Зборот "' + B + '" не постои.')
return None
return list(set(lstA + lstB))
def buildTree(self, query):
tree = Tree.buildOrTree(query)
return tree
def execute(self, query):
qArr = self.toArray(query)
if len(qArr) == 1:
lst = self.cacheIndex.find(qArr[0])
if not lst:
lst = self.db.find(qArr[0])
return lst
qTree = self.buildTree(qArr)
result = self.executeQuery(qTree)
return result
def executeQuery(self, tree):
lnode = tree.left
rnode = tree.right
if lnode and rnode:
if tree.value == 'OR':
try:
a = self.executeQuery(lnode)
b = self.executeQuery(rnode)
return self.orQ(a, b)
except Exception, e:
print e.message
return None
elif tree.value == 'AND':
try:
a = self.executeQuery(lnode)
b = self.executeQuery(rnode)
return self.andQ(a, b)
except Exception, e:
print e.message
return None
else:
return tree.value