def test_SMTPDataManager(self, get_smtp_server): "Test SMTPDataManager" transaction = Transaction() get_smtp_server.return_value = server = Mock() datamanager = transaction.join(SMTPDataManager()) # multiple join must return the same self.assertEqual(transaction.join(SMTPDataManager()), datamanager) msg1 = Mock(Message) msg2 = Mock(Message) datamanager.put("*****@*****.**", "*****@*****.**", msg1) datamanager.put("*****@*****.**", "*****@*****.**", msg2) transaction.commit() server.sendmail.assert_has_calls( [ call("*****@*****.**", "*****@*****.**", msg1.as_string()), call("*****@*****.**", "*****@*****.**", msg2.as_string()), ] ) server.quit.assert_called_once_with() self.assertFalse(datamanager.queue) server.reset_mock() datamanager.put("*****@*****.**", "*****@*****.**", Mock(Message)) transaction.rollback() server.sendmail.assert_not_called() self.assertFalse(datamanager.queue)
def create(self, vals): cursor = Transaction().cursor if vals.get('from_party', False): cursor.execute('INSERT INTO ' +self._table +\ ' (id, create_uid, party, company, peripatetic)'\ 'VALUES (%s, %s, %s, %s, %s)',\ (vals.get('id'), vals.get('create_uid'), vals.get('party'), Transaction().context.get('company'), False)) cursor.commit() res = self.browse(vals.get('id')) return res.id else: later = {} vals = vals.copy() for field in vals: if field in self._columns\ and hasattr(self._columns[field], 'set'): later[field] = vals[field] for field in later: del vals[field] if cursor.nextid(self._table): cursor.setnextid(self._table, cursor.currid(self._table)) new_id = super(Employee, self).create(vals) employee = self.browse(new_id) new_id = employee.party.id cursor.execute('UPDATE "' + self._table + '" SET id = %s '\ 'WHERE id = %s', (employee.party.id, employee.id)) ModelStorage.delete(self, employee.id) self.write(new_id, later) res = self.browse(new_id) return res.id
def test_ordered_search_same_timestamp(self): 'Test ordered search with same timestamp' pool = Pool() History = pool.get('test.history') transaction = Transaction() order = [('value', 'ASC')] history = History(value=1) history.save() first_stamp = history.create_date history.value = 4 history.save() second_stamp = history.write_date self.assertEqual(first_stamp, second_stamp) transaction.commit() results = [ (second_stamp, [history], [4]), (datetime.datetime.now(), [history], [4]), (datetime.datetime.max, [history], [4]), ] for timestamp, instances, values in results: with Transaction().set_context(_datetime=timestamp, last_test=True): records = History.search([], order=order) self.assertEqual(records, instances) self.assertEqual([x.value for x in records], values) transaction.rollback()
def test_read_same_timestamp(self): 'Test read history with same timestamp' pool = Pool() History = pool.get('test.history') transaction = Transaction() history = History(value=1) history.save() history_id = history.id first = history.create_date history.value = 2 history.save() second = history.write_date self.assertEqual(first, second) transaction.commit() history = History(history_id) history.value = 3 history.save() third = history.write_date transaction.commit() for timestamp, value in [ (first, 2), (third, 3), ]: with Transaction().set_context(_datetime=timestamp): history = History(history_id) self.assertEqual(history.value, value)
def button_process_continue(self, ids, start=False): cr = Transaction().cursor categs = self.read(ids,['category','exclusif','party', 'sales_purchase_active', 'profiling_active']) for categ in categs: if start: if categ['exclusif']: cr.execute('delete from party_category_rel where category=%s', (categ['categ'][0],)) id = categ['id'] cr.execute('select id from res_party order by id ') partys = [x[0] for x in cr.fetchall()] if categ['sales_purchase_active']: to_remove_list=[] cr.execute('select id from ekd_crm_segmentation_line where segmentation=%s', (id,)) line_ids = [x[0] for x in cr.fetchall()] for pid in partys: if (not self.pool.get('ekd.crm.segmentation.line').test(cr, uid, line_ids, pid)): to_remove_list.append(pid) for pid in to_remove_list: partys.remove(pid) for party in partys: cr.execute('insert into party_category_rel (category,party) values (%s,%s)', (categ['categ'][0],party)) cr.commit() self.write([id], {'state':'not running', 'party':0}) cr.commit() return True
def test_ordered_search_nested(self): "Test ordered search nested" pool = Pool() History = pool.get('test.history') HistoryLine = pool.get('test.history.line') transaction = Transaction() order = [('history.value', 'ASC')] history = History(value=1) history.save() history2 = History(value=2) history2.save() line = HistoryLine(history=history) line.save() line2 = HistoryLine(history=history2) line2.save() first_stamp = line2.create_date transaction.commit() history.value = 3 history.save() second_stamp = history.write_date transaction.commit() results = [ (first_stamp, [line, line2]), (second_stamp, [line2, line]), ] for timestamp, instances in results: with Transaction().set_context(_datetime=timestamp): records = HistoryLine.search([], order=order) self.assertListEqual(records, instances)
def test_SMTPDataManager(self, get_smtp_server): 'Test SMTPDataManager' transaction = Transaction() get_smtp_server.return_value = server = Mock() datamanager = transaction.join(SMTPDataManager()) # multiple join must return the same self.assertEqual(transaction.join(SMTPDataManager()), datamanager) msg1 = Mock(Message) msg2 = Mock(Message) datamanager.put('*****@*****.**', '*****@*****.**', msg1) datamanager.put('*****@*****.**', '*****@*****.**', msg2) transaction.commit() server.sendmail.assert_has_calls([ call('*****@*****.**', '*****@*****.**', msg1.as_string()), call('*****@*****.**', '*****@*****.**', msg2.as_string()), ]) server.quit.assert_called_once_with() self.assertFalse(datamanager.queue) server.reset_mock() datamanager.put('*****@*****.**', '*****@*****.**', Mock(Message)) transaction.rollback() server.sendmail.assert_not_called() self.assertFalse(datamanager.queue)
def test_restore_history_same_timestamp(self): 'Test restore history with same timestamp' pool = Pool() History = pool.get('test.history') transaction = Transaction() history = History(value=1) history.save() history_id = history.id first = history.create_date history.value = 2 history.save() second = history.create_date self.assertEqual(first, second) transaction.commit() history = History(history_id) history.value = 3 history.save() transaction.commit() History.restore_history([history_id], first) history = History(history_id) self.assertEqual(history.value, 2)
def post_import(pool, module, to_delete): """ Remove the records that are given in to_delete. """ transaction = Transaction() mdata_delete = [] ModelData = pool.get("ir.model.data") with Transaction().set_context(active_test=False): mdata = ModelData.search([ ('fs_id', 'in', to_delete), ('module', '=', module), ], order=[('id', 'DESC')]) for mrec in mdata: model, db_id, fs_id = mrec.model, mrec.db_id, mrec.fs_id logger.info('Deleting %s@%s from %s.%s', db_id, model, module, fs_id) try: # Deletion of the record try: Model = pool.get(model) except KeyError: Model = None if Model: Model.delete([Model(db_id)]) mdata_delete.append(mrec) else: logger.warning( 'Could not delete id %d of model %s because model no ' 'longer exists.', db_id, model) except Exception: transaction.rollback() logger.error( "Could not delete id %d from model %s.\n" "There may be a relation that points to this resource " "that must be manually fixed before restarting the update.", db_id, model, exc_info=True) if 'active' in Model._fields: try: Model.write([Model(db_id)], { 'active': False, }) except Exception: transaction.rollback() logger.error('Could not inactivate id: %d of model %s\n', db_id, model, exc_info=True) transaction.commit() # Clean model_data: if mdata_delete: ModelData.delete(mdata_delete) transaction.commit() return True
def test_browse(self): 'Test browsing history' pool = Pool() History = pool.get('test.history') Line = pool.get('test.history.line') transaction = Transaction() history = History(value=1) history.save() history_id = history.id line_a = Line(name='a', history=history) line_a.save() line_a_id = line_a.id line_b = Line(name='b', history=history) line_b.save() line_b_id = line_b.id first_stamp = line_b.create_date history.stamp = first_stamp history.save() transaction.commit() history = History(history_id) history.value = 2 history.save() Line.delete([Line(line_b_id)]) line_a = Line(line_a_id) line_a.name = 'c' line_a.save() second_stamp = line_a.write_date transaction.commit() history = History(history_id) self.assertEqual(history.value, 2) self.assertEqual([l.name for l in history.lines], ['c']) self.assertEqual(history.stamp, first_stamp) self.assertEqual( [l.name for l in history.lines_at_stamp], ['a', 'b']) with Transaction().set_context(_datetime=first_stamp): history = History(history_id) self.assertEqual(history.value, 1) self.assertEqual([l.name for l in history.lines], ['a', 'b']) with Transaction().set_context(_datetime=second_stamp): history = History(history_id) self.assertEqual(history.value, 2) self.assertEqual([l.name for l in history.lines], ['c']) self.assertEqual(history.stamp, first_stamp) self.assertEqual( [l.name for l in history.lines_at_stamp], ['a', 'b'])
def tearDown(self): pool = Pool() History = pool.get('test.history') cursor = Transaction().cursor table = History.__table__() history_table = History.__table_history__() cursor.execute(*table.delete()) cursor.execute(*history_table.delete()) cursor.commit()
def _load_modules(): global res TableHandler = backend.get('TableHandler') transaction = Transaction() with transaction.connection.cursor() as cursor: # Migration from 3.6: remove double module old_table = 'ir_module_module' new_table = 'ir_module' if TableHandler.table_exist(old_table): TableHandler.table_rename(old_table, new_table) if update: cursor.execute(*ir_module.select(ir_module.name, where=ir_module.state.in_(( 'installed', 'to install', 'to upgrade', 'to remove')))) else: cursor.execute(*ir_module.select(ir_module.name, where=ir_module.state.in_(( 'installed', 'to upgrade', 'to remove')))) module_list = [name for (name, ) in cursor.fetchall()] if update: module_list += update graph = create_graph(module_list)[0] load_module_graph(graph, pool, update, lang) if update: cursor.execute(*ir_module.select( ir_module.name, where=(ir_module.state == 'to remove'))) fetchall = cursor.fetchall() if fetchall: for (mod_name, ) in fetchall: # TODO check if ressource not updated by the user cursor.execute(*ir_model_data.select( ir_model_data.model, ir_model_data.db_id, where=(ir_model_data.module == mod_name), order_by=ir_model_data.id.desc)) for rmod, rid in cursor.fetchall(): Model = pool.get(rmod) Model.delete([Model(rid)]) Transaction().connection.commit() cursor.execute( *ir_module.update([ir_module.state], ['uninstalled'], where=( ir_module.state == 'to remove'))) Transaction().connection.commit() res = False Module = pool.get('ir.module') Module.update_list() # Need to commit to unlock SQLite database transaction.commit() Cache.resets(database_name)
def create(self, vals): new_id = super(Department, self).create(vals) if vals.get('as_stock'): cursor = Transaction().cursor cursor.execute('INSERT INTO ekd_company_department_stock'\ ' (id, create_uid, department)'\ 'VALUES (%s, %s, %s)',\ (new_id, Transaction().user, new_id)) cursor.commit() return new_id
def tearDown(self): pool = Pool() History = pool.get('test.history') transaction = Transaction() cursor = transaction.connection.cursor() table = History.__table__() history_table = History.__table_history__() cursor.execute(*table.delete()) cursor.execute(*history_table.delete()) transaction.commit()
def create(self, vals): new_id = super(Department, self).create(vals) if vals.get("as_stock"): cursor = Transaction().cursor cursor.execute( "INSERT INTO ekd_company_department_stock" " (id, create_uid, department)" "VALUES (%s, %s, %s)", (new_id, Transaction().user, new_id), ) cursor.commit() return new_id
def test_MessageDataManager_commit(self, get_twilio_client, sendmessage): "Test MessageDataManager commit" transaction = Transaction() get_twilio_client.return_value = client = Mock() datamanager = transaction.join(twilio_messages.MessageDataManager()) message = {'to': '+123456', 'body': "Message"} datamanager.put(message) transaction.commit() sendmessage.assert_called_once_with(message, client=client)
def tearDown(self): pool = Pool() History = pool.get('test.history') HistoryLine = pool.get('test.history.line') transaction = Transaction() cursor = transaction.connection.cursor() for Model in [History, HistoryLine]: table = Model.__table__() history_table = Model.__table_history__() cursor.execute(*table.delete()) cursor.execute(*history_table.delete()) transaction.commit()
def post_import(pool, module, to_delete): """ Remove the records that are given in to_delete. """ cursor = Transaction().cursor mdata_delete = [] ModelData = pool.get("ir.model.data") with Transaction().set_context(active_test=False): mdata = ModelData.search([ ('fs_id', 'in', to_delete), ('module', '=', module), ], order=[('id', 'DESC')]) object_name_list = set(pool.object_name_list()) for mrec in mdata: model, db_id = mrec.model, mrec.db_id logging.getLogger("convert").info( 'Deleting %s@%s' % (db_id, model)) try: # Deletion of the record if model in object_name_list: Model = pool.get(model) Model.delete([Model(db_id)]) mdata_delete.append(mrec) else: logging.getLogger("convert").warning( 'Could not delete id %d of model %s because model no ' 'longer exists.' % (db_id, model)) cursor.commit() except Exception: cursor.rollback() tb_s = ''.join(traceback.format_exception(*sys.exc_info())) logging.getLogger("convert").error( 'Could not delete id: %d of model %s\n' 'There should be some relation ' 'that points to this resource\n' 'You should manually fix this ' 'and restart --update=module\n' 'Exception: %s' % (db_id, model, tb_s)) if 'active' in Model._fields: Model.write([Model(db_id)], { 'active': False, }) # Clean model_data: if mdata_delete: ModelData.delete(mdata_delete) cursor.commit() return True
def test_check_timestamp(self): 'Test check timestamp' pool = Pool() ModelsqlTimestamp = pool.get('test.modelsql.timestamp') transaction = Transaction() # transaction must be committed between each changes otherwise NOW() # returns always the same timestamp. record, = ModelsqlTimestamp.create([{}]) transaction.commit() timestamp = ModelsqlTimestamp.read([record.id], ['_timestamp'])[0]['_timestamp'] if backend.name() in ('sqlite', 'mysql'): # timestamp precision of sqlite is the second time.sleep(1) ModelsqlTimestamp.write([record], {}) transaction.commit() transaction.timestamp[str(record)] = timestamp self.assertRaises(ConcurrencyException, ModelsqlTimestamp.write, [record], {}) transaction.timestamp[str(record)] = timestamp self.assertRaises(ConcurrencyException, ModelsqlTimestamp.delete, [record]) transaction.timestamp.pop(str(record), None) ModelsqlTimestamp.write([record], {}) transaction.commit() ModelsqlTimestamp.delete([record]) transaction.commit()
def write(self, ids, vals): cursor = Transaction().cursor if vals.get("as_stock"): for id_ in ids: cursor.execute( "INSERT INTO ekd_company_department_stock" " (id, create_uid, department)" "VALUES (%s, %s, %s)", (id_, Transaction().user, id_), ) cursor.commit() else: cursor.execute("DELETE FROM ekd_company_department_stock" " WHERE id = %s" % (ids)) cursor.commit() return super(Department, self).write(ids, vals)
def test_check_timestamp(self): 'Test check timestamp' pool = Pool() ModelsqlTimestamp = pool.get('test.modelsql.timestamp') transaction = Transaction() # transaction must be committed between each changes otherwise NOW() # returns always the same timestamp. record, = ModelsqlTimestamp.create([{}]) transaction.commit() timestamp = ModelsqlTimestamp.read([record.id], ['_timestamp'])[0]['_timestamp'] if backend.name() == 'sqlite': # timestamp precision of sqlite is the second time.sleep(1) ModelsqlTimestamp.write([record], {}) transaction.commit() transaction.timestamp[str(record)] = timestamp self.assertRaises(ConcurrencyException, ModelsqlTimestamp.write, [record], {}) transaction.timestamp[str(record)] = timestamp self.assertRaises(ConcurrencyException, ModelsqlTimestamp.delete, [record]) transaction.timestamp.pop(str(record), None) ModelsqlTimestamp.write([record], {}) transaction.commit() ModelsqlTimestamp.delete([record]) transaction.commit()
def write(self, ids, vals): cursor = Transaction().cursor if vals.get('as_stock'): for id_ in ids: cursor.execute('INSERT INTO ekd_company_department_stock'\ ' (id, create_uid, department)'\ 'VALUES (%s, %s, %s)',\ (id_, Transaction().user, id_)) cursor.commit() else: cursor.execute('DELETE FROM ekd_company_department_stock'\ ' WHERE id = %s'%(ids)) cursor.commit() return super(Department, self).write(ids, vals)
def test_lock(self): "Test lock" pool = Pool() Model = pool.get('test.modelsql.lock') transaction = Transaction() record_id = Model.create([{}])[0].id transaction.commit() with transaction.new_transaction(): record = Model(record_id) record.lock() with transaction.new_transaction(): record = Model(record_id) with self.assertRaises(backend.DatabaseOperationalError): record.lock()
def __register__(cls, module_name): '''handles the rewiring of the Jamaica parishes to merge Kingston and Saint Andrew (JM-01 and JM-02)''' super(PostOffice, cls).__register__(module_name) cursor = Transaction().cursor # update subdivision table to remove st. andrew and merge with Kgn cursor.execute('Select name from country_subdivision where code=%s', ('JM-02', )) standrew = cursor.fetchone() if standrew: sql = ['DELETE from country_subdivision where code=%s'] parms = [('JM-02', )] for query, query_param in zip(sql, parms): cursor.execute(query, query_param) cursor.commit()
def wrapper(*args, **kwargs): _db = Tdb._db _readonly = True if readonly is not None: _readonly = readonly elif 'request' in kwargs: _readonly = not (kwargs['request'].method in ('PUT', 'POST', 'DELETE', 'PATCH')) _user = user or 0 _context = {} _retry = Tdb._retry or 0 _is_open = (Transaction().cursor) if not _is_open: with Transaction().start(_db, 0): Cache.clean(_db) _context.update(default_context()) else: # Transaction().new_cursor(readonly=_readonly) pass _context.update(context or {}) # _context.update({'company': Tdb._company}) for count in range(_retry, -1, -1): with NoTransaction() if _is_open else Transaction().start( _db, _user, readonly=_readonly, context=_context): cursor = Transaction().cursor if withhold: cursor.cursor.withhold = True try: result = func(*args, **kwargs) if not _readonly: cursor.commit() except DatabaseOperationalError: cursor.rollback() if count and not _readonly: continue raise except Exception: cursor.rollback() raise Cache.resets(_db) return result
def resets(dbname): with Transaction().new_cursor(): cursor = Transaction().cursor table = Table('ir_cache') with Cache._resets_lock: Cache._resets.setdefault(dbname, set()) for name in Cache._resets[dbname]: cursor.execute( *table.select(table.name, where=table.name == name)) if cursor.fetchone(): # It would be better to insert only cursor.execute( *table.update([table.timestamp], [Now()], where=table.name == name)) else: cursor.execute(*table.insert( [table.timestamp, table.name], [[Now(), name]])) Cache._resets[dbname].clear() cursor.commit()
def test_history_revisions(self): 'Test history revisions' pool = Pool() History = pool.get('test.history') transaction = Transaction() history = History(value=1) history.save() history_id = history.id first = history.create_date transaction.commit() history = History(history_id) history.value = 2 history.save() second = history.write_date transaction.commit() history = History(history_id) history.value = 3 history.save() third = history.write_date transaction.commit() revisions = History.history_revisions([history_id]) self.assertEqual(revisions, [ (third, history_id, 'Administrator'), (second, history_id, 'Administrator'), (first, history_id, 'Administrator'), ])
def test_restore_history_before(self): 'Test restore history before' pool = Pool() History = pool.get('test.history') transaction = Transaction() history = History(value=1) history.save() history_id = history.id transaction.commit() history = History(history_id) history.value = 2 history.save() second = history.write_date transaction.commit() history = History(history_id) history.value = 3 history.save() transaction.commit() History.restore_history_before([history_id], second) history = History(history_id) self.assertEqual(history.value, 1)
def test_history_revisions(self): 'Test history revisions' pool = Pool() History = pool.get('test.history') transaction = Transaction() history = History(value=1) history.save() history_id = history.id first = history.create_date transaction.commit() history = History(history_id) history.value = 2 history.save() second = history.write_date transaction.commit() history = History(history_id) history.value = 3 history.save() third = history.write_date transaction.commit() revisions = History.history_revisions([history_id]) self.assertEqual(revisions, [ (third, history_id, u'Administrator'), (second, history_id, u'Administrator'), (first, history_id, u'Administrator'), ])
def test_subscribe_message(self): "Test subscribe with message" Bus.subscribe(DB_NAME, ['user:1']) transaction = Transaction() with transaction.start(DB_NAME, 1): notify("Test", "Message", user=1) transaction.commit() # Let the listen thread registers the message time.sleep(1) response = Bus.subscribe(DB_NAME, ['user:1']) self.assertTrue(response['message'].pop('message_id')) self.assertEqual(response, { 'message': { 'type': 'notification', 'title': "Test", 'body': "Message", 'priority': 1, }, 'channel': 'user:1', })
def _load_modules(): global res TableHandler = backend.get('TableHandler') cursor = Transaction().cursor # Migration from 3.6: remove double module old_table = 'ir_module_module' new_table = 'ir_module' if TableHandler.table_exist(cursor, old_table): TableHandler.table_rename(cursor, old_table, new_table) if update: cursor.execute(*ir_module.select(ir_module.name, where=ir_module.state.in_(('installed', 'to install', 'to upgrade', 'to remove')))) else: cursor.execute(*ir_module.select(ir_module.name, where=ir_module.state.in_(('installed', 'to upgrade', 'to remove')))) module_list = [name for (name,) in cursor.fetchall()] if update: module_list += update graph = create_graph(module_list)[0] try: load_module_graph(graph, pool, update, lang) except Exception: cursor.rollback() raise if update: cursor.execute(*ir_module.select(ir_module.name, where=(ir_module.state == 'to remove'))) fetchall = cursor.fetchall() if fetchall: for (mod_name,) in fetchall: # TODO check if ressource not updated by the user cursor.execute(*ir_model_data.select(ir_model_data.model, ir_model_data.db_id, where=(ir_model_data.module == mod_name), order_by=ir_model_data.id.desc)) for rmod, rid in cursor.fetchall(): Model = pool.get(rmod) Model.delete([Model(rid)]) cursor.commit() cursor.execute(*ir_module.update([ir_module.state], ['uninstalled'], where=(ir_module.state == 'to remove'))) cursor.commit() res = False Module = pool.get('ir.module') Module.update_list() cursor.commit() Cache.resets(database_name)
def _load_modules(): global res cursor = Transaction().cursor if update: cursor.execute( *ir_module.select(ir_module.name, where=ir_module.state.in_(('installed', 'to install', 'to upgrade', 'to remove')))) else: cursor.execute( *ir_module.select(ir_module.name, where=ir_module.state.in_(('installed', 'to upgrade', 'to remove')))) module_list = [name for (name, ) in cursor.fetchall()] if update: module_list += update graph = create_graph(module_list)[0] try: load_module_graph(graph, pool, update, lang) except Exception: cursor.rollback() raise if update: cursor.execute(*ir_module.select( ir_module.name, where=(ir_module.state == 'to remove'))) fetchall = cursor.fetchall() if fetchall: for (mod_name, ) in fetchall: # TODO check if ressource not updated by the user cursor.execute(*ir_model_data.select( ir_model_data.model, ir_model_data.db_id, where=(ir_model_data.module == mod_name), order_by=ir_model_data.id.desc)) for rmod, rid in cursor.fetchall(): Model = pool.get(rmod) Model.delete([Model(rid)]) cursor.commit() cursor.execute( *ir_module.update([ir_module.state], ['uninstalled'], where=(ir_module.state == 'to remove'))) cursor.commit() res = False Module = pool.get('ir.module.module') Module.update_list() cursor.commit() Cache.resets(database_name)
def test_read(self): 'Test read history' pool = Pool() History = pool.get('test.history') transaction = Transaction() # Create some history entry # It is needed to commit to have different timestamps history = History(value=1) history.save() history_id = history.id first = history.create_date transaction.commit() history = History(history_id) history.value = 2 history.save() second = history.write_date transaction.commit() history = History(history_id) history.value = 3 history.save() third = history.write_date transaction.commit() for timestamp, value in [ (first, 1), (second, 2), (third, 3), (datetime.datetime.now(), 3), (datetime.datetime.max, 3), ]: with Transaction().set_context(_datetime=timestamp): history = History(history_id) self.assertEqual(history.value, value) with Transaction().set_context(_datetime=datetime.datetime.min): with self.assertRaises(AccessError): History.read([history_id], ['value'])
def test_read(self): 'Test read history' pool = Pool() History = pool.get('test.history') transaction = Transaction() # Create some history entry # It is needed to commit to have different timestamps history = History(value=1) history.save() history_id = history.id first = history.create_date transaction.commit() history = History(history_id) history.value = 2 history.save() second = history.write_date transaction.commit() history = History(history_id) history.value = 3 history.save() third = history.write_date transaction.commit() for timestamp, value in [ (first, 1), (second, 2), (third, 3), (datetime.datetime.now(), 3), (datetime.datetime.max, 3), ]: with Transaction().set_context(_datetime=timestamp): history = History(history_id) self.assertEqual(history.value, value) with Transaction().set_context(_datetime=datetime.datetime.min): self.assertRaises(UserError, History.read, [history_id])
def test_restore_history(self): 'Test restore history' pool = Pool() History = pool.get('test.history') transaction = Transaction() history = History(value=1) history.save() history_id = history.id first = history.create_date transaction.commit() history = History(history_id) history.value = 2 history.save() transaction.commit() History.restore_history([history_id], first) history = History(history_id) self.assertEqual(history.value, 1) transaction.rollback() History.restore_history([history_id], datetime.datetime.min) with self.assertRaises(AccessError): History.read([history_id], ['value']) transaction.rollback() History.delete([History(history_id)]) transaction.commit() History.restore_history([history_id], datetime.datetime.max) with self.assertRaises(AccessError): History.read([history_id], ['value'])
def test_restore_history(self): 'Test restore history' pool = Pool() History = pool.get('test.history') transaction = Transaction() history = History(value=1) history.save() history_id = history.id first = history.create_date transaction.commit() history = History(history_id) history.value = 2 history.save() transaction.commit() History.restore_history([history_id], first) history = History(history_id) self.assertEqual(history.value, 1) transaction.rollback() History.restore_history([history_id], datetime.datetime.min) self.assertRaises(UserError, History.read, [history_id]) transaction.rollback() History.delete([History(history_id)]) transaction.commit() History.restore_history([history_id], datetime.datetime.max) self.assertRaises(UserError, History.read, [history_id])
def _load_modules(update): global res transaction = Transaction() with transaction.set_context(_no_trigger=True), \ transaction.connection.cursor() as cursor: # Migration from 3.6: remove double module old_table = 'ir_module_module' new_table = 'ir_module' if backend.TableHandler.table_exist(old_table): backend.TableHandler.table_rename(old_table, new_table) # Migration from 4.0: rename installed to activated cursor.execute( *ir_module.select(ir_module.name, where=ir_module.state.in_(('installed', 'uninstalled')))) if cursor.fetchone(): cursor.execute( *ir_module.update([ir_module.state], ['activated'], where=ir_module.state == 'installed')) cursor.execute( *ir_module.update([ir_module.state], ['not activated'], where=ir_module.state == 'uninstalled')) if update: cursor.execute(*ir_module.select(ir_module.name, where=ir_module.state.in_(( 'activated', 'to activate', 'to upgrade', 'to remove')))) else: cursor.execute(*ir_module.select(ir_module.name, where=ir_module.state.in_(( 'activated', 'to upgrade', 'to remove')))) module_list = [name for (name, ) in cursor] graph = None while graph is None: module_list += update try: graph = create_graph(module_list) except MissingDependenciesException as e: if not activatedeps: raise update += e.missings load_module_graph(graph, pool, update, lang) Configuration = pool.get('ir.configuration') Configuration(1).check() if update: cursor.execute(*ir_module.select( ir_module.name, where=(ir_module.state == 'to remove'))) for mod_name, in cursor: res = False # TODO check if ressource not updated by the user with transaction.connection.cursor() as cursor_delete: cursor_delete.execute(*ir_model_data.select( ir_model_data.model, ir_model_data.db_id, where=(ir_model_data.module == mod_name), order_by=ir_model_data.id.desc)) for rmod, rid in cursor_delete: Model = pool.get(rmod) Model.delete([Model(rid)]) transaction.connection.commit() cursor.execute( *ir_module.update([ir_module.state], ['not activated'], where=(ir_module.state == 'to remove'))) transaction.connection.commit() Module = pool.get('ir.module') Module.update_list() # Need to commit to unlock SQLite database transaction.commit()
def load_module_graph(graph, pool, update=None, lang=None): # Prevent to import backend when importing module from trytond.cache import Cache from trytond.ir.lang import get_parent_language if lang is None: lang = [config.get('database', 'language')] if update is None: update = [] modules_todo = [] models_to_update_history = set() # Load also parent languages lang = set(lang) for code in list(lang): while code: lang.add(code) code = get_parent_language(code) transaction = Transaction() with transaction.connection.cursor() as cursor: modules = [x.name for x in graph] module2state = dict() for sub_modules in tools.grouped_slice(modules): cursor.execute( *ir_module.select(ir_module.name, ir_module.state, where=ir_module.name.in_(list(sub_modules)))) module2state.update(cursor) modules = set(modules) for node in graph: module = node.name if module not in MODULES: continue logger.info(module) classes = pool.fill(module, modules) if update: pool.setup(classes) package_state = module2state.get(module, 'not activated') if (is_module_to_install(module, update) or (update and package_state in ('to activate', 'to upgrade'))): if package_state not in ('to activate', 'to upgrade'): if package_state == 'activated': package_state = 'to upgrade' elif package_state != 'to remove': package_state = 'to activate' for child in node: module2state[child.name] = package_state for type in list(classes.keys()): for cls in classes[type]: logger.info('%s:register %s', module, cls.__name__) cls.__register__(module) for model in classes['model']: if hasattr(model, '_history'): models_to_update_history.add(model.__name__) # Instanciate a new parser for the module tryton_parser = convert.TrytondXmlHandler( pool, module, package_state, modules, lang) for filename in node.info.get('xml', []): filename = filename.replace('/', os.sep) logger.info('%s:loading %s', module, filename) # Feed the parser with xml content: with tools.file_open(OPJ(module, filename), 'rb') as fp: tryton_parser.parse_xmlstream(fp) modules_todo.append((module, list(tryton_parser.to_delete))) load_translations(pool, node, lang) if package_state == 'to remove': continue cursor.execute(*ir_module.select( ir_module.id, where=(ir_module.name == module))) try: module_id, = cursor.fetchone() cursor.execute( *ir_module.update([ir_module.state], ['activated'], where=(ir_module.id == module_id))) except TypeError: cursor.execute(*ir_module.insert([ ir_module.create_uid, ir_module.create_date, ir_module.name, ir_module.state ], [ [0, CurrentTimestamp(), module, 'activated'], ])) module2state[module] = 'activated' # Avoid clearing cache to prevent dead lock on ir.cache table Cache.rollback(transaction) transaction.commit() # Clear transaction cache to update default_factory transaction.cache.clear() if not update: pool.setup() else: # Remove unknown models and fields Model = pool.get('ir.model') Model.clean() ModelField = pool.get('ir.model.field') ModelField.clean() transaction.commit() pool.setup_mixin(modules) for model_name in models_to_update_history: model = pool.get(model_name) if model._history: logger.info('history:update %s', model.__name__) model._update_history_table() # Vacuum : while modules_todo: (module, to_delete) = modules_todo.pop() convert.post_import(pool, module, to_delete) # Ensure cache is clear for other instances Cache.clear_all() Cache.refresh_pool(transaction) logger.info('all modules loaded')
def test_ordered_search(self): 'Test ordered search of history models' pool = Pool() History = pool.get('test.history') transaction = Transaction() order = [('value', 'ASC')] history = History(value=1) history.save() first_id = history.id first_stamp = history.create_date transaction.commit() history = History(value=2) history.save() second_id = history.id second_stamp = history.create_date transaction.commit() first, second = History.search([], order=order) self.assertEqual(first.id, first_id) self.assertEqual(second.id, second_id) first.value = 3 first.save() third_stamp = first.write_date transaction.commit() results = [ (first_stamp, [first]), (second_stamp, [first, second]), (third_stamp, [second, first]), (datetime.datetime.now(), [second, first]), (datetime.datetime.max, [second, first]), ] for timestamp, instances in results: with Transaction().set_context(_datetime=timestamp): records = History.search([], order=order) self.assertEqual(records, instances) transaction.rollback() to_delete, _ = History.search([], order=order) self.assertEqual(to_delete.id, second.id) History.delete([to_delete]) transaction.commit() results = [ (first_stamp, [first]), (second_stamp, [first, second]), (third_stamp, [second, first]), (datetime.datetime.now(), [first]), (datetime.datetime.max, [first]), ] for timestamp, instances in results: with Transaction().set_context(_datetime=timestamp, from_test=True): records = History.search([], order=order) self.assertEqual(records, instances) transaction.rollback()
def _deactivate_extension(cls): connection = Transaction().connection cursor = connection.cursor() cursor.execute('DROP EXTENSION "unaccent"') connection.commit() cls._clear_unaccent_cache()
def load_module_graph(graph, pool, update=None, lang=None): if lang is None: lang = [config.get('database', 'language')] if update is None: update = [] modules_todo = [] models_to_update_history = set() cursor = Transaction().cursor modules = [x.name for x in graph] cursor.execute(*ir_module.select(ir_module.name, ir_module.state, where=ir_module.name.in_(modules))) module2state = dict(cursor.fetchall()) for package in graph: module = package.name if module not in MODULES: continue logger.info(module) classes = pool.setup(module) package_state = module2state.get(module, 'uninstalled') if (is_module_to_install(module, update) or package_state in ('to install', 'to upgrade')): if package_state not in ('to install', 'to upgrade'): if package_state == 'installed': package_state = 'to upgrade' elif package_state != 'to remove': package_state = 'to install' for child in package.childs: module2state[child.name] = package_state for type in classes.keys(): for cls in classes[type]: logger.info('%s:register %s', module, cls.__name__) cls.__register__(module) for model in classes['model']: if hasattr(model, '_history'): models_to_update_history.add(model.__name__) # Instanciate a new parser for the package: tryton_parser = convert.TrytondXmlHandler(pool=pool, module=module, module_state=package_state) for filename in package.info.get('xml', []): filename = filename.replace('/', os.sep) logger.info('%s:loading %s', module, filename) # Feed the parser with xml content: with tools.file_open(OPJ(module, filename)) as fp: tryton_parser.parse_xmlstream(fp) modules_todo.append((module, list(tryton_parser.to_delete))) localedir = '%s/%s' % (package.info['directory'], 'locale') for filename in itertools.chain( iglob('%s/*.po' % localedir), iglob('%s/override/*.po' % localedir)): filename = filename.replace('/', os.sep) lang2 = os.path.splitext(os.path.basename(filename))[0] if lang2 not in lang: continue logger.info('%s:loading %s', module, filename[len(package.info['directory']) + 1:]) Translation = pool.get('ir.translation') Translation.translation_import(lang2, module, filename) if package_state == 'to remove': continue cursor.execute(*ir_module.select(ir_module.id, where=(ir_module.name == package.name))) try: module_id, = cursor.fetchone() cursor.execute(*ir_module.update([ir_module.state], ['installed'], where=(ir_module.id == module_id))) except TypeError: cursor.execute(*ir_module.insert( [ir_module.create_uid, ir_module.create_date, ir_module.name, ir_module.state], [[0, CurrentTimestamp(), package.name, 'installed']])) module2state[package.name] = 'installed' cursor.commit() for model_name in models_to_update_history: model = pool.get(model_name) if model._history: logger.info('history:update %s', model.__name__) model._update_history_table() # Vacuum : while modules_todo: (module, to_delete) = modules_todo.pop() convert.post_import(pool, module, to_delete) cursor.commit()
def test_browse(self): 'Test browsing history' pool = Pool() History = pool.get('test.history') Line = pool.get('test.history.line') transaction = Transaction() history = History(value=1) history.save() history_id = history.id line_a = Line(name='a', history=history) line_a.save() line_a_id = line_a.id line_b = Line(name='b', history=history) line_b.save() line_b_id = line_b.id first_stamp = line_b.create_date history.stamp = first_stamp history.save() transaction.commit() history = History(history_id) history.value = 2 history.save() Line.delete([Line(line_b_id)]) line_a = Line(line_a_id) line_a.name = 'c' line_a.save() second_stamp = line_a.write_date transaction.commit() history = History(history_id) self.assertEqual(history.value, 2) self.assertEqual([l.name for l in history.lines], ['c']) self.assertEqual(history.stamp, first_stamp) self.assertEqual( [l.name for l in history.lines_at_stamp], ['a', 'b']) with Transaction().set_context(_datetime=first_stamp): history = History(history_id) self.assertEqual(history.value, 1) self.assertEqual([l.name for l in history.lines], ['a', 'b']) with Transaction().set_context(_datetime=second_stamp): history = History(history_id) self.assertEqual(history.value, 2) self.assertEqual([l.name for l in history.lines], ['c']) self.assertEqual(history.stamp, first_stamp) self.assertEqual( [l.name for l in history.lines_at_stamp], ['a', 'b']) # COOG - JCA : Test _datetime_exclude with Transaction().set_context(_datetime=second_stamp, _datetime_exclude=True): history = History(history_id) self.assertEqual(history.value, 1) self.assertEqual([l.name for l in history.lines], ['a', 'b'])
def _load_modules(): global res TableHandler = backend.get("TableHandler") transaction = Transaction() with transaction.connection.cursor() as cursor: # Migration from 3.6: remove double module old_table = "ir_module_module" new_table = "ir_module" if TableHandler.table_exist(old_table): TableHandler.table_rename(old_table, new_table) if update: migrate_modules(cursor) cursor.execute( *ir_module.select( ir_module.name, where=ir_module.state.in_(("installed", "to install", "to upgrade", "to remove")), ) ) else: cursor.execute( *ir_module.select( ir_module.name, where=ir_module.state.in_(("installed", "to upgrade", "to remove")) ) ) module_list = [name for (name,) in cursor.fetchall()] if update: module_list += update graph = create_graph(module_list)[0] load_module_graph(graph, pool, update, lang) if update: cursor.execute(*ir_module.select(ir_module.name, where=(ir_module.state == "to remove"))) fetchall = cursor.fetchall() if fetchall: for (mod_name,) in fetchall: # TODO check if ressource not updated by the user cursor.execute( *ir_model_data.select( ir_model_data.model, ir_model_data.db_id, where=(ir_model_data.module == mod_name), order_by=ir_model_data.id.desc, ) ) for rmod, rid in cursor.fetchall(): Model = pool.get(rmod) Model.delete([Model(rid)]) Transaction().connection.commit() cursor.execute( *ir_module.update([ir_module.state], ["uninstalled"], where=(ir_module.state == "to remove")) ) Transaction().connection.commit() res = False Module = pool.get("ir.module") Module.update_list() # Need to commit to unlock SQLite database transaction.commit() Cache.resets(database_name)
def load_modules(database_name, pool, update=False, lang=None): res = True if not Transaction().cursor: contextmanager = Transaction().start(database_name, 0) else: contextmanager = contextlib.nested(Transaction().new_cursor(), Transaction().set_user(0), Transaction().reset_context()) with contextmanager: cursor = Transaction().cursor if update: # Migration from 2.2: workflow module removed cursor.execute('DELETE FROM ir_module_module ' 'WHERE name = %s', ('workflow',)) if 'all' in CONFIG['init']: cursor.execute("SELECT name FROM ir_module_module " "WHERE name != \'test\'") else: cursor.execute("SELECT name FROM ir_module_module " "WHERE state IN ('installed', 'to install', " "'to upgrade', 'to remove')") else: cursor.execute("SELECT name FROM ir_module_module " "WHERE state IN ('installed', 'to upgrade', 'to remove')") module_list = [name for (name,) in cursor.fetchall()] if update: for module in CONFIG['init'].keys(): if CONFIG['init'][module]: module_list.append(module) for module in CONFIG['update'].keys(): if CONFIG['update'][module]: module_list.append(module) graph = create_graph(module_list)[0] try: load_module_graph(graph, pool, lang) except Exception: cursor.rollback() raise if update: cursor.execute("SELECT name FROM ir_module_module " "WHERE state IN ('to remove')") fetchall = cursor.fetchall() if fetchall: for (mod_name,) in fetchall: #TODO check if ressource not updated by the user cursor.execute('SELECT model, db_id FROM ir_model_data ' 'WHERE module = %s ' 'ORDER BY id DESC', (mod_name,)) for rmod, rid in cursor.fetchall(): Model = pool.get(rmod) Model.delete([Model(rid)]) cursor.commit() cursor.execute("UPDATE ir_module_module SET state = %s " "WHERE state IN ('to remove')", ('uninstalled',)) cursor.commit() res = False Module = pool.get('ir.module.module') Module.update_list() cursor.commit() Cache.resets(database_name) return res
def load_module_graph(graph, pool, lang=None): if lang is None: lang = [CONFIG['language']] modules_todo = [] models_to_update_history = set() logger = logging.getLogger('modules') cursor = Transaction().cursor modules = [x.name for x in graph] cursor.execute('SELECT name, state FROM ir_module_module ' 'WHERE name in (' + ','.join(('%s',) * len(modules)) + ')', modules) module2state = dict(cursor.fetchall()) for package in graph: module = package.name if module not in MODULES: continue logger.info(module) sys.stdout.flush() classes = pool.setup(module) package_state = module2state.get(module, 'uninstalled') if (is_module_to_install(module) or package_state in ('to install', 'to upgrade')): if package_state not in ('to install', 'to upgrade'): package_state = 'to install' for child in package.childs: module2state[child.name] = package_state for type in classes.keys(): for cls in classes[type]: logger.info('%s:register %s' % (module, cls.__name__)) cls.__register__(module) for model in classes['model']: if hasattr(model, '_history'): models_to_update_history.add(model.__name__) #Instanciate a new parser for the package: tryton_parser = convert.TrytondXmlHandler(pool=pool, module=module) for filename in package.info.get('xml', []): filename = filename.replace('/', os.sep) logger.info('%s:loading %s' % (module, filename)) # Feed the parser with xml content: with tools.file_open(OPJ(module, filename)) as fp: tryton_parser.parse_xmlstream(fp) modules_todo.append((module, list(tryton_parser.to_delete))) for filename in iglob('%s/%s/*.po' % (package.info['directory'], 'locale')): filename = filename.replace('/', os.sep) lang2 = os.path.splitext(os.path.basename(filename))[0] if lang2 not in lang: continue logger.info('%s:loading %s' % (module, filename[len(package.info['directory']) + 1:])) Translation = pool.get('ir.translation') Translation.translation_import(lang2, module, filename) cursor.execute('SELECT id FROM ir_module_module ' 'WHERE name = %s', (package.name,)) try: module_id, = cursor.fetchone() cursor.execute('UPDATE ir_module_module SET state = %s ' 'WHERE id = %s', ('installed', module_id)) except TypeError: cursor.execute('INSERT INTO ir_module_module ' '(create_uid, create_date, name, state) ' 'VALUES (%s, %s, %s, %s)', (0, datetime.datetime.now(), package.name, 'installed')) module2state[package.name] = 'installed' cursor.commit() for model_name in models_to_update_history: model = pool.get(model_name) if model._history: logger.info('history:update %s' % model.__name__) model._update_history_table() # Vacuum : while modules_todo: (module, to_delete) = modules_todo.pop() convert.post_import(pool, module, to_delete) cursor.commit()
def load_module_graph(graph, pool, update=None, lang=None): from trytond.ir.lang import get_parent_language if lang is None: lang = [config.get('database', 'language')] if update is None: update = [] modules_todo = [] models_to_update_history = set() # Load also parent languages lang = set(lang) for code in list(lang): while code: lang.add(code) code = get_parent_language(code) transaction = Transaction() with transaction.connection.cursor() as cursor: modules = [x.name for x in graph] cursor.execute(*ir_module.select(ir_module.name, ir_module.state, where=ir_module.name.in_(modules))) module2state = dict(cursor.fetchall()) modules = set(modules) for node in graph: module = node.name if module not in MODULES: continue logger.info(module) classes = pool.fill(module, modules) if update: pool.setup(classes) package_state = module2state.get(module, 'not activated') if (is_module_to_install(module, update) or (update and package_state in ('to activate', 'to upgrade'))): if package_state not in ('to activate', 'to upgrade'): if package_state == 'activated': package_state = 'to upgrade' elif package_state != 'to remove': package_state = 'to activate' for child in node: module2state[child.name] = package_state for type in list(classes.keys()): for cls in classes[type]: logger.info('%s:register %s', module, cls.__name__) cls.__register__(module) for model in classes['model']: if hasattr(model, '_history'): models_to_update_history.add(model.__name__) # Instanciate a new parser for the module tryton_parser = convert.TrytondXmlHandler( pool, module, package_state, modules) for filename in node.info.get('xml', []): filename = filename.replace('/', os.sep) logger.info('%s:loading %s', module, filename) # Feed the parser with xml content: with tools.file_open(OPJ(module, filename), 'rb') as fp: tryton_parser.parse_xmlstream(fp) modules_todo.append((module, list(tryton_parser.to_delete))) localedir = '%s/%s' % (node.info['directory'], 'locale') lang2filenames = defaultdict(list) for filename in itertools.chain( iglob('%s/*.po' % localedir), iglob('%s/override/*.po' % localedir)): filename = filename.replace('/', os.sep) lang2 = os.path.splitext(os.path.basename(filename))[0] if lang2 not in lang: continue lang2filenames[lang2].append(filename) base_path_position = len(node.info['directory']) + 1 for language, files in lang2filenames.items(): filenames = [f[base_path_position:] for f in files] logger.info('%s:loading %s', module, ','.join(filenames)) Translation = pool.get('ir.translation') Translation.translation_import(language, module, files) if package_state == 'to remove': continue cursor.execute(*ir_module.select( ir_module.id, where=(ir_module.name == module))) try: module_id, = cursor.fetchone() cursor.execute( *ir_module.update([ir_module.state], ['activated'], where=(ir_module.id == module_id))) except TypeError: cursor.execute(*ir_module.insert([ ir_module.create_uid, ir_module.create_date, ir_module.name, ir_module.state ], [ [0, CurrentTimestamp(), module, 'activated'], ])) module2state[module] = 'activated' transaction.commit() if not update: pool.setup() else: # Remove unknown models and fields Model = pool.get('ir.model') Model.clean() ModelField = pool.get('ir.model.field') ModelField.clean() transaction.commit() pool.setup_mixin(modules) for model_name in models_to_update_history: model = pool.get(model_name) if model._history: logger.info('history:update %s', model.__name__) model._update_history_table() # Vacuum : while modules_todo: (module, to_delete) = modules_todo.pop() convert.post_import(pool, module, to_delete) logger.info('all modules loaded')
def load_module_graph(graph, pool, lang=None): if lang is None: lang = [CONFIG['language']] modules_todo = [] models_to_update_history = set() logger = logging.getLogger('modules') cursor = Transaction().cursor modules = [x.name for x in graph] cursor.execute('SELECT name, state FROM ir_module_module ' 'WHERE name in (' + ','.join(('%s',) * len(modules)) + ')', modules) module2state = dict(cursor.fetchall()) for package in graph: module = package.name if module not in MODULES: continue logger.info(module) sys.stdout.flush() objects = pool.instanciate(module) package_state = module2state.get(module, 'uninstalled') if (is_module_to_install(module) or package_state in ('to install', 'to upgrade')): for type in objects.keys(): for obj in objects[type]: logger.info('%s:init %s' % (module, obj._name)) obj.init(module) for model in objects['model']: if hasattr(model, '_history'): models_to_update_history.add(model._name) #Instanciate a new parser for the package: tryton_parser = convert.TrytondXmlHandler(pool=pool, module=module) for filename in package.info.get('xml', []): filename = filename.replace('/', os.sep) logger.info('%s:loading %s' % (module, filename)) # Feed the parser with xml content: with tools.file_open(OPJ(module, filename)) as fp: tryton_parser.parse_xmlstream(fp) modules_todo.append((module, list(tryton_parser.to_delete))) for filename in package.info.get('translation', []): filename = filename.replace('/', os.sep) lang2 = os.path.splitext(os.path.basename(filename))[0] if lang2 not in lang: continue logger.info('%s:loading %s' % (module, filename)) with tools.file_open(OPJ(module, filename)) as trans_file: po_path = trans_file.name translation_obj = pool.get('ir.translation') translation_obj.translation_import(lang2, module, po_path) cursor.execute("UPDATE ir_module_module SET state = 'installed' " \ "WHERE name = %s", (package.name,)) module2state[package.name] = 'installed' cursor.commit() # Create missing reports from trytond.report import Report report_obj = pool.get('ir.action.report') report_ids = report_obj.search([ ('module', '=', module), ]) report_names = pool.object_name_list(type='report') for report in report_obj.browse(report_ids): report_name = report.report_name if report_name not in report_names: report = object.__new__(Report) report._name = report_name pool.add(report, type='report') report.__init__() for model_name in models_to_update_history: model = pool.get(model_name) if model._history: logger.info('history:update %s' % model._name) model._update_history_table() # Vacuum : while modules_todo: (module, to_delete) = modules_todo.pop() convert.post_import(pool, module, to_delete) cursor.commit()
def load_module_graph(graph, pool, update=None, lang=None): if lang is None: lang = [config.get('database', 'language')] if update is None: update = [] modules_todo = [] models_to_update_history = set() cursor = Transaction().cursor modules = [x.name for x in graph] cursor.execute(*ir_module.select( ir_module.name, ir_module.state, where=ir_module.name.in_(modules))) module2state = dict(cursor.fetchall()) for package in graph: module = package.name if module not in MODULES: continue logger.info(module) classes = pool.setup(module) package_state = module2state.get(module, 'uninstalled') if (is_module_to_install(module, update) or package_state in ('to install', 'to upgrade')): if package_state not in ('to install', 'to upgrade'): if package_state == 'installed': package_state = 'to upgrade' elif package_state != 'to remove': package_state = 'to install' for child in package.childs: module2state[child.name] = package_state for type in classes.keys(): for cls in classes[type]: logger.info('%s:register %s', module, cls.__name__) cls.__register__(module) for model in classes['model']: if hasattr(model, '_history'): models_to_update_history.add(model.__name__) # Instanciate a new parser for the package: tryton_parser = convert.TrytondXmlHandler( pool=pool, module=module, module_state=package_state) for filename in package.info.get('xml', []): filename = filename.replace('/', os.sep) logger.info('%s:loading %s', module, filename) # Feed the parser with xml content: with tools.file_open(OPJ(module, filename)) as fp: tryton_parser.parse_xmlstream(fp) modules_todo.append((module, list(tryton_parser.to_delete))) localedir = '%s/%s' % (package.info['directory'], 'locale') for filename in itertools.chain( iglob('%s/*.po' % localedir), iglob('%s/override/*.po' % localedir)): filename = filename.replace('/', os.sep) lang2 = os.path.splitext(os.path.basename(filename))[0] if lang2 not in lang: continue logger.info('%s:loading %s', module, filename[len(package.info['directory']) + 1:]) Translation = pool.get('ir.translation') Translation.translation_import(lang2, module, filename) if package_state == 'to remove': continue cursor.execute(*ir_module.select( ir_module.id, where=(ir_module.name == package.name))) try: module_id, = cursor.fetchone() cursor.execute( *ir_module.update([ir_module.state], ['installed'], where=(ir_module.id == module_id))) except TypeError: cursor.execute(*ir_module.insert([ ir_module.create_uid, ir_module.create_date, ir_module.name, ir_module.state ], [[0, CurrentTimestamp(), package.name, 'installed']])) module2state[package.name] = 'installed' cursor.commit() for model_name in models_to_update_history: model = pool.get(model_name) if model._history: logger.info('history:update %s', model.__name__) model._update_history_table() # Vacuum : while modules_todo: (module, to_delete) = modules_todo.pop() convert.post_import(pool, module, to_delete) cursor.commit()
def _activate_extension(cls): connection = Transaction().connection cursor = connection.cursor() cursor.execute('CREATE EXTENSION "%s"' % cls.extension) connection.commit() cls._clear_cache()