You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ariatosca.apache.org by em...@apache.org on 2017/04/07 00:55:04 UTC

[11/14] incubator-ariatosca git commit: ARIA-137-Support-for-predicate-based-queries-in-the-SQL-mapi

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/422574e0
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/422574e0
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/422574e0

Branch: refs/heads/ARIA-92-plugin-in-implementation-string
Commit: 422574e03174e5dff57888af2519ed62048ce3fa
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 16:02:04 2017 +0300

----------------------------------------------------------------------
 aria/storage/sql_mapi.py            | 28 +++++++++++++++-
 tests/storage/test_model_storage.py | 57 ++++++++++++++++++++++++++++++++
 2 files changed, 84 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/422574e0/aria/storage/sql_mapi.py
----------------------------------------------------------------------
diff --git a/aria/storage/sql_mapi.py b/aria/storage/sql_mapi.py
index 59e1896..8d34bb4 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,28 @@ 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 not in _predicates:
+                        raise exceptions.StorageError(
+                            "{0} is not a valid predicate for filtering. Valid predicates are {1}"
+                            .format(predicate, ', '.join(_predicates.keys())))
+                    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/422574e0/tests/storage/test_model_storage.py
----------------------------------------------------------------------
diff --git a/tests/storage/test_model_storage.py b/tests/storage/test_model_storage.py
index e4f3eba..4dabfaf 100644
--- a/tests/storage/test_model_storage.py
+++ b/tests/storage/test_model_storage.py
@@ -15,6 +15,12 @@
 
 import pytest
 
+from sqlalchemy import (
+    Column,
+    Integer,
+    Text
+)
+
 from aria import (
     application_model_storage,
     modeling
@@ -150,3 +156,54 @@ def test_mapi_include(context):
 
     assert_include(service1)
     assert_include(service2)
+
+
+class MockModel(modeling.models.aria_declarative_base, modeling.mixins.ModelMixin): #pylint: disable=abstract-method
+    __tablename__ = 'op_mock_model'
+
+    name = Column(Text)
+    value = Column(Integer)
+
+
+class TestFilterOperands(object):
+
+    @pytest.fixture()
+    def storage(self):
+        model_storage = application_model_storage(
+            sql_mapi.SQLAlchemyModelAPI, initiator=tests_storage.init_inmemory_model_storage)
+        model_storage.register(MockModel)
+        for value in (1, 2, 3, 4):
+            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