storage no more in setting.py, code is now in storage/__init__.py
This commit is contained in:
parent
18fc5db4ac
commit
22bfbb9fa4
17 changed files with 437 additions and 196 deletions
121
test/test_state.py
Normal file
121
test/test_state.py
Normal file
|
@ -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)
|
|
@ -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():
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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 = {}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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__ = (,)
|
|
@ -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)
|
61
tiramisu/storage/dictionary/cache.py
Normal file
61
tiramisu/storage/dictionary/cache.py
Normal file
|
@ -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
|
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#
|
||||
# ____________________________________________________________
|
||||
|
||||
from tiramisu.storage.dictionary.storage import Cache
|
||||
from .cache import Cache
|
||||
|
||||
|
||||
class Values(Cache):
|
||||
|
|
|
@ -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)
|
98
tiramisu/storage/sqlite3/cache.py
Normal file
98
tiramisu/storage/sqlite3/cache.py
Normal file
|
@ -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
|
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#
|
||||
# ____________________________________________________________
|
||||
|
||||
from tiramisu.storage.sqlite3.storage import Cache
|
||||
from .cache import Cache
|
||||
from tiramisu.setting import owners
|
||||
|
||||
|
||||
|
|
|
@ -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):
|
||||
"""
|
||||
|
|
Loading…
Reference in a new issue