2 |
2 |
|
3 |
3 |
from __future__ import unicode_literals
|
4 |
4 |
|
|
5 |
from collections import OrderedDict, Counter
|
5 |
6 |
import datetime
|
6 |
7 |
import six
|
7 |
8 |
import copy
|
... | ... | |
610 |
611 |
self.formdef.schema.name])
|
611 |
612 |
self.formdef_sql_id = self.cur.fetchone()[0]
|
612 |
613 |
|
613 |
|
columns = [['status_id', 'smallint REFERENCES {status_table} (id)']]
|
614 |
|
|
615 |
|
comments = {}
|
616 |
|
|
617 |
|
# compute list of fields
|
618 |
|
fields = self.formdef.schema.fields
|
619 |
|
if self.formdef.schema.workflow:
|
620 |
|
fields += self.formdef.schema.workflow.fields
|
|
614 |
columns = OrderedDict()
|
|
615 |
columns['status_id'] = {'sql_col_name': 'status_id', 'sql_col_def': 'smallint REFERENCES {status_table} (id)'}
|
621 |
616 |
|
622 |
617 |
# add item fields
|
623 |
|
already_seen_varnames = set()
|
624 |
|
for field in fields:
|
625 |
|
if field.anonymise is True:
|
626 |
|
continue
|
627 |
|
if not field.varname or '-' in field.varname:
|
628 |
|
continue
|
629 |
|
if field.varname in already_seen_varnames:
|
630 |
|
continue
|
631 |
|
already_seen_varnames.add(field.varname)
|
|
618 |
for field in self.good_fields.values():
|
632 |
619 |
if field.type == 'item':
|
633 |
620 |
comment = ('valeurs du champ « %s » du formulaire %s'
|
634 |
621 |
% (field.label, self.formdef.schema.name))
|
... | ... | |
647 |
634 |
field_def = 'varchar'
|
648 |
635 |
else:
|
649 |
636 |
continue
|
650 |
|
self.fields.append(field)
|
651 |
|
at = 'field_%s' % field.varname
|
652 |
|
columns.append([at, field_def])
|
653 |
|
comments[at] = field.label
|
|
637 |
columns[field.varname] = {
|
|
638 |
'field': field,
|
|
639 |
'sql_col_name': 'field_%s' % field.varname,
|
|
640 |
'sql_col_def': field_def,
|
|
641 |
'sql_comment': field.label,
|
|
642 |
}
|
|
643 |
|
|
644 |
# keep loaded fields around
|
|
645 |
for key in columns:
|
|
646 |
if columns[key].get('field') is not None:
|
|
647 |
self.fields.append(columns[key].get('field'))
|
654 |
648 |
|
655 |
649 |
# add geolocation fields
|
656 |
650 |
for geolocation, label in self.formdef.schema.geolocations:
|
657 |
651 |
at = 'geolocation_%s' % geolocation
|
658 |
|
columns.append([at, 'point'])
|
659 |
|
comments[at] = label
|
|
652 |
columns[at] = {
|
|
653 |
'sql_col_name': at,
|
|
654 |
'sql_col_def': 'point',
|
|
655 |
'comment': 'géoloc « %s »' % label,
|
|
656 |
}
|
660 |
657 |
|
661 |
658 |
# add function fields
|
662 |
659 |
for function, name in self.formdef.schema.workflow.functions.iteritems():
|
663 |
660 |
at = 'function_%s' % slugify(function)
|
664 |
|
columns.append([at, 'smallint REFERENCES {role_table} (id)'])
|
665 |
|
comments[at] = 'fonction « %s »' % name
|
|
661 |
columns[at] = {
|
|
662 |
'sql_col_name': at,
|
|
663 |
'sql_col_def': 'smallint REFERENCES {role_table} (id)',
|
|
664 |
'comment': 'fonction « %s »' % name,
|
|
665 |
}
|
666 |
666 |
|
667 |
|
self.columns = ([name for name, _type in self.olap_feeder.columns] + [
|
668 |
|
name for name, _type in columns])
|
|
667 |
self.columns = [name for name, _type in self.olap_feeder.columns]
|
|
668 |
for key in columns:
|
|
669 |
self.columns.append(columns[key]['sql_col_name'])
|
669 |
670 |
self.columns.remove('geolocation_base')
|
670 |
671 |
|
671 |
|
self.create_table(self.table_name, columns, inherits='{generic_formdata_table}',
|
|
672 |
self.create_table(self.table_name,
|
|
673 |
[(columns[key]['sql_col_name'], columns[key]['sql_col_def']) for key in columns],
|
|
674 |
inherits='{generic_formdata_table}',
|
672 |
675 |
comment='formulaire %s' % self.formdef.schema.name)
|
673 |
|
for at, comment in comments.iteritems():
|
674 |
|
self.ex('COMMENT ON COLUMN {formdata_table}.%s IS %%s' % quote(at), vars=(comment,))
|
|
676 |
for key in columns:
|
|
677 |
column = columns[key]
|
|
678 |
if column.get('sql_comment'):
|
|
679 |
self.ex('COMMENT ON COLUMN {formdata_table}.%s IS %%s' % quote(column['sql_col_name']),
|
|
680 |
vars=(column['sql_comment'],))
|
675 |
681 |
|
676 |
682 |
# Creat index for JSON fields
|
677 |
683 |
if self.has_jsonb:
|
678 |
|
for field in fields:
|
679 |
|
if field.varname and '-' not in field.varname:
|
680 |
|
self.create_formdata_json_index(self.table_name, field.varname)
|
|
684 |
for varname in self.good_fields:
|
|
685 |
self.create_formdata_json_index(self.table_name, varname)
|
681 |
686 |
|
682 |
687 |
# PostgreSQL does not propagate foreign key constraints to child tables
|
683 |
688 |
# so we must recreate them manually
|
... | ... | |
900 |
905 |
|
901 |
906 |
# create cube
|
902 |
907 |
cube = self.cube = copy.deepcopy(self.base_cube)
|
|
908 |
|
|
909 |
def add_warning(message):
|
|
910 |
self.logger.warning('%s', message)
|
|
911 |
cube.setdefault('warnings', []).append(message)
|
|
912 |
|
903 |
913 |
# remove json field from formdef cubes
|
904 |
914 |
cube.pop('json_field', None)
|
905 |
915 |
cube.update({
|
... | ... | |
950 |
960 |
fields = self.formdef.schema.fields
|
951 |
961 |
if self.formdef.schema.workflow:
|
952 |
962 |
fields += self.formdef.schema.workflow.fields
|
|
963 |
|
|
964 |
# filter duplicates
|
|
965 |
duplicate_varnames = set()
|
|
966 |
self.good_fields = good_fields = OrderedDict()
|
953 |
967 |
for field in fields:
|
|
968 |
if field.type not in ('item', 'bool', 'string'):
|
|
969 |
continue
|
954 |
970 |
if field.anonymise is True:
|
955 |
971 |
continue
|
956 |
972 |
if not field.varname:
|
|
973 |
add_warning('le champ « %s » n\' a pas de nom de variable, il a été ignoré' % field.label)
|
957 |
974 |
continue
|
958 |
|
if '-' in field.varname:
|
|
975 |
if field.varname in good_fields:
|
|
976 |
# duplicate found
|
|
977 |
duplicate_varnames.add(field.varname)
|
|
978 |
add_warning('le champ « %(label)s » a un nom de variable dupliqué « %(varname)s »' % {
|
|
979 |
'label': good_fields[field.varname].label,
|
|
980 |
'varname': field.varname
|
|
981 |
})
|
|
982 |
del self.good_fields[field.varname]
|
|
983 |
if field.varname in duplicate_varnames:
|
|
984 |
add_warning('le champ « %(label)s » a un nom de variable dupliqué « %(varname)s »' % field.__dict__)
|
959 |
985 |
continue
|
|
986 |
self.good_fields[field.varname] = field
|
|
987 |
|
|
988 |
for field in good_fields.values():
|
960 |
989 |
join = None
|
961 |
990 |
|
962 |
991 |
if field.type == 'item':
|
963 |
|
-
|