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