[2/3] incubator-ariatosca git commit: ARIA-30 SQL based storage implementation

2016-12-01 Thread mxmrlv
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/c9df5b14/aria/storage/mapi/sql.py
--
diff --git a/aria/storage/mapi/sql.py b/aria/storage/mapi/sql.py
new file mode 100644
index 000..652dc9f
--- /dev/null
+++ b/aria/storage/mapi/sql.py
@@ -0,0 +1,368 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""
+SQLAlchemy based MAPI
+"""
+
+from sqlite3 import DatabaseError as SQLiteDBError
+from sqlalchemy.exc import SQLAlchemyError
+from sqlalchemy.sql.elements import Label
+
+try:
+from psycopg2 import DatabaseError as Psycopg2DBError
+sql_errors = (SQLAlchemyError, SQLiteDBError, Psycopg2DBError)
+except ImportError:
+sql_errors = (SQLAlchemyError, SQLiteDBError)
+Psycopg2DBError = None
+
+from aria.utils.collections import OrderedDict
+
+from ... import storage
+
+
+DEFAULT_SQL_DIALECT = 'sqlite'
+
+
+class SQLAlchemyModelAPI(storage.api.ModelAPI):
+"""
+SQL based MAPI.
+"""
+
+def __init__(self,
+ engine,
+ session,
+ **kwargs):
+super(SQLAlchemyModelAPI, self).__init__(**kwargs)
+self._engine = engine
+self._session = session
+
+def get(self, entry_id, include=None, filters=None, locking=False, 
**kwargs):
+"""Return a single result based on the model class and element ID
+"""
+filters = filters or {'id': entry_id}
+query = self._get_query(include, filters)
+if locking:
+query = query.with_for_update()
+result = query.first()
+
+if not result:
+raise storage.exceptions.StorageError(
+'Requested {0} with ID `{1}` was not found'
+.format(self.model_cls.__name__, entry_id)
+)
+return result
+
+def iter(self,
+ include=None,
+ filters=None,
+ pagination=None,
+ sort=None,
+ **kwargs):
+"""Return a (possibly empty) list of `model_class` results
+"""
+query = self._get_query(include, filters, sort)
+
+results, _, _, _ = self._paginate(query, pagination)
+
+for result in results:
+yield result
+
+def store(self, entry, **kwargs):
+"""Create a `model_class` instance from a serializable `model` object
+
+:param entry: A dict with relevant kwargs, or an instance of a class
+that has a `to_dict` method, and whose attributes match the columns
+of `model_class` (might also my just an instance of `model_class`)
+:return: An instance of `model_class`
+"""
+self._session.add(entry)
+self._safe_commit()
+return entry
+
+def delete(self, entry_id, filters=None, **kwargs):
+"""Delete a single result based on the model class and element ID
+"""
+try:
+instance = self.get(
+entry_id,
+filters=filters
+)
+except storage.exceptions.StorageError:
+raise storage.exceptions.StorageError(
+'Could not delete {0} with ID `{1}` - element not found'
+.format(
+self.model_cls.__name__,
+entry_id
+)
+)
+self._load_properties(instance)
+self._session.delete(instance)
+self._safe_commit()
+return instance
+
+# TODO: this might need rework
+def update(self, entry, **kwargs):
+"""Add `instance` to the DB session, and attempt to commit
+
+:return: The updated instance
+"""
+return self.store(entry)
+
+def refresh(self, entry):
+"""Reload the instance with fresh information from the DB
+
+:param entry: Instance to be re-loaded from the DB
+:return: The refreshed instance
+"""
+self._session.refresh(entry)
+self._load_properties(entry)
+return entry
+
+def _destroy_connection(self):
+pass
+
+def _establish_connection(self):
+pass
+
+def create(self):
+self.model_cls.__table__.create(self._engine)
+
+def drop(self):
+"""
+

[2/3] incubator-ariatosca git commit: ARIA-30 SQL based storage implementation

2016-12-01 Thread mxmrlv
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f6981ddb/aria/storage/mapi/sql.py
--
diff --git a/aria/storage/mapi/sql.py b/aria/storage/mapi/sql.py
new file mode 100644
index 000..652dc9f
--- /dev/null
+++ b/aria/storage/mapi/sql.py
@@ -0,0 +1,368 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""
+SQLAlchemy based MAPI
+"""
+
+from sqlite3 import DatabaseError as SQLiteDBError
+from sqlalchemy.exc import SQLAlchemyError
+from sqlalchemy.sql.elements import Label
+
+try:
+from psycopg2 import DatabaseError as Psycopg2DBError
+sql_errors = (SQLAlchemyError, SQLiteDBError, Psycopg2DBError)
+except ImportError:
+sql_errors = (SQLAlchemyError, SQLiteDBError)
+Psycopg2DBError = None
+
+from aria.utils.collections import OrderedDict
+
+from ... import storage
+
+
+DEFAULT_SQL_DIALECT = 'sqlite'
+
+
+class SQLAlchemyModelAPI(storage.api.ModelAPI):
+"""
+SQL based MAPI.
+"""
+
+def __init__(self,
+ engine,
+ session,
+ **kwargs):
+super(SQLAlchemyModelAPI, self).__init__(**kwargs)
+self._engine = engine
+self._session = session
+
+def get(self, entry_id, include=None, filters=None, locking=False, 
**kwargs):
+"""Return a single result based on the model class and element ID
+"""
+filters = filters or {'id': entry_id}
+query = self._get_query(include, filters)
+if locking:
+query = query.with_for_update()
+result = query.first()
+
+if not result:
+raise storage.exceptions.StorageError(
+'Requested {0} with ID `{1}` was not found'
+.format(self.model_cls.__name__, entry_id)
+)
+return result
+
+def iter(self,
+ include=None,
+ filters=None,
+ pagination=None,
+ sort=None,
+ **kwargs):
+"""Return a (possibly empty) list of `model_class` results
+"""
+query = self._get_query(include, filters, sort)
+
+results, _, _, _ = self._paginate(query, pagination)
+
+for result in results:
+yield result
+
+def store(self, entry, **kwargs):
+"""Create a `model_class` instance from a serializable `model` object
+
+:param entry: A dict with relevant kwargs, or an instance of a class
+that has a `to_dict` method, and whose attributes match the columns
+of `model_class` (might also my just an instance of `model_class`)
+:return: An instance of `model_class`
+"""
+self._session.add(entry)
+self._safe_commit()
+return entry
+
+def delete(self, entry_id, filters=None, **kwargs):
+"""Delete a single result based on the model class and element ID
+"""
+try:
+instance = self.get(
+entry_id,
+filters=filters
+)
+except storage.exceptions.StorageError:
+raise storage.exceptions.StorageError(
+'Could not delete {0} with ID `{1}` - element not found'
+.format(
+self.model_cls.__name__,
+entry_id
+)
+)
+self._load_properties(instance)
+self._session.delete(instance)
+self._safe_commit()
+return instance
+
+# TODO: this might need rework
+def update(self, entry, **kwargs):
+"""Add `instance` to the DB session, and attempt to commit
+
+:return: The updated instance
+"""
+return self.store(entry)
+
+def refresh(self, entry):
+"""Reload the instance with fresh information from the DB
+
+:param entry: Instance to be re-loaded from the DB
+:return: The refreshed instance
+"""
+self._session.refresh(entry)
+self._load_properties(entry)
+return entry
+
+def _destroy_connection(self):
+pass
+
+def _establish_connection(self):
+pass
+
+def create(self):
+self.model_cls.__table__.create(self._engine)
+
+def drop(self):
+"""
+

[2/3] incubator-ariatosca git commit: ARIA-30 SQL based storage implementation

2016-12-01 Thread mxmrlv
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/358cbe05/aria/storage/mapi/sql.py
--
diff --git a/aria/storage/mapi/sql.py b/aria/storage/mapi/sql.py
new file mode 100644
index 000..4408aa3
--- /dev/null
+++ b/aria/storage/mapi/sql.py
@@ -0,0 +1,369 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""
+SQLalchemy based MAPI
+"""
+
+from sqlite3 import DatabaseError as SQLiteDBError
+from sqlalchemy.exc import SQLAlchemyError
+from sqlalchemy.sql.elements import Label
+
+from aria.utils.collections import OrderedDict
+
+
+try:
+from psycopg2 import DatabaseError as Psycopg2DBError
+sql_errors = (SQLAlchemyError, SQLiteDBError, Psycopg2DBError)
+except ImportError:
+sql_errors = (SQLAlchemyError, SQLiteDBError)
+Psycopg2DBError = None
+
+from ... import storage
+
+
+DEFAULT_SQL_DIALECT = 'sqlite'
+
+
+class SQLAlchemyModelAPI(storage.api.ModelAPI):
+"""
+SQL based MAPI.
+"""
+
+def __init__(self,
+ engine,
+ session,
+ **kwargs):
+super(SQLAlchemyModelAPI, self).__init__(**kwargs)
+self._engine = engine
+self._session = session
+
+def get(self, entry_id, include=None, filters=None, locking=False, 
**kwargs):
+"""Return a single result based on the model class and element ID
+"""
+filters = filters or {'id': entry_id}
+query = self._get_query(include, filters)
+if locking:
+query = query.with_for_update()
+result = query.first()
+
+if not result:
+raise storage.exceptions.StorageError(
+'Requested {0} with ID `{1}` was not found'
+.format(self.model_cls.__name__, entry_id)
+)
+return result
+
+def iter(self,
+ include=None,
+ filters=None,
+ pagination=None,
+ sort=None,
+ **kwargs):
+"""Return a (possibly empty) list of `model_class` results
+"""
+query = self._get_query(include, filters, sort)
+
+results, _, _, _ = self._paginate(query, pagination)
+
+for result in results:
+yield result
+
+def store(self, entry, **kwargs):
+"""Create a `model_class` instance from a serializable `model` object
+
+:param entry: A dict with relevant kwargs, or an instance of a class
+that has a `to_dict` method, and whose attributes match the columns
+of `model_class` (might also my just an instance of `model_class`)
+:return: An instance of `model_class`
+"""
+self._session.add(entry)
+self._safe_commit()
+return entry
+
+def delete(self, entry_id, filters=None, **kwargs):
+"""Delete a single result based on the model class and element ID
+"""
+try:
+instance = self.get(
+entry_id,
+filters=filters
+)
+except storage.exceptions.StorageError:
+raise storage.exceptions.StorageError(
+'Could not delete {0} with ID `{1}` - element not found'
+.format(
+self.model_cls.__name__,
+entry_id
+)
+)
+self._load_properties(instance)
+self._session.delete(instance)
+self._safe_commit()
+return instance
+
+# TODO: this might need rework
+def update(self, entry, **kwargs):
+"""Add `instance` to the DB session, and attempt to commit
+
+:return: The updated instance
+"""
+return self.store(entry)
+
+def refresh(self, entry):
+"""Reload the instance with fresh information from the DB
+
+:param entry: Instance to be re-loaded from the DB
+:return: The refreshed instance
+"""
+self._session.refresh(entry)
+self._load_properties(entry)
+return entry
+
+def _destroy_connection(self):
+pass
+
+def _establish_connection(self):
+pass
+
+def create(self):
+self.model_cls.__table__.create(self._engine)
+
+def drop(self):
+"""
+  

[2/3] incubator-ariatosca git commit: ARIA-30-SQL-based-storage-implementation

2016-12-01 Thread mxmrlv
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/f68e11bf/aria/storage/mapi/sql.py
--
diff --git a/aria/storage/mapi/sql.py b/aria/storage/mapi/sql.py
new file mode 100644
index 000..4408aa3
--- /dev/null
+++ b/aria/storage/mapi/sql.py
@@ -0,0 +1,369 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""
+SQLalchemy based MAPI
+"""
+
+from sqlite3 import DatabaseError as SQLiteDBError
+from sqlalchemy.exc import SQLAlchemyError
+from sqlalchemy.sql.elements import Label
+
+from aria.utils.collections import OrderedDict
+
+
+try:
+from psycopg2 import DatabaseError as Psycopg2DBError
+sql_errors = (SQLAlchemyError, SQLiteDBError, Psycopg2DBError)
+except ImportError:
+sql_errors = (SQLAlchemyError, SQLiteDBError)
+Psycopg2DBError = None
+
+from ... import storage
+
+
+DEFAULT_SQL_DIALECT = 'sqlite'
+
+
+class SQLAlchemyModelAPI(storage.api.ModelAPI):
+"""
+SQL based MAPI.
+"""
+
+def __init__(self,
+ engine,
+ session,
+ **kwargs):
+super(SQLAlchemyModelAPI, self).__init__(**kwargs)
+self._engine = engine
+self._session = session
+
+def get(self, entry_id, include=None, filters=None, locking=False, 
**kwargs):
+"""Return a single result based on the model class and element ID
+"""
+filters = filters or {'id': entry_id}
+query = self._get_query(include, filters)
+if locking:
+query = query.with_for_update()
+result = query.first()
+
+if not result:
+raise storage.exceptions.StorageError(
+'Requested {0} with ID `{1}` was not found'
+.format(self.model_cls.__name__, entry_id)
+)
+return result
+
+def iter(self,
+ include=None,
+ filters=None,
+ pagination=None,
+ sort=None,
+ **kwargs):
+"""Return a (possibly empty) list of `model_class` results
+"""
+query = self._get_query(include, filters, sort)
+
+results, _, _, _ = self._paginate(query, pagination)
+
+for result in results:
+yield result
+
+def store(self, entry, **kwargs):
+"""Create a `model_class` instance from a serializable `model` object
+
+:param entry: A dict with relevant kwargs, or an instance of a class
+that has a `to_dict` method, and whose attributes match the columns
+of `model_class` (might also my just an instance of `model_class`)
+:return: An instance of `model_class`
+"""
+self._session.add(entry)
+self._safe_commit()
+return entry
+
+def delete(self, entry_id, filters=None, **kwargs):
+"""Delete a single result based on the model class and element ID
+"""
+try:
+instance = self.get(
+entry_id,
+filters=filters
+)
+except storage.exceptions.StorageError:
+raise storage.exceptions.StorageError(
+'Could not delete {0} with ID `{1}` - element not found'
+.format(
+self.model_cls.__name__,
+entry_id
+)
+)
+self._load_properties(instance)
+self._session.delete(instance)
+self._safe_commit()
+return instance
+
+# TODO: this might need rework
+def update(self, entry, **kwargs):
+"""Add `instance` to the DB session, and attempt to commit
+
+:return: The updated instance
+"""
+return self.store(entry)
+
+def refresh(self, entry):
+"""Reload the instance with fresh information from the DB
+
+:param entry: Instance to be re-loaded from the DB
+:return: The refreshed instance
+"""
+self._session.refresh(entry)
+self._load_properties(entry)
+return entry
+
+def _destroy_connection(self):
+pass
+
+def _establish_connection(self):
+pass
+
+def create(self):
+self.model_cls.__table__.create(self._engine)
+
+def drop(self):
+"""
+  

[2/3] incubator-ariatosca git commit: ARIA-30 SQL based storage implementation

2016-12-01 Thread mxmrlv
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/fe944e58/aria/storage/mapi/sql.py
--
diff --git a/aria/storage/mapi/sql.py b/aria/storage/mapi/sql.py
new file mode 100644
index 000..4408aa3
--- /dev/null
+++ b/aria/storage/mapi/sql.py
@@ -0,0 +1,369 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""
+SQLalchemy based MAPI
+"""
+
+from sqlite3 import DatabaseError as SQLiteDBError
+from sqlalchemy.exc import SQLAlchemyError
+from sqlalchemy.sql.elements import Label
+
+from aria.utils.collections import OrderedDict
+
+
+try:
+from psycopg2 import DatabaseError as Psycopg2DBError
+sql_errors = (SQLAlchemyError, SQLiteDBError, Psycopg2DBError)
+except ImportError:
+sql_errors = (SQLAlchemyError, SQLiteDBError)
+Psycopg2DBError = None
+
+from ... import storage
+
+
+DEFAULT_SQL_DIALECT = 'sqlite'
+
+
+class SQLAlchemyModelAPI(storage.api.ModelAPI):
+"""
+SQL based MAPI.
+"""
+
+def __init__(self,
+ engine,
+ session,
+ **kwargs):
+super(SQLAlchemyModelAPI, self).__init__(**kwargs)
+self._engine = engine
+self._session = session
+
+def get(self, entry_id, include=None, filters=None, locking=False, 
**kwargs):
+"""Return a single result based on the model class and element ID
+"""
+filters = filters or {'id': entry_id}
+query = self._get_query(include, filters)
+if locking:
+query = query.with_for_update()
+result = query.first()
+
+if not result:
+raise storage.exceptions.StorageError(
+'Requested {0} with ID `{1}` was not found'
+.format(self.model_cls.__name__, entry_id)
+)
+return result
+
+def iter(self,
+ include=None,
+ filters=None,
+ pagination=None,
+ sort=None,
+ **kwargs):
+"""Return a (possibly empty) list of `model_class` results
+"""
+query = self._get_query(include, filters, sort)
+
+results, _, _, _ = self._paginate(query, pagination)
+
+for result in results:
+yield result
+
+def store(self, entry, **kwargs):
+"""Create a `model_class` instance from a serializable `model` object
+
+:param entry: A dict with relevant kwargs, or an instance of a class
+that has a `to_dict` method, and whose attributes match the columns
+of `model_class` (might also my just an instance of `model_class`)
+:return: An instance of `model_class`
+"""
+self._session.add(entry)
+self._safe_commit()
+return entry
+
+def delete(self, entry_id, filters=None, **kwargs):
+"""Delete a single result based on the model class and element ID
+"""
+try:
+instance = self.get(
+entry_id,
+filters=filters
+)
+except storage.exceptions.StorageError:
+raise storage.exceptions.StorageError(
+'Could not delete {0} with ID `{1}` - element not found'
+.format(
+self.model_cls.__name__,
+entry_id
+)
+)
+self._load_properties(instance)
+self._session.delete(instance)
+self._safe_commit()
+return instance
+
+# TODO: this might need rework
+def update(self, entry, **kwargs):
+"""Add `instance` to the DB session, and attempt to commit
+
+:return: The updated instance
+"""
+return self.store(entry)
+
+def refresh(self, entry):
+"""Reload the instance with fresh information from the DB
+
+:param entry: Instance to be re-loaded from the DB
+:return: The refreshed instance
+"""
+self._session.refresh(entry)
+self._load_properties(entry)
+return entry
+
+def _destroy_connection(self):
+pass
+
+def _establish_connection(self):
+pass
+
+def create(self):
+self.model_cls.__table__.create(self._engine)
+
+def drop(self):
+"""
+