Added initial database setup
Change-Id: Ife4b36341f85e16f3c6a89b1394df56f8fbe2a35
This commit is contained in:
parent
039e899d8b
commit
3a43f97918
0
mistral/db/sqlalchemy/__init__.py
Normal file
0
mistral/db/sqlalchemy/__init__.py
Normal file
98
mistral/db/sqlalchemy/api.py
Normal file
98
mistral/db/sqlalchemy/api.py
Normal file
@ -0,0 +1,98 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright 2013 - Mirantis, Inc.
|
||||
#
|
||||
# Licensed 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.
|
||||
|
||||
import sqlalchemy as sa
|
||||
|
||||
from mistral.db.sqlalchemy import models as m
|
||||
from mistral.openstack.common.db.sqlalchemy import session as db_session
|
||||
from mistral.openstack.common import log as logging
|
||||
from mistral.openstack.common.db import exception as db_exc
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
get_engine = db_session.get_engine
|
||||
get_session = db_session.get_session
|
||||
|
||||
|
||||
def to_dict(func):
|
||||
def decorator(*args, **kwargs):
|
||||
res = func(*args, **kwargs)
|
||||
|
||||
if isinstance(res, list):
|
||||
return [item.to_dict() for item in res]
|
||||
|
||||
if res:
|
||||
return res.to_dict()
|
||||
else:
|
||||
return None
|
||||
|
||||
return decorator
|
||||
|
||||
|
||||
def model_query(model, session=None):
|
||||
"""Query helper.
|
||||
|
||||
:param model: base model to query
|
||||
:param context: context to query under
|
||||
:param project_only: if present and context is user-type, then restrict
|
||||
query to match the context's tenant_id.
|
||||
"""
|
||||
session = session or get_session()
|
||||
|
||||
return session.query(model)
|
||||
|
||||
|
||||
def setup_db():
|
||||
try:
|
||||
engine = db_session.get_engine(sqlite_fk=True)
|
||||
m.Event.metadata.create_all(engine)
|
||||
except sa.exc.OperationalError as e:
|
||||
LOG.exception("Database registration exception: %s", e)
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def drop_db():
|
||||
try:
|
||||
engine = db_session.get_engine(sqlite_fk=True)
|
||||
m.Event.metadata.drop_all(engine)
|
||||
except Exception as e:
|
||||
LOG.exception("Database shutdown exception: %s", e)
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def event_create(values):
|
||||
values = values.copy()
|
||||
event = m.Event()
|
||||
event.update(values)
|
||||
|
||||
session = get_session()
|
||||
with session.begin():
|
||||
try:
|
||||
event.save(session=session)
|
||||
except db_exc.DBDuplicateEntry as e:
|
||||
raise Exception
|
||||
LOG.exception("Database registration exception: %s", e)
|
||||
|
||||
return event_get(event.id)
|
||||
|
||||
|
||||
@to_dict
|
||||
def event_get(event_id):
|
||||
query = model_query(m.Event, get_session())
|
||||
return query.filter_by(id=event_id).first()
|
50
mistral/db/sqlalchemy/model_base.py
Normal file
50
mistral/db/sqlalchemy/model_base.py
Normal file
@ -0,0 +1,50 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright 2013 - Mirantis, Inc.
|
||||
#
|
||||
# Licensed 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.
|
||||
|
||||
from sqlalchemy.ext import declarative
|
||||
from sqlalchemy.orm import attributes
|
||||
|
||||
from mistral.openstack.common.db.sqlalchemy import models as oslo_models
|
||||
|
||||
|
||||
class _MistralBase(oslo_models.ModelBase, oslo_models.TimestampMixin):
|
||||
"""Base class for all Mistral SQLAlchemy DB Models."""
|
||||
|
||||
def to_dict(self):
|
||||
"""sqlalchemy based automatic to_dict method."""
|
||||
d = {}
|
||||
|
||||
# if a column is unloaded at this point, it is
|
||||
# probably deferred. We do not want to access it
|
||||
# here and thereby cause it to load...
|
||||
unloaded = attributes.instance_state(self).unloaded
|
||||
|
||||
for col in self.__table__.columns:
|
||||
if col.name not in unloaded:
|
||||
d[col.name] = getattr(self, col.name)
|
||||
|
||||
datetime_to_str(d, 'created_at')
|
||||
datetime_to_str(d, 'updated_at')
|
||||
|
||||
return d
|
||||
|
||||
|
||||
def datetime_to_str(dct, attr_name):
|
||||
if dct.get(attr_name) is not None:
|
||||
dct[attr_name] = dct[attr_name].isoformat(' ')
|
||||
|
||||
|
||||
MistralBase = declarative.declarative_base(cls=_MistralBase)
|
45
mistral/db/sqlalchemy/models.py
Normal file
45
mistral/db/sqlalchemy/models.py
Normal file
@ -0,0 +1,45 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright 2013 - Mirantis, Inc.
|
||||
#
|
||||
# Licensed 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.
|
||||
|
||||
import sqlalchemy as sa
|
||||
import uuid
|
||||
|
||||
from mistral.db.sqlalchemy import model_base as mb
|
||||
|
||||
## Helpers
|
||||
|
||||
|
||||
def _generate_unicode_uuid():
|
||||
return unicode(str(uuid.uuid4()))
|
||||
|
||||
|
||||
def _id_column():
|
||||
return sa.Column(sa.String(36),
|
||||
primary_key=True,
|
||||
default=_generate_unicode_uuid)
|
||||
|
||||
|
||||
class Event(mb.MistralBase):
|
||||
"""Contains all info about event."""
|
||||
|
||||
__tablename__ = 'events'
|
||||
|
||||
__table_args__ = (
|
||||
sa.UniqueConstraint('name'),
|
||||
)
|
||||
|
||||
id = _id_column()
|
||||
name = sa.Column(sa.String(80), nullable=False)
|
0
mistral/tests/unit/__init__.py
Normal file
0
mistral/tests/unit/__init__.py
Normal file
37
mistral/tests/unit/base.py
Normal file
37
mistral/tests/unit/base.py
Normal file
@ -0,0 +1,37 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright 2013 - Mirantis, Inc.
|
||||
#
|
||||
# Licensed 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.
|
||||
|
||||
|
||||
import os
|
||||
import tempfile
|
||||
|
||||
import unittest2
|
||||
|
||||
from mistral.db.sqlalchemy import api as db_api
|
||||
from mistral.openstack.common.db.sqlalchemy import session
|
||||
|
||||
|
||||
class DbTestCase(unittest2.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.db_fd, self.db_path = tempfile.mkstemp()
|
||||
session.set_defaults('sqlite:///' + self.db_path, self.db_path)
|
||||
db_api.setup_db()
|
||||
|
||||
def tearDown(self):
|
||||
db_api.drop_db()
|
||||
os.close(self.db_fd)
|
||||
os.unlink(self.db_path)
|
30
mistral/tests/unit/test_events.py
Normal file
30
mistral/tests/unit/test_events.py
Normal file
@ -0,0 +1,30 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright 2013 - Mirantis, Inc.
|
||||
#
|
||||
# Licensed 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.
|
||||
|
||||
from mistral.tests.unit import base as test_base
|
||||
from mistral.db.sqlalchemy import api as db_api
|
||||
|
||||
|
||||
SAMPLE_EVENT = {
|
||||
"id": "123",
|
||||
"name": "test_event"
|
||||
}
|
||||
|
||||
|
||||
class EventTest(test_base.DbTestCase):
|
||||
def test_event_create_list_delete(self):
|
||||
event_db_obj = db_api.event_create(SAMPLE_EVENT)
|
||||
self.assertIsInstance(event_db_obj, dict)
|
Loading…
Reference in New Issue
Block a user