aboutsummaryrefslogtreecommitdiff
path: root/dodai/config/db/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'dodai/config/db/__init__.py')
-rw-r--r--dodai/config/db/__init__.py179
1 files changed, 179 insertions, 0 deletions
diff --git a/dodai/config/db/__init__.py b/dodai/config/db/__init__.py
new file mode 100644
index 0000000..fa510ac
--- /dev/null
+++ b/dodai/config/db/__init__.py
@@ -0,0 +1,179 @@
1# Copyright (C) 2010 Leonard Thomas
2#
3# This file is part of Dodai.
4#
5# Dodai is free software: you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation, either version 3 of the License, or
8# (at your option) any later version.
9#
10# Dodai is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with Dodai. If not, see <http://www.gnu.org/licenses/>.
17
18class ConfigDb(object):
19
20 def __init__(self):
21 self.connections = {}
22 self._handlers = {}
23 from dodai.config.db.sa import Sa
24 self.register_handler('sa', Sa)
25
26 def register_handler(self, name, obj):
27 self._handlers[name] = [obj, None]
28
29 def add_config(self, config_parser=None):
30 if config_parser:
31 if hasattr(config_parser, 'sections') and \
32 hasattr(config_parser, 'options'):
33 config_obj = ConfigDbFile(config_parser)
34 self._add_connections(config_obj)
35 else:
36 raise NotConfigParserObject()
37
38 def _add_connections(self, config_obj):
39 connections = config_obj()
40 for name, obj in connections.items():
41 self.connections[name] = obj
42
43 def load(self, name):
44 if name in self.connections:
45 connection = self.connections[name]
46 if connection.db_obj:
47 return connection.db_obj
48 else:
49 handler = self._load_handler(connection.handler)
50 db_obj = handler.load(connection)
51 self.connections[name].db_obj = db_obj
52 return db_obj
53
54 def _load_handler(self, name):
55 if name in self._handlers:
56 handler = self._handlers[name]
57 cls = handler[0]
58 obj = handler[1]
59 if not obj:
60 obj = cls()
61 self._handlers[name] = [cls, obj]
62 return obj
63 raise UnknownHandlerException(name)
64
65
66
67class ConfigDbFile(object):
68
69 OPTIONS_REQUIRED = [
70 ['protocol', 'hostname', 'port', 'username', 'password','database'],
71 ['protocol', 'filename']
72 ]
73 OPTIONS_EXTRA = ['protocol_extra', 'handler']
74 DEFAULT_HANDLER = 'sa'
75
76 def __init__(self, config_parser):
77 self.parser = config_parser
78 self._options = self._all_options()
79 self.connections = {}
80
81 def __call__(self):
82 if not self.connections:
83 for section in self.parser.sections():
84 if self._is_valid(section):
85 obj = self._build_connection(section)
86 self.connections[obj.name] = obj
87 return self.connections
88
89 def _all_options(self):
90 out = []
91 for option_group in self.OPTIONS_REQUIRED:
92 for option in option_group:
93 if option not in out:
94 out.append(option)
95 for option in self.OPTIONS_EXTRA:
96 if option not in out:
97 out.append(option)
98 return out
99
100 def _is_valid(self, section):
101 for option_group in self.OPTIONS_REQUIRED:
102 total = len(option_group)
103 count = 0
104 for option in option_group:
105 if option in self.parser.options(section):
106 value = self.parser.get(section, option)
107 if value:
108 count += 1
109 if count >= total:
110 return True
111 return False
112
113 def _build_connection(self, section):
114 obj = ConfigDbConnection()
115 for option in self._options:
116 obj.name = section
117 if self.parser.has_option(section, option):
118 value = self.parser.get(section, option)
119 setattr(obj, option, value)
120 if not hasattr(obj, 'handler') or not obj.handler:
121 obj.handler = self.DEFAULT_HANDLER
122 return obj
123
124
125class BaseConfigDb(object):
126
127 PROTOCOLS = ['postgresql', 'mysql', 'sqlite', 'mssql', 'oracle']
128
129 def _clean(self, obj):
130 obj.protocol = self._clean_protocol(obj.protocol)
131 if hasattr(obj, 'port'):
132 obj.port = self._clean_port(obj.port)
133
134 def _clean_protocol(self, data):
135 data = data.lower()
136 if data in ('postgres', 'postgre'):
137 data = 'postgresql'
138 if data not in self.PROTOCOLS:
139 raise InvalidProtocolException(data)
140 else:
141 return data
142
143 def _clean_port(self, data):
144 try:
145 data = int(data)
146 except ValueError:
147 data = None
148 except TypeError:
149 data = None
150 if data:
151 if data <1 or data > 65535:
152 raise InvalidPortException(data)
153 return data
154
155
156class ConfigDbConnection(object):
157
158 def __init__(self):
159 self.db_obj = None
160
161
162class NotConfigParserObject(Exception):
163 pass
164
165
166class InvalidProtocolException(Exception):
167 pass
168
169
170class InvalidPortException(Exception):
171 pass
172
173
174class UnknownHandlerException(Exception):
175 pass
176
177
178class UnknownConnectionException(Exception):
179 pass