Skip to content
Snippets Groups Projects
Commit a123dc19 authored by Michael Hanselmann's avatar Michael Hanselmann
Browse files

Add simple query filter parser


This parser reads only the format described by the query2
design document: either an empty filter or an OR operator
with equality checks as operands.

Signed-off-by: default avatarMichael Hanselmann <hansmi@google.com>
Reviewed-by: default avatarIustin Pop <iustin@google.com>
parent 4ca96421
No related branches found
No related tags found
No related merge requests found
...@@ -138,6 +138,7 @@ pkgpython_PYTHON = \ ...@@ -138,6 +138,7 @@ pkgpython_PYTHON = \
lib/netutils.py \ lib/netutils.py \
lib/objects.py \ lib/objects.py \
lib/opcodes.py \ lib/opcodes.py \
lib/qlang.py \
lib/query.py \ lib/query.py \
lib/rpc.py \ lib/rpc.py \
lib/runtime.py \ lib/runtime.py \
...@@ -443,6 +444,7 @@ python_tests = \ ...@@ -443,6 +444,7 @@ python_tests = \
test/ganeti.netutils_unittest.py \ test/ganeti.netutils_unittest.py \
test/ganeti.objects_unittest.py \ test/ganeti.objects_unittest.py \
test/ganeti.opcodes_unittest.py \ test/ganeti.opcodes_unittest.py \
test/ganeti.qlang_unittest.py \
test/ganeti.query_unittest.py \ test/ganeti.query_unittest.py \
test/ganeti.rapi.client_unittest.py \ test/ganeti.rapi.client_unittest.py \
test/ganeti.rapi.resources_unittest.py \ test/ganeti.rapi.resources_unittest.py \
......
#
#
# Copyright (C) 2010 Google Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
"""Module for a simple query language"""
from ganeti import errors
OP_OR = "|"
OP_EQUAL = "="
def ReadSimpleFilter(namefield, filter_):
"""Function extracting wanted names from restricted filter.
This should only be used until proper filtering is implemented. The filter
must either be empty or of the format C{["|", ["=", field, "name1"], ["=",
field, "name2"], ...]}.
"""
if filter_ is None:
return []
if not isinstance(filter_, list):
raise errors.ParameterError("Filter should be list")
if not filter_ or filter_[0] != OP_OR:
raise errors.ParameterError("Filter should start with OR operator")
if len(filter_) < 2:
raise errors.ParameterError("Invalid filter, OR operator should have"
" operands")
result = []
for idx, item in enumerate(filter_[1:]):
if not isinstance(item, list):
raise errors.ParameterError("Invalid OR operator, operand %s not a"
" list" % idx)
if len(item) != 3 or item[0] != OP_EQUAL:
raise errors.ParameterError("Invalid OR operator, operand %s is not an"
" equality filter" % idx)
(_, name, value) = item
if not isinstance(value, basestring):
raise errors.ParameterError("Operand %s for OR should compare against a"
" string" % idx)
if name != namefield:
raise errors.ParameterError("Operand %s for OR should filter field '%s',"
" not '%s'" % (idx, namefield, name))
result.append(value)
return result
#!/usr/bin/python
#
# Copyright (C) 2010 Google Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
"""Script for testing ganeti.qlang"""
import unittest
from ganeti import utils
from ganeti import errors
from ganeti import qlang
import testutils
class TestReadSimpleFilter(unittest.TestCase):
def _Test(self, filter_, expected):
self.assertEqual(qlang.ReadSimpleFilter("name", filter_), expected)
def test(self):
self._Test(None, [])
self._Test(["|", ["=", "name", "xyz"]], ["xyz"])
for i in [1, 3, 10, 25, 140]:
self._Test(["|"] + [["=", "name", "node%s" % j] for j in range(i)],
["node%s" % j for j in range(i)])
def testErrors(self):
for i in [123, True, False, "", "Hello World", "a==b",
[], ["x"], ["x", "y", "z"], ["|"],
["|", ["="]], ["|", "x"], ["|", 123],
["|", ["=", "otherfield", "xyz"]],
["|", ["=", "name", "xyz"], "abc"],
["|", ["=", "name", "xyz", "too", "long"]],
["|", ["=", "name", []]],
["|", ["=", "name", 999]],
["|", ["=", "name", "abc"], ["=", "otherfield", "xyz"]]]:
self.assertRaises(errors.ParameterError, qlang.ReadSimpleFilter,
"name", i)
if __name__ == "__main__":
testutils.GanetiTestProgram()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment