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):
|
def getChanges(self, query, unreviewed=False):
|
||||||
self.database.log.debug("Search query: %s" % query)
|
self.database.log.debug("Search query: %s" % query)
|
||||||
search_filter = self.search.parse(query)
|
q = self.session().query(Change).filter(self.search.parse(query))
|
||||||
q = self.session().query(Change).filter(search_filter).order_by(change_table.c.number)
|
|
||||||
if unreviewed:
|
if unreviewed:
|
||||||
q = q.filter(change_table.c.hidden==False, change_table.c.reviewed==False)
|
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:
|
try:
|
||||||
return q.all()
|
return q.all()
|
||||||
except sqlalchemy.orm.exc.NoResultFound:
|
except sqlalchemy.orm.exc.NoResultFound:
|
||||||
|
@ -12,15 +12,22 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
import sqlalchemy.sql.expression
|
||||||
|
|
||||||
from gertty.search import tokenizer, parser
|
from gertty.search import tokenizer, parser
|
||||||
|
import gertty.db
|
||||||
|
|
||||||
|
|
||||||
class SearchSyntaxError(Exception):
|
class SearchSyntaxError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class SearchCompiler(object):
|
class SearchCompiler(object):
|
||||||
def __init__(self, app):
|
def __init__(self, app):
|
||||||
|
self.app = app
|
||||||
self.lexer = tokenizer.SearchTokenizer()
|
self.lexer = tokenizer.SearchTokenizer()
|
||||||
self.parser = parser.SearchParser()
|
self.parser = parser.SearchParser()
|
||||||
|
|
||||||
def parse(self, data):
|
def parse(self, data):
|
||||||
|
self.parser.username = self.app.config.username
|
||||||
return self.parser.parse(data, lexer=self.lexer)
|
return self.parser.parse(data, lexer=self.lexer)
|
||||||
|
@ -16,7 +16,7 @@ import datetime
|
|||||||
import re
|
import re
|
||||||
|
|
||||||
import ply.yacc as yacc
|
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.db
|
||||||
import gertty.search
|
import gertty.search
|
||||||
@ -53,7 +53,7 @@ def SearchParser():
|
|||||||
def p_negative_expr(p):
|
def p_negative_expr(p):
|
||||||
'''negative_expr : NOT expression
|
'''negative_expr : NOT expression
|
||||||
| NEG expression'''
|
| NEG expression'''
|
||||||
p[0] = not p[1]
|
p[0] = not_(p[2])
|
||||||
|
|
||||||
def p_term(p):
|
def p_term(p):
|
||||||
'''term : age_term
|
'''term : age_term
|
||||||
@ -120,15 +120,35 @@ def SearchParser():
|
|||||||
|
|
||||||
def p_owner_term(p):
|
def p_owner_term(p):
|
||||||
'''owner_term : OP_OWNER string'''
|
'''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):
|
def p_reviewer_term(p):
|
||||||
'''reviewer_term : OP_REVIEWER string'''
|
'''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):
|
def p_commit_term(p):
|
||||||
'''commit_term : OP_COMMIT string'''
|
'''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):
|
def p_project_term(p):
|
||||||
'''project_term : OP_PROJECT string'''
|
'''project_term : OP_PROJECT string'''
|
||||||
@ -167,6 +187,7 @@ def SearchParser():
|
|||||||
user = args.group('user')
|
user = args.group('user')
|
||||||
|
|
||||||
filters = []
|
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)
|
filters.append(gertty.db.approval_table.c.category == label)
|
||||||
if op == '=':
|
if op == '=':
|
||||||
filters.append(gertty.db.approval_table.c.value == value)
|
filters.append(gertty.db.approval_table.c.value == value)
|
||||||
@ -175,31 +196,58 @@ def SearchParser():
|
|||||||
elif op == '<=':
|
elif op == '<=':
|
||||||
filters.append(gertty.db.approval_table.c.value <= value)
|
filters.append(gertty.db.approval_table.c.value <= value)
|
||||||
if user is not None:
|
if user is not None:
|
||||||
filters.append(gertty.db.approval_table.c.name == user)
|
filters.append(
|
||||||
p[0] = and_(*filters)
|
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):
|
def p_message_term(p):
|
||||||
'''message_term : OP_MESSAGE string'''
|
'''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):
|
def p_comment_term(p):
|
||||||
'''comment_term : OP_COMMENT string'''
|
'''comment_term : OP_COMMENT string'''
|
||||||
p[0] = and_(gertty.db.message_table.c.message.like(p[1]),
|
filters = []
|
||||||
gertty.db.comment_table.c.message.like(p[1]))
|
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):
|
def p_has_term(p):
|
||||||
'''has_term : OP_HAS string'''
|
'''has_term : OP_HAS string'''
|
||||||
#TODO: implement star
|
#TODO: implement star
|
||||||
if p[2] == 'draft':
|
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:
|
else:
|
||||||
raise gertty.search.SearchSyntaxError('Syntax error: has:%s is not supported' % p[2])
|
raise gertty.search.SearchSyntaxError('Syntax error: has:%s is not supported' % p[2])
|
||||||
|
|
||||||
def p_is_term(p):
|
def p_is_term(p):
|
||||||
'''is_term : OP_IS string'''
|
'''is_term : OP_IS string'''
|
||||||
#TODO: implement starred, watched, owner, reviewer, draft
|
#TODO: implement starred, watched, owner, reviewer, draft
|
||||||
|
username = p.parser.username
|
||||||
if p[2] == 'reviewed':
|
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':
|
elif p[2] == 'open':
|
||||||
p[0] = gertty.db.change_table.c.status.notin_(['MERGED', 'ABANDONED'])
|
p[0] = gertty.db.change_table.c.status.notin_(['MERGED', 'ABANDONED'])
|
||||||
elif p[2] == 'closed':
|
elif p[2] == 'closed':
|
||||||
@ -210,6 +258,14 @@ def SearchParser():
|
|||||||
p[0] = gertty.db.change_table.c.status == 'MERGED'
|
p[0] = gertty.db.change_table.c.status == 'MERGED'
|
||||||
elif p[2] == 'abandoned':
|
elif p[2] == 'abandoned':
|
||||||
p[0] = gertty.db.change_table.c.status == '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:
|
else:
|
||||||
raise gertty.search.SearchSyntaxError('Syntax error: has:%s is not supported' % p[2])
|
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