update doc
This commit is contained in:
parent
3dc72c505c
commit
28ea4f0e90
11 changed files with 355 additions and 27 deletions
|
@ -11,4 +11,5 @@ Auto generated library's API
|
|||
tiramisu.value
|
||||
tiramisu.autolib
|
||||
tiramisu.error
|
||||
tiramisu.storage
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ A requirement is a list of dictionaries that have fairly this form::
|
|||
'transitive':True, 'same_action': True}]
|
||||
|
||||
Actually a transformation is made to this dictionary during the validation of
|
||||
this requires at the :class:`~option.Option()`'s init. The dictionairy becomes
|
||||
this requires at the :class:`~option.Option()`'s init. The dictionary becomes
|
||||
a tuple, wich is passed to the :meth:`~setting.Settings.apply_requires()`
|
||||
method. Take a look at the code to fully understand the exact meaning of the
|
||||
requirements:
|
||||
|
@ -103,7 +103,6 @@ hidden any more::
|
|||
['hidden']
|
||||
>>> print c.od1.var1
|
||||
Traceback (most recent call last):
|
||||
[...]
|
||||
tiramisu.error.PropertiesOptionError: trying to access to an option named:
|
||||
var1 with properties ['hidden']
|
||||
>>> c.od1.var2 = u'oui'
|
||||
|
@ -123,7 +122,6 @@ document.)::
|
|||
>>> c.od1.var2 = u'non'
|
||||
>>> print c.od2.var4
|
||||
Traceback (most recent call last):
|
||||
[...]
|
||||
tiramisu.error.PropertiesOptionError: trying to access to an option named: od2 with properties ['hidden']
|
||||
>>> c.od1.var2 = u'oui'
|
||||
>>> print c.od2.var4
|
||||
|
@ -144,21 +142,20 @@ Requirements can be accumulated for different or identical properties (inverted
|
|||
or not)::
|
||||
|
||||
>>> a = UnicodeOption('var3', '', u'value', requires=[{'option':od1.var2,
|
||||
'expected':'non', 'action':'hidden'}, {'option':od1.var1, 'expected':'oui',
|
||||
'action':'hidden'}])
|
||||
... 'expected':'non', 'action':'hidden'}, {'option':od1.var1, 'expected':'oui',
|
||||
... 'action':'hidden'}])
|
||||
>>> a = UnicodeOption('var3', '', u'value', requires=[{'option':od1.var2,
|
||||
'expected':'non', 'action':'hidden'}, {'option':od1.var1, 'excepted':'oui',
|
||||
'action':'disabled', 'inverse':True}])
|
||||
... 'expected':'non', 'action':'hidden'}, {'option':od1.var1, 'excepted':'oui',
|
||||
... 'action':'disabled', 'inverse':True}])
|
||||
|
||||
But it is not possible to have inverted requirements on the same property.
|
||||
Here is an impossible situation::
|
||||
|
||||
>>> a = UnicodeOption('var3', '', u'value', requires=[{'option':od1.var2,
|
||||
'expected':'non', 'action':'hidden'}, {'option':od1.var1, 'expected':'oui',
|
||||
'hidden', True}])
|
||||
... 'expected':'non', 'action':'hidden'}, {'option':od1.var1, 'expected':'oui',
|
||||
... 'hidden', True}])
|
||||
|
||||
Traceback (most recent call last):
|
||||
[...]
|
||||
ValueError: inconsistency in action types for option: var3 action: hidden
|
||||
|
||||
Validation upon a whole configuration object
|
||||
|
@ -184,11 +181,8 @@ Let's define validator (wich is a normal python function)::
|
|||
Here is an option wich uses this validator::
|
||||
|
||||
>>> var1 = UnicodeOption('var1', '', u'oui', validator=valid_a, validator_args={'letter': 'o'})
|
||||
>>>
|
||||
>>> od1 = OptionDescription('od1', '', [var1])
|
||||
>>>
|
||||
>>> rootod = OptionDescription('rootod', '', [od1])
|
||||
>>>
|
||||
>>> c = Config(rootod)
|
||||
>>> c.read_write()
|
||||
|
||||
|
@ -196,11 +190,10 @@ The validation is applied at the modification time::
|
|||
|
||||
>>> c.od1.var1 = u'non'
|
||||
Traceback (most recent call last):
|
||||
[...]
|
||||
ValueError: invalid value non for option var1
|
||||
>>> c.od1.var1 = u'oh non'
|
||||
|
||||
Il est possible de désactiver la validation :
|
||||
You can disabled this validation::
|
||||
|
||||
>>> c.cfgimpl_get_settings().remove('validator')
|
||||
>>> c.od1.var1 = u'non'
|
||||
|
|
|
@ -33,6 +33,7 @@ controlling options explanations
|
|||
|
||||
getting-started
|
||||
config
|
||||
storage
|
||||
option
|
||||
status
|
||||
consistency
|
||||
|
|
BIN
doc/storage.png
Normal file
BIN
doc/storage.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
265
doc/storage.svg
Normal file
265
doc/storage.svg
Normal file
|
@ -0,0 +1,265 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="400"
|
||||
height="200"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
sodipodi:docname="test.svg"
|
||||
inkscape:export-filename="/home/gnunux/git/tiramisu/doc/storage.png"
|
||||
inkscape:export-xdpi="135"
|
||||
inkscape:export-ydpi="135">
|
||||
<defs
|
||||
id="defs4">
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 526.18109 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="744.09448 : 526.18109 : 1"
|
||||
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
|
||||
id="perspective3827" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="1"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1"
|
||||
inkscape:cx="106.95445"
|
||||
inkscape:cy="208.15932"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1600"
|
||||
inkscape:window-height="841"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Calque 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-852.36218)">
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 235.5,78.588237 306,109"
|
||||
id="path4403"
|
||||
inkscape:connector-type="polyline"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:connection-start="#g4211"
|
||||
inkscape:connection-start-point="d4"
|
||||
transform="translate(0,852.36218)" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 235.5,131.08416 305,107"
|
||||
id="path4405"
|
||||
inkscape:connector-type="polyline"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:connection-start="#g4216"
|
||||
inkscape:connection-start-point="d4"
|
||||
transform="translate(0,852.36218)" />
|
||||
<g
|
||||
id="g4206"
|
||||
transform="translate(-17,590)">
|
||||
<text
|
||||
sodipodi:linespacing="686.00001%"
|
||||
id="text2985"
|
||||
y="368.36218"
|
||||
x="98"
|
||||
style="font-size:10px;font-style:normal;font-weight:normal;line-height:686.00001335%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
xml:space="preserve"><tspan
|
||||
y="368.36218"
|
||||
x="98"
|
||||
id="tspan2987"
|
||||
sodipodi:role="line">Config</tspan></text>
|
||||
<rect
|
||||
y="351.36218"
|
||||
x="81"
|
||||
height="30"
|
||||
width="63"
|
||||
id="rect3757"
|
||||
style="fill:none;stroke:#000000;stroke-linejoin:round;stroke-opacity:1" />
|
||||
</g>
|
||||
<g
|
||||
id="g4211"
|
||||
transform="translate(-17,590)">
|
||||
<rect
|
||||
y="312.36218"
|
||||
x="189.5"
|
||||
height="30"
|
||||
width="63"
|
||||
id="rect3757-2"
|
||||
style="fill:none;stroke:#000000;stroke-linejoin:round;stroke-opacity:1" />
|
||||
<text
|
||||
sodipodi:linespacing="686.00001%"
|
||||
id="text3777"
|
||||
y="330.36218"
|
||||
x="206"
|
||||
style="font-size:10px;font-style:normal;font-weight:normal;line-height:686.00001335%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
xml:space="preserve"><tspan
|
||||
y="330.36218"
|
||||
x="206"
|
||||
id="tspan3779"
|
||||
sodipodi:role="line">Values</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
id="g4216"
|
||||
transform="translate(-17,590)">
|
||||
<rect
|
||||
y="389.36218"
|
||||
x="189.5"
|
||||
height="30"
|
||||
width="63"
|
||||
id="rect3757-4"
|
||||
style="fill:none;stroke:#000000;stroke-linejoin:round;stroke-opacity:1" />
|
||||
<text
|
||||
sodipodi:linespacing="686.00001%"
|
||||
id="text3799"
|
||||
y="407.36218"
|
||||
x="200"
|
||||
style="font-size:10px;font-style:normal;font-weight:normal;line-height:686.00001335%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
xml:space="preserve"><tspan
|
||||
y="407.36218"
|
||||
x="200"
|
||||
id="tspan3801"
|
||||
sodipodi:role="line">Settings</tspan></text>
|
||||
</g>
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 127,967.39444 45.5,15.93548"
|
||||
id="path4028"
|
||||
inkscape:connector-type="polyline"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 127,945.0396 45.5,-16.35484"
|
||||
id="path4030"
|
||||
inkscape:connector-type="polyline"
|
||||
inkscape:connector-curvature="0" />
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none"
|
||||
id="rect4161"
|
||||
width="55.5"
|
||||
height="26"
|
||||
x="277.5"
|
||||
y="946.36218" />
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="fill:none;stroke:#000000;stroke-width:1.96347165;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
id="path3843"
|
||||
sodipodi:cx="401"
|
||||
sodipodi:cy="334.86218"
|
||||
sodipodi:rx="38"
|
||||
sodipodi:ry="10.5"
|
||||
d="m 439,334.86218 a 38,10.5 0 1 1 -76,0 38,10.5 0 1 1 76,0 z"
|
||||
transform="matrix(0.71325325,0,0,0.57998971,18.66254,749.17042)" />
|
||||
<path
|
||||
transform="matrix(0.71325325,0,0,0.57998971,18.57337,775.05247)"
|
||||
sodipodi:type="arc"
|
||||
style="fill:none;stroke:#000000;stroke-width:1.96347165;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
id="path3843-3"
|
||||
sodipodi:cx="401"
|
||||
sodipodi:cy="334.86218"
|
||||
sodipodi:rx="38"
|
||||
sodipodi:ry="10.5"
|
||||
d="m 439,334.86218 a 38,10.5 0 1 1 -76,0 38,10.5 0 1 1 76,0 z" />
|
||||
<path
|
||||
transform="matrix(0.71325325,0,0,0.57998971,18.52879,762.07519)"
|
||||
sodipodi:type="arc"
|
||||
style="fill:none;stroke:#000000;stroke-width:1.96347165;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
id="path3843-3-0"
|
||||
sodipodi:cx="401"
|
||||
sodipodi:cy="334.86218"
|
||||
sodipodi:rx="38"
|
||||
sodipodi:ry="10.5"
|
||||
d="m 439,334.86218 a 38,10.5 0 1 1 -76,0 38,10.5 0 1 1 76,0 z" />
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none"
|
||||
id="rect3883"
|
||||
width="62.989182"
|
||||
height="6.7061315"
|
||||
x="274.72043"
|
||||
y="949.91193" />
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none"
|
||||
id="rect3883-3"
|
||||
width="58.087975"
|
||||
height="6.4161367"
|
||||
x="277.34818"
|
||||
y="962.78046" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1.26286423;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
|
||||
d="m 277.52869,943.35095 -0.0442,26.02673"
|
||||
id="path3917"
|
||||
inkscape:connector-type="polyline"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1.26286423;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
|
||||
d="m 331.64698,969.26909 0.13377,-26.17203"
|
||||
id="path3921"
|
||||
inkscape:connector-type="polyline"
|
||||
inkscape:connector-curvature="0" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:10px;font-style:normal;font-weight:normal;line-height:686.00001335%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
x="286.33643"
|
||||
y="958.32324"
|
||||
id="text3821"
|
||||
sodipodi:linespacing="686.00001%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3823"
|
||||
x="286.33643"
|
||||
y="958.32324">Storage</tspan></text>
|
||||
<g
|
||||
id="g4201"
|
||||
transform="translate(-17,590)">
|
||||
<rect
|
||||
y="293.42468"
|
||||
x="81"
|
||||
height="30"
|
||||
width="63"
|
||||
id="rect3757-5"
|
||||
style="fill:none;stroke:#000000;stroke-linejoin:round;stroke-opacity:1" />
|
||||
<text
|
||||
sodipodi:linespacing="100%"
|
||||
id="text4190"
|
||||
y="309.42468"
|
||||
x="110.27588"
|
||||
style="font-size:10px;font-style:normal;font-weight:normal;text-align:center;line-height:100%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
xml:space="preserve"><tspan
|
||||
id="tspan4194"
|
||||
y="309.42468"
|
||||
x="110.27588"
|
||||
sodipodi:role="line">Option</tspan></text>
|
||||
</g>
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 95.5,913.42468 0,27.9375"
|
||||
id="path4199"
|
||||
inkscape:connector-type="polyline"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 9.4 KiB |
52
doc/storage.txt
Normal file
52
doc/storage.txt
Normal file
|
@ -0,0 +1,52 @@
|
|||
Storage
|
||||
=======
|
||||
|
||||
Config's informations are, by default, volatiles. This means, all values and
|
||||
settings changes will be lost.
|
||||
|
||||
The storage is the system Tiramisu uses to communicate with various DB.
|
||||
You can specified a persistent storage.
|
||||
|
||||
.. image:: storage.png
|
||||
|
||||
.. automodule:: tiramisu.storage
|
||||
|
||||
.. automethod:: tiramisu.storage.set_storage
|
||||
|
||||
Dictionary
|
||||
~~~~~~~~~~
|
||||
|
||||
.. automodule:: tiramisu.storage.dictionary
|
||||
|
||||
Dictionary settings:
|
||||
|
||||
.. automethod:: tiramisu.storage.dictionary.storage.Setting
|
||||
|
||||
Sqlite3
|
||||
~~~~~~~
|
||||
|
||||
.. automodule:: tiramisu.storage.sqlite3
|
||||
|
||||
Sqlite3 settings:
|
||||
|
||||
.. automethod:: tiramisu.storage.sqlite3.storage.Setting
|
||||
|
||||
Example
|
||||
~~~~~~~
|
||||
|
||||
>>> from tiramisu.option import StrOption, OptionDescription
|
||||
>>> from tiramisu.config import Config
|
||||
>>> from tiramisu.storage import set_storage
|
||||
>>> set_storage('sqlite3', dir_database='/tmp/tiramisu')
|
||||
>>> s = StrOption('str', '')
|
||||
>>> o = OptionDescription('od', '', [s])
|
||||
>>> c1 = Config(o, persistent=True, session_id='xxxx')
|
||||
>>> c1.str
|
||||
>>> c1.str = 'yes'
|
||||
>>> c1.str
|
||||
'yes'
|
||||
>>> del(c1)
|
||||
>>> c2 = Config(o, persistent=True, session_id='xxxx')
|
||||
>>> c2.str
|
||||
'yes'
|
||||
|
|
@ -19,11 +19,9 @@
|
|||
# the whole pypy projet is under MIT licence
|
||||
# ____________________________________________________________
|
||||
|
||||
"""Storage connections, executions and managements.
|
||||
|
||||
Storage is basic components used to set Config informations in DB.
|
||||
The primary "entry point" class into this package is the StorageType and it's
|
||||
public configurator ``set_storage()``.
|
||||
"""Storage is basic components used to set Config informations in DB.
|
||||
The primary "entry point" class is the StorageType and it's public
|
||||
configurator ``set_storage()``.
|
||||
"""
|
||||
|
||||
|
||||
|
@ -43,6 +41,8 @@ class StorageType(object):
|
|||
|
||||
def set(self, name):
|
||||
if self.storage_type is not None:
|
||||
if self.storage_type == name:
|
||||
return
|
||||
raise ConfigError(_('storage_type is already set, cannot rebind it'))
|
||||
self.storage_type = name
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# -*- 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
|
||||
|
@ -17,8 +16,16 @@
|
|||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
# ____________________________________________________________
|
||||
"""Default plugin for storage. All informations are store in a simple
|
||||
dictionary in memory.
|
||||
|
||||
You cannot have persistente informations with this kind of storage.
|
||||
|
||||
The advantage of this solution is that you can easily create a Config and
|
||||
use it. But if something goes wrong, you will lost your modifications.
|
||||
"""
|
||||
from .value import Values
|
||||
from .setting import Settings
|
||||
from .storage import Storage, list_sessions, delete_session
|
||||
from .storage import Setting, Storage, list_sessions, delete_session
|
||||
|
||||
__all__ = (Values, Settings, Storage, list_sessions, delete_session)
|
||||
__all__ = (Setting, Values, Settings, Storage, list_sessions, delete_session)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# -*- 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
|
||||
|
@ -22,6 +21,8 @@ from tiramisu.error import ConfigError
|
|||
|
||||
|
||||
class Setting(object):
|
||||
"""Dictionary storage has no particular setting.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# -*- 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
|
||||
|
@ -17,8 +16,14 @@
|
|||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
# ____________________________________________________________
|
||||
"""Sqlite3 plugin for storage. This storage is not made to be used in productive
|
||||
environment. It was developing as proof of concept.
|
||||
|
||||
You should not configure differents Configs with same session_id.
|
||||
|
||||
"""
|
||||
from .value import Values
|
||||
from .setting import Settings
|
||||
from .storage import Storage, list_sessions, delete_session
|
||||
from .storage import Setting, Storage, list_sessions, delete_session
|
||||
|
||||
__all__ = (Values, Settings, Storage, list_sessions, delete_session)
|
||||
__all__ = (Setting, Values, Settings, Storage, list_sessions, delete_session)
|
||||
|
|
|
@ -25,6 +25,9 @@ from glob import glob
|
|||
|
||||
|
||||
class Setting(object):
|
||||
""":param extension: database file extension (by default: db)
|
||||
:param dir_database: root database directory (by default: /tmp)
|
||||
"""
|
||||
extension = 'db'
|
||||
dir_database = '/tmp'
|
||||
|
||||
|
|
Loading…
Reference in a new issue