| Trees | Indices | Help |
|
|---|
|
|
1 """GNUmed configuration handling.
2
3 Two sources of configuration information are supported:
4
5 - database tables
6
7 Theory of operation:
8
9 It is helpful to have a solid log target set up before importing this
10 module in your code. This way you will be able to see even those log
11 messages generated during module import.
12
13 Once your software has established database connectivity you can
14 set up a config source from the database. You can limit the option
15 applicability by the constraints "workplace", "user", and "cookie".
16
17 The basic API for handling items is get()/set().
18 The database config objects auto-syncs with the backend.
19
20 @copyright: GPL
21 """
22 # TODO:
23 # - optional arg for set -> type
24 #==================================================================
25 # $Source: /cvsroot/gnumed/gnumed/gnumed/client/pycommon/gmCfg.py,v $
26 __version__ = "$Revision: 1.60 $"
27 __author__ = "Karsten Hilbert <Karsten.Hilbert@gmx.net>"
28
29 # standard modules
30 import sys, types, cPickle, decimal, logging, re as regex
31
32
33 # gnumed modules
34 if __name__ == '__main__':
35 sys.path.insert(0, '../../')
36 from Gnumed.pycommon import gmPG2, gmTools
37
38
39 _log = logging.getLogger('gm.cfg')
40 _log.info(__version__)
41
42 # don't change this without knowing what you do as
43 # it will already be in many databases
44 cfg_DEFAULT = "xxxDEFAULTxxx"
45 #==================================================================
46 # FIXME: make a cBorg around this
50 #-----------------------------------------------
51 # external API
52 #-----------------------------------------------
53 - def get2(self, option=None, workplace=None, cookie=None, bias=None, default=None, sql_return_type=None):
54 """Retrieve configuration option from backend.
55
56 @param bias: Determine the direction into which to look for config options.
57
58 'user': When no value is found for "current_user/workplace" look for a value
59 for "current_user" regardless of workspace. The corresponding concept is:
60
61 "Did *I* set this option anywhere on this site ? If so, reuse the value."
62
63 'workplace': When no value is found for "current_user/workplace" look for a value
64 for "workplace" regardless of user. The corresponding concept is:
65
66 "Did anyone set this option for *this workplace* ? If so, reuse that value."
67 @param default: if no value is found for the option this value is returned
68 instead, also the option is set to this value in the backend, if <None>
69 a missing option will NOT be created in the backend
70 @param sql_return_type: a PostgreSQL type the value of the option is to be
71 cast to before returning, if None no cast will be applied, you will
72 want to make sure that sql_return_type and type(default) are compatible
73 """
74
75 # this is the one to use (Sa 17 Feb 2007 12:16:56 CET)
76
77 if None in [option, workplace]:
78 raise ValueError, 'neither <option> (%s) nor <workplace> (%s) may be [None]' % (option, workplace)
79 if bias not in ['user', 'workplace']:
80 raise ValueError, '<bias> must be "user" or "workplace"'
81
82 # does this option exist ?
83 cmd = u"select type from cfg.cfg_template where name=%(opt)s"
84 rows, idx = gmPG2.run_ro_queries(link_obj=self.ro_conn, queries = [{'cmd': cmd, 'args': {'opt': option}}])
85 if len(rows) == 0:
86 # not found ...
87 if default is None:
88 # ... and no default either
89 return None
90 _log.info('creating option [%s] with default [%s]' % (option, default))
91 success = self.set(workplace = workplace, cookie = cookie, option = option, value = default)
92 if not success:
93 # ... but cannot create option with default value either
94 _log.error('creating option failed')
95 return default
96
97 cfg_table_type_suffix = rows[0][0]
98 args = {
99 'opt': option,
100 'wp': workplace,
101 'cookie': cookie,
102 'def': cfg_DEFAULT
103 }
104
105 if cfg_table_type_suffix == u'data':
106 sql_return_type = u''
107 else:
108 sql_return_type = gmTools.coalesce (
109 initial = sql_return_type,
110 instead = u'',
111 template_initial = u'::%s'
112 )
113
114 # 1) search value with explicit workplace and current user
115 where_parts = [
116 u'vco.owner = CURRENT_USER',
117 u'vco.workplace = %(wp)s',
118 u'vco.option = %(opt)s'
119 ]
120 where_parts.append(gmTools.coalesce (
121 initial = cookie,
122 instead = u'vco.cookie is null',
123 template_initial = u'vco.cookie = %(cookie)s'
124 ))
125 cmd = u"select vco.value%s from cfg.v_cfg_opts_%s vco where %s limit 1" % (
126 sql_return_type,
127 cfg_table_type_suffix,
128 u' and '.join(where_parts)
129 )
130 rows, idx = gmPG2.run_ro_queries(link_obj=self.ro_conn, queries = [{'cmd': cmd, 'args': args}])
131 if len(rows) > 0:
132 if cfg_table_type_suffix == u'data':
133 return cPickle.loads(str(rows[0][0]))
134 return rows[0][0]
135
136 _log.warning('no user AND workplace specific value for option [%s] in config database' % option)
137
138 # 2) search value with biased query
139 if bias == 'user':
140 # did *I* set this option on *any* workplace ?
141 where_parts = [
142 u'vco.option = %(opt)s',
143 u'vco.owner = CURRENT_USER',
144 ]
145 else:
146 # did *anyone* set this option on *this* workplace ?
147 where_parts = [
148 u'vco.option = %(opt)s',
149 u'vco.workplace = %(wp)s'
150 ]
151 where_parts.append(gmTools.coalesce (
152 initial = cookie,
153 instead = u'vco.cookie is null',
154 template_initial = u'vco.cookie = %(cookie)s'
155 ))
156 cmd = u"select vco.value%s from cfg.v_cfg_opts_%s vco where %s" % (
157 sql_return_type,
158 cfg_table_type_suffix,
159 u' and '.join(where_parts)
160 )
161 rows, idx = gmPG2.run_ro_queries(link_obj=self.ro_conn, queries = [{'cmd': cmd, 'args': args}])
162 if len(rows) > 0:
163 # set explicitely for user/workplace
164 self.set (
165 workplace = workplace,
166 cookie = cookie,
167 option = option,
168 value = rows[0][0]
169 )
170 if cfg_table_type_suffix == u'data':
171 return cPickle.loads(str(rows[0][0]))
172 return rows[0][0]
173
174 _log.warning('no user OR workplace specific value for option [%s] in config database' % option)
175
176 # 3) search value within default site policy
177 where_parts = [
178 u'vco.owner = %(def)s',
179 u'vco.workplace = %(def)s',
180 u'vco.option = %(opt)s'
181 ]
182 cmd = u"select vco.value%s from cfg.v_cfg_opts_%s vco where %s" % (
183 sql_return_type,
184 cfg_table_type_suffix,
185 u' and '.join(where_parts)
186 )
187 rows, idx = gmPG2.run_ro_queries(link_obj=self.ro_conn, queries = [{'cmd': cmd, 'args': args}])
188 if len(rows) > 0:
189 # set explicitely for user/workplace
190 self.set (
191 workplace = workplace,
192 cookie = cookie,
193 option = option,
194 value = rows[0]['value']
195 )
196 if cfg_table_type_suffix == u'data':
197 return cPickle.loads(str(rows[0]['value']))
198 return rows[0]['value']
199
200 _log.warning('no default site policy value for option [%s] in config database' % option)
201
202 # 4) not found, set default ?
203 if default is None:
204 _log.warning('no default value for option [%s] supplied by caller' % option)
205 return None
206 _log.info('setting option [%s] to default [%s]' % (option, default))
207 success = self.set (
208 workplace = workplace,
209 cookie = cookie,
210 option = option,
211 value = default
212 )
213 if not success:
214 return None
215
216 return default
217 #-----------------------------------------------
219 """Get config value from database.
220
221 - unset arguments are assumed to mean database defaults except for <cookie>
222 """
223 # sanity checks
224 if option is None:
225 _log.error("Need to know which option to retrieve.")
226 return None
227
228 alias = self.__make_alias(workplace, 'CURRENT_USER', cookie, option)
229
230 # construct query
231 where_parts = [
232 'vco.option=%(opt)s',
233 'vco.workplace=%(wplace)s'
234 ]
235 where_args = {
236 'opt': option,
237 'wplace': workplace
238 }
239 if workplace is None:
240 where_args['wplace'] = cfg_DEFAULT
241
242 where_parts.append('vco.owner=CURRENT_USER')
243
244 if cookie is not None:
245 where_parts.append('vco.cookie=%(cookie)s')
246 where_args['cookie'] = cookie
247 where_clause = ' and '.join(where_parts)
248 cmd = u"""
249 select vco.pk_cfg_item
250 from cfg.v_cfg_options vco
251 where %s
252 limit 1""" % where_clause
253
254 rows, idx = gmPG2.run_ro_queries(link_obj=self.ro_conn, queries = [{'cmd': cmd, 'args': where_args}], return_data=True)
255 if len(rows) == 0:
256 _log.warning('option definition for [%s] not in config database' % alias)
257 return None
258 return rows[0][0]
259 #----------------------------
261 """Set (insert or update) option value in database.
262
263 Any parameter that is None will be set to the database default.
264
265 Note: you can't change the type of a parameter once it has been
266 created in the backend. If you want to change the type you will
267 have to delete the parameter and recreate it using the new type.
268 """
269 # sanity checks
270 if None in [option, value]:
271 raise ValueError('invalid arguments (option=<%s>, value=<%s>)' % (option, value))
272
273 rw_conn = gmPG2.get_connection(readonly=False)
274
275 alias = self.__make_alias(workplace, 'CURRENT_USER', cookie, option)
276
277 opt_value = value
278 sql_type_cast = u''
279 if isinstance(value, basestring):
280 sql_type_cast = u'::text'
281 elif isinstance(value, types.BooleanType):
282 opt_value = int(opt_value)
283 elif isinstance(value, (types.FloatType, types.IntType, types.LongType, decimal.Decimal, types.BooleanType)):
284 sql_type_cast = u'::numeric'
285 elif isinstance(value, types.ListType):
286 # there can be different syntaxes for list types so don't try to cast them
287 pass
288 elif isinstance(value, types.BufferType):
289 # can go directly into bytea
290 pass
291 else:
292 try:
293 opt_value = gmPG2.dbapi.Binary(cPickle.dumps(value))
294 sql_type_cast = '::bytea'
295 except cPickle.PicklingError:
296 _log.error("cannot pickle option of type [%s] (key: %s, value: %s)", type(value), alias, str(value))
297 raise
298 except:
299 _log.error("don't know how to store option of type [%s] (key: %s, value: %s)", type(value), alias, str(value))
300 raise
301
302 cmd = u'select cfg.set_option(%%(opt)s, %%(val)s%s, %%(wp)s, %%(cookie)s, NULL)' % sql_type_cast
303 args = {
304 'opt': option,
305 'val': opt_value,
306 'wp': workplace,
307 'cookie': cookie
308 }
309 try:
310 rows, idx = gmPG2.run_rw_queries(link_obj=rw_conn, queries=[{'cmd': cmd, 'args': args}], return_data=True)
311 result = rows[0][0]
312 except:
313 _log.exception('cannot set option')
314 result = False
315
316 rw_conn.commit() # will rollback if transaction failed
317 rw_conn.close()
318
319 return result
320 #-------------------------------------------
322 """Get names of all stored parameters for a given workplace/(user)/cookie-key.
323 This will be used by the ConfigEditor object to create a parameter tree.
324 """
325 # if no workplace given: any workplace (= cfg_DEFAULT)
326 where_snippets = [
327 u'cfg_template.pk=cfg_item.fk_template',
328 u'cfg_item.workplace=%(wplace)s'
329 ]
330 where_args = {'wplace': workplace}
331
332 # if no user given: current db user
333 if user is None:
334 where_snippets.append(u'cfg_item.owner=CURRENT_USER')
335 else:
336 where_snippets.append(u'cfg_item.owner=%(usr)s')
337 where_args['usr'] = user
338
339 where_clause = u' and '.join(where_snippets)
340
341 cmd = u"""
342 select name, cookie, owner, type, description
343 from cfg.cfg_template, cfg.cfg_item
344 where %s""" % where_clause
345
346 # retrieve option definition
347 rows, idx = gmPG2.run_ro_queries(link_obj=self.ro_conn, queries = [{'cmd': cmd, 'args': where_args}], return_data=True)
348 return rows
349 #----------------------------
351 """
352 Deletes an option or a whole group.
353 Note you have to call store() in order to save
354 the changes.
355 """
356 if option is None:
357 raise ValueError('<option> cannot be None')
358
359 if cookie is None:
360 cmd = u"""
361 delete from cfg.cfg_item where
362 fk_template=(select pk from cfg.cfg_template where name = %(opt)s) and
363 owner = CURRENT_USER and
364 workplace = %(wp)s and
365 cookie is Null
366 """
367 else:
368 cmd = u"""
369 delete from cfg.cfg_item where
370 fk_template=(select pk from cfg.cfg_template where name = %(opt)s) and
371 owner = CURRENT_USER and
372 workplace = %(wp)s and
373 cookie = %(cookie)s
374 """
375 args = {'opt': option, 'wp': workplace, 'cookie': cookie}
376 gmPG2.run_rw_queries(queries=[{'cmd': cmd, 'args': args}])
377 return True
378 #----------------------------
381 #===================================================================
383 """Convenience function to get config value from database.
384
385 will search for context dependant match in this order:
386 - CURRENT_USER_CURRENT_WORKPLACE
387 - CURRENT_USER_DEFAULT_WORKPLACE
388 - DEFAULT_USER_CURRENT_WORKPLACE
389 - DEFAULT_USER_DEFAULT_WORKPLACE
390
391 We assume that the config tables are found on service "default".
392 That way we can handle the db connection inside this function.
393
394 Returns (value, set) of first match.
395 """
396
397 # FIXME: depending on set store for user ...
398
399 if option is None:
400 return (None, None)
401
402 # connect to database (imports gmPG2 if need be)
403 dbcfg = cCfgSQL()
404
405 # (set_name, user, workplace)
406 sets2search = []
407 if workplace is not None:
408 sets2search.append(['CURRENT_USER_CURRENT_WORKPLACE', None, workplace])
409 sets2search.append(['CURRENT_USER_DEFAULT_WORKPLACE', None, None])
410 if workplace is not None:
411 sets2search.append(['DEFAULT_USER_CURRENT_WORKPLACE', cfg_DEFAULT, workplace])
412 sets2search.append(['DEFAULT_USER_DEFAULT_WORKPLACE', cfg_DEFAULT, None])
413 # loop over sets
414 matchingSet = None
415 result = None
416 for set in sets2search:
417 result = dbcfg.get(
418 workplace = set[2],
419 user = set[1],
420 option = option,
421 cookie = cookie
422 )
423 if result is not None:
424 matchingSet = set[0]
425 break
426 _log.debug('[%s] not found for [%s@%s]' % (option, set[1], set[2]))
427
428 # cleanup
429 if matchingSet is None:
430 _log.warning('no config data for [%s]' % option)
431 return (result, matchingSet)
432 #-------------------------------------------------------------
434 """Convenience function to store config values in database.
435
436 We assume that the config tables are found on service "default".
437 That way we can handle the db connection inside this function.
438
439 Omitting any parameter (or setting to None) will store database defaults for it.
440
441 - returns True/False
442 """
443 # connect to database
444 dbcfg = cCfgSQL()
445 # set value
446 success = dbcfg.set(
447 workplace = workplace,
448 user = user,
449 option = option,
450 value = value
451 )
452
453 if not success:
454 return False
455 return True
456 #=============================================================
457 # main
458 #=============================================================
459 if __name__ == "__main__":
460
461 root = logging.getLogger()
462 root.setLevel(logging.DEBUG)
463
464 #---------------------------------------------------------
466 print "testing database config"
467 print "======================="
468
469 myDBCfg = cCfgSQL()
470
471 print "delete() works:", myDBCfg.delete(option='font name', workplace = 'test workplace')
472 print "font is initially:", myDBCfg.get2(option = 'font name', workplace = 'test workplace', bias = 'user')
473 print "set() works:", myDBCfg.set(option='font name', value="Times New Roman", workplace = 'test workplace')
474 print "font after set():", myDBCfg.get2(option = 'font name', workplace = 'test workplace', bias = 'user')
475 print "delete() works:", myDBCfg.delete(option='font name', workplace = 'test workplace')
476 print "font after delete():", myDBCfg.get2(option = 'font name', workplace = 'test workplace', bias = 'user')
477 print "font after get() with default:", myDBCfg.get2(option = 'font name', workplace = 'test workplace', bias = 'user', default = 'WingDings')
478 print "font right after get() with another default:", myDBCfg.get2(option = 'font name', workplace = 'test workplace', bias = 'user', default = 'default: Courier')
479 print "set() works:", myDBCfg.set(option='font name', value="Times New Roman", workplace = 'test workplace')
480 print "font after set() on existing option:", myDBCfg.get2(option = 'font name', workplace = 'test workplace', bias = 'user')
481
482 print "setting array option"
483 print "array now:", myDBCfg.get2(option = 'test array', workplace = 'test workplace', bias = 'user')
484 aList = ['val 1', 'val 2']
485 print "set():", myDBCfg.set(option='test array', value = aList, workplace = 'test workplace')
486 print "array now:", myDBCfg.get2(option = 'test array', workplace = 'test workplace', bias = 'user')
487 aList = ['val 11', 'val 12']
488 print "set():", myDBCfg.set(option='test array', value = aList, workplace = 'test workplace')
489 print "array now:", myDBCfg.get2(option = 'test array', workplace = 'test workplace', bias = 'user')
490 print "delete() works:", myDBCfg.delete(option='test array', workplace='test workplace')
491 print "array now:", myDBCfg.get2(option = 'test array', workplace = 'test workplace', bias = 'user')
492
493 print "setting complex option"
494 data = {1: 'line 1', 2: 'line2', 3: {1: 'line3.1', 2: 'line3.2'}, 4: 1234}
495 print "set():", myDBCfg.set(option = "complex option test", value = data, workplace = 'test workplace')
496 print "complex option now:", myDBCfg.get2(workplace = 'test workplace', option = "complex option test", bias = 'user')
497 print "delete() works:", myDBCfg.delete(option = "complex option test", workplace = 'test workplace')
498 print "complex option now:", myDBCfg.get2(workplace = 'test workplace', option = "complex option test", bias = 'user')
499
500 #---------------------------------------------------------
501 if (len(sys.argv) > 1) and (sys.argv[1] == 'test'):
502 try:
503 test_db_cfg()
504 except:
505 _log.exception('test suite failed')
506 raise
507
508 #=============================================================
509 # $Log: gmCfg.py,v $
510 # Revision 1.60 2008/08/20 13:53:45 ncq
511 # - robustify type handling in get2/set:
512 # - explicitely support buffer()
513 # - properly handle _data table
514 # - unpickle retrieved bytea
515 #
516 # Revision 1.59 2008/04/13 13:57:32 ncq
517 # - lay to rest the venerable cCfgFile, it
518 # has served us well
519 #
520 # Revision 1.58 2008/01/30 14:04:32 ncq
521 # - disable support from gmCfgFile()
522 #
523 # Revision 1.57 2007/12/26 18:34:02 ncq
524 # - no more old CLI lib
525 #
526 # Revision 1.56 2007/12/23 11:57:14 ncq
527 # - cleanup
528 #
529 # Revision 1.55 2007/12/11 15:35:28 ncq
530 # - use std lib logging
531 #
532 # Revision 1.54 2007/02/22 17:41:13 ncq
533 # - adjust to gmPerson changes
534 #
535 # Revision 1.53 2007/02/17 14:11:56 ncq
536 # - better get2 docs
537 # - allow custom cast on get2() return value
538 #
539 # Revision 1.52 2007/01/30 17:38:06 ncq
540 # - cleanup and a comment
541 #
542 # Revision 1.51 2006/12/22 15:20:12 ncq
543 # - do not fail hard if config file not found, after all, user
544 # may want to set it later, but still do not hide exceptions
545 #
546 # Revision 1.50 2006/12/21 10:49:38 ncq
547 # - do not hide exceptiosn
548 #
549 # Revision 1.49 2006/12/13 14:55:56 ncq
550 # - remove get() from SQL source
551 #
552 # Revision 1.48 2006/12/05 13:54:02 ncq
553 # - better error messages
554 # - u''ify some query parts
555 # - simplify some code
556 #
557 # Revision 1.47 2006/11/14 16:27:36 ncq
558 # - improved test suite
559 #
560 # Revision 1.46 2006/11/07 00:27:45 ncq
561 # - psycopg2 knows how to adapt lists/tuples to ARRAY syntax, at
562 # least when SQL_IN is loaded, so we can't use explicit casts with
563 # <datatype>[] anymore in our SQL
564 #
565 # Revision 1.45 2006/11/05 16:00:17 ncq
566 # - unicode is text so don't pickle it
567 #
568 # Revision 1.44 2006/10/25 07:19:03 ncq
569 # - no more gmPG
570 #
571 # Revision 1.43 2006/10/08 11:02:02 ncq
572 # - support decimal type, too
573 # - make queries unicode
574 #
575 # Revision 1.42 2006/09/21 19:41:21 ncq
576 # - convert to use gmPG2
577 # - axe cCfgBase
578 # - massive cCfgSQL cleanup
579 # - axe get()
580 # - axe get_by_workplace()
581 # - pump up get2(), set() and delete()
582 # - getID() still pending review
583 # - get2(bytea) still pending fixes
584 # - fix up database config test suite
585 #
586 # Revision 1.41 2006/09/12 17:20:36 ncq
587 # - mark up the deprecated sql get()ters
588 #
589 # Revision 1.40 2006/07/24 14:16:56 ncq
590 # - get_by_user() never worked so axe it
591 #
592 # Revision 1.39 2006/05/16 15:50:07 ncq
593 # - several small fixes in get2() regarding
594 # less travelled codepathes
595 #
596 # Revision 1.38 2006/05/01 18:44:43 ncq
597 # - fix gmPG -> gmPG_ usage
598 #
599 # Revision 1.37 2006/02/27 15:39:06 ncq
600 # - add cCfg_SQL.get2()
601 #
602 # Revision 1.36 2006/01/13 14:57:14 ncq
603 # - really fix get_by_workplace() - still needs set() functionality
604 #
605 # Revision 1.35 2006/01/01 17:22:08 ncq
606 # - get_by_workplace always returns default value in case of
607 # errors/option not found except when there is not default given
608 # in which case it will return None on error
609 #
610 # Revision 1.34 2005/12/30 16:51:03 ncq
611 # - slightly improved method documentation
612 #
613 # Revision 1.33 2005/12/14 16:56:09 ncq
614 # - enhance get_by_user() and get_by_workplace() with a default
615 # which if set will enable to store the option even if there's
616 # no template in the database
617 # - fix unit test
618 #
619 # Revision 1.32 2005/12/14 10:41:11 ncq
620 # - allow cCfgSQL to set up its own connection if none given
621 # - add cCfgSQL.get_by_user()
622 # - smarten up cCfgSQL.get()
623 #
624 # Revision 1.31 2005/11/19 08:47:56 ihaywood
625 # tiny bugfixes
626 #
627 # Revision 1.30 2005/11/18 15:48:44 ncq
628 # - config tables now in cfg.* schema so adjust to that
629 # - also some id -> pk changes
630 #
631 # Revision 1.29 2005/10/10 18:05:46 ncq
632 # - ignore error on failing to delete non-existant backup config
633 # file as that was way over the top behaviour
634 #
635 # Revision 1.28 2005/10/08 09:24:09 ihaywood
636 # lack of a backup config file is now an warning only.
637 #
638 # Revision 1.27 2005/08/14 15:35:31 ncq
639 # - cleanup
640 #
641 # Revision 1.26 2005/02/05 10:58:09 ihaywood
642 # fixed patient picture problem (gratutious use of a named parameter)
643 # more rationalisation of loggin in gmCfg
644 #
645 # Revision 1.24 2005/01/10 11:46:51 ncq
646 # - make cCfgSQL also support arbitrary option values in cfg_data
647 #
648 # Revision 1.23 2004/09/06 22:18:12 ncq
649 # - eventually fix the get/setDBParam(), at least it appears to work
650 #
651 # Revision 1.22 2004/09/02 00:39:27 ncq
652 # - use new v_cfg_options
653 # - remove personalize argument from getDBParam() in favour of clarity
654 #
655 # Revision 1.21 2004/08/24 13:40:43 ncq
656 # - when cleaning up cfgSQL.set() I screwed up, fixed
657 #
658 # Revision 1.20 2004/08/23 10:24:10 ncq
659 # - made setdbparam saner re default params, eg. param=None will set to
660 # database default, eg if anything else wanted user needs to explicitely
661 # set
662 # - cleanup
663 #
664 # Revision 1.19 2004/08/20 13:22:13 ncq
665 # - cleanup
666 # - getFirstMatchingDBSet() -> getDBParam()
667 # - argument personalize default true in getDBParam() stores
668 # option value if found for other that current user/current workspace
669 #
670 # Revision 1.18 2004/08/16 12:15:20 ncq
671 # - don't hide module global gmDefCfgFile inside "if __name__ == '__main__'" so
672 # that epydoc picks it up properly for documentation
673 #
674 # Revision 1.17 2004/08/16 12:06:50 ncq
675 # - hopefully improve docstring by including import example
676 #
677 # Revision 1.16 2004/08/11 11:07:33 ncq
678 # - needless args on cfg queries removed
679 #
680 # Revision 1.15 2004/08/11 08:00:05 ncq
681 # - improve log prefix
682 # - cleanup SQL cfg/remove old use of _USER
683 #
684 # Revision 1.14 2004/07/24 17:10:09 ncq
685 # - fix getAllParams()
686 #
687 # Revision 1.13 2004/07/19 13:53:35 ncq
688 # - some cleanup re setDBParam()/getFirstMatchingDBset()
689 #
690 # Revision 1.12 2004/07/19 11:50:42 ncq
691 # - cfg: what used to be called "machine" really is "workplace", so fix
692 #
693 # Revision 1.11 2004/07/17 21:08:51 ncq
694 # - gmPG.run_query() now has a verbosity parameter, so use it
695 #
696 # Revision 1.10 2004/07/12 13:49:39 ncq
697 # - log version
698 #
699 # Revision 1.9 2004/07/12 02:48:40 ihaywood
700 # same again
701 #
702 # Revision 1.8 2004/07/12 02:44:12 ihaywood
703 # it should not be neccessary to specify the full path when
704 # importing from the same package.
705 # It makes the file gratutiously dependent on being in the gnumed
706 # directory structure.
707 #
708 # Revision 1.7 2004/07/06 00:25:17 ncq
709 # - assign Null design pattern instance if no default cfg file found
710 #
711 # Revision 1.6 2004/06/28 22:36:33 hinnef
712 # added lazy loading of gmPG to gmCfgSQL:getAllParams
713 #
714 # Revision 1.5 2004/06/22 07:58:47 ihaywood
715 # minor bugfixes
716 # let gmCfg cope with config files that are not real files
717 #
718 # Revision 1.4 2004/06/19 18:55:44 shilbert
719 # - fixes for various import statements
720 #
721 # Revision 1.3 2004/02/26 14:32:46 ncq
722 # - fixed and lazied even more
723 #
724 # Revision 1.2 2004/02/25 22:56:38 sjtan
725 #
726 # probably a typo ; temp fix until authors see it.
727 #
728 # Revision 1.1 2004/02/25 09:30:13 ncq
729 # - moved here from python-common
730 #
731 # Revision 1.71 2004/02/25 08:46:12 ncq
732 # - hopefully lazyied the import of gmCLI, too
733 #
734 # Revision 1.70 2004/02/25 08:39:04 ncq
735 # - I think I removed the dependancy on gmPG as long as cCfgSQL isn't used
736 #
737 # Revision 1.69 2004/01/06 23:44:40 ncq
738 # - __default__ -> xxxDEFAULTxxx
739 #
740 # Revision 1.68 2003/11/22 02:03:48 ihaywood
741 # reverted to version 1.66
742 #
743 # Revision 1.66 2003/10/22 22:05:18 ncq
744 # - cleanup, coding style
745 #
746 # Revision 1.65 2003/10/22 21:37:04 hinnef
747 # added convenience function setDBParam() to reduce redundant code on setting backend parameters
748 #
749 # Revision 1.64 2003/10/02 20:01:15 hinnef
750 # fixed selection of user in gmcfgSQL.get/getID/getAllParams so that _user will be found, too
751 #
752 # Revision 1.63 2003/09/26 19:35:21 hinnef
753 # - added delete() methods in cCfgFile and cCfgSQL, small fixes in cfgSQL.set()
754 #
755 # Revision 1.62 2003/09/24 10:32:13 ncq
756 # - in _get_conf_name() we need to make std_dirs when aName is None,
757 # not aDir, also init base_name/base_dir to a known state
758 #
759 # Revision 1.61 2003/09/21 08:37:47 ihaywood
760 # database code now properly escaped
761 #
762 # Revision 1.60 2003/08/24 13:36:39 hinnef
763 # added getFirstMatchingDBSet() for convenient config data retrieval
764 #
765 # Revision 1.59 2003/08/24 08:01:44 ncq
766 # - removed some dead code, cleanup
767 #
768 # Revision 1.58 2003/08/23 18:33:50 hinnef
769 # added small comment in __get_conf_name(), commented out two verbose debug messages
770 #
771 # Revision 1.57 2003/08/10 00:53:09 ncq
772 # - cleanup to Hilmars nice additions
773 #
774 # Revision 1.56 2003/08/07 23:31:04 hinnef
775 # changed CfgFile.__get_conf_name so that files can be searched in more than one location
776 #
777 # Revision 1.55 2003/07/21 20:53:50 ncq
778 # - fix string screwup
779 #
780 # Revision 1.54 2003/07/21 19:18:06 ncq
781 # - use gmPG.run_query(), not home-brew
782 # - kill gmPG.esc() use
783 # - cleanup/comments
784 #
785 # Revision 1.53 2003/06/26 21:29:58 ncq
786 # - (cmd, arg) style, fatal->verbose
787 #
788 # Revision 1.52 2003/06/26 04:18:40 ihaywood
789 # Fixes to gmCfg for commas
790 #
791 # Revision 1.51 2003/06/21 10:44:09 ncq
792 # - handle read-only media better when modifying config file
793 #
794 # Revision 1.50 2003/06/17 22:21:53 ncq
795 # - improve __get_conf_name()
796 #
797 # Revision 1.49 2003/06/03 21:52:23 hinnef
798 # - fixed a bug in cfgSQL.set() when updating a value
799 #
800 # Revision 1.48 2003/05/12 09:12:48 ncq
801 # - minor cleanups
802 #
803 # Revision 1.47 2003/05/10 18:45:52 hinnef
804 # - added getAllParams for use in gmConfigRegistry
805 #
806 # Revision 1.46 2003/04/14 07:45:47 ncq
807 # - better temp names in cfgFile.store()
808 #
809 # Revision 1.45 2003/03/31 00:26:46 ncq
810 # - forgot "\n"
811 #
812 # Revision 1.44 2003/03/30 21:38:28 ncq
813 # - put some blurb in new, empty config files
814 #
815 # Revision 1.43 2003/03/27 21:10:12 ncq
816 # - move '__default__' to cfg_DEFAULT constant
817 #
818 # Revision 1.42 2003/03/23 10:32:50 ncq
819 # - improve console messages a bit
820 #
821 # Revision 1.41 2003/02/21 08:58:51 ncq
822 # - improve PgArray detection even more
823 #
824 # Revision 1.40 2003/02/21 08:51:57 ncq
825 # - catch exception on missing PgArray
826 #
827 # Revision 1.39 2003/02/15 08:51:05 ncq
828 # - don't remove empty lines in lists
829 #
830 # Revision 1.38 2003/02/11 16:52:36 ncq
831 # - log one more failing corner case
832 #
833 # Revision 1.37 2003/02/09 09:48:28 ncq
834 # - revert breakage created by sjtan
835 #
836 # Revision 1.36 2003/02/09 02:02:30 sjtan
837 #
838 # allows first time run of gmGuiMain without a conf file. A Default conf file called gnumed.conf is created.
839 #
840 # Revision 1.35 2003/01/28 10:53:09 ncq
841 # - clarification to test code
842 #
843 # Revision 1.34 2003/01/12 11:53:58 ncq
844 # - fixed subtle bug resulting from ro/rw connections:
845 # - set() would request a rw conn thus CURRENT_USER = "_user"
846 # - get() would use a ro conn, thus CURRENT_USER == "user"
847 # - there'd never be a match and the items would keep proliferating
848 #
849 # Revision 1.33 2003/01/05 09:56:58 ncq
850 # - ironed out some bugs in the array handling
851 # - streamlined code
852 # - have cfg.set() explicitely use rw conn to DB only when needed
853 #
854 # Revision 1.32 2003/01/04 12:19:04 ncq
855 # - better comment
856 #
857 # Revision 1.31 2003/01/04 12:17:05 ncq
858 # - backup old config file before overwriting
859 #
860 # Revision 1.30 2002/12/26 15:49:10 ncq
861 # - better comments
862 #
863 # Revision 1.29 2002/12/26 15:21:18 ncq
864 # - database config now works even with string lists
865 #
866 # Revision 1.28 2002/12/01 01:11:42 ncq
867 # - log config file line number on parse errors
868 #
869 # Revision 1.27 2002/11/28 11:40:12 ncq
870 # - added database config
871 # - reorganized self test
872 #
873 # Revision 1.26 2002/11/18 09:41:25 ncq
874 # - removed magic #! interpreter incantation line to make Debian happy
875 #
876 # Revision 1.25 2002/11/17 20:09:10 ncq
877 # - always display __doc__ when called standalone
878 #
879 # Revision 1.24 2002/11/05 18:15:03 ncq
880 # - new helper getOptions()
881 # - modified example code to show real use
882 #
883 # Revision 1.23 2002/11/04 15:38:28 ncq
884 # - moved empty config file creation to helper function
885 #
886 # Revision 1.22 2002/11/03 14:11:19 ncq
887 # - autocreate log file on failing to find one
888 #
889 # Revision 1.21 2002/11/03 13:21:05 ncq
890 # - phase 1: error levels more suitable
891 #
892 # Revision 1.20 2002/10/22 21:11:44 ncq
893 # - throwing exception ImportError on failing to load the
894 # default config file wasn't such a good idea after all
895 # since we might _actually_ only be interested in a different
896 # file ...
897 #
898 # Revision 1.19 2002/10/22 15:30:16 ncq
899 # - added getGroups()
900 #
901 # Revision 1.18 2002/10/19 19:30:13 ncq
902 # - on being imported always raise ImportError on failing to use default config file
903 #
904 # Revision 1.17 2002/10/19 19:24:37 ncq
905 # - fixed some whitespace breakage
906 # - raise error on failing to parse default config file, if you really want
907 # to override this you should handle that exception in your own code
908 #
909 # Revision 1.16 2002/10/18 19:57:09 hinnef
910 # fixed problems when a invalid filename is given, static class variables and
911 # changed the initialization of gmDefCfgFile so that it can be imported from
912 # standalone modules
913 #
914 # Revision 1.15 2002/09/30 10:58:27 ncq
915 # - consistently spell GnuMed
916 #
917 # Revision 1.14 2002/09/26 13:21:37 ncq
918 # - log version
919 #
920 # Revision 1.13 2002/09/12 23:11:14 ncq
921 # - fixed one nasty overwriting bug in store()
922 #
923 # Revision 1.12 2002/09/12 10:07:29 ncq
924 # - properly normalize : -> =
925 #
926 # Revision 1.11 2002/09/12 09:17:11 ncq
927 # - windows unsucked
928 #
929 # Revision 1.10 2002/09/10 18:43:02 ncq
930 # - windows sucks !
931 #
932 # Revision 1.9 2002/09/10 18:31:45 ncq
933 # - windows is strange: os.rename -> shutil.copyfile + os.remove
934 #
935 # Revision 1.8 2002/09/10 18:15:28 ncq
936 # - os.rename() over existing files fails on non-UNIX
937 #
938 # Revision 1.7 2002/09/10 17:51:33 ncq
939 # - more sensible log levels for some data
940 #
941 # Revision 1.6 2002/09/08 15:55:47 ncq
942 # - added log cvs keyword
943 #
944
| Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Tue Feb 9 04:01:42 2010 | http://epydoc.sourceforge.net |