deb-zaqar/zaqar/storage/sqlalchemy/catalogue.py
Flavio Percoco 161f5848d1 Don't create a connection on constructor
Some controllers in the sqlalchemy driver were creating connections in
their constructors. This, besides creating a connection when it's not
needed, ended up creating such connection in the wrong thread.

The above is an issue when using sqlite or non-thread-safe drivers since
the connection would be shared accross different threads when running
under scalable wsgi containers.

This patch moves the connection back to being lazy.

Change-Id: I4b45ad1b20b81962a56536fd875d165072493ade
2015-09-09 08:59:50 +02:00

109 lines
3.0 KiB
Python

# Copyright (c) 2014 Rackspace Hosting, 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.
"""Sql storage controller for the queues catalogue.
Serves to construct an association between a project + queue -> pool
name: string -> Pools.name
project: string
queue: string
"""
import sqlalchemy as sa
from zaqar.storage import base
from zaqar.storage import errors
from zaqar.storage.sqlalchemy import tables
def _match(project, queue):
clauses = [
tables.Catalogue.c.project == project,
tables.Catalogue.c.queue == queue
]
return sa.sql.and_(*clauses)
class CatalogueController(base.CatalogueBase):
def list(self, project):
stmt = sa.sql.select([tables.Catalogue]).where(
tables.Catalogue.c.project == project
)
cursor = self.driver.connection.execute(stmt)
return (_normalize(v) for v in cursor)
def get(self, project, queue):
stmt = sa.sql.select([tables.Catalogue]).where(
_match(project, queue)
)
entry = self.driver.connection.execute(stmt).fetchone()
if entry is None:
raise errors.QueueNotMapped(queue, project)
return _normalize(entry)
def exists(self, project, queue):
try:
return self.get(project, queue) is not None
except errors.QueueNotMapped:
return False
def insert(self, project, queue, pool):
try:
stmt = sa.sql.insert(tables.Catalogue).values(
project=project, queue=queue, pool=pool
)
self.driver.connection.execute(stmt)
except sa.exc.IntegrityError:
self._update(project, queue, pool)
def delete(self, project, queue):
stmt = sa.sql.delete(tables.Catalogue).where(
_match(project, queue)
)
self.driver.connection.execute(stmt)
def _update(self, project, queue, pool):
stmt = sa.sql.update(tables.Catalogue).where(
_match(project, queue)
).values(pool=pool)
self.driver.connection.execute(stmt)
def update(self, project, queue, pool=None):
if pool is None:
return
if not self.exists(project, queue):
raise errors.QueueNotMapped(queue, project)
self._update(project, queue, pool)
def drop_all(self):
stmt = sa.sql.expression.delete(tables.Catalogue)
self.driver.connection.execute(stmt)
def _normalize(entry):
name, project, queue = entry
return {
'queue': queue,
'project': project,
'pool': name
}