1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
"""
This module defines a singleton configurator object with a single
public method .get_uri(alias).
When .get_uri is called, the environment variable $SQLPLAIN is looked at.
It should contain the name of a configuration file. If $SQLPLAIN is missing,
the configuration file name is assumed to be ~/.sqlplain. The configuration
file must exists and must contain a section [uri] as follows:
[uri]
dev: mssql://user:passwd@host:port/dev_db
test: mssql://user:passwd@host:port/test_db
prod: mssql://user:passwd@host:port/prod_db
Then .get_alias('dev') returns the URI mssql://user:passwd@host:port/dev_db.
Analogously for 'test' and 'prod'.
The configuration file may also contain a [dir] section specifying the
full pathname for the directory containing the creational scripts of
the corresponding database.
"""
import os
from ConfigParser import RawConfigParser # no magic interpolation
class ReadOnlyObject(object):
"""
Take a list [(name, value), ...] and returns a read-only object
with associated attributes. The names cannot be private. The ordering
is preserved in the list ._names. The object has a ._name attribute
useful for debugging (the default is 'anonymous').
"""
def __init__(self, items, name='anonymous'):
names = []
for name, value in items:
if name.startswith('_'):
raise TypeError('Inner attributes cannot begin with "_"')
object.__setattr__(self, name, value)
names.append(name)
object.__setattr__(self, '_names', names)
object.__setattr__(self, '_name', name)
def __iter__(self):
for name in self._names:
yield name, getattr(self, name)
def __contains__(self, name):
return name in self._names
def __len__(self):
return self(self._names)
def __setattr__(self, name, value):
if name in self._dic:
raise TypeError('Read-only object!')
else:
object.__setattr__(self, name, value)
def __str__(self):
return '\n'.join('%s=%s' % (k, v) for k, v in self)
def __repr__(self):
return '<%s:%s>' % (self.__class__.__name__, self._name)
class _Configurator(object): # singleton
_initialized = False
def _initialize(self):
"You may want to call this again if you modify the config file"
cfp = RawConfigParser()
self._conf_file = os.environ.get(
'SQLPLAIN', os.path.expanduser('~/.sqlplain'))
cfp.readfp(file(self._conf_file))
self._conf_obj = ReadOnlyObject(
[(sect, ReadOnlyObject(cfp.items(sect), sect))
for sect in cfp.sections()], self._conf_file)
self._initialized = True
self._databases = self._conf_obj.uri._names
def __getattr__(self, name):
if not self._initialized:
self._initialize()
return getattr(self._conf_obj, name)
configurator = _Configurator()
|