Antony Lesuisse (OpenERP) has proposed merging 
lp:~openerp-dev/openobject-server/trunk-dbcreatecache-vmt into 
lp:openobject-server.

Requested reviews:
  OpenERP Core Team (openerp)

For more details, see:
https://code.launchpad.net/~openerp-dev/openobject-server/trunk-dbcreatecache-vmt/+merge/77777

createdb cache
-- 
https://code.launchpad.net/~openerp-dev/openobject-server/trunk-dbcreatecache-vmt/+merge/77777
Your team OpenERP R&D Team is subscribed to branch 
lp:~openerp-dev/openobject-server/trunk-dbcreatecache-vmt.
=== modified file 'openerp/service/web_services.py'
--- openerp/service/web_services.py	2011-09-30 13:59:42 +0000
+++ openerp/service/web_services.py	2011-10-01 02:26:18 +0000
@@ -30,6 +30,7 @@
 import threading
 import time
 import traceback
+import zlib
 from cStringIO import StringIO
 from openerp.tools.translate import _
 import openerp.netsvc as netsvc
@@ -49,6 +50,7 @@
     procedures to be called. Each method has its own arguments footprint.
 """
 
+<<<<<<< TREE
 RPC_VERSION_1 = {'server_version': '6.1', 'protocol_version': 1}
 
 # This should be moved to openerp.modules.db, along side initialize().
@@ -57,35 +59,101 @@
     try:
         serv.actions[id]['progress'] = 0
         cr = sql_db.db_connect(db_name).cursor()
+=======
+DBInitializerCache = {}
+
+class DBInitializer(object):
+    def __init__(self, service, action_id, db_name, db_demo, db_lang, db_user_password='admin'):
+        self.service = service
+        self.action_id = action_id
+        self.action = self.service.actions[action_id]
+        self.db_name = db_name
+        self.db_lang = db_lang
+        self.db_demo = db_demo
+        self.db_user_password = db_user_password
+        self.registry = None
+
+    def __call__(self):
+        self.run()
+
+    def with_cr(self, f):
+        cr = None
+        try:
+            cr = sql_db.db_connect(self.db_name).cursor()
+            f(cr)
+        finally:
+            if cr:
+                cr.close()
+
+    def run(self):
+        try:
+            self.action['progress'] = 0
+            key = (self.db_lang, self.db_demo)
+            if key not in DBInitializerCache:
+                self.run_new(key)
+            else:
+                self.run_cached(key)
+        except Exception, e:
+            e_str = StringIO()
+            traceback.print_exc(file=e_str)
+            traceback_str = e_str.getvalue()
+            e_str.close()
+            netsvc.Logger().notifyChannel('web-services', netsvc.LOG_ERROR, 'CREATE DATABASE\n%s' % (traceback_str))
+            self.action['clean'] = False
+            self.action['exception'] = e
+            self.action['traceback'] = traceback_str
+
+    def run_new(self, key):
+        self.service._create_empty_database(self.db_name)
+        self.with_cr(self.init_base)
+        self.with_cr(self.init_lang)
+        try:
+            s = zlib.compress(self.service.exp_dump(self.db_name), 9)
+            DBInitializerCache[key] = s
+            netsvc.Logger().notifyChannel('web-services', netsvc.LOG_DEBUG, 'CREATE DATABASE cached %r size %d' % (key, len(s)))
+        except Exception,e:
+            pass
+            self.with_cr(self.init_user)
+
+    def run_cached(self, key):
+        s = DBInitializerCache[key]
+        self.service.exp_restore(self.db_name, zlib.decompress(s))
+        self.registry = pooler.restart_pool(self.db_name, self.db_demo, None)[1]
+        self.with_cr(self.init_user)
+        self.with_cr(self.init_cached)
+
+    def init_base(self, cr):
+>>>>>>> MERGE-SOURCE
         openerp.modules.db.initialize(cr) # TODO this should be removed as it is done by pooler.restart_pool.
-        tools.config['lang'] = lang
         cr.commit()
-        cr.close()
-
-        pool = pooler.restart_pool(db_name, demo, serv.actions[id],
-                                   update_module=True)[1]
-
-        cr = sql_db.db_connect(db_name).cursor()
-
-        if lang:
-            modobj = pool.get('ir.module.module')
+        tools.config['lang'] = self.db_lang
+        self.registry = pooler.restart_pool(self.db_name, self.db_demo, self.action, update_module=True)[1]
+
+    def init_lang(self, cr):
+        if self.db_lang:
+            modobj = self.registry.get('ir.module.module')
             mids = modobj.search(cr, 1, [('state', '=', 'installed')])
-            modobj.update_translations(cr, 1, mids, lang)
+            modobj.update_translations(cr, 1, mids, self.db_lang)
+            cr.commit()
 
-        cr.execute('UPDATE res_users SET password=%s, context_lang=%s, active=True WHERE login=%s', (
-            user_password, lang, 'admin'))
-        cr.execute('SELECT login, password, name ' \
-                   '  FROM res_users ' \
-                   ' ORDER BY login')
-        serv.actions[id].update(users=cr.dictfetchall(), clean=True)
+    def init_user(self, cr):
+        cr.execute('UPDATE res_users SET password=%s, context_lang=%s, active=True WHERE login=%s', ( self.db_user_password, self.db_lang, 'admin'))
+        cr.execute('SELECT login, password, name FROM res_users ORDER BY login')
+        self.action['users'] = cr.dictfetchall()
+        self.action['clean'] = True
         cr.commit()
-        cr.close()
-    except Exception, e:
-        serv.actions[id].update(clean=False, exception=e)
-        logging.getLogger('db.create').exception('CREATE DATABASE failed:')
-        serv.actions[id]['traceback'] = traceback.format_exc()
-        if cr:
-            cr.close()
+
+    def init_cached(self, cr):
+        cr.execute('DELETE from ir_config_parameter')
+        self.registry.get('ir.config_parameter').init(cr)
+        cr.execute('UPDATE res_users SET password=%s WHERE id=1',(self.db_user_password,))
+        for i in self.registry.obj_list():
+            table = self.registry.get(i)._table
+            cr.execute("SELECT c.relname FROM pg_class c, pg_attribute a WHERE c.oid=a.attrelid AND c.relname=%s AND a.attname=%s", (table, 'create_date'))
+        if len(cr.fetchall()) > 0:
+            cr.execute('UPDATE %s SET create_date = NOW() WHERE create_date IS NOT NULL'%table)
+            cr.execute('UPDATE %s SET write_date = NOW() WHERE write_date IS NOT NULL'%table)
+            cr.commit()
 
 class db(netsvc.ExportService):
     def __init__(self, name="db"):
@@ -113,6 +181,12 @@
         fn = getattr(self, 'exp_'+method)
         return fn(*params)
 
+<<<<<<< TREE
+=======
+    def new_dispatch(self,method,auth,params):
+        pass
+
+>>>>>>> MERGE-SOURCE
     def _create_empty_database(self, name):
         db = sql_db.db_connect('template1')
         cr = db.cursor()
@@ -130,11 +204,13 @@
 
         self.actions[id] = {'clean': False}
 
-        self._create_empty_database(db_name)
+        if self.exp_db_exist(db_name):
+            logging.getLogger("db.create").warning('CREATE DATABASE: %s already exists' % (db_name,))
+            raise Exception, "Database already exists"
 
         logging.getLogger('db.create').info('CREATE DATABASE %s', db_name.lower())
-        create_thread = threading.Thread(target=_initialize_db,
-                args=(self, id, db_name, demo, lang, user_password))
+        dbi = DBInitializer(self, id, db_name, demo, lang, user_password)
+        create_thread = threading.Thread(target=dbi)
         create_thread.start()
         self.actions[id]['thread'] = create_thread
         return id
@@ -257,11 +333,12 @@
             args2=list(args2)
             args2.append(' ' + tmpfile)
             args2=tuple(args2)
-        stdin, stdout = tools.exec_pg_command_pipe(*args2)
+        p = tools.exec_pg_command_pipe_subprocess(*args2)
         if not os.name == "nt":
-            stdin.write(base64.decodestring(data))
-        stdin.close()
-        res = stdout.close()
+            p.stdin.write(base64.decodestring(data))
+        p.stdin.close()
+        p.stdout.close()
+        res = p.wait()
         if res:
             raise Exception, "Couldn't restore database"
         logger.notifyChannel("web-services", netsvc.LOG_INFO,
@@ -401,18 +478,12 @@
         @return string if extended is False else tuple
         """
 
-        info = _('''
-
-OpenERP is an ERP+CRM program for small and medium businesses.
-
-The whole source code is distributed under the terms of the
-GNU Public Licence.
-
-(c) 2003-TODAY, Fabien Pinckaers - Tiny sprl''')
+        info = 'OpenERP'
 
         if extended:
             return info, release.version
-        return info
+        else:
+            return info
 
     def exp_timezone_get(self, db, login, password):
         return tools.misc.get_server_timezone()
@@ -429,7 +500,6 @@
         except tm.RemoteContractException, e:
             netsvc.abort_response(1, 'Migration Error', 'warning', str(e))
 
-
     def exp_get_migration_scripts(self, contract_id, contract_password):
         l = netsvc.Logger()
         import openerp.tools.maintenance as tm
@@ -781,6 +851,4 @@
     wizard()
     report_spool()
 
-
 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
-

=== modified file 'openerp/tools/misc.py'
--- openerp/tools/misc.py	2011-09-22 09:54:43 +0000
+++ openerp/tools/misc.py	2011-10-01 02:26:18 +0000
@@ -97,15 +97,19 @@
 
     return subprocess.call(args2)
 
+def exec_pg_command_pipe_subprocess(name, *args):
+    prog = find_pg_tool(name)
+    if not prog:
+        raise Exception('Couldn\'t find %s' % name)
+    # On win32, passing close_fds=True is not compatible
+    # with redirecting std{in,err,out}.
+    pop = subprocess.Popen((prog,) + args, bufsize= -1,
+        stdin=subprocess.PIPE, stdout=subprocess.PIPE,
+        close_fds=(os.name=="posix"))
+    return pop
+
 def exec_pg_command_pipe(name, *args):
-    prog = find_pg_tool(name)
-    if not prog:
-        raise Exception('Couldn\'t find %s' % name)
-    # on win32, passing close_fds=True is not compatible
-    # with redirecting std[in/err/out]
-    pop = subprocess.Popen((prog,) + args, bufsize= -1,
-          stdin=subprocess.PIPE, stdout=subprocess.PIPE,
-          close_fds=(os.name=="posix"))
+    pop = exec_pg_command_pipe_subprocess(name, *args)
     return (pop.stdin, pop.stdout)
 
 def exec_command_pipe(name, *args):

_______________________________________________
Mailing list: https://launchpad.net/~openerp-dev-gtk
Post to     : [email protected]
Unsubscribe : https://launchpad.net/~openerp-dev-gtk
More help   : https://help.launchpad.net/ListHelp

Reply via email to