diff --git a/tiramisu/error.py b/tiramisu/error.py index c1bf3a5..3a29159 100644 --- a/tiramisu/error.py +++ b/tiramisu/error.py @@ -56,3 +56,8 @@ class RequirementError(StandardError): class SlaveError(StandardError): "problem with a slave's value length" pass + + +class ConstError(TypeError): + "no uniq value in _NameSpace" + pass diff --git a/tiramisu/option.py b/tiramisu/option.py index 479dbdd..498ddf3 100644 --- a/tiramisu/option.py +++ b/tiramisu/option.py @@ -488,7 +488,7 @@ class SymLinkOption(object): def __getattr__(self, name): if name in ('_name', '_opt', '_consistencies'): - return object.__gettattr__(self, name) + return object.__getattr__(self, name) else: return getattr(self._opt, name) diff --git a/tiramisu/setting.py b/tiramisu/setting.py index edcccac..c9d4a0b 100644 --- a/tiramisu/setting.py +++ b/tiramisu/setting.py @@ -22,7 +22,8 @@ # ____________________________________________________________ from time import time from copy import copy -from tiramisu.error import RequirementError, PropertiesOptionError +from tiramisu.error import (RequirementError, PropertiesOptionError, + ConstError, ConfigError) from tiramisu.i18n import _ @@ -34,28 +35,46 @@ ro_append = ('frozen', 'disabled', 'validator', 'everything_frozen', rw_remove = ('permissive', 'everything_frozen', 'mandatory') rw_append = ('frozen', 'disabled', 'validator', 'hidden') default_properties = ('expire', 'validator') -storage_type = 'dictionary' -class _const: +class StorageType: + default_storage = 'dictionary' + storage_type = None + + def set_storage(self, name): + if self.storage_type is not None: + raise ConfigError(_('storage_type is already set, cannot rebind it')) + self.storage_type = name + + def get_storage(self): + if self.storage_type is None: + storage = self.default_storage + else: + storage = self.storage_type + return 'tiramisu.storage.{0}.storage'.format( + storage) + + +storage_type = StorageType() + + +class _NameSpace: """convenient class that emulates a module and builds constants (that is, unique names)""" - class ConstError(TypeError): - pass def __setattr__(self, name, value): if name in self.__dict__: - raise self.ConstError, _("can't rebind group ({})").format(name) + raise ConstError(_("can't rebind {0}").format(name)) self.__dict__[name] = value def __delattr__(self, name): if name in self.__dict__: - raise self.ConstError, _("can't unbind group ({})").format(name) + raise ConstError(_("can't unbind {0}").format(name)) raise ValueError(name) # ____________________________________________________________ -class GroupModule(_const): +class GroupModule(_NameSpace): "emulates a module to manage unique group (OptionDescription) names" class GroupType(str): """allowed normal group (OptionDescription) names @@ -87,7 +106,7 @@ populate_groups() # ____________________________________________________________ -class OwnerModule(_const): +class OwnerModule(_NameSpace): """emulates a module to manage unique owner names. owners are living in `Config._cfgimpl_value_owners` @@ -124,7 +143,7 @@ def populate_owners(): populate_owners() -class MultiTypeModule(_const): +class MultiTypeModule(_NameSpace): "namespace for the master/slaves" class MultiType(str): pass @@ -184,9 +203,17 @@ class Property(object): return str(list(self._properties)) -def set_storage(name): - global storage_type - storage_type = name +def set_storage(name, **args): + storage_type.set_storage(name) + settings = __import__(storage_type.get_storage(), globals(), locals(), + ['Setting'], -1).Setting() + for option, value in args.items(): + try: + getattr(settings, option) + setattr(settings, option, value) + except AttributeError: + raise ValueError(_('option {0} not already exists in storage {1}' + '').format(option, name)) def get_storage(context, session_id, is_persistent): @@ -195,9 +222,8 @@ def get_storage(context, session_id, is_persistent): if session_id is None: session_id = gen_id(context) - import_lib = 'tiramisu.storage.{0}.storage'.format(storage_type) - return __import__(import_lib, globals(), locals(), ['Storage'], - -1).Storage(session_id, is_persistent) + return __import__(storage_type.get_storage(), globals(), locals(), + ['Storage'], -1).Storage(session_id, is_persistent) #____________________________________________________________ diff --git a/tiramisu/storage/dictionary/storage.py b/tiramisu/storage/dictionary/storage.py index 759e5e0..be95260 100644 --- a/tiramisu/storage/dictionary/storage.py +++ b/tiramisu/storage/dictionary/storage.py @@ -23,11 +23,18 @@ from tiramisu.i18n import _ from tiramisu.error import ConfigError -def enumerate(): +class Setting(object): + pass + + +setting = Setting() + + +def list_sessions(): return [] -def delete(session_id): +def delete_session(session_id): raise ConfigError(_('dictionary storage cannot delete session')) diff --git a/tiramisu/storage/sqlite3/storage.py b/tiramisu/storage/sqlite3/storage.py index 8c5bc86..f7a168e 100644 --- a/tiramisu/storage/sqlite3/storage.py +++ b/tiramisu/storage/sqlite3/storage.py @@ -25,22 +25,27 @@ import sqlite3 from glob import glob -extension = 'db' -dir_database = '/tmp' +class Setting(object): + extension = 'db' + dir_database = '/tmp' + + +setting = Setting() def _gen_filename(name): - return join(dir_database, '{0}.{1}'.format(name, extension)) + return join(setting.dir_database, '{0}.{1}'.format(name, + setting.extension)) -def enumerate(): +def list_sessions(): names = [] for filename in glob(_gen_filename('*')): names.append(basename(splitext(filename)[0])) return names -def delete(session_id): +def delete_session(session_id): unlink(_gen_filename(session_id)) @@ -73,7 +78,7 @@ class Storage(object): self._cursor.close() self._conn.close() if not self.is_persistent: - delete(self._session_id) + delete_session(self._session_id) class Cache(object): diff --git a/tiramisu/storage/sqlite3/value.py b/tiramisu/storage/sqlite3/value.py index af4164d..647c41e 100644 --- a/tiramisu/storage/sqlite3/value.py +++ b/tiramisu/storage/sqlite3/value.py @@ -28,11 +28,16 @@ class Values(Cache): def __init__(self, storage): """init plugin means create values storage """ - values_table = 'CREATE TABLE IF NOT EXISTS value(path text primary ' - values_table += 'key, value text, owner text)' # should init cache too super(Values, self).__init__('value', storage) + values_table = 'CREATE TABLE IF NOT EXISTS value(path text primary ' + values_table += 'key, value text, owner text)' self.storage.execute(values_table) + for owner in self.storage.select("SELECT DISTINCT owner FROM value", tuple(), False): + try: + getattr(owners, owner[0]) + except AttributeError: + owners.add_owner(owner[0]) # sqlite def _sqlite_select(self, path): @@ -102,4 +107,10 @@ class Values(Cache): if owner is None: return default else: - return getattr(owners, owner[0]) + owner = owner[0] + # autocreate owners + try: + return getattr(owners, owner) + except AttributeError: + owners.add_owner(owner) + return getattr(owners, owner) diff --git a/tiramisu/value.py b/tiramisu/value.py index b5092d8..cd57a4c 100644 --- a/tiramisu/value.py +++ b/tiramisu/value.py @@ -142,7 +142,7 @@ class Values(object): index=index) def __getitem__(self, opt): - "enables us to use the pythonic dictionnary-like access to values" + "enables us to use the pythonic dictionary-like access to values" return self.getitem(opt) def getitem(self, opt, path=None, validate=True, force_permissive=False,