[2/3] incubator-ariatosca git commit: ARIA-30 SQL based storage implementation
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
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
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
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
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): +""" +