diff options
Diffstat (limited to 'keystone/common/sql/core.py')
-rw-r--r-- | keystone/common/sql/core.py | 65 |
1 files changed, 53 insertions, 12 deletions
diff --git a/keystone/common/sql/core.py b/keystone/common/sql/core.py index d75c73a8..2d3114f2 100644 --- a/keystone/common/sql/core.py +++ b/keystone/common/sql/core.py @@ -32,10 +32,12 @@ from keystone import exception from keystone.openstack.common import jsonutils +LOG = logging.getLogger(__name__) CONF = config.CONF -# maintain a single engine reference for sqlite in-memory +# maintain a single engine reference for sqlalchemy engine GLOBAL_ENGINE = None +GLOBAL_ENGINE_CALLBACKS = set() ModelBase = declarative.declarative_base() @@ -78,13 +80,6 @@ def initialize_decorator(init): v = str(v) if column.type.length and \ column.type.length < len(v): - #if signing.token_format == 'PKI', the id will - #store it's public key which is very long. - if config.CONF.signing.token_format == 'PKI' and \ - self.__tablename__ == 'token' and \ - k == 'id': - continue - raise exception.StringLengthExceeded( string=v, type=k, length=column.type.length) @@ -95,9 +90,49 @@ ModelBase.__init__ = initialize_decorator(ModelBase.__init__) def set_global_engine(engine): + """Set the global engine. + + This sets the current global engine, which is returned by + Base.get_engine(allow_global_engine=True). + + When the global engine is changed, all of the callbacks registered via + register_global_engine_callback since the last time set_global_engine was + changed are called. The callback functions are invoked with no arguments. + + """ + global GLOBAL_ENGINE + global GLOBAL_ENGINE_CALLBACKS + + if engine is GLOBAL_ENGINE: + # It's the same engine so nothing to do. + return + GLOBAL_ENGINE = engine + cbs = GLOBAL_ENGINE_CALLBACKS + GLOBAL_ENGINE_CALLBACKS = set() + for cb in cbs: + try: + cb() + except Exception: + LOG.exception(_("Global engine callback raised.")) + # Just logging the exception so can process other callbacks. + + +def register_global_engine_callback(cb_fn): + """Register a function to be called when the global engine is set. + + Note that the callback will be called only once or not at all, so to get + called each time the global engine is changed the function must be + re-registered. + + """ + + global GLOBAL_ENGINE_CALLBACKS + + GLOBAL_ENGINE_CALLBACKS.add(cb_fn) + # Special Fields class JsonBlob(sql_types.TypeDecorator): @@ -208,10 +243,12 @@ class Base(object): def get_session(self, autocommit=True, expire_on_commit=False): """Return a SQLAlchemy session.""" - self._engine = self._engine or self.get_engine() - self._sessionmaker = self._sessionmaker or self.get_sessionmaker( - self._engine) - return self._sessionmaker() + if not self._engine: + self._engine = self.get_engine() + self._sessionmaker = self.get_sessionmaker(self._engine) + register_global_engine_callback(self.clear_engine) + return self._sessionmaker(autocommit=autocommit, + expire_on_commit=expire_on_commit) def get_engine(self, allow_global_engine=True): """Return a SQLAlchemy engine. @@ -264,6 +301,10 @@ class Base(object): autocommit=autocommit, expire_on_commit=expire_on_commit) + def clear_engine(self): + self._engine = None + self._sessionmaker = None + def handle_conflicts(type='object'): """Converts IntegrityError into HTTP 409 Conflict.""" |