LEFT | RIGHT |
1 #This file is part of Tryton. The COPYRIGHT file at the top level of | 1 #This file is part of Tryton. The COPYRIGHT file at the top level of |
2 #this repository contains the full copyright notices and license terms. | 2 #this repository contains the full copyright notices and license terms. |
3 from __future__ import with_statement | 3 from __future__ import with_statement |
4 import contextlib | 4 import contextlib |
5 import datetime | 5 import datetime |
6 import re | 6 import re |
| 7 from decimal import Decimal |
7 from trytond.model import ModelStorage | 8 from trytond.model import ModelStorage |
8 from trytond.model import fields | 9 from trytond.model import fields |
9 from trytond.backend import FIELDS, TableHandler | 10 from trytond.backend import FIELDS, TableHandler |
10 from trytond.backend import DatabaseIntegrityError, Database | 11 from trytond.backend import DatabaseIntegrityError, Database |
11 from trytond.tools import reduce_ids | 12 from trytond.tools import reduce_ids |
12 from trytond.const import OPERATORS | 13 from trytond.const import OPERATORS |
13 from trytond.transaction import Transaction | 14 from trytond.transaction import Transaction |
14 _RE_UNIQUE = re.compile('UNIQUE\s*\((.*)\)', re.I) | 15 _RE_UNIQUE = re.compile('UNIQUE\s*\((.*)\)', re.I) |
15 _RE_CHECK = re.compile('CHECK\s*\((.*)\)', re.I) | 16 _RE_CHECK = re.compile('CHECK\s*\((.*)\)', re.I) |
16 | 17 |
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
377 mode='create') | 378 mode='create') |
378 if domain1: | 379 if domain1: |
379 cursor.execute('SELECT id FROM "' + self._table + '" ' \ | 380 cursor.execute('SELECT id FROM "' + self._table + '" ' \ |
380 'WHERE id = %s AND (' + domain1 + ')', | 381 'WHERE id = %s AND (' + domain1 + ')', |
381 [id_new] + domain2) | 382 [id_new] + domain2) |
382 if not cursor.fetchone(): | 383 if not cursor.fetchone(): |
383 self.raise_user_error('access_error', self._description) | 384 self.raise_user_error('access_error', self._description) |
384 | 385 |
385 Transaction().create_records.setdefault(self._name, set()).add(id_new) | 386 Transaction().create_records.setdefault(self._name, set()).add(id_new) |
386 | 387 |
| 388 for field in values: |
| 389 if getattr(self._columns[field], 'translate', False): |
| 390 self.pool.get('ir.translation')._set_ids( |
| 391 self._name + ',' + field, 'model', |
| 392 Transaction().language, [id_new], values[field]) |
| 393 |
387 upd_todo.sort(lambda x, y: self._columns[x].priority - \ | 394 upd_todo.sort(lambda x, y: self._columns[x].priority - \ |
388 self._columns[y].priority) | 395 self._columns[y].priority) |
389 for field in upd_todo: | 396 for field in upd_todo: |
390 self._columns[field].set([id_new], self, field, values[field]) | 397 self._columns[field].set([id_new], self, field, values[field]) |
391 | 398 |
392 if self._history: | 399 if self._history: |
393 cursor.execute('INSERT INTO "' + self._table + '__history" ' \ | 400 cursor.execute('INSERT INTO "' + self._table + '__history" ' \ |
394 '(id' + upd0 + ') ' \ | 401 '(id' + upd0 + ') ' \ |
395 'SELECT id' + upd0 + ' ' \ | 402 'SELECT id' + upd0 + ' ' \ |
396 'FROM "' + self._table + '" ' \ | 403 'FROM "' + self._table + '" ' \ |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
476 history_clause = ' AND (COALESCE(write_date, create_date) <= %s)' | 483 history_clause = ' AND (COALESCE(write_date, create_date) <= %s)' |
477 history_order = ' ORDER BY COALESCE(write_date, create_date) DESC' | 484 history_order = ' ORDER BY COALESCE(write_date, create_date) DESC' |
478 history_limit = cursor.limit_clause('', 1) | 485 history_limit = cursor.limit_clause('', 1) |
479 history_args = [Transaction().context['_datetime']] | 486 history_args = [Transaction().context['_datetime']] |
480 if len(fields_pre) : | 487 if len(fields_pre) : |
481 fields_pre2 = ['"%s"."%s" AS "%s"' % (self._table, x, x) | 488 fields_pre2 = ['"%s"."%s" AS "%s"' % (self._table, x, x) |
482 for x in fields_pre if x != '_timestamp'] | 489 for x in fields_pre if x != '_timestamp'] |
483 if '_timestamp' in fields_pre: | 490 if '_timestamp' in fields_pre: |
484 if not self.table_query(): | 491 if not self.table_query(): |
485 fields_pre2 += ['CAST(EXTRACT(EPOCH FROM ' | 492 fields_pre2 += ['CAST(EXTRACT(EPOCH FROM ' |
486 '(COALESCE("%s".write_date, "%s".create_date))) AS %
s' | 493 '(COALESCE("%s".write_date, "%s".create_date)))' |
487 ') AS _timestamp' % | 494 'AS VARCHAR) AS _timestamp' % |
488 (self._table, self._table, | 495 (self._table, self._table)] |
489 FIELDS['numeric'].sql_type(self.create_date)[1])
] | |
490 | 496 |
491 for i in range(0, len(ids), in_max): | 497 for i in range(0, len(ids), in_max): |
492 sub_ids = ids[i:i + in_max] | 498 sub_ids = ids[i:i + in_max] |
493 red_sql, red_ids = reduce_ids('id', sub_ids) | 499 red_sql, red_ids = reduce_ids('id', sub_ids) |
494 if domain1: | 500 if domain1: |
495 cursor.execute('SELECT ' + \ | 501 cursor.execute('SELECT ' + \ |
496 ','.join(fields_pre2 + | 502 ','.join(fields_pre2 + |
497 ['"%s".id AS id' % self._table]) + \ | 503 ['"%s".id AS id' % self._table]) + \ |
498 ' FROM ' + table_query + '\"' + self._table +'\" ' \ | 504 ' FROM ' + table_query + '\"' + self._table +'\" ' \ |
499 'WHERE ' + red_sql + \ | 505 'WHERE ' + red_sql + \ |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
619 to_del = [] | 625 to_del = [] |
620 fields_related2values = {} | 626 fields_related2values = {} |
621 for field in fields_related.keys() + datetime_fields: | 627 for field in fields_related.keys() + datetime_fields: |
622 if field not in fields_names: | 628 if field not in fields_names: |
623 to_del.append(field) | 629 to_del.append(field) |
624 if field not in self._columns: | 630 if field not in self._columns: |
625 continue | 631 continue |
626 if field not in fields_related.keys(): | 632 if field not in fields_related.keys(): |
627 continue | 633 continue |
628 fields_related2values.setdefault(field, {}) | 634 fields_related2values.setdefault(field, {}) |
629 if self._columns[field]._type == 'many2one': | 635 if self._columns[field]._type in ('many2one', 'one2one'): |
630 obj = self.pool.get(self._columns[field].model_name) | 636 if hasattr(self._columns[field], 'model_name'): |
| 637 obj = self.pool.get(self._columns[field].model_name) |
| 638 else: |
| 639 obj = self._columns[field].get_target(self.pool) |
631 if hasattr(self._columns[field], 'datetime_field') \ | 640 if hasattr(self._columns[field], 'datetime_field') \ |
632 and self._columns[field].datetime_field: | 641 and self._columns[field].datetime_field: |
633 for record in res: | 642 for record in res: |
634 if not record[field]: | 643 if not record[field]: |
635 continue | 644 continue |
636 with Transaction().set_context(_datetime= | 645 with Transaction().set_context(_datetime= |
637 record[self._columns[field].datetime_field]): | 646 record[self._columns[field].datetime_field]): |
638 record2 = obj.read(record[field], | 647 record2 = obj.read(record[field], |
639 fields_related[field]) | 648 fields_related[field]) |
640 record_id = record2['id'] | 649 record_id = record2['id'] |
(...skipping 24 matching lines...) Expand all Loading... |
665 record2 = obj.read(record_id, fields_related[field]) | 674 record2 = obj.read(record_id, fields_related[field]) |
666 del record2['id'] | 675 del record2['id'] |
667 fields_related2values[field][record_id] = record2 | 676 fields_related2values[field][record_id] = record2 |
668 | 677 |
669 if to_del or fields_related.keys() or datetime_fields: | 678 if to_del or fields_related.keys() or datetime_fields: |
670 for record in res: | 679 for record in res: |
671 for field in fields_related.keys(): | 680 for field in fields_related.keys(): |
672 if field not in self._columns: | 681 if field not in self._columns: |
673 continue | 682 continue |
674 for related in fields_related[field]: | 683 for related in fields_related[field]: |
675 if self._columns[field]._type == 'many2one': | 684 if self._columns[field]._type in ('many2one', 'one2one')
: |
676 if record[field]: | 685 if record[field]: |
677 record[field + '.' + related] = \ | 686 record[field + '.' + related] = \ |
678 fields_related2values[field]\ | 687 fields_related2values[field]\ |
679 [record[field]][record['id']][related] | 688 [record[field]][record['id']][related] |
680 else: | 689 else: |
681 record[field + '.' + related] = False | 690 record[field + '.' + related] = False |
682 elif self._columns[field]._type == 'reference': | 691 elif self._columns[field]._type == 'reference': |
683 if record[field]: | 692 if record[field]: |
684 model_name, record_id = record[field].split( | 693 model_name, record_id = record[field].split( |
685 ',', 1) | 694 ',', 1) |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
736 sub_ids = ids[i:i + cursor.IN_MAX] | 745 sub_ids = ids[i:i + cursor.IN_MAX] |
737 clause = ('(id = %s AND ' | 746 clause = ('(id = %s AND ' |
738 'CAST(EXTRACT(EPOCH FROM ' | 747 'CAST(EXTRACT(EPOCH FROM ' |
739 'COALESCE(write_date, create_date)) AS ' + \ | 748 'COALESCE(write_date, create_date)) AS ' + \ |
740 FIELDS['numeric'].sql_type(self.create_date)[1] + \ | 749 FIELDS['numeric'].sql_type(self.create_date)[1] + \ |
741 ') > %s)') | 750 ') > %s)') |
742 args = [] | 751 args = [] |
743 for i in sub_ids: | 752 for i in sub_ids: |
744 if Transaction().timestamp.get(self._name + ',' + str(i)): | 753 if Transaction().timestamp.get(self._name + ',' + str(i)): |
745 args.append(i) | 754 args.append(i) |
746 args.append(Transaction().timestamp[ | 755 args.append(Decimal(Transaction().timestamp[ |
747 self._name + ',' +str(i)]) | 756 self._name + ',' +str(i)])) |
748 if args: | 757 if args: |
749 cursor.execute("SELECT id " \ | 758 cursor.execute("SELECT id " \ |
750 'FROM "' + self._table + '" ' \ | 759 'FROM "' + self._table + '" ' \ |
751 'WHERE ' + ' OR '.join( | 760 'WHERE ' + ' OR '.join( |
752 (clause,) * (len(args)/2)), args) | 761 (clause,) * (len(args)/2)), args) |
753 if cursor.fetchone(): | 762 if cursor.fetchone(): |
754 raise Exception('ConcurrencyException', | 763 raise Exception('ConcurrencyException', |
755 'Records were modified in the meanwhile') | 764 'Records were modified in the meanwhile') |
756 for i in ids: | 765 for i in ids: |
757 if Transaction().timestamp.get(self._name + ',' + str(i)): | 766 if Transaction().timestamp.get(self._name + ',' + str(i)): |
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1096 self.raise_user_error(error) | 1105 self.raise_user_error(error) |
1097 for name, error in self._sql_error_messages: | 1106 for name, error in self._sql_error_messages: |
1098 if name in exception[0]: | 1107 if name in exception[0]: |
1099 self.raise_user_error(error) | 1108 self.raise_user_error(error) |
1100 raise | 1109 raise |
1101 | 1110 |
1102 if self._history: | 1111 if self._history: |
1103 for obj_id in ids: | 1112 for obj_id in ids: |
1104 cursor.execute('INSERT INTO "' + self._table + '__history" ' \ | 1113 cursor.execute('INSERT INTO "' + self._table + '__history" ' \ |
1105 '(id, write_uid, write_date) VALUES (%s, %s, %s)', | 1114 '(id, write_uid, write_date) VALUES (%s, %s, %s)', |
1106 (obj_id, user, datetime.datetime.now())) | 1115 (obj_id, Transaction().user, datetime.datetime.now())) |
1107 | 1116 |
1108 for k in tree_ids.keys(): | 1117 for k in tree_ids.keys(): |
1109 field = self._columns[k] | 1118 field = self._columns[k] |
1110 if len(tree_ids[k]) == 1: | 1119 if len(tree_ids[k]) == 1: |
1111 self._update_tree(tree_ids[k][0], k, field.left, field.right) | 1120 self._update_tree(tree_ids[k][0], k, field.left, field.right) |
1112 else: | 1121 else: |
1113 with Transaction().set_user(0): | 1122 with Transaction().set_user(0): |
1114 self._rebuild_tree(k, False, 0) | 1123 self._rebuild_tree(k, False, 0) |
1115 | 1124 |
1116 return True | 1125 return True |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1171 select_fields += [ | 1180 select_fields += [ |
1172 '"' + self._table + '"."' + x[0] + '" AS "' + x[0] + '"' \ | 1181 '"' + self._table + '"."' + x[0] + '" AS "' + x[0] + '"' \ |
1173 for x in self._columns.iteritems() \ | 1182 for x in self._columns.iteritems() \ |
1174 if not hasattr(x[1], 'get') \ | 1183 if not hasattr(x[1], 'get') \ |
1175 and (x[0] != 'id') | 1184 and (x[0] != 'id') |
1176 and (not getattr(x[1], 'translate', False) \ | 1185 and (not getattr(x[1], 'translate', False) \ |
1177 and x[1]._type not in ('text', 'binary'))] | 1186 and x[1]._type not in ('text', 'binary'))] |
1178 if not self.table_query(): | 1187 if not self.table_query(): |
1179 select_fields += ['CAST(EXTRACT(EPOCH FROM ' | 1188 select_fields += ['CAST(EXTRACT(EPOCH FROM ' |
1180 '(COALESCE("' + self._table + '".write_date, ' | 1189 '(COALESCE("' + self._table + '".write_date, ' |
1181 '"' + self._table + '".create_date))) AS ' + \ | 1190 '"' + self._table + '".create_date))) AS VARCHAR' |
1182 FIELDS['numeric'].sql_type(self.create_date)[1] + \ | |
1183 ') AS _timestamp'] | 1191 ') AS _timestamp'] |
1184 query_str = cursor.limit_clause( | 1192 query_str = cursor.limit_clause( |
1185 'SELECT ' + ','.join(select_fields) + ' FROM ' + \ | 1193 'SELECT ' + ','.join(select_fields) + ' FROM ' + \ |
1186 ' '.join(tables) + (qu1 and ' WHERE ' + qu1 or '') + \ | 1194 ' '.join(tables) + (qu1 and ' WHERE ' + qu1 or '') + \ |
1187 (order_by and ' ORDER BY ' + order_by or ''), limit, offset) | 1195 (order_by and ' ORDER BY ' + order_by or ''), limit, offset) |
1188 if query_string: | 1196 if query_string: |
1189 return (query_str, tables_args + qu2) | 1197 return (query_str, tables_args + qu2) |
1190 cursor.execute(query_str, tables_args + qu2) | 1198 cursor.execute(query_str, tables_args + qu2) |
1191 | 1199 |
1192 datas = cursor.dictfetchmany(cursor.IN_MAX) | 1200 datas = cursor.dictfetchmany(cursor.IN_MAX) |
(...skipping 988 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2181 for i in range(0, len(ids), cursor.IN_MAX): | 2189 for i in range(0, len(ids), cursor.IN_MAX): |
2182 sub_ids = ids[i:i + cursor.IN_MAX] | 2190 sub_ids = ids[i:i + cursor.IN_MAX] |
2183 red_sql, red_ids = reduce_ids('id', sub_ids) | 2191 red_sql, red_ids = reduce_ids('id', sub_ids) |
2184 cursor.execute('SELECT id ' \ | 2192 cursor.execute('SELECT id ' \ |
2185 'FROM "' + self._table + '" ' \ | 2193 'FROM "' + self._table + '" ' \ |
2186 'WHERE NOT (' + sql + ') ' \ | 2194 'WHERE NOT (' + sql + ') ' \ |
2187 'AND ' + red_sql, red_ids) | 2195 'AND ' + red_sql, red_ids) |
2188 if cursor.fetchone(): | 2196 if cursor.fetchone(): |
2189 self.raise_user_error(error) | 2197 self.raise_user_error(error) |
2190 continue | 2198 continue |
LEFT | RIGHT |