You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ariatosca.apache.org by mx...@apache.org on 2017/04/05 09:33:15 UTC
incubator-ariatosca git commit:
ARIA-137-Support-for-predicate-based-queries-in-the-SQL-mapi [Forced Update!]
Repository: incubator-ariatosca
Updated Branches:
refs/heads/ARIA-137-Support-for-predicate-based-queries-in-the-SQL-mapi 89e21301e -> 3cb3ac7b5 (forced update)
ARIA-137-Support-for-predicate-based-queries-in-the-SQL-mapi
Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/3cb3ac7b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/3cb3ac7b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/3cb3ac7b
Branch: refs/heads/ARIA-137-Support-for-predicate-based-queries-in-the-SQL-mapi
Commit: 3cb3ac7b54fbd9ec4d3a96cfd4c8d111d6469458
Parents: e7ffc73
Author: max-orlov <ma...@gigaspaces.com>
Authored: Tue Apr 4 20:41:59 2017 +0300
Committer: max-orlov <ma...@gigaspaces.com>
Committed: Wed Apr 5 12:33:03 2017 +0300
----------------------------------------------------------------------
aria/storage/sql_mapi.py | 24 +++++++++++-
tests/storage/test_model_storage.py | 65 ++++++++++++++++++++++++++++++++
2 files changed, 88 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3cb3ac7b/aria/storage/sql_mapi.py
----------------------------------------------------------------------
diff --git a/aria/storage/sql_mapi.py b/aria/storage/sql_mapi.py
index 59e1896..59312b8 100644
--- a/aria/storage/sql_mapi.py
+++ b/aria/storage/sql_mapi.py
@@ -31,6 +31,13 @@ from . import (
exceptions,
)
+_predicates = {'ge': '__ge__',
+ 'gt': '__gt__',
+ 'lt': '__lt__',
+ 'le': '__le__',
+ 'eq': '__eq__',
+ 'ne': '__ne__'}
+
class SQLAlchemyModelAPI(api.ModelAPI):
"""
@@ -243,7 +250,10 @@ class SQLAlchemyModelAPI(api.ModelAPI):
@staticmethod
def _add_value_filter(query, filters):
for column, value in filters.items():
- if isinstance(value, (list, tuple)):
+ if isinstance(value, dict):
+ for predicate, operand in value.items():
+ query = query.filter(getattr(column, predicate)(operand))
+ elif isinstance(value, (list, tuple)):
query = query.filter(column.in_(value))
else:
query = query.filter(column == value)
@@ -269,12 +279,24 @@ class SQLAlchemyModelAPI(api.ModelAPI):
include, filters, sort, joins = self._get_joins_and_converted_columns(
include, filters, sort
)
+ filters = self._convert_operands(filters)
query = self._get_base_query(include, joins)
query = self._filter_query(query, filters)
query = self._sort_query(query, sort)
return query
+ @staticmethod
+ def _convert_operands(filters):
+ for column, conditions in filters.items():
+ if isinstance(conditions, dict):
+ for predicate, operand in conditions.items():
+ if predicate in _predicates:
+ del filters[column][predicate]
+ filters[column][_predicates[predicate]] = operand
+
+ return filters
+
def _get_joins_and_converted_columns(self,
include,
filters,
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/3cb3ac7b/tests/storage/test_model_storage.py
----------------------------------------------------------------------
diff --git a/tests/storage/test_model_storage.py b/tests/storage/test_model_storage.py
index e4f3eba..dcfa3f7 100644
--- a/tests/storage/test_model_storage.py
+++ b/tests/storage/test_model_storage.py
@@ -31,6 +31,16 @@ from tests import (
modeling as tests_modeling
)
+from sqlalchemy import (
+ Column,
+ Integer,
+ Text)
+
+from aria.modeling import (
+ models,
+ mixins
+)
+
@pytest.fixture
def storage():
@@ -150,3 +160,58 @@ def test_mapi_include(context):
assert_include(service1)
assert_include(service2)
+
+
+class MockModel(models.aria_declarative_base, mixins.ModelMixin): #pylint: disable=abstract-method
+ __tablename__ = 'op_mock_model'
+
+ name = Column(Text)
+ value = Column(Integer)
+
+
+class TestFilterOperands(object):
+
+ @pytest.fixture
+ def values(self):
+ return {1, 2, 3, 4}
+
+ @pytest.fixture()
+ def storage(self, values):
+ model_storage = application_model_storage(
+ sql_mapi.SQLAlchemyModelAPI, initiator=tests_storage.init_inmemory_model_storage)
+ model_storage.register(MockModel)
+ for value in values:
+ model_storage.op_mock_model.put(MockModel(value=value))
+ yield model_storage
+ tests_storage.release_sqlite_storage(model_storage)
+
+ def test_gt(self, storage):
+ assert len(storage.op_mock_model.list(filters=dict(value=dict(gt=3)))) == 1
+ assert len(storage.op_mock_model.list(filters=dict(value=dict(gt=4)))) == 0
+
+ def test_ge(self, storage):
+ assert len(storage.op_mock_model.list(filters=dict(value=dict(ge=3)))) == 2
+ assert len(storage.op_mock_model.list(filters=dict(value=dict(ge=5)))) == 0
+
+ def test_lt(self, storage):
+ assert len(storage.op_mock_model.list(filters=dict(value=dict(lt=2)))) == 1
+ assert len(storage.op_mock_model.list(filters=dict(value=dict(lt=1)))) == 0
+
+ def test_le(self, storage):
+ assert len(storage.op_mock_model.list(filters=dict(value=dict(le=2)))) == 2
+ assert len(storage.op_mock_model.list(filters=dict(value=dict(le=0)))) == 0
+
+ def test_eq(self, storage):
+ assert len(storage.op_mock_model.list(filters=dict(value=dict(eq=2)))) == 1
+ assert len(storage.op_mock_model.list(filters=dict(value=dict(eq=0)))) == 0
+
+ def test_neq(self, storage):
+ assert len(storage.op_mock_model.list(filters=dict(value=dict(ne=2)))) == 3
+
+ def test_gt_and_lt(self, storage):
+ assert len(storage.op_mock_model.list(filters=dict(value=dict(gt=1, lt=3)))) == 1
+ assert len(storage.op_mock_model.list(filters=dict(value=dict(gt=2, lt=2)))) == 0
+
+ def test_eq_and_ne(self, storage):
+ assert len(storage.op_mock_model.list(filters=dict(value=dict(eq=1, ne=3)))) == 1
+ assert len(storage.op_mock_model.list(filters=dict(value=dict(eq=1, ne=1)))) == 0