diff --git a/bin/addons/__init__.py b/bin/addons/__init__.py index 156688c322a..74ecc9a6f04 100644 --- a/bin/addons/__init__.py +++ b/bin/addons/__init__.py @@ -270,25 +270,26 @@ def load_module_graph(cr, graph, status=None, **kwargs): cr.execute('update ir_module_module set demo=%s where name=%s', (True, package.name)) package_todo.append(package.name) cr.execute("update ir_module_module set state='installed' where state in ('to upgrade', 'to install') and name=%s", (package.name,)) - - # check if all model of the module have at least a access rule. - cr.execute(""" SELECT name - FROM ir_model m - WHERE EXISTS (SELECT 1 - FROM ir_model_data - WHERE module = %s - AND model = m.name - ) - AND NOT EXISTS (SELECT 1 - FROM ir_model_access - WHERE model_id = m.id - ) - """, (m,)) - for (model,) in cr.fetchall(): - logger.notifyChannel('init', netsvc.LOG_WARNING, 'addon:%s:object %s has no access rules!' % (m,model,)) + # check if all model of the module have at least a access rule. + # TODO: improve this query which is very slow !!! + cr.execute(""" SELECT name + FROM ir_model m + WHERE EXISTS (SELECT 1 + FROM ir_model_data + WHERE module = %s + AND model = m.name + ) + AND NOT EXISTS (SELECT 1 + FROM ir_model_access + WHERE model_id = m.id + ) + """, (m,)) - cr.commit() + for (model,) in cr.fetchall(): + logger.notifyChannel('init', netsvc.LOG_WARNING, 'addon:%s:object %s has no access rules!' % (m,model,)) + + cr.commit() statusi+=1 pool = pooler.get_pool(cr.dbname) diff --git a/bin/osv/expression.py b/bin/osv/expression.py index 842dabf031f..b98c6fac9fc 100644 --- a/bin/osv/expression.py +++ b/bin/osv/expression.py @@ -17,12 +17,11 @@ class expression(object): and element in ['&', '|', '!'] def _is_leaf(self, element): - return isinstance(element, tuple) \ + return (isinstance(element, tuple) or isinstance(element, list)) \ and len(element) == 3 \ - and element[1] in ('=', '!=', '<>', '<=', '<', '>', '>=', '=like', 'like', 'not like', 'ilike', 'not ilike', 'in', 'not in', 'child_of') + and element[1] in ('=', '!=', '<>', '<=', '<', '>', '>=', '=like', 'like', 'not like', 'ilike', 'not ilike', 'in', 'not in', 'child_of', 'inselect') def __execute_recursive_in(self, cr, s, f, w, ids): - #deprecated -> use _left and _right... res = [] for i in range(0, len(ids), cr.IN_MAX): subids = ids[i:i+cr.IN_MAX] @@ -50,23 +49,30 @@ class expression(object): if not self.__exp: return self - def _rec_get(ids, table, parent): - if table._parent_store: + def _rec_get(ids, table, parent, left='id', prefix=''): + if table._parent_store and (not table.pool._init): +# TODO: Improve where joins are implemented for many with '.', replace by: +# doms += ['&',(prefix+'.parent_left','<',o.parent_right),(prefix+'.parent_left','>=',o.parent_left)] doms = [] for o in table.browse(cr, uid, ids, context=context): if doms: doms.insert(0,'|') doms += ['&',('parent_left','<',o.parent_right),('parent_left','>=',o.parent_left)] - return table.search(cr, uid, doms, context=context) + if prefix: + return [(left, 'in', table.search(cr, uid, doms, context=context))] + return doms else: if not ids: return [] ids2 = table.search(cr, uid, [(parent, 'in', ids)], context=context) - return ids + _rec_get(ids2, table, parent) + return [(prefix+left, 'in', ids2+ids)] self.__main_table = table - for i, e in enumerate(self.__exp): + i = -1 + while i+1 pleft: - treeshift = pleft - cleft + 1 - leftbound = pleft+1 - rightbound = cleft-1 - cwidth = cright-cleft+1 - leftrange = cright - rightrange = pleft + cr.execute('select parent_left,parent_right from '+self._table+' where id=%d', (vals[self._parent_name],)) + res = cr.fetchone() + if res: + pleft,pright = res else: - treeshift = pleft - cright - leftbound = cright + 1 - rightbound = pleft - cwidth = cleft-cright-1 - leftrange = pleft+1 - rightrange = cleft - cr.execute('UPDATE '+self._table+''' - SET - parent_left = CASE - WHEN parent_left BETWEEN %d AND %d THEN parent_left + %d - WHEN parent_left BETWEEN %d AND %d THEN parent_left + %d - ELSE parent_left - END, - parent_right = CASE - WHEN parent_right BETWEEN %d AND %d THEN parent_right + %d - WHEN parent_right BETWEEN %d AND %d THEN parent_right + %d - ELSE parent_right - END - WHERE - parent_left<%d OR parent_right>%d; - ''', (leftbound,rightbound,cwidth,cleft,cright,treeshift,leftbound,rightbound, - cwidth,cleft,cright,treeshift,leftrange,rightrange)) + cr.execute('select max(parent_right),max(parent_right)+1 from '+self._table) + pleft,pright = cr.fetchone() + cr.execute('select parent_left,parent_right,id from '+self._table+' where id in ('+','.join(map(lambda x:'%d',ids))+')', ids) + dest = pleft + 1 + for cleft,cright,cid in cr.fetchall(): + if cleft > pleft: + treeshift = pleft - cleft + 1 + leftbound = pleft+1 + rightbound = cleft-1 + cwidth = cright-cleft+1 + leftrange = cright + rightrange = pleft + else: + treeshift = pleft - cright + leftbound = cright + 1 + rightbound = pleft + cwidth = cleft-cright-1 + leftrange = pleft+1 + rightrange = cleft + cr.execute('UPDATE '+self._table+''' + SET + parent_left = CASE + WHEN parent_left BETWEEN %d AND %d THEN parent_left + %d + WHEN parent_left BETWEEN %d AND %d THEN parent_left + %d + ELSE parent_left + END, + parent_right = CASE + WHEN parent_right BETWEEN %d AND %d THEN parent_right + %d + WHEN parent_right BETWEEN %d AND %d THEN parent_right + %d + ELSE parent_right + END + WHERE + parent_left<%d OR parent_right>%d; + ''', (leftbound,rightbound,cwidth,cleft,cright,treeshift,leftbound,rightbound, + cwidth,cleft,cright,treeshift,leftrange,rightrange)) if 'read_delta' in context: del context['read_delta'] @@ -2206,16 +2231,19 @@ class orm(orm_template): self._validate(cr, user, [id_new], context) if self._parent_store: - parent = vals.get(self._parent_name, False) - if parent: - cr.execute('select parent_left from '+self._table+' where id=%d', (parent,)) - pleft = cr.fetchone()[0] + if self.pool._init: + self.pool._init_parent[self._name]=True else: - cr.execute('select max(parent_right) from '+self._table) - pleft = cr.fetchone()[0] or 0 - cr.execute('update '+self._table+' set parent_left=%d,parent_right=%d', (pleft+1,pleft+2)) - cr.execute('update '+self._table+' set parent_left=parent_left+2 where parent_left>%d', (pleft,)) - cr.execute('update '+self._table+' set parent_right=parent_right+2 where parent_right>%d', (pleft,)) + parent = vals.get(self._parent_name, False) + if parent: + cr.execute('select parent_left from '+self._table+' where id=%d', (parent,)) + pleft = cr.fetchone()[0] + else: + cr.execute('select max(parent_right) from '+self._table) + pleft = cr.fetchone()[0] or 0 + cr.execute('update '+self._table+' set parent_left=%d,parent_right=%d', (pleft+1,pleft+2)) + cr.execute('update '+self._table+' set parent_left=parent_left+2 where parent_left>%d', (pleft,)) + cr.execute('update '+self._table+' set parent_right=parent_right+2 where parent_right>%d', (pleft,)) wf_service = netsvc.LocalService("workflow") wf_service.trg_create(user, self._name, id_new, cr) @@ -2281,7 +2309,7 @@ class orm(orm_template): # records unless they were explicitely asked for if 'active' in self._columns and (active_test and context.get('active_test', True)): if args: - args = ['&', ('active', '=', 1)] + args + args.insert(0, ('active', '=', 1)) else: args = [('active', '=', 1)] diff --git a/bin/osv/osv.py b/bin/osv/osv.py index 369f006c9df..8e2944eed76 100644 --- a/bin/osv/osv.py +++ b/bin/osv/osv.py @@ -60,6 +60,8 @@ class osv_pool(netsvc.Service): self.created = [] self._sql_error = {} self._store_function = {} + self._init = True + self._init_parent = {} netsvc.Service.__init__(self, 'object_proxy', audience='') self.joinGroup('web-services') self.exportMethod(self.exportedMethods) @@ -68,6 +70,17 @@ class osv_pool(netsvc.Service): self.exportMethod(self.execute) self.exportMethod(self.execute_cr) + def init_set(self, cr, mode): + if mode<>self._init: + if mode: + self._init_parent={} + if not mode: + for o in self._init_parent: + self.get(o)._parent_store_compute(cr) + self._init = mode + return True + return False + def execute_cr(self, cr, uid, obj, method, *args, **kw): try: object = pooler.get_pool(cr.dbname).get(obj) diff --git a/bin/pooler.py b/bin/pooler.py index e5c5b82be98..fd23a9edaae 100644 --- a/bin/pooler.py +++ b/bin/pooler.py @@ -54,6 +54,10 @@ def get_db_and_pool(db_name, force_demo=False, status=None, update_module=False) pool = osv.osv.osv_pool() pool_dic[db_name] = pool addons.load_modules(db, force_demo, status, update_module) + cr = db.cursor() + pool.init_set(cr, False) + cr.commit() + cr.close() if not update_module: import report diff --git a/bin/sql_db.py b/bin/sql_db.py index 9da6293cfac..05a5577490c 100644 --- a/bin/sql_db.py +++ b/bin/sql_db.py @@ -59,7 +59,6 @@ class fake_cursor: self.dbname = dbname def execute(self, sql, params=None): - print sql, params if not params: params=() def base_string(s):