Use account table in search
Change-Id: Id7dd6342e50d1403cc6c9f3f2a882a2d2125e08d
This commit is contained in:
parent
9195a05684
commit
9fca5b6ba4
@ -464,10 +464,11 @@ class DatabaseSession(object):
|
||||
|
||||
def getChanges(self, query, unreviewed=False):
|
||||
self.database.log.debug("Search query: %s" % query)
|
||||
search_filter = self.search.parse(query)
|
||||
q = self.session().query(Change).filter(search_filter).order_by(change_table.c.number)
|
||||
q = self.session().query(Change).filter(self.search.parse(query))
|
||||
if unreviewed:
|
||||
q = q.filter(change_table.c.hidden==False, change_table.c.reviewed==False)
|
||||
q = q.order_by(change_table.c.number)
|
||||
self.database.log.debug("Search SQL: %s" % q)
|
||||
try:
|
||||
return q.all()
|
||||
except sqlalchemy.orm.exc.NoResultFound:
|
||||
|
@ -12,15 +12,22 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import sqlalchemy.sql.expression
|
||||
|
||||
from gertty.search import tokenizer, parser
|
||||
import gertty.db
|
||||
|
||||
|
||||
class SearchSyntaxError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class SearchCompiler(object):
|
||||
def __init__(self, app):
|
||||
self.app = app
|
||||
self.lexer = tokenizer.SearchTokenizer()
|
||||
self.parser = parser.SearchParser()
|
||||
|
||||
def parse(self, data):
|
||||
self.parser.username = self.app.config.username
|
||||
return self.parser.parse(data, lexer=self.lexer)
|
||||
|
@ -16,7 +16,7 @@ import datetime
|
||||
import re
|
||||
|
||||
import ply.yacc as yacc
|
||||
from sqlalchemy.sql.expression import and_, or_
|
||||
from sqlalchemy.sql.expression import and_, or_, not_, exists, select
|
||||
|
||||
import gertty.db
|
||||
import gertty.search
|
||||
@ -53,7 +53,7 @@ def SearchParser():
|
||||
def p_negative_expr(p):
|
||||
'''negative_expr : NOT expression
|
||||
| NEG expression'''
|
||||
p[0] = not p[1]
|
||||
p[0] = not_(p[2])
|
||||
|
||||
def p_term(p):
|
||||
'''term : age_term
|
||||
@ -120,15 +120,35 @@ def SearchParser():
|
||||
|
||||
def p_owner_term(p):
|
||||
'''owner_term : OP_OWNER string'''
|
||||
p[0] = gertty.db.change_table.c.owner == p[2]
|
||||
if p[2] == 'self':
|
||||
username = p.parser.username
|
||||
p[0] = gertty.db.account_table.c.username == username
|
||||
else:
|
||||
p[0] = or_(gertty.db.account_table.c.username == p[2],
|
||||
gertty.db.account_table.c.email == p[2],
|
||||
gertty.db.account_table.c.name == p[2])
|
||||
|
||||
def p_reviewer_term(p):
|
||||
'''reviewer_term : OP_REVIEWER string'''
|
||||
p[0] = gertty.db.approval_table.c.name == p[2]
|
||||
filters = []
|
||||
filters.append(gertty.db.approval_table.c.change_key == gertty.db.change_table.c.key)
|
||||
if p[2] == 'self':
|
||||
username = p.parser.username
|
||||
filters.append(gertty.db.account_table.c.username == username)
|
||||
else:
|
||||
filters.append(or_(gertty.db.account_table.c.username == p[2],
|
||||
gertty.db.account_table.c.email == p[2],
|
||||
gertty.db.account_table.c.name == p[2]))
|
||||
s = select([gertty.db.change_table.c.key], correlate=False).where(and_(*filters))
|
||||
p[0] = gertty.db.change_table.c.key.in_(s)
|
||||
|
||||
def p_commit_term(p):
|
||||
'''commit_term : OP_COMMIT string'''
|
||||
p[0] = gertty.db.revision_table.c.commit == p[2]
|
||||
filters = []
|
||||
filters.append(gertty.db.revision_table.c.change_key == gertty.db.change_table.c.key)
|
||||
filters.append(gertty.db.revision_table.c.commit == p[2])
|
||||
s = select([gertty.db.change_table.c.key], correlate=False).where(and_(*filters))
|
||||
p[0] = gertty.db.change_table.c.key.in_(s)
|
||||
|
||||
def p_project_term(p):
|
||||
'''project_term : OP_PROJECT string'''
|
||||
@ -167,6 +187,7 @@ def SearchParser():
|
||||
user = args.group('user')
|
||||
|
||||
filters = []
|
||||
filters.append(gertty.db.approval_table.c.change_key == gertty.db.change_table.c.key)
|
||||
filters.append(gertty.db.approval_table.c.category == label)
|
||||
if op == '=':
|
||||
filters.append(gertty.db.approval_table.c.value == value)
|
||||
@ -175,31 +196,58 @@ def SearchParser():
|
||||
elif op == '<=':
|
||||
filters.append(gertty.db.approval_table.c.value <= value)
|
||||
if user is not None:
|
||||
filters.append(gertty.db.approval_table.c.name == user)
|
||||
p[0] = and_(*filters)
|
||||
filters.append(
|
||||
or_(gertty.db.account_table.c.username == user,
|
||||
gertty.db.account_table.c.email == user,
|
||||
gertty.db.account_table.c.name == user))
|
||||
s = select([gertty.db.change_table.c.key], correlate=False).where(and_(*filters))
|
||||
p[0] = gertty.db.change_table.c.key.in_(s)
|
||||
|
||||
def p_message_term(p):
|
||||
'''message_term : OP_MESSAGE string'''
|
||||
p[0] = gertty.db.revision_table.c.message.like(p[1])
|
||||
filters = []
|
||||
filters.append(gertty.db.revision_table.c.change_key == gertty.db.change_table.c.key)
|
||||
filters.append(gertty.db.revision_table.c.message == p[2])
|
||||
s = select([gertty.db.change_table.c.key], correlate=False).where(and_(*filters))
|
||||
p[0] = gertty.db.change_table.c.key.in_(s)
|
||||
|
||||
def p_comment_term(p):
|
||||
'''comment_term : OP_COMMENT string'''
|
||||
p[0] = and_(gertty.db.message_table.c.message.like(p[1]),
|
||||
gertty.db.comment_table.c.message.like(p[1]))
|
||||
filters = []
|
||||
filters.append(gertty.db.revision_table.c.change_key == gertty.db.change_table.c.key)
|
||||
filters.append(gertty.db.revision_table.c.message == p[2])
|
||||
revision_select = select([gertty.db.change_table.c.key], correlate=False).where(and_(*filters))
|
||||
filters = []
|
||||
filters.append(gertty.db.revision_table.c.change_key == gertty.db.change_table.c.key)
|
||||
filters.append(gertty.db.comment_table.c.revision_key == gertty.db.revision_table.c.key)
|
||||
filters.append(gertty.db.comment_table.c.message == p[2])
|
||||
comment_select = select([gertty.db.change_table.c.key], correlate=False).where(and_(*filters))
|
||||
p[0] = or_(gertty.db.change_table.c.key.in_(comment_select),
|
||||
gertty.db.change_table.c.key.in_(revision_select))
|
||||
|
||||
def p_has_term(p):
|
||||
'''has_term : OP_HAS string'''
|
||||
#TODO: implement star
|
||||
if p[2] == 'draft':
|
||||
p[0] = gertty.db.message_table.c.pending == True
|
||||
filters = []
|
||||
filters.append(gertty.db.revision_table.c.change_key == gertty.db.change_table.c.key)
|
||||
filters.append(gertty.db.message_table.c.revision_key == gertty.db.revision_table.c.key)
|
||||
filters.append(gertty.db.message_table.c.pending == True)
|
||||
s = select([gertty.db.change_table.c.key], correlate=False).where(and_(*filters))
|
||||
p[0] = gertty.db.change_table.c.key.in_(s)
|
||||
else:
|
||||
raise gertty.search.SearchSyntaxError('Syntax error: has:%s is not supported' % p[2])
|
||||
|
||||
def p_is_term(p):
|
||||
'''is_term : OP_IS string'''
|
||||
#TODO: implement starred, watched, owner, reviewer, draft
|
||||
username = p.parser.username
|
||||
if p[2] == 'reviewed':
|
||||
p[0] = gertty.db.approval_table.c.value != 0
|
||||
filters = []
|
||||
filters.append(gertty.db.approval_table.c.change_key == gertty.db.change_table.c.key)
|
||||
filters.append(gertty.db.approval_table.c.value != 0)
|
||||
s = select([gertty.db.change_table.c.key], correlate=False).where(and_(*filters))
|
||||
p[0] = gertty.db.change_table.c.key.in_(s)
|
||||
elif p[2] == 'open':
|
||||
p[0] = gertty.db.change_table.c.status.notin_(['MERGED', 'ABANDONED'])
|
||||
elif p[2] == 'closed':
|
||||
@ -210,6 +258,14 @@ def SearchParser():
|
||||
p[0] = gertty.db.change_table.c.status == 'MERGED'
|
||||
elif p[2] == 'abandoned':
|
||||
p[0] = gertty.db.change_table.c.status == 'ABANDONED'
|
||||
elif p[2] == 'owner':
|
||||
p[0] = gertty.db.account_table.c.username == username
|
||||
elif p[2] == 'reviewer':
|
||||
filters = []
|
||||
filters.append(gertty.db.approval_table.c.change_key == gertty.db.change_table.c.key)
|
||||
filters.append(gertty.db.account_table.c.username == username)
|
||||
s = select([gertty.db.change_table.c.key], correlate=False).where(and_(*filters))
|
||||
p[0] = gertty.db.change_table.c.key.in_(s)
|
||||
else:
|
||||
raise gertty.search.SearchSyntaxError('Syntax error: has:%s is not supported' % p[2])
|
||||
|
||||
|
@ -1,73 +0,0 @@
|
||||
import gertty.search
|
||||
import re
|
||||
import sys
|
||||
|
||||
label_re = re.compile(r'(?P<label>[a-zA-Z0-9_-]+([a-zA-Z]|((?<![-+])[0-9])))'
|
||||
r'(?P<operator>[<>]?=?)(?P<value>[-+]?[0-9]+)'
|
||||
r'($|,user=(?P<user>\S+))')
|
||||
|
||||
for a in [
|
||||
'Code-Review=1',
|
||||
'Code-Review=+1',
|
||||
'Code-Review=-1',
|
||||
'Code-Review>=+1',
|
||||
'Code-Review<=-1',
|
||||
'Code-Review+1',
|
||||
'Code-Review-1',
|
||||
]:
|
||||
for b in [
|
||||
'',
|
||||
',user=corvus',
|
||||
]:
|
||||
data = a+b
|
||||
print
|
||||
print data
|
||||
m = label_re.match(data)
|
||||
print 'res', m and m.groups()
|
||||
|
||||
#sys.exit(0)
|
||||
parser = gertty.search.SearchCompiler(None)
|
||||
|
||||
import tokenizer
|
||||
lexer = tokenizer.SearchTokenizer()
|
||||
lexer.input("project:foo/bar")
|
||||
|
||||
# Tokenize
|
||||
while True:
|
||||
tok = lexer.token()
|
||||
if not tok: break # No more input
|
||||
print tok
|
||||
|
||||
#TODO: unit test
|
||||
for a in [
|
||||
'label:Code-Review=1',
|
||||
'label:Code-Review=+1',
|
||||
'label:Code-Review=-1',
|
||||
'label:Code-Review>=+1',
|
||||
'label:Code-Review<=-1',
|
||||
'label:Code-Review+1',
|
||||
'label:Code-Review-1',
|
||||
]:
|
||||
for b in [
|
||||
'',
|
||||
',user=corvus',
|
||||
]:
|
||||
data = a+b
|
||||
print
|
||||
print data
|
||||
result = parser.parse(data)
|
||||
print 'res', str(result)
|
||||
|
||||
for data in [
|
||||
'_project_key:18 status:open',
|
||||
'project:foo/bar status:open',
|
||||
'project:foo and status:open',
|
||||
'project:foo or status:open',
|
||||
'project:foo and (status:merged or status:new)',
|
||||
'project:foo or project:bar or project:baz',
|
||||
'project:foo project:bar project:baz',
|
||||
]:
|
||||
print
|
||||
print data
|
||||
result = parser.parse(data)
|
||||
print 'res', str(result)
|
Loading…
x
Reference in New Issue
Block a user