From 22bfbb9fa4449d4fb8acc19da8b619c05710e61e Mon Sep 17 00:00:00 2001 From: Emmanuel Garette Date: Fri, 6 Sep 2013 23:15:28 +0200 Subject: [PATCH] storage no more in setting.py, code is now in storage/__init__.py --- test/test_state.py | 121 ++++++++++++++++++++++++ test/test_storage.py | 2 +- tiramisu/config.py | 15 +-- tiramisu/option.py | 2 +- tiramisu/setting.py | 59 +----------- tiramisu/storage/__init__.py | 90 ++++++++++++++++++ tiramisu/storage/dictionary/__init__.py | 24 +++++ tiramisu/storage/dictionary/cache.py | 61 ++++++++++++ tiramisu/storage/dictionary/setting.py | 2 +- tiramisu/storage/dictionary/storage.py | 46 +-------- tiramisu/storage/dictionary/value.py | 2 +- tiramisu/storage/sqlite3/__init__.py | 24 +++++ tiramisu/storage/sqlite3/cache.py | 98 +++++++++++++++++++ tiramisu/storage/sqlite3/setting.py | 2 +- tiramisu/storage/sqlite3/storage.py | 79 ---------------- tiramisu/storage/sqlite3/value.py | 2 +- tiramisu/value.py | 4 +- 17 files changed, 437 insertions(+), 196 deletions(-) create mode 100644 test/test_state.py create mode 100644 tiramisu/storage/dictionary/cache.py create mode 100644 tiramisu/storage/sqlite3/cache.py diff --git a/test/test_state.py b/test/test_state.py new file mode 100644 index 0000000..03ab670 --- /dev/null +++ b/test/test_state.py @@ -0,0 +1,121 @@ +from tiramisu.option import BoolOption, UnicodeOption, SymLinkOption, \ + OptionDescription +from pickle import dumps, loads + + +def _get_slots(opt): + slots = set() + for subclass in opt.__class__.__mro__: + if subclass is not object: + slots.update(subclass.__slots__) + return slots + + +def _no_state(opt): + for attr in _get_slots(opt): + if 'state' in attr: + try: + getattr(opt, attr) + except: + pass + else: + raise Exception('opt should have already attribute {0}'.format(attr)) + + +def _diff_opt(opt1, opt2): + attr1 = set(_get_slots(opt1)) + attr2 = set(_get_slots(opt2)) + diff1 = attr1 - attr2 + diff2 = attr2 - attr1 + if diff1 != set(): + raise Exception('more attribute in opt1 {0}'.format(list(diff1))) + if diff2 != set(): + raise Exception('more attribute in opt2 {0}'.format(list(diff2))) + for attr in attr1: + if attr in ['_cache_paths']: + continue + err1 = False + err2 = False + val1 = None + val2 = None + try: + val1 = getattr(opt1, attr) + except: + err1 = True + + try: + val2 = getattr(opt2, attr) + except: + err2 = True + assert err1 == err2 + if val1 is None: + assert val1 == val2 + elif attr == '_children': + assert val1[0] == val2[0] + for index, _opt in enumerate(val1[1]): + assert _opt._name == val2[1][index]._name + elif attr == '_requires': + assert val1[0][0][0]._name == val2[0][0][0]._name + assert val1[0][0][1:] == val2[0][0][1:] + elif attr == '_opt': + assert val1._name == val2._name + elif attr == '_consistencies': + # dict is only a cache + if isinstance(val1, list): + for index, consistency in enumerate(val1): + assert consistency[0] == val2[index][0] + assert consistency[1]._name == val2[index][1]._name + else: + assert val1 == val2 + + +def test_diff_opt(): + b = BoolOption('b', '') + u = UnicodeOption('u', '', requires=[{'option': b, 'expected': True, 'action': 'disabled', 'inverse': True}]) + #u.impl_add_consistency('not_equal', b) + s = SymLinkOption('s', u) + o = OptionDescription('o', '', [b, u, s]) + o1 = OptionDescription('o1', '', [o]) + + a = dumps(o1) + q = loads(a) + _diff_opt(o1, q) + _diff_opt(o1.o, q.o) + _diff_opt(o1.o.b, q.o.b) + _diff_opt(o1.o.u, q.o.u) + _diff_opt(o1.o.s, q.o.s) + + +def test_diff_opt_cache(): + b = BoolOption('b', '') + u = UnicodeOption('u', '', requires=[{'option': b, 'expected': True, 'action': 'disabled', 'inverse': True}]) + u.impl_add_consistency('not_equal', b) + s = SymLinkOption('s', u) + o = OptionDescription('o', '', [b, u, s]) + o1 = OptionDescription('o1', '', [o]) + o1.impl_build_cache() + + a = dumps(o1) + q = loads(a) + _diff_opt(o1, q) + _diff_opt(o1.o, q.o) + _diff_opt(o1.o.b, q.o.b) + _diff_opt(o1.o.u, q.o.u) + _diff_opt(o1.o.s, q.o.s) + + +def test_no_state_attr(): + # all _state_xxx attributes should be deleted + b = BoolOption('b', '') + u = UnicodeOption('u', '', requires=[{'option': b, 'expected': True, 'action': 'disabled', 'inverse': True}]) + s = SymLinkOption('s', u) + o = OptionDescription('o', '', [b, u, s]) + o1 = OptionDescription('o1', '', [o]) + + a = dumps(o1) + q = loads(a) + _no_state(q) + _no_state(q.o) + _no_state(q.o.b) + _no_state(q.o.u) + _no_state(q.o.s) diff --git a/test/test_storage.py b/test/test_storage.py index 56c44e5..1527f5f 100644 --- a/test/test_storage.py +++ b/test/test_storage.py @@ -5,7 +5,7 @@ import autopath from tiramisu.config import Config from tiramisu.option import BoolOption, OptionDescription from tiramisu.setting import owners -from tiramisu.setting import list_sessions, delete_session +from tiramisu.storage import list_sessions, delete_session def test_non_persistent(): diff --git a/tiramisu/config.py b/tiramisu/config.py index 8537c0d..4659b51 100644 --- a/tiramisu/config.py +++ b/tiramisu/config.py @@ -23,7 +23,8 @@ import weakref from tiramisu.error import PropertiesOptionError, ConfigError from tiramisu.option import OptionDescription, Option, SymLinkOption -from tiramisu.setting import groups, Settings, default_encoding, get_storage +from tiramisu.setting import groups, Settings, default_encoding +from tiramisu.storage import get_storage from tiramisu.value import Values from tiramisu.i18n import _ @@ -535,9 +536,9 @@ class Config(CommonConfig): :param persistent: if persistent, don't delete storage when leaving :type persistent: `boolean` """ - storage = get_storage(self, session_id, persistent) - self._impl_settings = Settings(self, storage) - self._impl_values = Values(self, storage) + settings, values = get_storage(self, session_id, persistent) + self._impl_settings = Settings(self, settings) + self._impl_values = Values(self, values) super(Config, self).__init__(descr, weakref.ref(self)) self._impl_build_all_paths() self._impl_meta = None @@ -575,9 +576,9 @@ class Config(CommonConfig): # child._impl_meta = self # self._impl_children = children -# storage = get_storage(self, session_id, persistent) -# self._impl_settings = Settings(self, storage) -# self._impl_values = Values(self, storage) +# settings, values = get_storage(self, session_id, persistent) +# self._impl_settings = Settings(self, settings) +# self._impl_values = Values(self, values) # self._impl_meta = None # def cfgimpl_get_children(self): diff --git a/tiramisu/option.py b/tiramisu/option.py index 6e4d9da..6d7f3b3 100644 --- a/tiramisu/option.py +++ b/tiramisu/option.py @@ -658,7 +658,7 @@ else: class SymLinkOption(BaseOption): - __slots__ = ('_name', '_opt', '_state_opt', '_consistencies') + __slots__ = ('_name', '_opt', '_state_opt') _opt_type = 'symlink' #not return _opt consistencies _consistencies = {} diff --git a/tiramisu/setting.py b/tiramisu/setting.py index 99fda6a..3c88c1c 100644 --- a/tiramisu/setting.py +++ b/tiramisu/setting.py @@ -24,7 +24,7 @@ from time import time from copy import copy import weakref from tiramisu.error import (RequirementError, PropertiesOptionError, - ConstError, ConfigError) + ConstError) from tiramisu.i18n import _ @@ -38,26 +38,6 @@ rw_append = set(['frozen', 'disabled', 'validator', 'hidden']) default_properties = ('expire', 'validator') -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: - self.storage_type = self.default_storage - 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)""" @@ -203,39 +183,6 @@ class Property(object): return str(list(self._properties)) -def set_storage(name, **args): - storage_type.set_storage(name) - settings = __import__(storage_type.get_storage(), globals(), locals(), - ['Setting']).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, persistent): - def gen_id(config): - return str(id(config)) + str(time()) - - if session_id is None: - session_id = gen_id(context) - return __import__(storage_type.get_storage(), globals(), locals(), - ['Storage']).Storage(session_id, persistent) - - -def list_sessions(): - return __import__(storage_type.get_storage(), globals(), locals(), - ['list_sessions']).list_sessions() - - -def delete_session(session_id): - return __import__(storage_type.get_storage(), globals(), locals(), - ['delete_session']).delete_session(session_id) - - #____________________________________________________________ class Settings(object): "``Config()``'s configuration options" @@ -254,9 +201,7 @@ class Settings(object): # generic owner self._owner = owners.user self.context = weakref.ref(context) - import_lib = 'tiramisu.storage.{0}.setting'.format(storage.storage) - self._p_ = __import__(import_lib, globals(), locals(), ['Settings'] - ).Settings(storage) + self._p_ = storage #____________________________________________________________ # properties methods diff --git a/tiramisu/storage/__init__.py b/tiramisu/storage/__init__.py index e69de29..5476f26 100644 --- a/tiramisu/storage/__init__.py +++ b/tiramisu/storage/__init__.py @@ -0,0 +1,90 @@ +# Copyright (C) 2013 Team tiramisu (see AUTHORS for all contributors) +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# The original `Config` design model is unproudly borrowed from +# the rough gus of pypy: pypy: http://codespeak.net/svn/pypy/dist/pypy/config/ +# the whole pypy projet is under MIT licence +# ____________________________________________________________ + +"""Storage connections, executions and managements. + +Storage is basic components used to set informations in DB +""" + + +from time import time +from tiramisu.error import ConfigError +from tiramisu.i18n import _ + + +class StorageType(object): + default_storage = 'dictionary' + storage_type = None + mod = None + + def set(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(self): + if self.storage_type is None: + self.storage_type = self.default_storage + storage = self.storage_type + if self.mod is None: + modulepath = 'tiramisu.storage.{0}'.format(storage) + mod = __import__(modulepath) + for token in modulepath.split(".")[1:]: + mod = getattr(mod, token) + self.mod = mod + return self.mod + + +storage_type = StorageType() + + +def set_storage(name, **args): + storage_type.set(name) + settings = storage_type.get().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, persistent): + def gen_id(config): + return str(id(config)) + str(time()) + + if session_id is None: + session_id = gen_id(context) + imp = storage_type.get() + storage = imp.Storage(session_id, persistent) + return imp.Settings(storage), imp.Values(storage) + + +def list_sessions(): + return storage_type.get().list_sessions() + + +def delete_session(session_id): + return storage_type.get().delete_session(session_id) + + +#__all__ = (,) diff --git a/tiramisu/storage/dictionary/__init__.py b/tiramisu/storage/dictionary/__init__.py index e69de29..a53e505 100644 --- a/tiramisu/storage/dictionary/__init__.py +++ b/tiramisu/storage/dictionary/__init__.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +"default plugin for storage: set it in a simple dictionary" +# Copyright (C) 2013 Team tiramisu (see AUTHORS for all contributors) +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# ____________________________________________________________ +from .value import Values +from .setting import Settings +from .storage import Storage, list_sessions, delete_session + +__all__ = (Values, Settings, Storage, list_sessions, delete_session) diff --git a/tiramisu/storage/dictionary/cache.py b/tiramisu/storage/dictionary/cache.py new file mode 100644 index 0000000..664990d --- /dev/null +++ b/tiramisu/storage/dictionary/cache.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +"default plugin for cache: set it in a simple dictionary" +# Copyright (C) 2013 Team tiramisu (see AUTHORS for all contributors) +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# ____________________________________________________________ + + +class Cache(object): + __slots__ = ('_cache', 'storage') + key_is_path = False + + def __init__(self, storage): + self._cache = {} + self.storage = storage + + def setcache(self, cache_type, path, val, time): + self._cache[path] = (val, time) + + def getcache(self, cache_type, path, exp): + value, created = self._cache[path] + if exp < created: + return True, value + return False, None + + def hascache(self, cache_type, path): + """ path is in the cache + + :param cache_type: value | property + :param path: the path's option + """ + return path in self._cache + + def reset_expired_cache(self, cache_type, exp): + for key in tuple(self._cache.keys()): + val, created = self._cache[key] + if exp > created: + del(self._cache[key]) + + def reset_all_cache(self, cache_type): + "empty the cache" + self._cache.clear() + + def get_cached(self, cache_type, context): + """return all values in a dictionary + example: {'path1': ('value1', 'time1'), 'path2': ('value2', 'time2')} + """ + return self._cache diff --git a/tiramisu/storage/dictionary/setting.py b/tiramisu/storage/dictionary/setting.py index 580cba3..ea59513 100644 --- a/tiramisu/storage/dictionary/setting.py +++ b/tiramisu/storage/dictionary/setting.py @@ -17,7 +17,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # ____________________________________________________________ -from tiramisu.storage.dictionary.storage import Cache +from .cache import Cache class Settings(Cache): diff --git a/tiramisu/storage/dictionary/storage.py b/tiramisu/storage/dictionary/storage.py index d4904c6..5442c5d 100644 --- a/tiramisu/storage/dictionary/storage.py +++ b/tiramisu/storage/dictionary/storage.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -"default plugin for cache: set it in a simple dictionary" +"default plugin for storage: set it in a simple dictionary" # Copyright (C) 2013 Team tiramisu (see AUTHORS for all contributors) # # This program is free software; you can redistribute it and/or modify @@ -38,7 +38,7 @@ def delete_session(session_id): class Storage(object): - __slots__ = ('session_id',) + __slots__ = ('session_id', 'values', 'settings') storage = 'dictionary' def __init__(self, session_id, persistent): @@ -54,45 +54,3 @@ class Storage(object): _list_sessions.remove(self.session_id) except AttributeError: pass - - -class Cache(object): - __slots__ = ('_cache', 'storage') - key_is_path = False - - def __init__(self, storage): - self._cache = {} - self.storage = storage - - def setcache(self, cache_type, path, val, time): - self._cache[path] = (val, time) - - def getcache(self, cache_type, path, exp): - value, created = self._cache[path] - if exp < created: - return True, value - return False, None - - def hascache(self, cache_type, path): - """ path is in the cache - - :param cache_type: value | property - :param path: the path's option - """ - return path in self._cache - - def reset_expired_cache(self, cache_type, exp): - for key in tuple(self._cache.keys()): - val, created = self._cache[key] - if exp > created: - del(self._cache[key]) - - def reset_all_cache(self, cache_type): - "empty the cache" - self._cache.clear() - - def get_cached(self, cache_type, context): - """return all values in a dictionary - example: {'path1': ('value1', 'time1'), 'path2': ('value2', 'time2')} - """ - return self._cache diff --git a/tiramisu/storage/dictionary/value.py b/tiramisu/storage/dictionary/value.py index c1bf2eb..ed1017e 100644 --- a/tiramisu/storage/dictionary/value.py +++ b/tiramisu/storage/dictionary/value.py @@ -18,7 +18,7 @@ # # ____________________________________________________________ -from tiramisu.storage.dictionary.storage import Cache +from .cache import Cache class Values(Cache): diff --git a/tiramisu/storage/sqlite3/__init__.py b/tiramisu/storage/sqlite3/__init__.py index e69de29..adcdfdc 100644 --- a/tiramisu/storage/sqlite3/__init__.py +++ b/tiramisu/storage/sqlite3/__init__.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +"set storage in sqlite3" +# Copyright (C) 2013 Team tiramisu (see AUTHORS for all contributors) +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# ____________________________________________________________ +from .value import Values +from .setting import Settings +from .storage import Storage, list_sessions, delete_session + +__all__ = (Values, Settings, Storage, list_sessions, delete_session) diff --git a/tiramisu/storage/sqlite3/cache.py b/tiramisu/storage/sqlite3/cache.py new file mode 100644 index 0000000..183c4d0 --- /dev/null +++ b/tiramisu/storage/sqlite3/cache.py @@ -0,0 +1,98 @@ +# -*- coding: utf-8 -*- +"sqlite3 cache" +# Copyright (C) 2013 Team tiramisu (see AUTHORS for all contributors) +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# ____________________________________________________________ +from pickle import dumps, loads + + +class Cache(object): + __slots__ = ('storage',) + key_is_path = True + + def __init__(self, cache_type, storage): + self.storage = storage + cache_table = 'CREATE TABLE IF NOT EXISTS cache_{0}(path '.format( + cache_type) + cache_table += 'text primary key, value text, time real)' + self.storage.execute(cache_table) + + # value + def _sqlite_decode_path(self, path): + if path == '_none': + return None + else: + return path + + def _sqlite_encode_path(self, path): + if path is None: + return '_none' + else: + return path + + def _sqlite_decode(self, value): + return loads(value) + + def _sqlite_encode(self, value): + if isinstance(value, list): + value = list(value) + return dumps(value) + + def setcache(self, cache_type, path, val, time): + convert_value = self._sqlite_encode(val) + path = self._sqlite_encode_path(path) + self.storage.execute("DELETE FROM cache_{0} WHERE path = ?".format( + cache_type), (path,), False) + self.storage.execute("INSERT INTO cache_{0}(path, value, time) " + "VALUES (?, ?, ?)".format(cache_type), + (path, convert_value, time)) + + def getcache(self, cache_type, path, exp): + path = self._sqlite_encode_path(path) + cached = self.storage.select("SELECT value FROM cache_{0} WHERE " + "path = ? AND time >= ?".format( + cache_type), (path, exp)) + if cached is None: + return False, None + else: + return True, self._sqlite_decode(cached[0]) + + def hascache(self, cache_type, path): + path = self._sqlite_encode_path(path) + return self.storage.select("SELECT value FROM cache_{0} WHERE " + "path = ?".format(cache_type), + (path,)) is not None + + def reset_expired_cache(self, cache_type, exp): + self.storage.execute("DELETE FROM cache_{0} WHERE time < ?".format( + cache_type), (exp,)) + + def reset_all_cache(self, cache_type): + self.storage.execute("DELETE FROM cache_{0}".format(cache_type)) + + def get_cached(self, cache_type, context): + """return all values in a dictionary + example: {'path1': ('value1', 'time1'), 'path2': ('value2', 'time2')} + """ + ret = {} + for path, value, time in self.storage.select("SELECT * FROM cache_{0}" + "".format(cache_type), + only_one=False): + path = self._sqlite_decode_path(path) + value = self._sqlite_decode(value) + ret[path] = (value, time) + return ret diff --git a/tiramisu/storage/sqlite3/setting.py b/tiramisu/storage/sqlite3/setting.py index f91f9fd..11506bb 100644 --- a/tiramisu/storage/sqlite3/setting.py +++ b/tiramisu/storage/sqlite3/setting.py @@ -17,7 +17,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # ____________________________________________________________ -from tiramisu.storage.sqlite3.storage import Cache +from .cache import Cache class Settings(Cache): diff --git a/tiramisu/storage/sqlite3/storage.py b/tiramisu/storage/sqlite3/storage.py index d855c88..ed5abd9 100644 --- a/tiramisu/storage/sqlite3/storage.py +++ b/tiramisu/storage/sqlite3/storage.py @@ -18,7 +18,6 @@ # # ____________________________________________________________ -from pickle import dumps, loads from os import unlink from os.path import basename, splitext, join import sqlite3 @@ -79,81 +78,3 @@ class Storage(object): self._conn.close() if not self.persistent: delete_session(self._session_id) - - -class Cache(object): - __slots__ = ('storage',) - key_is_path = True - - def __init__(self, cache_type, storage): - self.storage = storage - cache_table = 'CREATE TABLE IF NOT EXISTS cache_{0}(path '.format( - cache_type) - cache_table += 'text primary key, value text, time real)' - self.storage.execute(cache_table) - - # value - def _sqlite_decode_path(self, path): - if path == '_none': - return None - else: - return path - - def _sqlite_encode_path(self, path): - if path is None: - return '_none' - else: - return path - - def _sqlite_decode(self, value): - return loads(value) - - def _sqlite_encode(self, value): - if isinstance(value, list): - value = list(value) - return dumps(value) - - def setcache(self, cache_type, path, val, time): - convert_value = self._sqlite_encode(val) - path = self._sqlite_encode_path(path) - self.storage.execute("DELETE FROM cache_{0} WHERE path = ?".format( - cache_type), (path,), False) - self.storage.execute("INSERT INTO cache_{0}(path, value, time) " - "VALUES (?, ?, ?)".format(cache_type), - (path, convert_value, time)) - - def getcache(self, cache_type, path, exp): - path = self._sqlite_encode_path(path) - cached = self.storage.select("SELECT value FROM cache_{0} WHERE " - "path = ? AND time >= ?".format( - cache_type), (path, exp)) - if cached is None: - return False, None - else: - return True, self._sqlite_decode(cached[0]) - - def hascache(self, cache_type, path): - path = self._sqlite_encode_path(path) - return self.storage.select("SELECT value FROM cache_{0} WHERE " - "path = ?".format(cache_type), - (path,)) is not None - - def reset_expired_cache(self, cache_type, exp): - self.storage.execute("DELETE FROM cache_{0} WHERE time < ?".format( - cache_type), (exp,)) - - def reset_all_cache(self, cache_type): - self.storage.execute("DELETE FROM cache_{0}".format(cache_type)) - - def get_cached(self, cache_type, context): - """return all values in a dictionary - example: {'path1': ('value1', 'time1'), 'path2': ('value2', 'time2')} - """ - ret = {} - for path, value, time in self.storage.select("SELECT * FROM cache_{0}" - "".format(cache_type), - only_one=False): - path = self._sqlite_decode_path(path) - value = self._sqlite_decode(value) - ret[path] = (value, time) - return ret diff --git a/tiramisu/storage/sqlite3/value.py b/tiramisu/storage/sqlite3/value.py index 2b9ddc7..687e7dd 100644 --- a/tiramisu/storage/sqlite3/value.py +++ b/tiramisu/storage/sqlite3/value.py @@ -18,7 +18,7 @@ # # ____________________________________________________________ -from tiramisu.storage.sqlite3.storage import Cache +from .cache import Cache from tiramisu.setting import owners diff --git a/tiramisu/value.py b/tiramisu/value.py index b401634..f35c16d 100644 --- a/tiramisu/value.py +++ b/tiramisu/value.py @@ -44,9 +44,7 @@ class Values(object): """ self.context = weakref.ref(context) # the storage type is dictionary or sqlite3 - import_lib = 'tiramisu.storage.{0}.value'.format(storage.storage) - self._p_ = __import__(import_lib, globals(), locals(), ['Values'], - ).Values(storage) + self._p_ = storage def _getdefault(self, opt): """