| Index: appengine/monorail/proto/ast_pb2.py
|
| diff --git a/appengine/monorail/proto/ast_pb2.py b/appengine/monorail/proto/ast_pb2.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..db911270118c85eca4b011cdb155ac7ac3913c5a
|
| --- /dev/null
|
| +++ b/appengine/monorail/proto/ast_pb2.py
|
| @@ -0,0 +1,87 @@
|
| +# Copyright 2016 The Chromium Authors. All rights reserved.
|
| +# Use of this source code is govered by a BSD-style
|
| +# license that can be found in the LICENSE file or at
|
| +# https://developers.google.com/open-source/licenses/bsd
|
| +
|
| +"""Protocol buffers for user queries parsed into abstract syntax trees.
|
| +
|
| +A user issue query can look like [Type=Defect owner:jrobbins "memory leak"].
|
| +In that simple form, all the individual search conditions are simply ANDed
|
| +together. In the code, a list of conditions to be ANDed is called a
|
| +conjunction.
|
| +
|
| +Monorail also supports a quick-or feature: [Type=Defect,Enhancement]. That
|
| +will match any issue that has labels Type-Defect or Type-Enhancement, or both.
|
| +
|
| +TODO(jrobbins): Monorail should also support a top-level "OR" keyword that can
|
| +be used to logically OR a series of conjunctions. For example:
|
| +[Type=Defect stars>10 OR Type=Enhancement stars>50]. Right now, these queries
|
| +are parsed and represented in the AST, but not fully processed.
|
| +
|
| +There are no parenthesis and no "AND" keyword. So, the AST is always exactly
|
| +two levels: the overall tree consistes of a list of conjunctions, and each
|
| +conjunction consists of a list of conditions.
|
| +
|
| +A condition can look like [stars>10] or [summary:memory] or
|
| +[Type=Defect,Enhancement]. Each condition has a single comparison operator.
|
| +Most conditions refer to a single field definition, but in the case of
|
| +cross-project search a single condition can have a list of field definitions
|
| +from the different projects being searched. Each condition can have a list
|
| +of constant values to compare against. The values may be all strings or all
|
| +integers.
|
| +
|
| +Some conditions are procesed by the SQL database and others by the GAE
|
| +search API. All conditions are passed to each module and it is up to
|
| +the module to decide which conditions to handle and which to ignore.
|
| +"""
|
| +
|
| +from protorpc import messages
|
| +
|
| +from proto import tracker_pb2
|
| +
|
| +
|
| +# This is a special field_name for a FieldDef that means to do a fulltext
|
| +# search for words that occur in any part of the issue.
|
| +ANY_FIELD = 'any_field'
|
| +
|
| +
|
| +class QueryOp(messages.Enum):
|
| + """Enumeration of possible query condition operators."""
|
| + EQ = 1
|
| + NE = 2
|
| + LT = 3
|
| + GT = 4
|
| + LE = 5
|
| + GE = 6
|
| + TEXT_HAS = 7
|
| + NOT_TEXT_HAS = 8
|
| + TEXT_MATCHES = 9
|
| + NOT_TEXT_MATCHES = 10
|
| + IS_DEFINED = 11
|
| + IS_NOT_DEFINED = 12
|
| + KEY_HAS = 13
|
| +
|
| +
|
| +class Condition(messages.Message):
|
| + """Representation of one query condition. E.g., [Type=Defect,Task]."""
|
| + op = messages.EnumField(QueryOp, 1, required=True)
|
| + field_defs = messages.MessageField(tracker_pb2.FieldDef, 2, repeated=True)
|
| + str_values = messages.StringField(3, repeated=True)
|
| + int_values = messages.IntegerField(4, repeated=True)
|
| +
|
| +
|
| +class Conjunction(messages.Message):
|
| + """A list of conditions that are implicitly ANDed together."""
|
| + conds = messages.MessageField(Condition, 1, repeated=True)
|
| +
|
| +
|
| +class QueryAST(messages.Message):
|
| + """Abstract syntax tree for the user's query."""
|
| + conjunctions = messages.MessageField(Conjunction, 1, repeated=True)
|
| +
|
| +
|
| +def MakeCond(op, field_defs, str_values, int_values):
|
| + """Shorthand function to construct a Condition PB."""
|
| + return Condition(
|
| + op=op, field_defs=field_defs, str_values=str_values,
|
| + int_values=int_values)
|
|
|