~donkirkby/openobject-server/setup-site-packages

« back to all changes in this revision

Viewing changes to bin/service/web_services.py

  • Committer: Christophe Simonis
  • Date: 2010-01-20 16:39:13 UTC
  • Revision ID: chs@tinyerp.com-20100120163913-5ftbs7e85lwqb1et
[FIX] remove the lock on database connections
[ADD] exported method check_connectivity
[REF] better logging of the Connection and ConnectionPool objects
[REF] use template0 as template when create new database

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
import logging
25
25
import os
26
26
import security
27
 
import string
28
27
import thread
29
28
import threading
30
29
import time
39
38
import sql_db
40
39
import tools
41
40
import locale
 
41
from cStringIO import StringIO
 
42
 
42
43
logging.basicConfig()
43
44
 
44
45
class db(netsvc.Service):
62
63
 
63
64
        self._pg_psw_env_var_is_set = False # on win32, pg_dump need the PGPASSWORD env var
64
65
 
 
66
    def _create_empty_database(self, name):
 
67
        db = sql_db.db_connect('template1')
 
68
        cr = db.cursor()
 
69
        try:
 
70
            cr.autocommit(True) # avoid transaction block
 
71
            cr.execute("""CREATE DATABASE "%s" ENCODING 'unicode' TEMPLATE "template0" """ % name)
 
72
        finally:
 
73
            cr.close()
 
74
 
65
75
    def create(self, password, db_name, demo, lang, user_password='admin'):
66
76
        security.check_super(password)
67
77
        self.id_protect.acquire()
71
81
 
72
82
        self.actions[id] = {'clean': False}
73
83
 
74
 
        db = sql_db.db_connect('template1')
75
 
        db.lock()
76
 
        try:
77
 
            cr = db.cursor()
78
 
            try:
79
 
                cr.autocommit(True) # avoid transaction block
80
 
                cr.execute('CREATE DATABASE "%s" ENCODING \'unicode\'' % db_name)
81
 
            finally:
82
 
                cr.close()
83
 
        finally:
84
 
            db.release()
 
84
        self._create_empty_database(db_name)
85
85
 
86
86
        class DBInitialize(object):
87
87
            def __call__(self, serv, id, db_name, demo, lang, user_password='admin'):
88
88
                cr = None
89
89
                try:
90
90
                    serv.actions[id]['progress'] = 0
91
 
                    clean = False
92
91
                    cr = sql_db.db_connect(db_name).cursor()
93
92
                    tools.init_db(cr)
94
93
                    cr.commit()
116
115
                except Exception, e:
117
116
                    serv.actions[id]['clean'] = False
118
117
                    serv.actions[id]['exception'] = e
119
 
                    from cStringIO import StringIO
120
118
                    import traceback
121
119
                    e_str = StringIO()
122
120
                    traceback.print_exc(file=e_str)
137
135
 
138
136
    def get_progress(self, password, id):
139
137
        security.check_super(password)
 
138
        tools.debug((id, self.actions.keys()))
140
139
        if self.actions[id]['thread'].isAlive():
141
140
#           return addons.init_progress[db_name]
142
141
            return (min(self.actions[id].get('progress', 0),0.95), [])
144
143
            clean = self.actions[id]['clean']
145
144
            if clean:
146
145
                users = self.actions[id]['users']
147
 
                del self.actions[id]
 
146
                self.actions.pop(id)
148
147
                return (1.0, users)
149
148
            else:
150
149
                e = self.actions[id]['exception']
151
 
                del self.actions[id]
 
150
                self.actions.pop(id)
152
151
                raise Exception, e
153
152
 
154
153
    def drop(self, password, db_name):
157
156
        logger = netsvc.Logger()
158
157
 
159
158
        db = sql_db.db_connect('template1')
160
 
        db.lock()
 
159
        cr = db.cursor()
 
160
        cr.autocommit(True) # avoid transaction block
161
161
        try:
162
 
            cr = db.cursor()
163
 
            cr.autocommit(True) # avoid transaction block
164
162
            try:
165
 
                try:
166
 
                    cr.execute('DROP DATABASE "%s"' % db_name)
167
 
                except Exception, e:
168
 
                    logger.notifyChannel("web-services", netsvc.LOG_ERROR,
169
 
                            'DROP DB: %s failed:\n%s' % (db_name, e))
170
 
                    raise Exception("Couldn't drop database %s: %s" % (db_name, e))
171
 
                else:
172
 
                    logger.notifyChannel("web-services", netsvc.LOG_INFO,
173
 
                        'DROP DB: %s' % (db_name))
174
 
            finally:
175
 
                cr.close()
 
163
                cr.execute('DROP DATABASE "%s"' % db_name)
 
164
            except Exception, e:
 
165
                logger.notifyChannel("web-services", netsvc.LOG_ERROR,
 
166
                        'DROP DB: %s failed:\n%s' % (db_name, e))
 
167
                raise Exception("Couldn't drop database %s: %s" % (db_name, e))
 
168
            else:
 
169
                logger.notifyChannel("web-services", netsvc.LOG_INFO,
 
170
                    'DROP DB: %s' % (db_name))
176
171
        finally:
177
 
            db.release()
 
172
            cr.close()
178
173
        return True
179
174
 
180
175
    def _set_pg_psw_env_var(self):
227
222
                    'RESTORE DB: %s already exists' % (db_name,))
228
223
            raise Exception, "Database already exists"
229
224
 
230
 
        db = sql_db.db_connect('template1')
231
 
        db.lock()
232
 
        try:
233
 
            cr = db.cursor()
234
 
            cr.autocommit(True) # avoid transaction block
235
 
            try:
236
 
                cr.execute("""CREATE DATABASE "%s" ENCODING 'unicode' TEMPLATE "template0" """ % db_name)
237
 
            finally:
238
 
                cr.close()
239
 
        finally:
240
 
            db.release()
 
225
        self._create_empty_database(db_name)
241
226
 
242
227
        cmd = ['pg_restore', '--no-owner']
243
228
        if tools.config['db_user']:
276
261
        logger = netsvc.Logger()
277
262
 
278
263
        db = sql_db.db_connect('template1')
279
 
        db.lock()
 
264
        cr = db.cursor()
280
265
        try:
281
 
            cr = db.cursor()
282
266
            try:
283
 
                try:
284
 
                    cr.execute('ALTER DATABASE "%s" RENAME TO "%s"' % (old_name, new_name))
285
 
                except Exception, e:
286
 
                    logger.notifyChannel("web-services", netsvc.LOG_ERROR,
287
 
                            'RENAME DB: %s -> %s failed:\n%s' % (old_name, new_name, e))
288
 
                    raise Exception("Couldn't rename database %s to %s: %s" % (old_name, new_name, e))
289
 
                else:
290
 
                    fs = os.path.join(tools.config['root_path'], 'filestore')
291
 
                    if os.path.exists(os.path.join(fs, old_name)):
292
 
                        os.rename(os.path.join(fs, old_name), os.path.join(fs, new_name))
 
267
                cr.execute('ALTER DATABASE "%s" RENAME TO "%s"' % (old_name, new_name))
 
268
            except Exception, e:
 
269
                logger.notifyChannel("web-services", netsvc.LOG_ERROR,
 
270
                        'RENAME DB: %s -> %s failed:\n%s' % (old_name, new_name, e))
 
271
                raise Exception("Couldn't rename database %s to %s: %s" % (old_name, new_name, e))
 
272
            else:
 
273
                fs = os.path.join(tools.config['root_path'], 'filestore')
 
274
                if os.path.exists(os.path.join(fs, old_name)):
 
275
                    os.rename(os.path.join(fs, old_name), os.path.join(fs, new_name))
293
276
 
294
 
                    logger.notifyChannel("web-services", netsvc.LOG_INFO,
295
 
                        'RENAME DB: %s -> %s' % (old_name, new_name))
296
 
            finally:
297
 
                cr.close()
 
277
                logger.notifyChannel("web-services", netsvc.LOG_INFO,
 
278
                    'RENAME DB: %s -> %s' % (old_name, new_name))
298
279
        finally:
299
 
            db.release()
 
280
            cr.close()
300
281
        return True
301
282
 
302
283
    def db_exist(self, db_name):
308
289
            raise Exception('AccessDenied')
309
290
 
310
291
        db = sql_db.db_connect('template1')
311
 
        db.lock()
 
292
        cr = db.cursor()
312
293
        try:
313
 
            cr = db.cursor()
314
294
            try:
315
 
                try:
316
 
                    db_user = tools.config["db_user"]
317
 
                    if not db_user and os.name == 'posix':
318
 
                        import pwd
319
 
                        db_user = pwd.getpwuid(os.getuid())[0]
320
 
                    if not db_user:
321
 
                        cr.execute("select decode(usename, 'escape') from pg_user where usesysid=(select datdba from pg_database where datname=%s)", (tools.config["db_name"],))
322
 
                        res = cr.fetchone()
323
 
                        db_user = res and str(res[0])
324
 
                    if db_user:
325
 
                        cr.execute("select decode(datname, 'escape') from pg_database where datdba=(select usesysid from pg_user where usename=%s) and datname not in ('template0', 'template1', 'postgres') order by datname", (db_user,))
326
 
                    else:
327
 
                        cr.execute("select decode(datname, 'escape') from pg_database where datname not in('template0', 'template1','postgres') order by datname")
328
 
                    res = [str(name) for (name,) in cr.fetchall()]
329
 
                except:
330
 
                    res = []
331
 
            finally:
332
 
                cr.close()
 
295
                db_user = tools.config["db_user"]
 
296
                if not db_user and os.name == 'posix':
 
297
                    import pwd
 
298
                    db_user = pwd.getpwuid(os.getuid())[0]
 
299
                if not db_user:
 
300
                    cr.execute("select decode(usename, 'escape') from pg_user where usesysid=(select datdba from pg_database where datname=%s)", (tools.config["db_name"],))
 
301
                    res = cr.fetchone()
 
302
                    db_user = res and str(res[0])
 
303
                if db_user:
 
304
                    cr.execute("select decode(datname, 'escape') from pg_database where datdba=(select usesysid from pg_user where usename=%s) and datname not in ('template0', 'template1', 'postgres') order by datname", (db_user,))
 
305
                else:
 
306
                    cr.execute("select decode(datname, 'escape') from pg_database where datname not in('template0', 'template1','postgres') order by datname")
 
307
                res = [str(name) for (name,) in cr.fetchall()]
 
308
            except:
 
309
                res = []
333
310
        finally:
334
 
            db.release()
 
311
            cr.close()
335
312
        res.sort()
336
313
        return res
337
314
 
366
343
                self.abortResponse(1, inst.name, 'warning', inst.value)
367
344
            except except_osv, inst:
368
345
                self.abortResponse(1, inst.name, inst.exc_type, inst.value)
369
 
            except Exception, e:
 
346
            except Exception:
370
347
                import traceback
371
348
                tb_s = reduce(lambda x, y: x+y, traceback.format_exception( sys.exc_type, sys.exc_value, sys.exc_traceback))
372
349
                l.notifyChannel('web-services', netsvc.LOG_ERROR, tb_s)
389
366
        self.exportMethod(self.get_migration_scripts)
390
367
        self.exportMethod(self.get_server_environment)
391
368
        self.exportMethod(self.login_message)
 
369
        self.exportMethod(self.check_connectivity)
392
370
 
393
371
    def ir_set(self, db, uid, password, keys, args, name, value, replace=True, isobject=False):
394
372
        security.check(db, uid, password)
512
490
                        l.notifyChannel('migration', netsvc.LOG_ERROR, 'unable to read the module %s' % (module,))
513
491
                        raise
514
492
 
515
 
                    zip_contents = cStringIO.StringIO(base64_decoded)
 
493
                    zip_contents = StringIO(base64_decoded)
516
494
                    zip_contents.seek(0)
517
495
                    try:
518
496
                        try:
570
548
                    %(platform.release(), platform.version(), platform.architecture()[0],
571
549
                      os_lang, platform.python_version(),release.version,rev_id)
572
550
        return environment
573
 
    
574
551
 
575
552
    def login_message(self):
576
553
        return tools.config.get('login_message', False)
577
554
 
 
555
    def check_connectivity(self):
 
556
        return bool(sql_db.db_connect('template1'))
 
557
 
578
558
common()
579
559
 
580
560
class objects_proxy(netsvc.Service):