From 3d6ae2f1fe1579f9b81cc53afdcee5dfbb6c8c94 Mon Sep 17 00:00:00 2001 From: Andy Beverley Date: Sun, 4 Jan 2026 22:39:16 +0000 Subject: [PATCH] Performance - link latest record version (D1098) This commit improves performance by linking the current version of a record to its main stub, thereby making retrieval faster for records with lots of versions. The version retrieval functionality is retained for the purpose of historical view, which operates as it previously did. This commit also includes the addition of curval subfields to the y-axis of graphs (back-end only) which was needed to test some of the changes. It also includes sorting for grouping, which was needed for keeping the grouping tests working as before. --- lib/GADS.pm | 1 - lib/GADS/API.pm | 9 +- lib/GADS/Column.pm | 44 +- lib/GADS/Column/Autocur.pm | 7 +- lib/GADS/Column/Createddate.pm | 2 +- lib/GADS/Column/Curcommon.pm | 19 +- lib/GADS/Column/Curval.pm | 7 +- lib/GADS/Column/Filval.pm | 7 +- lib/GADS/Column/Id.pm | 2 +- lib/GADS/Column/Serial.pm | 2 +- lib/GADS/DateTime.pm | 5 + lib/GADS/Graph.pm | 45 +- lib/GADS/Graph/Data.pm | 19 +- lib/GADS/Layout.pm | 8 +- lib/GADS/Record.pm | 80 +- lib/GADS/Records.pm | 799 +- lib/GADS/RecordsJoin.pm | 441 +- lib/GADS/Role/Presentation/Column.pm | 1 + lib/GADS/Role/Presentation/Records.pm | 2 +- lib/GADS/Schema.pm | 2 +- lib/GADS/Schema/Result/Current.pm | 27 + lib/GADS/Schema/Result/Graph.pm | 14 + share/fixtures/110/conf/all_tables.json | 285 + share/fixtures/110/conf/current.json | 73 + share/fixtures/110/conf/graphs.json | 17 + share/fixtures/110/conf/layout.json | 53 + share/fixtures/110/conf/permissions.json | 17 + share/fixtures/110/conf/views_global.json | 28 + share/fixtures/110/permissions/_config_set | 17 + .../fixtures/110/permissions/_dumper_version | 1 + .../110/permissions/permission/10.fix | 7 + .../110/permissions/permission/12.fix | 7 + .../fixtures/110/permissions/permission/3.fix | 7 + .../MySQL/deploy/110/001-auto-__VERSION.sql | 18 + .../migrations/MySQL/deploy/110/001-auto.sql | 1279 +++ .../MySQL/downgrade/110-109/001-auto.sql | 19 + .../MySQL/upgrade/109-110/001-auto.sql | 19 + .../deploy/110/001-auto-__VERSION.sql | 18 + .../PostgreSQL/deploy/110/001-auto.sql | 1902 ++++ .../PostgreSQL/downgrade/110-109/001-auto.sql | 27 + .../PostgreSQL/upgrade/109-110/001-auto.sql | 29 + .../109-110/002-populate-current-versions.pl | 73 + .../_source/deploy/110/001-auto-__VERSION.yml | 92 + .../_source/deploy/110/001-auto.yml | 9765 +++++++++++++++++ t/003_search.t | 2 +- t/004_aggregate.t | 2 +- t/004_group.t | 55 +- t/012_graph_historical.t | 656 +- t/025_approval.t | 16 + t/026_purge.t | 15 +- t/lib/Test/GADS/DataSheet.pm | 2 + views/data_table.tt | 2 +- 52 files changed, 15187 insertions(+), 859 deletions(-) create mode 100644 share/fixtures/110/conf/all_tables.json create mode 100644 share/fixtures/110/conf/current.json create mode 100644 share/fixtures/110/conf/graphs.json create mode 100644 share/fixtures/110/conf/layout.json create mode 100644 share/fixtures/110/conf/permissions.json create mode 100644 share/fixtures/110/conf/views_global.json create mode 100644 share/fixtures/110/permissions/_config_set create mode 100644 share/fixtures/110/permissions/_dumper_version create mode 100644 share/fixtures/110/permissions/permission/10.fix create mode 100644 share/fixtures/110/permissions/permission/12.fix create mode 100644 share/fixtures/110/permissions/permission/3.fix create mode 100644 share/migrations/MySQL/deploy/110/001-auto-__VERSION.sql create mode 100644 share/migrations/MySQL/deploy/110/001-auto.sql create mode 100644 share/migrations/MySQL/downgrade/110-109/001-auto.sql create mode 100644 share/migrations/MySQL/upgrade/109-110/001-auto.sql create mode 100644 share/migrations/PostgreSQL/deploy/110/001-auto-__VERSION.sql create mode 100644 share/migrations/PostgreSQL/deploy/110/001-auto.sql create mode 100644 share/migrations/PostgreSQL/downgrade/110-109/001-auto.sql create mode 100644 share/migrations/PostgreSQL/upgrade/109-110/001-auto.sql create mode 100644 share/migrations/_common/upgrade/109-110/002-populate-current-versions.pl create mode 100644 share/migrations/_source/deploy/110/001-auto-__VERSION.yml create mode 100644 share/migrations/_source/deploy/110/001-auto.yml diff --git a/lib/GADS.pm b/lib/GADS.pm index 62ba1fa71..100959b0e 100644 --- a/lib/GADS.pm +++ b/lib/GADS.pm @@ -2762,7 +2762,6 @@ prefix '/:layout_name' => sub { $params->{aggregate} = $records->aggregate_presentation; $params->{columns} = [ map $_->presentation( group => $records->is_group, - group_col_ids => $records->group_col_ids, sort => $records->sort_first, filters => \@additional_filters, query_parameters => query_parameters, diff --git a/lib/GADS/API.pm b/lib/GADS/API.pm index c0a92b940..a8566e1b2 100644 --- a/lib/GADS/API.pm +++ b/lib/GADS/API.pm @@ -1183,7 +1183,7 @@ sub _get_records { # Check user has access error __"Invalid column ID for sort" unless $col_order && $col_order->user_can('read'); - my $sort = { type => $params->get('order[0][dir]'), id => $col_order->id }; + my $sort = { type => $params->get('order[0][dir]'), id => $col_order->id, parent_id => $col_order->parent_id }; $records->clear_sorts; $records->sort($sort); @@ -1203,11 +1203,10 @@ sub _get_records { { # Construct filter URL which will show all of this group of records my @filters; - foreach my $group_col_id (@{$records->group_col_ids}) + foreach my $group_col (@{$records->group_cols}) { - my $group_col = $layout->column($group_col_id); my $filter_value = $rec->get_field_value($group_col)->filter_value || ''; - push @filters, "$group_col_id=".uri_escape_utf8($filter_value); + push @filters, $group_col->id."=".uri_escape_utf8($filter_value); } my $desc = $rec->id_count == 1 ? 'record' : 'records'; $data->{_count} = { @@ -1220,7 +1219,7 @@ sub _get_records { else { $data->{_id} = $rec->current_id; }; - $data->{$_->id} = $rec->get_field_value($_)->for_table + $data->{$_->full_id} = $rec->get_field_value($_)->for_table foreach @{$records->columns_render}; push @{$return->{data}}, $data; diff --git a/lib/GADS/Column.pm b/lib/GADS/Column.pm index 6691922f8..651ed0c9f 100644 --- a/lib/GADS/Column.pm +++ b/lib/GADS/Column.pm @@ -70,6 +70,21 @@ has instance_id => ( isa => Int, ); +# If this is a field belonging to a curval and if so what that parent curval is +has parent_id => ( + is => 'ro', +); + +has parent => ( + is => 'lazy', +); + +sub _build_parent +{ my $self = shift; + return if !$self->parent_id; + $self->layout->column($self->parent_id); +} + has from_id => ( is => 'rw', trigger => sub { @@ -103,6 +118,12 @@ has id => ( isa => Int, ); +sub full_id +{ my $self = shift; + return $self->id if !$self->parent_id; + $self->parent_id."_".$self->id; +} + has internal => ( is => 'ro', isa => Bool, @@ -864,6 +885,16 @@ sub _build_instance_id $self->layout->instance_id; } +sub clone +{ my ($self, %params) = @_; + ref($self)->new( + schema => $self->schema, + layout => $self->layout, + set_values => $self->set_values, + %params, + ); +} + sub build_values { my ($self, $original) = @_; @@ -926,19 +957,6 @@ sub filter_value_to_text return $value; } -# Overridden where required -sub sort_columns -{ my $self = shift; - ($self); -} - -# Whether the sort columns when added should be added with a parent, and -# if so what is the paremt -sub sort_parent -{ my $self = shift; - return undef; # default no, undef in case used in arrays -} - # Overridden in child classes. This function is used # to cleanup specialist column data when a column # is deleted diff --git a/lib/GADS/Column/Autocur.pm b/lib/GADS/Column/Autocur.pm index ece4906c7..d6ce0771f 100644 --- a/lib/GADS/Column/Autocur.pm +++ b/lib/GADS/Column/Autocur.pm @@ -87,12 +87,15 @@ sub _build_refers_from_value_field } sub make_join -{ my ($self, @joins) = @_; +{ my ($self, $options, @joins) = @_; + my $join_current_version = $options->{join_current_version}; +{ $self->field => { record => { current => { - record_single => ['record_later', @joins], + $join_current_version + ? (current_version => [@joins]) + : (record_single => ['record_later', @joins]) } } } diff --git a/lib/GADS/Column/Createddate.pm b/lib/GADS/Column/Createddate.pm index 7a0457887..da91cc81a 100644 --- a/lib/GADS/Column/Createddate.pm +++ b/lib/GADS/Column/Createddate.pm @@ -45,7 +45,7 @@ has '+userinput' => ( default => 0, ); -sub tjoin {}; +sub tjoin { undef }; sub has_time { 1 }; diff --git a/lib/GADS/Column/Curcommon.pm b/lib/GADS/Column/Curcommon.pm index b604b2928..6a9387dea 100644 --- a/lib/GADS/Column/Curcommon.pm +++ b/lib/GADS/Column/Curcommon.pm @@ -119,7 +119,14 @@ has '+use_id_in_filter' => ( sub tjoin { my ($self, %options) = @_; - $self->make_join(map { $_->tjoin(already_seen => $options{already_seen}) } grep { !$_->internal } @{$self->curval_fields_retrieve(%options)}); + $self->make_join( + { join_current_version => $options{join_current_version} }, + map { + $_->tjoin(already_seen => $options{already_seen}) + } grep { + !$_->internal + } @{$self->curval_fields_retrieve(%options)} + ); } sub _build_fetch_with_record @@ -227,16 +234,6 @@ sub curval_fields_all [ map { $self->layout_parent->column($_, permission => 'read') } @{$self->curval_field_ids_all} ]; } -sub sort_columns -{ my $self = shift; - map { $_->sort_columns } @{$self->curval_fields}; -} - -sub sort_parent -{ my $self = shift; - $self; # This field is the parent for sort columns -} - # Does this column reference the field? sub has_curval_field { my ($self, $field) = @_; diff --git a/lib/GADS/Column/Curval.pm b/lib/GADS/Column/Curval.pm index ef9e56869..7933621cd 100644 --- a/lib/GADS/Column/Curval.pm +++ b/lib/GADS/Column/Curval.pm @@ -253,13 +253,16 @@ sub _build_refers_to_instance_id } sub make_join -{ my ($self, @joins) = @_; +{ my ($self, $options, @joins) = @_; + my $join_current_version = $options->{join_current_version}; return $self->field if !@joins; +{ $self->field => { value => { - record_single => ['record_later', @joins], + $join_current_version + ? ('current_version' => [@joins]) + : (record_single => ['record_later', @joins]) } } }; diff --git a/lib/GADS/Column/Filval.pm b/lib/GADS/Column/Filval.pm index 7eca57932..ef36db5d7 100644 --- a/lib/GADS/Column/Filval.pm +++ b/lib/GADS/Column/Filval.pm @@ -42,13 +42,16 @@ has '+table' => ( # Same as Column::Curval sub make_join -{ my ($self, @joins) = @_; +{ my ($self, $options, @joins) = @_; + my $join_current_version = $options->{join_current_version}; return $self->field if !@joins; +{ $self->field => { value => { - record_single => ['record_later', @joins], + $join_current_version + ? (current_version => [@joins]) + : (record_single => ['record_later', @joins]) } } }; diff --git a/lib/GADS/Column/Id.pm b/lib/GADS/Column/Id.pm index fd3cc9590..623a92757 100644 --- a/lib/GADS/Column/Id.pm +++ b/lib/GADS/Column/Id.pm @@ -47,7 +47,7 @@ has '+value_field' => ( sub cleanup {} -sub tjoin {} +sub tjoin { undef } 1; diff --git a/lib/GADS/Column/Serial.pm b/lib/GADS/Column/Serial.pm index cee4daeca..1a44975dd 100644 --- a/lib/GADS/Column/Serial.pm +++ b/lib/GADS/Column/Serial.pm @@ -57,7 +57,7 @@ has '+value_field' => ( default => 'serial', ); -sub tjoin {} +sub tjoin { undef } sub validate_search { my ($self, $value) = @_; diff --git a/lib/GADS/DateTime.pm b/lib/GADS/DateTime.pm index f0f9644ee..9a1a50f28 100644 --- a/lib/GADS/DateTime.pm +++ b/lib/GADS/DateTime.pm @@ -227,5 +227,10 @@ sub _parse_db $db_parser->parse_datetime($value); } +sub dt_parser +{ my $self = shift; + $self->schema->storage->datetime_parser; +} + 1; diff --git a/lib/GADS/Graph.pm b/lib/GADS/Graph.pm index 9bcf9dfdb..6c4cf9dd5 100644 --- a/lib/GADS/Graph.pm +++ b/lib/GADS/Graph.pm @@ -50,7 +50,7 @@ has _graph => ( my $graph = $self->schema->resultset('Graph')->find({ 'me.id' => $self->id },{ - prefetch => [qw/x_axis x_axis_link y_axis group_by/], + prefetch => [qw/x_axis x_axis_link y_axis y_axis_link group_by/], }); $graph or error __x"Requested graph ID {id} not found", id => $self->id; @@ -66,6 +66,7 @@ has set_values => ( $self->x_axis_link($original->{x_axis_link}); $self->x_axis_grouping($original->{x_axis_grouping}); $self->y_axis($original->{y_axis}); + $self->y_axis_link($original->{y_axis_link}); $self->y_axis_stack($original->{y_axis_stack}); $self->description($original->{description}); $self->stackseries($original->{stackseries}); @@ -238,12 +239,37 @@ has as_percent => ( builder => sub { $_[0]->_graph && $_[0]->_graph->as_percent }, ); +sub set_y_axis +{ my ($self, $value) = @_; + if ($value =~ /^([0-9]+)_([0-9]+)$/) + { + $self->y_axis($2); + $self->y_axis_link($1); + return; + } + $self->y_axis_link(undef); + $self->y_axis($value); +} + has y_axis => ( is => 'rw', lazy => 1, builder => sub { $_[0]->_graph && $_[0]->_graph->y_axis && $_[0]->_graph->y_axis->id }, ); +has y_axis_link => ( + is => 'rw', + lazy => 1, + builder => sub { $_[0]->_graph && $_[0]->_graph->y_axis_link && $_[0]->_graph->y_axis_link->id }, +); + +sub y_axis_full +{ my $self = shift; + return $self->y_axis_link."_".$self->y_axis + if $self->y_axis_link; + return $self->y_axis; +} + has y_axis_label => ( is => 'rw', lazy => 1, @@ -338,8 +364,15 @@ sub write if ($newgraph->{y_axis} = $self->y_axis) { - $self->layout->column_this_instance($self->y_axis) - or error __x"Invalid Y-axis {y_axis}", y_axis => $self->y_axis; + if ($self->y_axis_link) + { + $self->layout->column_this_instance($self->y_axis_link) + or error __x"Invalid Y-axis parent {y_axis_link}", y_axis_link => $self->y_axis_link; + } + else { + $self->layout->column_this_instance($self->y_axis) + or error __x"Invalid Y-axis {y_axis}", y_axis => $self->y_axis; + } } $newgraph->{y_axis_stack} = $self->y_axis_stack or error __"A valid value is required for Y-axis stacking"; @@ -348,6 +381,7 @@ sub write $newgraph->{y_axis_stack} eq 'sum' && !$newgraph->{y_axis} and error __"Please select a Y-axis"; + $newgraph->{y_axis_link} = $self->y_axis_link; $newgraph->{y_axis_label} = $self->y_axis_label; @@ -447,6 +481,10 @@ sub import_hash old => $self->y_axis_stack, new => $values->{y_axis_stack}, name => $self->title if $options{report_only} && $self->y_axis_stack ne $values->{y_axis_stack}; $self->y_axis_stack($values->{y_axis_stack}); + notice __x"Updating y_axis_link from {old} to {new} for graph {name}", + old => $self->y_axis_link, new => $values->{y_axis_link}, name => $self->title + if $options{report_only} && $self->y_axis_link != $values->{y_axis_link}; + $self->y_axis_link($values->{y_axis_link}); notice __x"Updating y_axis_label from {old} to {new} for graph {name}", old => $self->y_axis_label, new => $values->{y_axis_label}, name => $self->title if $options{report_only} && $self->y_axis_label ne $values->{y_axis_label}; @@ -521,6 +559,7 @@ sub export_hash title => $self->title, description => $self->description, y_axis => $self->y_axis, + y_axis_link => $self->y_axis_link, y_axis_stack => $self->y_axis_stack, y_axis_label => $self->y_axis_label, x_axis => $self->x_axis, diff --git a/lib/GADS/Graph/Data.pm b/lib/GADS/Graph/Data.pm index 1ddc6ba35..170ba1074 100644 --- a/lib/GADS/Graph/Data.pm +++ b/lib/GADS/Graph/Data.pm @@ -339,6 +339,11 @@ sub y_axis_col $self->records->layout->column($self->y_axis); } +sub y_axis_link_col +{ my $self = shift; + $self->records->layout->column($self->y_axis_link); +} + sub trend_range_amount { my $self = shift; return undef if !$self->x_axis_range; @@ -403,8 +408,9 @@ sub _build_data $records->view($self->view); push @columns, +{ - id => $self->y_axis, - operator => $self->y_axis_stack, + id => $self->y_axis, + operator => $self->y_axis_stack, + parent_id => $self->y_axis_link, # What the parent curval is, if we're picking a field from within a curval } if $self->y_axis; $records->columns(\@columns); @@ -473,23 +479,18 @@ sub _build_data my ($results, $series_keys, $datemin, $datemax); if ($self->trend) { - # Force current IDs as of today (without rewind set) to be calculated - # first, otherwise the current IDs as at the start of the period will - # be used - $records->generate_cid_query; - my $search = $records->search; # Retain quick search across historical queries foreach my $x (@x) { - $records->clear(retain_current_ids => 1); # Retain record IDs across results + $records->clear; $records->search($search); # The period to retrieve ($x) will be at the beginning of the # period. Move to the end of the period, by adding on one unit # (e.g. month) and then moving into the previous day by a second my $rewind = $x->clone->add($self->x_axis_grouping_calculated.'s' => 1)->subtract(seconds => 1); - $records->rewind($rewind); + $records->rewind_values($rewind); my $this_results; my $this_series_keys; ($this_results, $this_series_keys, $datemin, $datemax) = $self->_records_to_results($records, x_daterange => $x_daterange, diff --git a/lib/GADS/Layout.pm b/lib/GADS/Layout.pm index 2c6dcc650..bff65f70c 100644 --- a/lib/GADS/Layout.pm +++ b/lib/GADS/Layout.pm @@ -1575,14 +1575,16 @@ sub purge $_->delete foreach reverse $self->all(order_dependencies => 1, include_hidden => 1); $self->schema->resultset('UserLastrecord')->delete; + my $current_rs = $self->schema->resultset('Current')->search({ + instance_id => $self->instance_id, + }); + $current_rs->update({ current_version_id => undef }); $self->schema->resultset('Record')->search({ instance_id => $self->instance_id, },{ join => 'current', })->delete; - $self->schema->resultset('Current')->search({ - instance_id => $self->instance_id, - })->delete; + $current_rs->delete; $self->schema->resultset('InstanceGroup')->search({ instance_id => $self->instance_id, })->delete; diff --git a/lib/GADS/Record.pm b/lib/GADS/Record.pm index 1dfbc64c1..892fc244c 100644 --- a/lib/GADS/Record.pm +++ b/lib/GADS/Record.pm @@ -55,6 +55,7 @@ use MooX::Types::MooseLike::Base qw(Maybe Bool Int ArrayRef HashRef); use MooX::Types::MooseLike::DateTime qw/DateAndTime/; use namespace::clean; +with 'GADS::DateTime'; with 'GADS::Role::Presentation::Record'; my $hooks = GADS::Hooks->instance; @@ -635,7 +636,7 @@ sub _build_deleted return $self->schema->resultset('Record')->find($self->record_id)->deleted; } $self->set_deleted or return undef; - $self->schema->storage->datetime_parser->parse_datetime( + $self->dt_parser->parse_datetime( $self->set_deleted ); } @@ -836,7 +837,6 @@ sub _find layout => $self->layout, schema => $self->schema, columns => $self->columns, - rewind => $self->rewind, is_deleted => $find{deleted}, is_draft => $find{draftuser_id} || $find{include_draft}, no_view_limits => !!$find{draftuser_id}, @@ -844,6 +844,13 @@ sub _find include_children => 1, ignore_view_limit_extra => 1, ); + # Build automatically unless override required for chronology + $params{cvo_values} = 0 + if $find{chronology}; + # Only pass in if defined, otherwise it causes current_version_only to be + # cleared + $params{rewind} = $self->rewind + if $self->rewind; my $records = GADS::Records->new(%params); $self->columns_retrieved_do($records->columns_retrieved_do); @@ -854,13 +861,20 @@ sub _find my $record = {}; my $limit = 10; my $page = 1; my $first_run = 1; my $current_id; my @record_ids; while (1) { + my %common = ( + prefetch => 1, + limit => $limit, + page => $page, + current_version_only => $records->cvo_values, + rewind => $records->rewind_values + ); # No linked here so that we get the ones needed in accordance with this loop (could be either) - my @prefetches = $records->jpfetch(prefetch => 1, search => 1, limit => $limit, page => $page); # Still need search in case of view limit + my @prefetches = $records->jpfetch(search => 1, %common); # Still need search in case of view limit last if !@prefetches && !$first_run; my %options = $find{current_id} || $find{draftuser_id} ? () : (root_table => 'record', no_current => 1); - my $search = $records->search_query(prefetch => 1, linked => 1, limit => $limit, page => $page, chronology => $find{chronology}, %options); + my $search = $records->search_query(linked => 1, chronology => $find{chronology}, rewind => $records->rewind_values, %common, %options); # Still need search in case of view limit - @prefetches = $records->jpfetch(prefetch => 1, search => 1, linked => 0, limit => $limit, page => $page, %options); + @prefetches = $records->jpfetch(search => 1, linked => 0, %common, %options); my $root_table; if (my $record_id = $find{record_id}) @@ -869,7 +883,7 @@ sub _find { 'current' => [ 'deletedby', - $records->linked_hash(prefetch => 1, limit => $limit, page => $page), + $records->linked_hash(%common), ], }, ); # Add info about related current record @@ -897,14 +911,15 @@ sub _find panic "Unexpected find parameters"; } @prefetches = ( - $records->linked_hash(prefetch => 1, limit => $limit, page => $page), + $records->linked_hash(%common), 'deletedby', 'currents', { - 'record_single' => [ + $records->cvo_values ? ('current_version' => [@prefetches]) + : ('record_single' => [ 'record_later', @prefetches, - ], + ]), }, ); $root_table = 'Current'; @@ -913,17 +928,17 @@ sub _find panic "record_id or current_id needs to be passed to _find"; } - local $GADS::Schema::Result::Record::REWIND = $records->rewind_formatted + local $GADS::Schema::Result::Record::REWIND = $self->dt_parser->format_datetime($records->rewind) if $records->rewind; # Don't specify linked for fetching columns, we will get whataver is needed linked or not linked - my @columns_fetch = $records->columns_fetch(search => 1, limit => $limit, page => $page, %options); # Still need search in case of view limit - my $has_linked = $records->has_linked(prefetch => 1, limit => $limit, page => $page, %options); - my $base = $find{record_id} ? 'me' : $records->record_name(prefetch => 1, search => 1, limit => $limit, page => $page); + my @columns_fetch = $records->columns_fetch(search => 1, %common, %options); # Still need search in case of view limit + my $has_linked = $records->has_linked(%common, %options); + my $base = $find{record_id} ? 'me' : $records->record_name(search => 1, %common, current_version_only => $records->cvo_values); push @columns_fetch, {id => "$base.id"}; push @columns_fetch, $find{record_id} ? {deleted => "current.deleted"} : {deleted => "me.deleted"}; push @columns_fetch, $find{record_id} ? {linked_id => "current.linked_id"} : {linked_id => "me.linked_id"}; - push @columns_fetch, {linked_record_id => "record_single.id"} + push @columns_fetch, {linked_record_id => $records->cvo_values ? "current_version.id" : "record_single.id"} if $has_linked; push @columns_fetch, $find{record_id} ? {draftuser_id => "current.draftuser_id"} : {draftuser_id => "me.draftuser_id"}; push @columns_fetch, {current_id => "$base.current_id"}; @@ -1238,7 +1253,7 @@ sub versions 'current_id' => $self->current_id, approval => 0, }; - $search->{'me.created'} = { '<' => $self->schema->storage->datetime_parser->format_datetime($self->rewind) } + $search->{'me.created'} = { '<' => $self->dt_parser->format_datetime($self->rewind) } if $self->rewind; my @records = $self->schema->resultset('Record')->search($search,{ prefetch => 'createdby', @@ -1397,7 +1412,7 @@ sub initialise_field column => $column, schema => $record->schema, layout => $record->layout, - datetime_parser => $record->schema->storage->datetime_parser, + datetime_parser => $record->dt_parser, ); } } @@ -1884,12 +1899,14 @@ sub write return; } + my $current; + # New record? if ($self->new_entry) { $self->delete_user_drafts unless $options{no_draft_delete}; # Delete any drafts first, for both draft save and full save my $instance_id = $self->layout->instance_id; - my $current = $self->schema->resultset('Current')->create({ + $current = $self->schema->resultset('Current')->create({ parent_id => $self->parent_id, linked_id => $self->linked_id, instance_id => $instance_id, @@ -1923,6 +1940,9 @@ sub write $self->current_id($current->id); } + else { + $current = $self->schema->resultset('Current')->find($self->current_id); + } if ($need_rec && !$options{update_only}) { @@ -1933,6 +1953,9 @@ sub write })->id; $self->record_id_old($self->record_id) if $self->record_id; $self->record_id($id); + $current->update({ + current_version_id => $id, + }); } elsif ($self->layout->forget_history) { @@ -2618,8 +2641,25 @@ sub purge { my $self = shift; error __"You do not have permission to purge records" unless !$self->user || $self->user_can_purge; + my $guard = $self->schema->txn_scope_guard; $self->_purge_record_values($self->record_id); - $self->schema->resultset('Record')->find($self->record_id)->delete; + my $record_rs = $self->schema->resultset('Record')->find($self->record_id); + my $current_rs = $record_rs->current; + if ($record_rs->id == $current_rs->current_version_id) + { + error __"Unable to delete this version as there are none others" + if $current_rs->records < 2; + # Find previous version to save to current record + my $previous_version = $current_rs->records->search({ + 'me.id' => { '!=' => $record_rs->id }, + },{ + rows => 1, + order_by => { -desc => ['me.created', 'me.id'] }, + })->next; + $current_rs->update({ current_version_id => $previous_version->id }); + } + $record_rs->delete; + $guard->commit; } sub restore @@ -2888,9 +2928,11 @@ sub purge_current } $self->schema->resultset('Record') ->search({ current_id => $id })->update({ record_id => undef }); $self->schema->resultset('AlertCache')->search({ current_id => $id })->delete; + my $current = $self->schema->resultset('Current')->find($id); + $current->update({ current_version_id => undef }); $self->schema->resultset('Record')->search({ current_id => $id })->delete; $self->schema->resultset('AlertSend')->search({ current_id => $id })->delete; - $self->schema->resultset('Current')->find($id)->delete; + $current->delete; $guard->commit; my $user_id = $self->user && $self->user->id; diff --git a/lib/GADS/Records.pm b/lib/GADS/Records.pm index 637cf5327..380829b01 100644 --- a/lib/GADS/Records.pm +++ b/lib/GADS/Records.pm @@ -42,6 +42,7 @@ use MooX::Types::MooseLike::Base qw(Maybe Str ArrayRef HashRef Bool Int); use MooX::Types::MooseLike::DateTime qw/DateAndTime/; with 'GADS::RecordsJoin', 'GADS::Role::Presentation::Records', 'GADS::Helper::ConditionBuilder'; +with 'GADS::DateTime'; # Preferably this is passed in to prevent extra # DB reads, but loads it if it isn't @@ -361,31 +362,69 @@ has page => ( is => 'rw', ); -# Whether to take results from some previous point in time +# Whether to take values and search from some previous point in time has rewind => ( - is => 'rw', - isa => Maybe[DateAndTime], + is => 'rw', + isa => Maybe[DateAndTime], + trigger => sub { + my $self = shift; + $self->clear_current_version_only; + $self->clear_rewind_values; + $self->clear_rewind_recordset; + }, ); -sub rewind_formatted -{ my $self = shift; - $self->rewind or return; - $self->schema->storage->datetime_parser->format_datetime($self->rewind); -} +# Whether to take values from some previous point in time +has rewind_values => ( + is => 'rw', + isa => Maybe[DateAndTime], + lazy => 1, + trigger => sub { shift->clear_current_version_only }, + clearer => 1, + builder => sub { shift->rewind }, +); + +# Whether to take resultset of records from some previous point in time +has rewind_recordset => ( + is => 'rw', + isa => Maybe[DateAndTime], + lazy => 1, + trigger => sub { shift->clear_current_version_only }, + clearer => 1, + builder => sub { shift->rewind }, +); has include_approval => ( is => 'rw', default => 0, ); -# Internal parameter to set the exact current IDs that will be retrieved, -# without running any search queries. Used when downloading chunked data, when -# all the current IDs have already been retrieved -has _set_current_ids => ( - is => 'rw', - isa => Maybe[ArrayRef], +has cvo_values => ( + is => 'lazy', + clearer => 1, ); +sub clear_current_version_only +{ my $self = shift; + $self->clear_cvo_values; + $self->clear_cvo_recordset; +} + +sub _build_cvo_values +{ my $self = shift; + $self->rewind_values || $self->record_earlier || $self->previous_values ? 0 : 1; +} + +has cvo_recordset => ( + is => 'lazy', + clearer => 1, +); + +sub _build_cvo_recordset +{ my $self = shift; + $self->rewind_recordset || $self->record_earlier || $self->previous_values ? 0 : 1; +} + # A parameter that can be used externally to restrict to a set of current IDs. # This will also have the search parameters applied, which could include # limited views for the user (unlike the above internal parameter) @@ -396,17 +435,24 @@ has limit_current_ids => ( # Current ID results, or limit to specific current IDs has current_ids => ( - is => 'lazy', + is => 'rwp', isa => Maybe[ArrayRef], # If undef will be ignored + lazy => 1, + builder => 1, clearer => 1, predicate => 1, ); sub _build_current_ids { my $self = shift; - local $GADS::Schema::Result::Record::REWIND = $self->rewind_formatted - if $self->rewind; - $self->_set_current_ids || [$self->_current_ids_rs->all]; + local $GADS::Schema::Result::Record::REWIND = $self->dt_parser->format_datetime($self->rewind_recordset) + if $self->rewind_recordset; + my $params; + $params->{rows} = $self->rows if $self->rows; + $params->{page} = $self->page if $self->page; + $params->{rows} ||= $self->max_results + if $self->max_results; + [$self->_current_rs->search({},$params)->get_column('me.id')->all]; } # Common search parameters used across different queries @@ -464,7 +510,6 @@ sub search_query my @search = $self->_query_params(%options); my $root_table = $options{root_table} || 'current'; my $current = $options{alias} ? $options{alias} : $root_table eq 'current' ? 'me' : 'current'; - my $record_single = $self->record_name(%options); push @search, $self->_approval_query(%options); # Current IDs from quick search if used push @search, { "$current.id" => $self->_search_all_fields->{cids} } if $self->search; @@ -473,9 +518,8 @@ sub search_query push @search, $self->common_search($current); push @search, $self->record_later_search(%options, linked => $linked, search => 1) unless $options{chronology} || $options{no_record_later}; - push @search, { - "$record_single.created" => { '<=' => $self->rewind_formatted }, - } if $self->rewind; + push @search, {$self->record_single_rewind(%options)} + if $options{rewind}; [@search]; } @@ -558,15 +602,16 @@ sub linked_hash { my $alt = $options{alt} ? "_alternative" : ""; my @tables = $self->jpfetch(%options, linked => 1); + my $version_join = $self->rewind_recordset ? { + "record_single$alt" => [ + "record_later$alt", + @tables, + ] + } : { + current_version => \@tables, + }; return { - linked => [ - { - "record_single$alt" => [ - "record_later$alt", - @tables, - ] - }, - ], + linked => $version_join, }; } else { @@ -609,10 +654,9 @@ sub search_view my @searches = ({ 'me.instance_id' => $self->layout->instance_id, }); - push @searches, $self->record_later_search(linked => 1, search => 1); # Perform search construct twice, to ensure all value joins are consistent numbers - $self->_search_construct($decoded, ignore_perms => 1, user => $user); - push @searches, $self->_search_construct($decoded, ignore_perms => 1, user => $user); + $self->_search_construct($decoded, ignore_perms => 1, user => $user, current_version_only => 1); + push @searches, $self->_search_construct($decoded, ignore_perms => 1, user => $user, current_version_only => 1); my $i = 0; my @ids; while ($i < @$current_ids) { @@ -628,12 +672,9 @@ sub search_view $search->{'me.id'} = [@{$current_ids}[$i..$max]]; push @ids, $self->schema->resultset('Current')->search($search, { join => [ - [$self->linked_hash(search => 1)], + [$self->linked_hash(search => 1, current_version_only => 1)], { - 'record_single' => [ - $self->jpfetch(search => 1), - 'record_later', - ], + 'current_version' => [$self->jpfetch(search => 1)], }, ], })->get_column('id')->all; @@ -803,32 +844,73 @@ sub _build__search_all_fields # Need to get correct "value" number for search, in case it's been incremented through view_limits my $s = $field->{sub} ? $self->value_next_join(search => 1).".$value_field" : "$plural.$value_field"; - my $joins = $field->{type} eq 'current_id' # Include joins for limited views - ? { - 'record_single' => [ - 'record_later', - $self->jpfetch(search => 1), - ] - } - : $field->{sub} - ? { - 'record_single' => [ - 'record_later', - $self->jpfetch(search => 1), - { - $plural => ['value', 'layout'] - }, - ] - } - : { - 'record_single' => [ - 'record_later', - $self->jpfetch(search => 1), - { - $plural => 'layout' - }, - ] - }; + my $joins; + if ($field->{type} eq 'current_id') # Include joins for limited views + { + if ($self->cvo_recordset) + { + $joins = { + 'current_version' => [$self->jpfetch(search => 1)], + }; + } + else { + $joins = { + 'record_single' => [ + 'record_later', + $self->jpfetch(search => 1), + ] + }; + } + } + elsif ($field->{sub}) + { + if ($self->cvo_recordset) + { + $joins = { + 'current_version' => [ + $self->jpfetch(search => 1), + { + $plural => ['value', 'layout'] + }, + ] + }; + } + else { + $joins = { + 'record_single' => [ + 'record_later', + $self->jpfetch(search => 1), + { + $plural => ['value', 'layout'] + }, + ] + }; + } + } + else { + if ($self->cvo_recordset) + { + $joins = { + 'current_version' => [ + $self->jpfetch(search => 1), + { + $plural => 'layout' + }, + ] + }; + } + else { + $joins = { + 'record_single' => [ + 'record_later', + $self->jpfetch(search => 1), + { + $plural => 'layout' + }, + ] + }; + } + } my @search = @basic_search; push @search, @@ -843,7 +925,7 @@ sub _build__search_all_fields } else { push @search, { 'layout.id' => \@columns_can_view }; - push @search, $self->record_later_search(search => 1); + push @search, $self->record_later_search(search => 1, current_version_only => $self->cvo_recordset); } my @currents = $self->schema->resultset('Current')->search({ -and => \@search},{ join => $joins, @@ -962,55 +1044,69 @@ sub _me_created_value })->get_column('createdby.value')->as_query; } -# Produce a standard set of results without grouping sub _current_ids_rs +{ my $self = shift; + $self->_current_rs->get_column('me.id'); +} + +sub _current_rs { my ($self, %options) = @_; - my %limit = ( - limit => $options{limit}, - page => $options{limit}, + my %common = ( + search => 1, + sort => 1, + limit => $options{limit}, + page => $options{limit}, + current_version_only => $self->cvo_recordset, ); + # Build the search query first, to ensure that all join numbers are correct - my $search_query = $self->search_query(search => 1, sort => 1, linked => 1, %limit); # Need to call first to build joins - my @prefetches = $self->jpfetch(prefetch => 1, linked => 0, %limit); - my @linked_prefetch = $self->linked_hash(prefetch => 1, %limit); + my $search_query = $self->search_query(linked => 1, rewind => $self->rewind_recordset, %common); # Need to call first to build joins + my @prefetches = $self->jpfetch(prefetch => 1, linked => 0, %common); + my @linked_prefetch = $self->linked_hash(prefetch => 1, %common); # Run 2 queries. First to get the current IDs of the matching records, then # the second to get the actual data for the records. Although this means # 2 separate DB queries, it prevents queries with large SELECT and WHERE # clauses, which can be very slow (with Pg at least). + my $version_join = $self->cvo_recordset + ? { + current_version => [ + $self->jpfetch(linked => 0, %common), + ] + } : { + 'record_single' => [ # The (assumed) single record for the required version of current + $self->record_earlier ? 'record_earlier' : 'record_later', # The record after the single record (undef when single is latest) + $self->jpfetch(linked => 0, %common), + ], + }; my $select = { join => [ - [$self->linked_hash(search => 1, sort => 1, %limit)], - { - 'record_single' => [ # The (assumed) single record for the required version of current - $self->record_earlier ? 'record_earlier' : 'record_later', # The record after the single record (undef when single is latest) - $self->jpfetch(search => 1, sort => 1, linked => 0, %limit), - ], - }, + [$self->linked_hash(%common)], + $version_join, ], - order_by => $self->order_by(search => 1, with_min => 1, %limit), + order_by => $self->order_by(with_min => 1, %common), distinct => 1, # Otherwise multiple records returned for multivalue fields select => [ 'me.id', ], '+select' => [ - $self->has_created_time(search => 1, sort => 1, %limit) ? { + $self->has_created_time(%common) ? { "" => $self->_me_created_date, -as => 'record_created_date', } : (), - $self->has_created_user(search => 1, sort => 1, %limit) ? { + $self->has_created_user(%common) ? { "" => $self->_me_created_user, -as => 'record_created_user', } : (), - $self->has_created_user(search => 1, sort => 1, %limit) ? { + $self->has_created_user(%common) ? { "" => $self->_me_created_value, -as => 'record_created_value', } : (), ], '+as' => [ - $self->has_created_time(search => 1, sort => 1, %limit) ? 'record_created_date' : (), - $self->has_created_user(search => 1, sort => 1, %limit) ? ( + $self->has_created_time(%common) ? 'record_created_date' : (), + $self->has_created_user(%common) ? ( 'record_created_user', 'record_created_value', ) : (), @@ -1023,65 +1119,40 @@ sub _current_ids_rs $page = $self->pages if $page && $page > 1 && $page > $self->pages; # Building page count is expensive, avoid if not needed - if (!$self->is_group && !$options{aggregate}) - { - $select->{rows} = $self->rows if $self->rows; - $select->{page} = $page if $page; - $select->{rows} ||= $self->max_results - if $self->max_results; - } - # Get the current IDs # Only take the latest record_single (no later ones) $self->schema->resultset('Current')->search( [-and => $search_query], $select - )->get_column('me.id'); -} - -sub generate_cid_query -{ my $self = shift; - $self->_cid_search_query; + ); } -has _cid_search_query_cache => ( - is => 'rw', - clearer => 1, -); - # Produce a search query that filters by all the required current IDs. This # needs to include the list of current IDs itself, plus a filter to ensure only # the required version of a record is retrieved. Assumes that REWIND has # already been set by the calling function. -sub _cid_search_query +sub _resultset_search { my ($self, %options) = @_; - my $search = $self->_cid_search_query_cache; - if (!$search) - { - $search = { map { %$_ } $self->record_later_search(prefetch => 1, sort => 1, linked => 1, group => 1, retain_join_order => 1, %options) }; - - # If this is a group query then we will not be limiting by number of - # records (but will be reducing number of results by group), and therefore - # it's best to pass the current IDs required as a SQL query (otherwise we - # could be passing in 1000s of ID values). If we're doing the opposite, - # then we would be creating some very big queries with the sub-query, and - # therefore performance (Pg at least) has been shown to be better if we run - # the ID subquery first and only pass the IDs in to the main query - if ($self->is_group || $options{aggregate}) - { - $search->{'me.id'} = { -in => $self->_current_ids_rs(%options)->as_query }; - } - else { - $search->{'me.id'} = $self->current_ids; - } - } - my $record_single = $self->record_name(linked => 0); - $search->{"$record_single.created"} = { '<=' => $self->rewind_formatted } - if $self->rewind; - my $approval_query = $self->_approval_query(%options); - $search = { %$search, %$approval_query } if $approval_query; - $self->_cid_search_query_cache($search); - $search; + my %search = map { %$_ } $self->record_later_search(%options); + + # If this is a group query then we will not be limiting by number of + # records (but will be reducing number of results by group), and therefore + # it's best to pass the current IDs required as a SQL query (otherwise we + # could be passing in 1000s of ID values). If we're doing the opposite, + # then we would be creating some very big queries with the sub-query, and + # therefore performance (Pg at least) has been shown to be better if we run + # the ID subquery first and only pass the IDs in to the main query + $search{'me.id'} = $options{is_group} + ? { -in => $self->_current_ids_rs->as_query } + : $self->current_ids; + + # Rewind clause added only if needed + %search = (%search, $self->record_single_rewind(%options, rewind => $self->rewind_values)); + + # Need to add an approval clause? + %search = (%search, %{$self->_approval_query(%options) || {}}); + + \%search; } has already_seen => ( @@ -1102,48 +1173,57 @@ sub _build_results sub _build_standard_results { my $self = shift; - local $GADS::Schema::Result::Record::REWIND = $self->rewind_formatted - if $self->rewind; + local $GADS::Schema::Result::Record::REWIND = $self->dt_parser->format_datetime($self->rewind_values) + if $self->rewind_values; # XXX A lot of this code is duplicated in GADS::Record # Need to call first to build all joins - my $search_query = $self->search_query(search => 1, sort => 1, linked => 1); + my $search_query = $self->search_query(search => 1, sort => 1, linked => 1, rewind => $self->rewind_values); my $records = {}; my $limit = 10; my $page = 1; my $first_run = 1; my @retrieved_order; while (1) { + my %common = ( + prefetch => 1, + sort => 1, + limit => $limit, + page => $page, + current_version_only => $self->cvo_values, + ); # No linked here so that we get the ones needed in accordance with this loop (could be either) - my @prefetches = $self->jpfetch(prefetch => 1, sort => 1, limit => $limit, page => $page); + my @prefetches = $self->jpfetch(%common); last if !@prefetches && !$first_run; # We need to use the retain_join_order as we are only using joins, not # joins as well as prefetches. With the commit that this comment is # going in with, it looks like this may always be the case now. # Therefore, retain_join_order may now be redundent and could possibly # be made the default and removed in a future commit. - @prefetches = $self->jpfetch(prefetch => 1, sort => 1, linked => 0, limit => $limit, page => $page, retain_join_order => 1); + @prefetches = $self->jpfetch(%common, linked => 0, retain_join_order => 1); @prefetches = ( - $self->linked_hash(prefetch => 1, sort => 1, limit => $limit, page => $page, retain_join_order => 1), + $self->linked_hash(%common, retain_join_order => 1), 'deletedby', 'currents', { - 'record_single' => [ + $self->cvo_values + ? ('current_version' => [@prefetches]) + : ('record_single' => [ 'record_later', @prefetches, - ], + ]) }, ); # Don't specify linked for fetching columns, we will get whataver is needed linked or not linked - my @columns_fetch = $self->columns_fetch(sort => 1, limit => $limit, page => $page, retain_join_order => 1); - my $has_linked = $self->has_linked(prefetch => 1, sort => 1, limit => $limit, page => $page); - my $base = $self->record_name(prefetch => 1, sort => 1, limit => $limit, page => $page); + my @columns_fetch = $self->columns_fetch(%common, retain_join_order => 1); + my $has_linked = $self->has_linked(%common); + my $base = $self->record_name(%common); push @columns_fetch, {id => "$base.id"}; push @columns_fetch, {deleted => "me.deleted"}; push @columns_fetch, {linked_id => "me.linked_id"}; - push @columns_fetch, {linked_record_id => "record_single.id"} + push @columns_fetch, {linked_record_id => $self->cvo_values ? "current_version.id" : "record_single.id"} if $has_linked; push @columns_fetch, {draftuser_id => "me.draftuser_id"}; push @columns_fetch, {current_id => "$base.current_id"}; @@ -1153,33 +1233,32 @@ sub _build_standard_results push @columns_fetch, {parent_id => "me.parent_id"}; push @columns_fetch, "deletedby.$_" foreach @GADS::Column::Person::person_properties; - $self->_clear_cid_search_query_cache; - my $result = $self->schema->resultset('Current')->search($self->_cid_search_query(prefetch => 1, sort => 1, limit => $limit, page => $page), + my $result = $self->schema->resultset('Current')->search($self->_resultset_search(%common), { join => [@prefetches], columns => \@columns_fetch, '+select' => [ - $self->has_created_time(prefetch => 1, sort => 1, limit => $limit, page => $page) ? { + $self->has_created_time(%common) ? { "" => $self->_me_created_date, -as => 'record_created_date', } : (), - $self->has_created_user(prefetch => 1, sort => 1, limit => $limit, page => $page) ? { + $self->has_created_user(%common) ? { "" => $self->_me_created_user, -as => 'record_created_user', } : (), - $self->has_created_user(prefetch => 1, sort => 1, limit => $limit, page => $page) ? { + $self->has_created_user(%common) ? { "" => $self->_me_created_value, -as => 'record_created_value', } : (), ], '+as' => [ - $self->has_created_time(prefetch => 1, sort => 1, limit => $limit, page => $page) ? 'record_created_date' : (), - $self->has_created_user(prefetch => 1, sort => 1, limit => $limit, page => $page) ? ( + $self->has_created_time(%common) ? 'record_created_date' : (), + $self->has_created_user(%common) ? ( 'record_created_user', 'record_created_value', ) : (), ], - order_by => $self->order_by(prefetch => 1, limit => $limit, page => $page, retain_join_order => 1), + order_by => $self->order_by(%common, retain_join_order => 1), }, ); @@ -1256,7 +1335,6 @@ sub _build_standard_results my $record = GADS::Record->new( schema => $self->schema, record => $rec, - rewind => $self->rewind, serial => $rec->{serial}, child_records => \@children, parent_id => $rec->{parent_id}, @@ -1369,18 +1447,19 @@ sub fetch_multivalues # IDs. We retrieve them now. This should really # be abstracted to a function elsewhere - it is # too low level. - local $GADS::Schema::Result::Record::REWIND = $self->rewind_formatted - if $self->rewind; + local $GADS::Schema::Result::Record::REWIND = $self->dt_parser->format_datetime($self->rewind_values) + if $self->rewind_values; my $search = { 'me.id' => \@value_ids, - 'record_later.id' => undef, }; - $search->{'record_single.created'} = { '<=' => $self->rewind_formatted } - if $self->rewind; + $search->{'record_later.id'} = undef + if !$self->cvo_values; + $search->{'record_single.created'} = { '<=' => $self->dt_parser->format_datetime($self->rewind_values) } + if $self->rewind_values; my @curs = $self->schema->resultset('Current')->search($search,{ - select => ['me.id', 'record_single.id'], + select => ['me.id', $self->cvo_values ? 'me.current_version_id' : 'record_single.id'], as => ['current_id', 'record_id'], - join => { + join => $self->cvo_values ? 'current_version' : { record_single => 'record_later', }, })->all; @@ -1412,7 +1491,7 @@ sub fetch_multivalues foreach my $val ($col->fetch_multivalues( \@retrieve_ids, is_draft => $params{is_draft}, - rewind => $self->rewind, # Would be better in a context object + rewind => $self->rewind_values, already_seen => $already_seen, limit_rows => $limit_rows, )) @@ -1532,10 +1611,8 @@ sub single # Set those IDs for the next chunk retrieved from the DB $self->_set_current_ids($cid_fetch); - $self->clear_current_ids; $self->clear_results; $self->delete_already_seen; - $self->_clear_cid_search_query_cache; $next_id = 0; } @@ -1563,19 +1640,19 @@ sub _build_count # and if there is no other need to look at the records join (approval, # rewind etc) my ($search_query, $select); - if ($self->rewind || $self->_query_params(search => 1) || $self->_approval_query) + if ($self->rewind_recordset || $self->_query_params(search => 1) || $self->_approval_query) { - $search_query = $self->search_query(search => 1, linked => 1); - my @joins = $self->jpfetch(search => 1, linked => 0); - my @linked = $self->linked_hash(search => 1, linked => 1); + $search_query = $self->search_query(search => 1, linked => 1, current_version_only => $self->cvo_values, rewind => $self->rewind_values); + my @joins = $self->jpfetch(search => 1, linked => 0, current_version_only => $self->cvo_values); + my @linked = $self->linked_hash(search => 1, linked => 1, current_version_only => $self->cvo_values); $select = { join => [ [@linked], { - 'record_single' => [ + $self->cvo_values ? ('current_version' => \@joins) : ('record_single' => [ 'record_later', @joins - ], + ]), }, ], distinct => 1, # Otherwise multiple records returned for multivalue fields @@ -1583,11 +1660,11 @@ sub _build_count } else { # record joins not needed, remove with fresh call - $search_query = $self->search_query(search => 1, linked => 1, no_record_later => 1); + $search_query = $self->search_query(search => 1, linked => 1, no_record_later => 1, current_version_only => $self->cvo_values, rewind => $self->rewind_values); } - local $GADS::Schema::Result::Record::REWIND = $self->rewind_formatted - if $self->rewind; + local $GADS::Schema::Result::Record::REWIND = $self->dt_parser->format_datetime($self->rewind_recordset) + if $self->rewind_recordset; $self->schema->resultset('Current')->search( [-and => $search_query], $select @@ -1614,9 +1691,9 @@ sub exists $search_query = $cache->{search_query}; } else { - $search_query = $self->search_query(search => 1, linked => 1); - @joins = $self->jpfetch(search => 1, linked => 0); - @linked = $self->linked_hash(search => 1, linked => 1); + $search_query = $self->search_query(search => 1, linked => 1, current_version_only => $self->cvo_values, rewind => $self->rewind_values); + @joins = $self->jpfetch(search => 1, linked => 0, current_version_only => $self->cvo_values); + @linked = $self->linked_hash(search => 1, linked => 1, current_version_only => $self->cvo_values); $self->_exists_cache({ joins => \@joins, linked => \@linked, @@ -1648,10 +1725,10 @@ sub exists join => [ [@linked], { - 'record_single' => [ + $self->cvo_values ? ('current_version' => \@joins): ('record_single' => [ 'record_later', @joins - ], + ]) }, ], rows => 1, @@ -1662,27 +1739,32 @@ sub exists )->get_column('me.id')->next; } +# Whether this set of records has any child records within it sub _build_has_children { my $self = shift; - my @search_query = @{$self->search_query(search => 1, linked => 1)}; + # Use is_group to ensure that WHERE clause consists of query instead of + # full list of current IDs + my $search_query = $self->_resultset_search(search => 1, linked => 1, is_group => 1, current_version_only => $self->cvo_values); my $linked = $self->linked_hash(search => 1); my $select = { join => [ $linked, { - 'record_single' => [ - 'record_later', - $self->jpfetch(search => 1), - ], + $self->cvo_values + ? ('current_version' => [$self->jpfetch(search => 1, current_version_only => $self->cvo_values)]) + : ('record_single' => [ + 'record_later', + $self->jpfetch(search => 1, current_version_only => $self->cvo_values), + ]) }, ], rows => 1, }; - push @search_query, { 'me.parent_id' => { '!=' => undef }}; + $search_query->{'me.parent_id'} = { '!=' => undef }; my @child = $self->schema->resultset('Current')->search( - [-and => [@search_query]], $select + $search_query, $select )->all; @child ? 1 : 0; } @@ -1704,10 +1786,13 @@ sub _build_columns_retrieved_do } } + my %view_group_cols = map { $_->layout_id => $_->parent_id } $self->view ? @{$self->view->groups} : (); foreach my $c (@columns) { # We're viewing this, so prefetch all the values - $self->add_prefetch($c, include_multivalue => $self->separate_records_for_multicol); + my $parent_id = $view_group_cols{$c->id}; + my $parent = $parent_id && $self->layout->column($parent_id); + $self->add_prefetch($c, parent => $parent, include_multivalue => $self->separate_records_for_multicol); $self->add_linked_prefetch($c->link_parent) if $c->link_parent; } @@ -1730,16 +1815,19 @@ has separate_records_for_multicol => ( is => 'rw', ); -has group_col_ids => ( +has group_cols => ( is => 'lazy', isa => ArrayRef, clearer => 1, ); -sub _build_group_col_ids +sub _build_group_cols { my $self = shift; return [] if !$self->view; - [map $_->layout_id, @{$self->view->groups}]; + [map { + my $col = $self->layout->column($_->layout_id); + $col->clone(parent_id => $_->parent_id) + } @{$self->view->groups}]; } has has_group_col_id => ( @@ -1751,7 +1839,7 @@ has has_group_col_id => ( sub _build_has_group_col_id { my $self = shift; +{ - map { $_ => 1 } @{$self->group_col_ids} + map { $_->id => 1 } @{$self->group_cols} }; } @@ -1806,7 +1894,7 @@ sub _build_columns_render # the order selected @cols = grep !$self->has_group_col_id->{$_->id}, @cols if $self->is_group; - unshift @cols, grep $_->user_can('read'), map $self->layout->column($_), @{$self->group_col_ids} + unshift @cols, grep $_->user_can('read'), @{$self->group_cols} if $self->is_group; } @@ -1836,10 +1924,7 @@ sub clear_records $self->clear_aggregate_results; $self->_set__next_single_id(0); $self->_single_page(0); - $self->_set_current_ids(undef); $self->_clear_all_cids_store; - $self->_clear_cid_search_query_cache - unless $options{retain_current_ids}; } sub clear @@ -1858,7 +1943,8 @@ sub clear $self->clear_is_group; $self->clear_additional_filters; $self->clear_has_group_col_id; - $self->clear_group_col_ids; + $self->clear_group_cols; + $self->clear_current_version_only; $self->clear_records(%options); } @@ -2047,10 +2133,18 @@ sub _sort_builder { foreach my $s (@{$self->sort}) { + my $col = $self->layout->column($s->{id}) + or next; + my $col_parent = $self->layout->column($s->{parent_id}); + !$s->{parent_id} || $col_parent + or next; + error __x"Column {id} requested for sort from different table without parent", id => $col->id + if $col->instance_id != $self->layout->instance_id && !$col_parent; push @sorts, { - id => $s->{id} || $column_id->id, # Default ID - type => $s->{type} || 'asc', - } if $self->layout->column($s->{id}); + id => $col->id, + parent_id => $col_parent && $col_parent->id, + type => $s->{type} || 'asc', + }; } } if (!@sorts && $self->view && @{$self->view->sorts}) { @@ -2086,6 +2180,8 @@ sub order_by ? @{$self->_sorts_limit} : @{$self->_sorts}; + my $group_cols = delete $options{group_cols}; + my @order_by; my %has_time; foreach my $s (@sorts) { @@ -2099,8 +2195,26 @@ sub order_by my $column = $self->layout->column($s->{id}, permission => 'read') or next; my $column_parent = $self->layout->column($s->{parent_id}); - my @cols_main = $column->sort_columns; - my @cols_link = $column->link_parent ? $column->link_parent->sort_columns : (); + my @cols_main; + if ($column->is_curcommon) + { + @cols_main = @{$column->curval_fields}; + $column_parent = $column; + } + else { + @cols_main = ($column); + } + my @cols_link; + if (my $link_parent = $column->link_parent) + { + if ($link_parent->is_curcommon) + { + @cols_link = @{$link_parent->curval_fields}; + } + else { + @cols_link = ($link_parent); + } + } foreach my $col_sort (@cols_main) { if ($column_parent) @@ -2109,11 +2223,9 @@ sub order_by $self->add_join($col_sort, sort => 1, parent => $column_parent); } else { - $self->add_join($column->sort_parent, sort => 1) - if $column->sort_parent; - $self->add_join($col_sort, sort => 1, parent => $column->sort_parent); + $self->add_join($col_sort, sort => 1); } - my $s_table = $self->table_name($col_sort, sort => 1, %options, parent => $column_parent || $column->sort_parent); + my $s_table = $self->table_name($col_sort, sort => 1, %options, parent => $column_parent); my $sort_name; if ($column->name_short && $column->name_short eq '_created_user') { @@ -2137,9 +2249,21 @@ sub order_by else { $sort_name = "$s_table.".$col_sort->sort_field; } - push @order_by, { - $type => $sort_name, - }; + my $query; + if ($options{group}) + { + # Assume that if the column is appearing in the group_by + # that it will already have been added as a grouped column + # and therefore there is no need to add the is_grouped flag + # here. This relies on calling this order_by function after + # the grouped columns have been added. + my $agg = $self->add_aggregate($col_sort, 'max', parent => $column_parent, group_cols => $group_cols, sort => 1, %options); + $query = { $type => $agg->{as} }; + } + else { + $query = { $type => $sort_name }; + } + push @order_by, $query; $has_time{$sort_name} = 1 if $col_sort->has_time; } } @@ -2157,8 +2281,8 @@ sub order_by # is made even though it doesn't match (in SQLite anyway). E.g. "< # 2019-04-05 00:00" will match a date field of "2019-04-05" my $date = $has_time{$field} - ? $self->schema->storage->datetime_parser->format_datetime($self->from || $self->to) - : $self->schema->storage->datetime_parser->format_date($self->from || $self->to); + ? $self->dt_parser->format_datetime($self->from || $self->to) + : $self->dt_parser->format_date($self->from || $self->to); my $quoted = $self->quote($field); if ($field eq 'record_created_date') { @@ -2289,7 +2413,7 @@ sub rule_to_condition if ($filter->{value} =~ /CURDATE/) # XXX repeated below, quick fix { my $vdt = GADS::View->parse_date_filter($filter->{value}); - my $dtf = $self->schema->storage->datetime_parser; + my $dtf = $self->dt_parser; $value = $dtf->format_date($vdt); } else { @@ -2427,8 +2551,7 @@ sub rule_to_condition if ($_ && $_ =~ /CURDATE/) { my $vdt = GADS::View->parse_date_filter($_); - my $dtf = $self->schema->storage->datetime_parser; - $_ = $dtf->format_date($vdt); + $_ = $self->dt_parser->format_date($vdt); } elsif ($transform_date || ($column->return_type eq 'date' && $_)) { @@ -2538,6 +2661,7 @@ sub _resolve my $multivalue = $options{parent} ? $options{parent}->multivalue : $column->multivalue; my $reverse = $options{reverse}; my $previous_values = $options{previous_values}; + my $me_table = $options{alias} || 'me'; if ($condition->{type} eq 'changed_after') { local $GADS::Helper::Changed::CHANGED_PARAMS = { @@ -2566,10 +2690,16 @@ sub _resolve })->get_column('id')->as_query; return ( - 'me.id' => [{ -in => $sub1 } , { -in => $sub2}] + "$me_table.id" => [{ -in => $sub1 } , { -in => $sub2}] ); } - elsif ($multivalue && $condition->{type} eq 'not_equal' && !$previous_values) + elsif ($multivalue && $condition->{type} eq 'not_equal' && !$previous_values + # If this set of records is a search across all versions + # ($records->previous_values is true) then perform a normal join of all + # these conditions, so that only a match is made when they are all true + # for a particular version + && !$self->previous_values + ) { # Create a non-negative match of all the IDs that we don't want to # match. Use a Records object so that all the normal requirements are @@ -2588,7 +2718,7 @@ sub _resolve ), ); return ( - 'me.id' => { + "$me_table.id" => { # We want everything that is *not* those records -not_in => $records->_current_ids_rs->as_query, } @@ -2618,14 +2748,14 @@ sub _resolve if ($reverse) { return ( - 'me.id' => { + "$me_table.id" => { -not_in => $records->_current_ids_rs->as_query, } ); } else { return ( - 'me.id' => { + "$me_table.id" => { -in => $records->_current_ids_rs->as_query, } ); @@ -2654,7 +2784,7 @@ sub _resolve ), ); return ( - 'me.id' => { + "$me_table.id" => { -in => $records->_current_ids_rs->as_query, } ); @@ -2677,8 +2807,8 @@ sub _date_for_db { my ($self, $column, $value) = @_; my $dt = $column->parse_date($value); $column->has_time - ? $self->schema->storage->datetime_parser->format_datetime($dt) - : $self->schema->storage->datetime_parser->format_date($dt); + ? $self->dt_parser->format_datetime($dt) + : $self->dt_parser->format_date($dt); } has _csv => ( @@ -2959,7 +3089,7 @@ sub _max_date { shift->_min_max_date('max', @_) }; sub _min_max_date { my ($self, $action, $date1, $date2) = @_; - my $dt_parser = $self->schema->storage->datetime_parser; + my $dt_parser = $self->dt_parser; my $d1 = $date1 && $dt_parser->parse_date($date1); my $d2 = $date2 && $dt_parser->parse_date($date2); return $d1 if !$d2; @@ -3055,7 +3185,7 @@ sub _build_aggregate_results return undef if ! @columns; - $self->_clear_cid_search_query_cache; # Clear any list of record IDs from previous results() call + $self->clear_current_ids; # Clear any list of record IDs from previous results() call my $results = $self->_build_group_results(columns => \@columns, is_group => 1, aggregate => 1); panic "Unexpected number of aggregate results" @@ -3076,6 +3206,11 @@ sub _build_group_results my @cols; my $view = $self->view; + # During building grouped results an aggregate field can be added via + # sorting or as a selected column. This needs to be cleared each time, as + # group results can require different aggregate functions + $self->clear_aggregate_fields; + my $is_table_group = !$self->isa('GADS::RecordsGraph') && !$self->isa('GADS::RecordsGlobe'); if ($options{columns}) @@ -3100,8 +3235,13 @@ sub _build_group_results } my @parents; - my %group_cols; - %group_cols = map { $_->layout_id => 1 } @{$view->groups} + my @group_cols; + @group_cols = map { + +{ + column => $self->layout->column($_->layout_id), + parent => $_->parent_id && $self->layout->column($_->parent_id), + } + } @{$view->groups} if $is_table_group && $view && !$options{aggregate}; foreach my $col (@cols) @@ -3115,8 +3255,8 @@ sub _build_group_results # sub-fields will be added, which for a multivalue curval will mean # many unnecessary sub-queries below. We may want to add these later if # making it possible to manually group by a curval sub-field - $group_cols{$col->{id}} = 1 - if $col->{group} && !$col->{parent}; + push @group_cols, { column => $column } + if $col->{group} && !$col->{parent} && ! grep $_->{column}->id == $column->id, @group_cols; # If it's got a parent curval, then add that too if ($col->{parent_id}) @@ -3148,7 +3288,6 @@ sub _build_group_results } # Combine and flatten columns - unshift @cols, @parents; my @newcols; foreach my $col (@cols) { @@ -3164,7 +3303,7 @@ sub _build_group_results @cols = @newcols; # Add all columns first so that join numbers are correct - foreach my $col (@cols) + foreach my $col (@parents, @cols) { my $column = $col->{column}; next if $column->internal; @@ -3192,9 +3331,14 @@ sub _build_group_results } } - my $as_index = $self->group_values_as_index; my $drcol = !!$self->dr_column; + # Need to set before any subqueries are built + local $GADS::Schema::Result::Record::REWIND = $self->dt_parser->format_datetime($self->rewind_values) + if $self->rewind_values; + + my %sort_mapping; + foreach my $col (@cols) { my $op = $col->{operator}; @@ -3203,147 +3347,7 @@ sub _build_group_results next if $options{aggregate} && $column->aggregate && $column->aggregate eq 'recalc'; - my $select; - my $as = $column->field; - $as = $as.'_count' if $op eq 'count'; - $as = $as.'_sum' if $op eq 'sum'; - $as = $as.'_distinct' if $op eq 'distinct' && !$col->{group}; - - # The select statement to get this column's value varies depending on - # what we want to retrieve. If we're selecting a field with multiple - # values, then we have to run this as a separate subquery, otherwise if - # there are more than one multiple-value retrieval then that aggregates - # will be counting multiple times for each set of multiple values (due - # to the multiple joins) - - # Field is either multivalue or its parent is - if (($column->multivalue || ($parent && $parent->multivalue)) && !$col->{group} && !$col->{drcol}) - { - # Assume curval if it's a parent - we need to search the curval - # table for all the curvals that are part of the records retrieved. - # XXX add search query? - if ($parent) - { - my $f_rs = $self->schema->resultset('Curval')->search({ - 'mecurval.record_id' => { - -ident => 'record_single.id' # Match against main query's records - }, - 'mecurval.layout_id' => $parent->id, - 'record_later.id' => undef, - }, - { - alias => 'mecurval', # Can't use default "me" as already used in main query - join => { - 'value' => { - 'record_single_alternative' => [ - 'record_later', - $column->tjoin, - ], - }, - }, - }); - if ($column->numeric && $op eq 'sum') - { - $select = $f_rs->get_column((ref $column->tjoin eq 'HASH' ? 'value_2' : $column->field).".".$column->value_field)->sum_rs->as_query; - } - elsif (!$is_table_group) - { - $select = $f_rs->get_column((ref $column->tjoin eq 'HASH' ? 'value_2' : $column->field).".".$column->value_field)->max_rs->as_query; - } - else { - # At the moment we do not expect a distinct count to be - # necessary for a field from within a curval. We might want - # to add this functionality in the future, in which case it - # will look something like the next else block - panic __x"Unexpected count distinct for curval sub-field {name} ({id})", - name => $column->name, id => $column->id; - } - } - # Otherwise a standard subquery select for that type of field - else { - # Also need to add the main search query, otherwise if we take - # all the field's values for each record, then we won't be - # filtering the non-matched ones in the case of multivalue - # fields. - # Need to include "group" as an option to the subquery, to - # ensure that the grouping column is added to match to the main - # query's group column. This does not apply if doing an overall - # aggregate though, as there is only a need to retrieve the - # overall results, not for each matching grouped row. If the - # "group" option is included unnecessarily, then this can cause - # joins of multiple-value fields which can include too many - # results in the aggregate. - my $include_group = %group_cols ? 1 : 0; - my $searchq = $self->search_query(search => 1, extra_column => $column, linked => 0, group => $include_group, alt => 1, alias => 'mefield'); - foreach my $group_id (keys %group_cols) - { - my $group_col = $self->layout->column($group_id); - push @$searchq, { - $self->fqvalue($group_col, as_index => $as_index, search => 1, linked => 0, group => 1, alt => 1, extra_column => $group_col, drcol => $drcol) => { - -ident => $self->fqvalue($group_col, as_index => $as_index, search => 1, linked => 0, group => 1, extra_column => $group_col, drcol => $drcol) - }, - }; - } - $select = $self->schema->resultset('Current')->search( - [-and => $searchq ], - { - alias => 'mefield', - join => [ - [$self->linked_hash(search => 1, group => $include_group, alt => 1, extra_column => $column)], - { - 'record_single_alternative' => [ # The (assumed) single record for the required version of current - 'record_later_alternative', # The record after the single record (undef when single is latest) - $self->jpfetch(search => 1, linked => 0, group => $include_group, extra_column => $column, alt => 1), - ], - }, - ], - select => { - count => { distinct => $self->fqvalue($column, as_index => $as_index, search => 1, linked => 0, group => 1, alt => 1, extra_column => $column, drcol => $drcol) }, - -as => 'sub_query_as', - }, - }, - ); - my $col_fq = $self->fqvalue($column, as_index => $as_index, search => 1, linked => 0, group => 1, alt => 1, extra_column => $column, drcol => $drcol); - if ($column->numeric && $op eq 'sum') - { - $select = $select->get_column($col_fq)->sum_rs->as_query; - $op = 'max'; - } - elsif ($self->isa('GADS::RecordsGraph') || $self->isa('GADS::RecordsGlobe')) - { - $select = $select->get_column($col_fq)->max_rs->as_query; - } - else { - $select = $select->get_column('sub_query_as')->as_query; - $op = 'max'; - } - } - } - # Standard single-value field - select directly, no need for a subquery - else { - $select = $self->fqvalue($column, as_index => $as_index, prefetch => 1, group => 1, search => 0, linked => 0, parent => $parent, retain_join_order => 1, drcol => $drcol); - } - - if ($op eq 'distinct') - { - $select = { - count => { distinct => $select }, - -as => $as, - }; - push @select_fields, $select; - } - else { - push @select_fields, { - $op => $select, - -as => $as, - }; - } - - # Also add linked column if required - push @select_fields, { - $op => $self->fqvalue($column->link_parent, as_index => $as_index, prefetch => 1, search => 0, linked => 1, parent => $parent, retain_join_order => 1, drcol => $drcol), - -as => $as."_link", - } if $column->link_parent; + $self->add_aggregate($column, $op, search => 0, parent => $parent, group_cols => \@group_cols, is_grouped => $col->{group} || $col->{drcol}); } push @select_fields, { @@ -3368,7 +3372,7 @@ sub _build_group_results { min => "$field.$from_field", -as => 'start_date'}, { max => "$field.$to_field", -as => 'end_date'}, ]; - my $search = $self->search_query(search => 1, prefetch => 1, linked => 0); + my $search = $self->search_query(search => 1, prefetch => 1, linked => 0, current_version_only => $self->cvo_values, rewind => $self->rewind_values); # Include linked field if applicable if ($field_link) { @@ -3378,24 +3382,27 @@ sub _build_group_results ); } - local $GADS::Schema::Result::Record::REWIND = $self->rewind_formatted - if $self->rewind; + # Get min and max dates of range my ($result) = $self->schema->resultset('Current')->search( [-and => $search], { select => $select, join => [ - $self->linked_hash(search => 1, prefetch => 1), + $self->linked_hash(search => 1, prefetch => 1, current_version_only => $self->cvo_values), { - 'record_single' => [ + $self->cvo_values + ? ('current_version' => [ + $self->jpfetch(search => 1, prefetch => 1, linked => 0, current_version_only => $self->cvo_values) + ]) + : ('record_single' => [ 'record_later', - $self->jpfetch(search => 1, prefetch => 1, linked => 0), - ], + $self->jpfetch(search => 1, prefetch => 1, linked => 0, current_version_only => $self->cvo_values), + ]) }, ], }, )->all; - my $dt_parser = $self->schema->storage->datetime_parser; + my $dt_parser = $self->dt_parser; # Find min/max dates from above, including linked field if required my $daterange_from = $self->from ? $self->from->clone : $self->_min_date( $result->get_column('start_date'), @@ -3517,32 +3524,46 @@ sub _build_group_results } }; - my $q = $self->search_query(prefetch => 1, search => 1, retain_join_order => 1, group => 1, sort => 0, drcol => $drcol); # Called first to generate joins + my $q = $self->search_query(prefetch => 1, search => 1, retain_join_order => 1, group => 1, sort => 1, drcol => $drcol); # Called first to generate joins # Ensure that no joins are added here that are multi-value fields, # otherwise they will generate multiple rows for a single records, which # will cause multiple aggregates and double-counting of other fields. The # prefetch joins should only have been added above, and if they are - # multi-value fields should be added as independent sub-queries + # multi-value fields should be added as independent sub-queries. + # The "multivalue" parameter below removes any multi-value columns. + my %common = ( + group => 1, + prefetch => 1, + # Search not needed as performed with subquery + search => 0, + sort => 1, + drcol => $drcol, + current_version_only => $self->cvo_values, + ); + + my @jp_fetch = $self->jpfetch(%common, multivalue => 0, linked => 0, retain_join_order => 1, aggregate => $options{aggregate}); + my $order_by = $self->order_by(%common, group_cols => \@group_cols, retain_join_order => 1); + push @select_fields, map $_->{select}, @{$self->aggregate_fields}; my $select = { select => [@select_fields], join => [ - $self->linked_hash(group => 1, prefetch => 1, search => 0, retain_join_order => 1, sort => 0, aggregate => $options{aggregate}, drcol => $drcol), + $self->linked_hash(%common, retain_join_order => 1, aggregate => $options{aggregate}), { - 'record_single' => [ - 'record_later', - $self->jpfetch(group => 1, prefetch => 1, search => 0, linked => 0, retain_join_order => 1, sort => 0, aggregate => $options{aggregate}, drcol => $drcol), - ], + $self->cvo_values + ? ('current_version' => \@jp_fetch) + : ('record_single' => [ + 'record_later', @jp_fetch, + ]) }, ], group_by => [@g], + order_by => $order_by, }; - local $GADS::Schema::Result::Record::REWIND = $self->rewind_formatted - if $self->rewind; - my $result = $self->schema->resultset('Current')->search( - $self->_cid_search_query(sort => 0, aggregate => $options{aggregate}), $select + # Outer search query so needs to match values being retrieved + $self->_resultset_search(sort => 0, is_group => 1, prefetch => 1, current_version_only => $self->cvo_values), $select ); return [$result->all] @@ -3563,7 +3584,7 @@ sub _build_group_results # will then force the sum. At the moment the only aggregate is sum, # but that may change in the future is_group => $options{is_group} || $self->is_group, - group_cols => \%group_cols, + group_cols => {map { $_->{column}->id => 1 } @group_cols}, user => $self->user, layout => $self->layout, columns_retrieved_no => $self->columns_retrieved_no, diff --git a/lib/GADS/RecordsJoin.pm b/lib/GADS/RecordsJoin.pm index 2e39fd395..0c06583c8 100644 --- a/lib/GADS/RecordsJoin.pm +++ b/lib/GADS/RecordsJoin.pm @@ -72,18 +72,17 @@ sub _add_children { my ($self, $join, $column, %options) = @_; $join->{children} ||= []; my %existing = map { $_->{column}->id => 1 } @{$join->{children}}; - foreach my $c (@{$column->curval_fields_retrieve(all_fields => $options{all_fields}, already_seen => $options{already_seen})}) + foreach my $c (@{$column->curval_fields_retrieve}) { next if $c->internal; # prefetch and linked match the parent. # search and sort are left blank, but may be updated with an # additional direct call with just the child and that option. my $child = { - join => $c->tjoin(all_fields => $options{all_fields}, already_seen => $options{already_seen}), - prefetch => 1, - curval => $c->is_curcommon, - column => $c, - parent => $column, + prefetch => 1, + curval => $c->is_curcommon, + column => $c, + parent => $column, }; push @{$join->{children}}, $child if !$existing{$c->id}; @@ -98,10 +97,6 @@ sub _add_jp panic __x"Link parent of field ID {id} is from same table as field itself", id => $column->id if $column->link_parent && $column->link_parent->instance_id == $column->instance_id; - my $key; - my $toadd = $column->tjoin(all_fields => $options{all_fields}); - ($key) = keys %$toadd if ref $toadd eq 'HASH'; - trace __x"Checking or adding {field} to the store", field => $column->field if $debug; @@ -114,11 +109,7 @@ sub _add_jp { trace __x"Checking join {field}", field => $j->{column}->field if $debug; - if ( - ($key && ref $j->{join} eq 'HASH' && Compare($toadd, $j->{join})) - || ($toadd && $j->{join} && $toadd eq $j->{join}) - || (!$toadd && $column->id == $j->{column}->id) - ) + if ($column->id == $j->{column}->id) { trace __x"Possibly found, checking to see if parents match" if $debug; @@ -132,17 +123,7 @@ sub _add_jp $j->{drcol} ||= $options{drcol}; if ($column->is_curcommon && $prefetch) { - my $tree = $self->already_seen; - my ($daughter) = grep { $_->name == $column->id} $tree->daughters; - # If add_join / add_prefetch is called early, such as - # during initial building of columns, then the column won't - # exist in the tree. Therefore add it now. - if (!$daughter) - { - $daughter = Tree::DAG_Node->new({name => $column->id}); - $tree->add_daughter($daughter); - } - $self->_add_children($j, $column, %options, already_seen => $daughter); + $self->_add_children($j, $column, %options); } trace __x"Found existing, returning" if $debug; @@ -157,7 +138,6 @@ sub _add_jp if $debug; my $join_add = { - join => $toadd, # Never prefetch multivalue columns, which can result in huge numbers of rows being retrieved. prefetch => $prefetch, # Whether values should be retrieved search => $options{search}, # Whether it's used in a WHERE clause @@ -173,10 +153,7 @@ sub _add_jp # part of the curval if ($column->is_curcommon) { - my $tree = $self->already_seen; - my $daughter = Tree::DAG_Node->new({name => $column->id}); - $tree->add_daughter($daughter); - $self->_add_children($join_add, $column, %options, already_seen => $daughter) + $self->_add_children($join_add, $column, %options) if $prefetch; } @@ -256,15 +233,15 @@ sub has_created_user !! grep $_->{column}->name_short && $_->{column}->name_short eq '_created_user', $self->_jpfetch(%options); } -sub record_later_search -{ my ($self, %options) = @_; +sub _root_is_record +{ my (%options) = @_; + $options{root_table} && $options{root_table} eq 'record'; +} - return () if $self->previous_values; - return ({ - "record_earlier.id" => undef, - }) if $self->record_earlier; +sub _count_version_joins +{ my ($self, %options) = @_; - my $count = $options{no_current} ? 0 : 1; # Always at least one if joining onto current + my $count = _root_is_record(%options) ? 0 : 1; # Always at least one if joining onto current my $include_linked = $options{linked} && $self->has_linked(%options); @@ -304,6 +281,21 @@ sub record_later_search } } } + $count; +} + +sub record_later_search +{ my ($self, %options) = @_; + + # Do not add record_later search if using previous_values (in which case + # all versions selected) or current_version_only (direct version join). + return () if $self->previous_values || $options{current_version_only}; + + return ({ + "record_earlier.id" => undef, + }) if $self->record_earlier; + + my $count = $self->_count_version_joins(%options); my @search; for (1..$count) @@ -317,9 +309,41 @@ sub record_later_search @search; } +sub record_single_rewind +{ my ($self, %options) = @_; + my $rewind = $options{rewind} + or return (); + + my $count = $self->_count_version_joins(%options); + + # Special case for "record" being the root table that is being selected + # from, and this being the first call to record_single_rewind(). In this + # case and at this point the count will be zero thus returning no join, + # even though one is needed for a rewind search (to ensure that a request + # for a specific version returns nothing if the rewind time is earlier than + # that version). For later calls in the same query, the count stands as + # normal and the record_name will be its normal "record" value rather than + # "me". + $count = 1 if _root_is_record(%options) && $count == 0; + + my $record_single = $self->record_name(%options, linked => 0); + my @search; + for (1..$count) + { + my $id = $_ == 1 ? '' : "_$_"; + my $alt = $options{alt} ? "_alternative" : ""; + push @search, ( + "$record_single$alt$id.created" => { + '<=' => $self->dt_parser->format_datetime($rewind), + } + ); + } + @search; +} + sub _jpfetch { my ($self, %options) = @_; - my $joins = []; + my @joins; my @jpstore; # Normally we want joins to be added and then prefetches, as they are @@ -340,17 +364,12 @@ sub _jpfetch foreach (@jpstore2) { - # Include only aggregate columns if requested. This is used when a - # records object has been built, but then only the aggregate columns - # within that are required for an aggregate query - next if $options{aggregate} && !$_->{column}->aggregate; next if exists $options{prefetch} && !$options{prefetch} && $_->{prefetch} && !$options{group} && !$options{drcol}; - $self->_jpfetch_add(options => \%options, join => $_, return => $joins); + push @joins, $self->_jpfetch_add(options => \%options, join => $_,); } my @return; - if ($options{limit} && @$joins) + if ($options{limit} && @joins) { - my @joins = @$joins; my $offset = ($options{page} - 1) * $options{limit}; return if @joins < $offset; my $end = $options{limit}-1+$offset ; @@ -362,7 +381,7 @@ sub _jpfetch push @return, grep { $_->{sort} } @joins[$end+1..@joins-1] if $options{sort}; } else { - @return = @$joins; + @return = @joins; } my @return2; foreach (@return) @@ -384,48 +403,56 @@ sub _jpfetch_add my $return = $params{return}; my $parent = $params{parent}; + my $current_version_only = $options->{current_version_only}; + if ( ($options->{search} && $join->{search}) || ($options->{sort} && $join->{sort}) || ($options->{group} && $join->{group}) || ($options->{drcol} && $join->{drcol}) - || ($options->{prefetch} && $join->{prefetch}) + || ( + # Include only aggregate columns if requested. This is used when a + # records object has been built, but then only the aggregate columns + # within that are required for an aggregate query + $options->{prefetch} && $join->{prefetch} + && (!$options->{aggregate} || $join->{column}->aggregate) + ) || ($options->{extra_column} && $join->{column}->id == $options->{extra_column}->id) ) { - if ($join->{column}->is_curcommon) + my $column = $join->{column}; + if ($column->is_curcommon) { - my $children = []; + my @children; foreach my $child (@{$join->{children}}) { - $self->_jpfetch_add(options => $options, join => $child, return => $children, parent => $join->{column}); + push @children, $self->_jpfetch_add(options => $options, join => $child, parent => $column); } my $simple = {%$join}; - $simple->{join} = $join->{column}->sprefix; + $simple->{join} = $column->sprefix; # Remove multivalues to prevent huge amount of rows being fetched. # These will be fetched later as individual columns. # Keep any for a sort - these still need to be used when fetching rows. - my @children = @$children; - @children = grep { $_->{search} || $_->{sort} || $_->{column}->fetch_with_record || $options->{include_multivalue} || $_->{group} || $_->{drcol} } @$children + @children = grep { $_->{search} || $_->{sort} || $_->{column}->fetch_with_record || $options->{include_multivalue} || $_->{group} || $_->{drcol} } @children if $options->{prefetch}; - push @$return, { + my $options = { + join_current_version => $current_version_only, + }; + return { + %$join, parent => $parent, - column => $join->{column}, - join => $join->{column}->make_join(map {$_->{join}} @children), - search => $join->{search}, - sort => $join->{sort}, - group => $join->{group}, - drcol => $join->{drcol}, - prefetch => $join->{prefetch}, - linked => $join->{linked}, - all_joins => [$simple, @children], + column => $column, + join => $column->make_join($options, map $_->{join}, @children), children => \@children, }; } else { - push @$return, $join; + return { %$join, join => $join->{column}->tjoin(join_current_version => $current_version_only) }; } } + else { + return (); + } } # See comments on alternative join in GADS::DB @@ -445,7 +472,10 @@ sub _to_alt sub jpfetch { my ($self, %options) = @_; - my @joins = grep $_, map { $_->{join} } $self->_jpfetch(%options); + my @cols = $self->_jpfetch(%options); + @cols = grep $_->{column}->multivalue == $options{multivalue} || $_->{group}, @cols + if defined $options{multivalue}; + my @joins = grep $_, map { $_->{join} } @cols; @joins = map { _to_alt($_) } @joins if $options{alt}; return @joins; @@ -485,8 +515,10 @@ sub columns_fetch } sub _record_name_by_count -{ my $count = shift; +{ my ($self, $count, %options) = @_; my $c_offset = $count == 1 ? '' : "_$count"; + return "current_version$c_offset" + if $options{current_version_only}; return "record_single$c_offset"; } @@ -499,7 +531,7 @@ sub record_name # record will be joined to the Current table. if ($options{root_table} && $options{root_table} eq 'record') { - return 'me' if !$options{linked} && !$options{column}; + return 'me' if !$options{column}; $count = 0; } elsif ($self->has_linked(%options)) { @@ -510,7 +542,7 @@ sub record_name } # Linked is always first. Drop straight back if that's what's wanted - return _record_name_by_count($count) + return $self->_record_name_by_count($count, %options) if $options{linked}; # Now add on for any curval columns in the linked section @@ -519,12 +551,13 @@ sub record_name next unless $c->{column}->is_curcommon && $c->{linked}; next if !@{$c->{children}}; # No record_singles unless fields selected from curval $count++; - return _record_name_by_count($count) if $options{column} && $options{column}->id == $c->{column}->id; + return $self->_record_name_by_count($count, %options) + if $options{column} && $options{column}->id == $c->{column}->id; } # Now the query of the main record $count++ - unless $options{no_current}; + unless _root_is_record(%options); # And now add on any curval columns in the normal section @@ -543,7 +576,7 @@ sub record_name } my $c_offset = $count == 1 ? '' : "_$count"; - return _record_name_by_count($count); + return $self->_record_name_by_count($count, %options); } =pod @@ -560,12 +593,14 @@ sub table_name { my ($self, $column, %options) = @_; if ($column->internal) { - return $options{no_current} ? 'current' : 'me' if $column->table eq 'Current'; + return _root_is_record(%options) ? 'current' : ($options{alias} || 'me') if $column->table eq 'Current'; if ($column->sprefix eq 'record') { return $self->record_name(%options); } - return $column->sprefix; + my $tn = $column->sprefix; + $tn .= "_alternative" if $options{alt}; + return $tn; } my $jn = $self->_join_number($column, %options); my $index = $jn > 1 ? "_$jn" : ''; @@ -601,18 +636,21 @@ sub _join_number { trace "Checking join ".$j->{column}->id if $debug; - my $n; - if ($j->{all_joins}) + my $n = _find($column, $j, $stash, %options); + trace __x"return from find request is: {n}", n => $n + if $debug; + return $n if $n; + if ($j->{children}) { trace "This join has other joins, checking..." if $debug; - foreach my $j2 (@{$j->{all_joins}}) + foreach my $j2 (@{$j->{children}}) { - if ($j2->{all_joins}) + if ($j2->{children}) { trace "This join has other joins, checking..." if $debug; - foreach my $j3 (@{$j2->{all_joins}}) # Replace with recursive function? + foreach my $j3 (@{$j2->{children}}) # Replace with recursive function? { trace "Looking at join ".$j3->{column}->id if $debug; @@ -622,22 +660,14 @@ sub _join_number return $n if $n; } } - else { - trace "Looking at join ".$j2->{column}->id - if $debug; - $n = _find($column, $j2, $stash, %options); - trace __x"return from find request is: {n}", n => $n - if $debug; - return $n if $n; - } + trace "Looking at join ".$j2->{column}->id + if $debug; + $n = _find($column, $j2, $stash, %options); + trace __x"return from find request is: {n}", n => $n + if $debug; + return $n if $n; } } - else { - $n = _find($column, $j, $stash, %options); - trace __x"return from find request is: {n}", n => $n - if $debug; - } - return $n if $n; } return $stash->{value} if $options{find_value}; @@ -659,9 +689,15 @@ sub _find trace "Checking against join ".$jp->{column}->id if $debug; - if (ref $jp->{join} eq 'HASH') + my $is_cc = $jp->{column}->type eq 'curval' || $jp->{column}->type eq 'filval'; + my $join = $jp->{column}->is_curcommon + ? $jp->{column}->sprefix + #: $is_cc + #? { $jp->{column}->sprefix => 'value' } + : $jp->{column}->tjoin(join_current_version => $options{current_version_only}); + if (ref $join eq 'HASH') { - my ($key, $value) = %{$jp->{join}}; + my ($key, $value) = %$join; trace __x"This join is a hash with key:{key} and value: {value}", key => $key, value => Dumper($value) if $debug; trace __x"We are looking for value being equal to {needle}", needle => $needle->sprefix @@ -695,11 +731,11 @@ sub _find } } } - elsif (ref $jp->{join} eq 'ARRAY') + elsif (ref $join eq 'ARRAY') { trace "This join is an array" if $debug; - foreach (@{$jp->{join}}) + foreach (@$join) { my $n = _find($needle, $_, $stash); trace "Return from find is $n" @@ -710,14 +746,14 @@ sub _find else { trace "This join is a standard join" if $debug; - $stash->{$jp->{join}}++ - if $jp->{join}; + $stash->{$join}++ + if $join; if ($jp->{parent} && !$stash->{parents_included}->{$jp->{parent}->id}) { $stash->{value}++ if $jp->{parent}->value_field eq 'value'; $stash->{parents_included}->{$jp->{parent}->id} = 1; } - if (!$options{find_value} && $jp->{join} && $needle->sprefix eq $jp->{join}) + if (!$options{find_value} && $join && $needle->sprefix eq $join) { # Single table join if (_compare_parents($options{parent}, $jp->{parent}) @@ -754,6 +790,211 @@ sub fqvalue "$tn." . $value_field; } +has aggregate_fields => ( + is => 'ro', + lazy => 1, + clearer => 1, + builder => sub { [] }, +); + +sub add_aggregate +{ my ($self, $column, $operator, %options) = @_; + + # Whether this column appears in the group_by statement, therefore meaning + # it does not require a separate sql select statement. This can possibly be + # removed in the future by checking the fields that have been added as + # grouped. + my $is_grouped = delete $options{is_grouped}; + my $is_linked = delete $options{is_linked}; + # Whether there are any group_by statements at all in the planned sql query + my @group_cols = $options{group_cols} ? @{delete $options{group_cols}} : (); + my $parent = delete $options{parent}; + my $as_index = $self->group_values_as_index; + my $drcol = !!$self->dr_column; + + my ($existing) = grep { + $_->{column}->id == $column->id + && ((!$_->{parent} && !$parent) || ($_->{parent} && $parent && $_->{parent}->id == $parent->id)) + && $_->{operator} ne $operator + } @{$self->aggregate_fields}; + + return $existing if $existing; + + my $select; + my $as = $is_linked ? $is_linked->field : $column->field; + $as = $as.'_count' if $operator eq 'count'; + $as = $as.'_sum' if $operator eq 'sum'; + $as = $as.'_distinct' if $operator eq 'distinct' && !$is_grouped; + $as = $as.'_link' if $is_linked; + + # The select statement to get this column's value varies depending on + # what we want to retrieve. If we're selecting a field with multiple + # values, then we have to run this as a separate subquery, otherwise if + # there are more than one multiple-value retrieval then that aggregates + # will be counting multiple times for each set of multiple values (due + # to the multiple joins) + + # Field is either multivalue or its parent is + if (($column->multivalue || ($parent && $parent->multivalue)) && !$is_grouped) + { + # Assume curval if it's a parent - we need to search the curval + # table for all the curvals that are part of the records retrieved. + if ($parent) + { + my $f_rs = $self->schema->resultset('Curval')->search({ + 'mecurval.record_id' => { + # Match against main query's records (use cvo_values as + # we are matching against the record ID of the outer + # select statement, not the record IDs in the record + # selection) + -ident => $self->cvo_values ? 'current_version.id' : 'record_single.id' + }, + 'mecurval.layout_id' => $parent->id, + # If retrieving from a previous point in time then add + # required search criteria to only retrieve single correct + # record + $self->cvo_values ? () : ('record_later.id' => undef), + $self->rewind_values ? ('record_single_alternative.created' => { + '<=' => $self->dt_parser->format_datetime($self->rewind_values) + }) : () + }, + { + alias => 'mecurval', # Can't use default "me" as already used in main query + join => { + 'value' => { + $self->cvo_values + ? ('current_version_alternative' => [ + $column->tjoin(join_current_version => 1) + ]) + : ('record_single_alternative' => [ + 'record_later', + $column->tjoin, + ]) + }, + }, + }); + if ($column->numeric && $operator eq 'sum') + { + $select = $f_rs->get_column((ref $column->tjoin(join_current_version => $self->cvo_values) eq 'HASH' ? 'value_2' : $column->field).".".$column->value_field)->sum_rs->as_query; + } + elsif ($operator eq 'sum' || $operator eq 'max') # Default to max for sum of non-numeric columns + { + my $fn = (ref $column->tjoin(join_current_version => $self->cvo_values) eq 'HASH' ? 'value_2' : $column->field).".".$column->value_field; + $select = $f_rs->get_column($fn)->max_rs->as_query; + } + elsif ($operator eq 'distinct') { + # At the moment we do not expect a distinct count to be + # necessary for a field from within a curval. We might want + # to add this functionality in the future, in which case it + # will look something like the next else block + panic __x"Unexpected count distinct for curval sub-field {name} ({id})", + name => $column->name, id => $column->id; + } + else { + panic "Unknown operator $operator"; + } + } + # Otherwise a standard subquery select for that type of field + else { + # Also need to add the main search query, otherwise if we take + # all the field's values for each record, then we won't be + # filtering the non-matched ones in the case of multivalue + # fields. + # Need to include "group" as an option to the subquery, to + # ensure that the grouping column is added to match to the main + # query's group column. This does not apply if doing an overall + # aggregate though, as there is only a need to retrieve the + # overall results, not for each matching grouped row. If the + # "group" option is included unnecessarily, then this can cause + # joins of multiple-value fields which can include too many + # results in the aggregate. + my $has_grouped = @group_cols; + my $searchq = $self->search_query(%options, search => 1, extra_column => $column, linked => 0, group => $has_grouped, alt => 1, alias => 'mefield', current_version_only => $self->cvo_values, rewind => $self->rewind_values); + foreach my $group (@group_cols) + { + push @$searchq, { + $self->fqvalue($group->{column}, %options, search => 1, as_index => $as_index, linked => 0, group => 1, alt => 1, extra_column => $group->{column}, parent => $group->{parent}, drcol => $drcol, current_version_only => $self->cvo_values) => { + -ident => $self->fqvalue($group->{column}, %options, search => 1, parent => $group->{parent}, as_index => $as_index, linked => 0, group => 1, extra_column => $group->{column}, drcol => $drcol, current_version_only => $self->cvo_values) + }, + }; + } + $select = $self->schema->resultset('Current')->search( + [-and => $searchq ], + { + alias => 'mefield', + join => [ + [$self->linked_hash(%options, search => 1, group => $has_grouped, alt => 1, extra_column => $column, current_version_only => $self->cvo_values)], + { + $self->cvo_values + ? ('current_version_alternative' => [ + $self->jpfetch(%options, search => 1, linked => 0, group => $has_grouped, extra_column => $column, alt => 1, current_version_only => 1) + ]) + : ('record_single_alternative' => [ # The (assumed) single record for the required version of current + 'record_later_alternative', # The record after the single record (undef when single is latest) + $self->jpfetch(%options, search => 1, linked => 0, group => $has_grouped, extra_column => $column, alt => 1, current_version_only => 0), + ]) + }, + ], + select => { + count => { distinct => $self->fqvalue($column, %options, search => 1, as_index => $as_index, linked => 0, group => 1, alt => 1, extra_column => $column, drcol => $drcol, current_version_only => $self->cvo_values) }, + -as => 'sub_query_as', + }, + }, + ); + my $col_fq = $self->fqvalue($column, %options, search => 1, as_index => $as_index, linked => 0, group => 1, alt => 1, extra_column => $column, drcol => $drcol, current_version_only => $self->cvo_values); + if ($column->numeric && $operator eq 'sum') + { + $select = $select->get_column($col_fq)->sum_rs->as_query; + $operator = 'max'; + } + # Default to max for sum of non-numeric columns. + # count selects max here and then count as the operator below + elsif ($operator eq 'sum' || $operator eq 'max' || $operator eq 'count') + { + $select = $select->get_column($col_fq)->max_rs->as_query; + } + elsif ($operator eq 'distinct' || $operator eq 'count') + { + $select = $select->get_column('sub_query_as')->as_query; + $operator = 'max'; + } + else { + panic "Unknown operator $operator"; + } + } + } + # Standard single-value field - select directly, no need for a subquery + else { + $select = $self->fqvalue($column, %options, as_index => $as_index, prefetch => 1, group => 1, linked => 0, parent => $parent, retain_join_order => 1, drcol => $drcol, current_version_only => $self->cvo_values); + } + + my $overall_select = $operator eq 'distinct' + ? { + count => { distinct => $select }, + -as => $as, + } + : { + $operator => $select, + -as => $as, + }; + + my $aggfield = { + column => $column, + parent => $parent, + select => $overall_select, + operator => $operator, + as => $as, + }; + + push @{$self->aggregate_fields}, $aggfield; + + # Also add linked column if required + $self->add_aggregate($column->link_parent, $operator, is_linked => $column, parent => $parent, group_cols => \@group_cols, is_grouped => $is_grouped) + if $column->link_parent; + + $aggfield; +} + sub _dump_child { my ($self, $dd, $child, $indent) = @_; no warnings 'uninitialized'; diff --git a/lib/GADS/Role/Presentation/Column.pm b/lib/GADS/Role/Presentation/Column.pm index d84d8cf40..c48b445a2 100644 --- a/lib/GADS/Role/Presentation/Column.pm +++ b/lib/GADS/Role/Presentation/Column.pm @@ -29,6 +29,7 @@ sub presentation { my $return = { id => $self->id, + full_id => $self->full_id, type => $self->type, name => $self->name, name_short => $self->name_short, diff --git a/lib/GADS/Role/Presentation/Records.pm b/lib/GADS/Role/Presentation/Records.pm index 1bbf572cd..f10683ee2 100644 --- a/lib/GADS/Role/Presentation/Records.pm +++ b/lib/GADS/Role/Presentation/Records.pm @@ -6,7 +6,7 @@ sub presentation { my $self = shift; return [ - map $_->presentation(group => $self->is_group, group_col_ids => $self->group_col_ids, @_), @{$self->results} + map $_->presentation(group => $self->is_group, group_cols => $self->group_cols, @_), @{$self->results} ]; } diff --git a/lib/GADS/Schema.pm b/lib/GADS/Schema.pm index 431917eaa..3efa4b382 100644 --- a/lib/GADS/Schema.pm +++ b/lib/GADS/Schema.pm @@ -8,7 +8,7 @@ use base 'DBIx::Class::Schema'; __PACKAGE__->load_namespaces; -our $VERSION = 109; +our $VERSION = 110; our $IGNORE_PERMISSIONS; our $IGNORE_PERMISSIONS_SEARCH; diff --git a/lib/GADS/Schema/Result/Current.pm b/lib/GADS/Schema/Result/Current.pm index 17b6d1ddf..dd1033fdd 100644 --- a/lib/GADS/Schema/Result/Current.pm +++ b/lib/GADS/Schema/Result/Current.pm @@ -18,6 +18,8 @@ __PACKAGE__->add_columns( { data_type => "bigint", is_auto_increment => 1, is_nullable => 0 }, "serial", { data_type => "bigint", is_nullable => 1 }, + "current_version_id", + { data_type => "bigint", is_foreign_key => 1, is_nullable => 1 }, "parent_id", { data_type => "bigint", is_foreign_key => 1, is_nullable => 1 }, "instance_id", @@ -54,6 +56,31 @@ __PACKAGE__->has_many( { cascade_copy => 0, cascade_delete => 0 }, ); +__PACKAGE__->belongs_to( + "current_version", + "GADS::Schema::Result::Record", + { id => "current_version_id" }, + { + is_deferrable => 1, + join_type => "LEFT", + on_delete => "NO ACTION", + on_update => "NO ACTION", + }, +); + +# See comments below regarding record_single_alternative +__PACKAGE__->belongs_to( + "current_version_alternative", + "GADS::Schema::Result::Record", + { id => "current_version_id" }, + { + is_deferrable => 1, + join_type => "LEFT", + on_delete => "NO ACTION", + on_update => "NO ACTION", + }, +); + __PACKAGE__->has_many( "currents", "GADS::Schema::Result::Current", diff --git a/lib/GADS/Schema/Result/Graph.pm b/lib/GADS/Schema/Result/Graph.pm index 70d3987cb..9cef998a8 100644 --- a/lib/GADS/Schema/Result/Graph.pm +++ b/lib/GADS/Schema/Result/Graph.pm @@ -19,6 +19,8 @@ __PACKAGE__->add_columns( { data_type => "text", is_nullable => 1 }, "y_axis", { data_type => "integer", is_foreign_key => 1, is_nullable => 1 }, + "y_axis_link", + { data_type => "integer", is_foreign_key => 1, is_nullable => 1 }, "y_axis_stack", { data_type => "varchar", is_nullable => 1, size => 45 }, "y_axis_label", @@ -138,6 +140,18 @@ __PACKAGE__->belongs_to( }, ); +__PACKAGE__->belongs_to( + "y_axis_link", + "GADS::Schema::Result::Layout", + { id => "y_axis_link" }, + { + is_deferrable => 1, + join_type => "LEFT", + on_delete => "NO ACTION", + on_update => "NO ACTION", + }, +); + __PACKAGE__->belongs_to( "user", "GADS::Schema::Result::User", diff --git a/share/fixtures/110/conf/all_tables.json b/share/fixtures/110/conf/all_tables.json new file mode 100644 index 000000000..d72a63724 --- /dev/null +++ b/share/fixtures/110/conf/all_tables.json @@ -0,0 +1,285 @@ +{ + "might_have" : { + "fetch" : 0 + }, + "sets" : [ + { + "quantity" : "all", + "class" : "Team" + }, + { + "class" : "Current", + "quantity" : "all" + }, + { + "quantity" : "all", + "class" : "Enumval" + }, + { + "quantity" : "all", + "class" : "Changed" + }, + { + "class" : "CurvalField", + "quantity" : "all" + }, + { + "class" : "Dashboard", + "quantity" : "all" + }, + { + "class" : "Daterange", + "quantity" : "all" + }, + { + "class" : "AlertCache", + "quantity" : "all" + }, + { + "class" : "Calc", + "quantity" : "all" + }, + { + "quantity" : "all", + "class" : "Record" + }, + { + "quantity" : "all", + "class" : "Curval" + }, + { + "class" : "Filter", + "quantity" : "all" + }, + { + "quantity" : "all", + "class" : "Date" + }, + { + "class" : "UserGroup", + "quantity" : "all" + }, + { + "quantity" : "all", + "class" : "Ragval" + }, + { + "class" : "Calcval", + "quantity" : "all" + }, + { + "quantity" : "all", + "class" : "CalcUnique" + }, + { + "class" : "ImportRow", + "quantity" : "all" + }, + { + "class" : "Oauthtoken", + "quantity" : "all" + }, + { + "quantity" : "all", + "class" : "Oauthclient" + }, + { + "class" : "Submission", + "quantity" : "all" + }, + { + "quantity" : "all", + "class" : "LayoutGroup" + }, + { + "quantity" : "all", + "class" : "AlertColumn" + }, + { + "class" : "MetricGroup", + "quantity" : "all" + }, + { + "quantity" : "all", + "class" : "Intgr" + }, + { + "class" : "ViewGroup", + "quantity" : "all" + }, + { + "class" : "Sort", + "quantity" : "all" + }, + { + "class" : "Title", + "quantity" : "all" + }, + { + "quantity" : "all", + "class" : "Enum" + }, + { + "class" : "Person", + "quantity" : "all" + }, + { + "class" : "Site", + "quantity" : "all" + }, + { + "quantity" : "all", + "class" : "FileOption" + }, + { + "class" : "ViewLimit", + "quantity" : "all" + }, + { + "quantity" : "all", + "class" : "UserGraph" + }, + { + "quantity" : "all", + "class" : "ReportGroup" + }, + { + "class" : "ViewLayout", + "quantity" : "all" + }, + { + "class" : "Instance", + "quantity" : "all" + }, + { + "class" : "Widget", + "quantity" : "all" + }, + { + "quantity" : "all", + "class" : "Export" + }, + { + "class" : "AlertSend", + "quantity" : "all" + }, + { + "class" : "ReportLayout", + "quantity" : "all" + }, + { + "class" : "Report", + "quantity" : "all" + }, + { + "quantity" : "all", + "class" : "DisplayField" + }, + { + "class" : "Organisation", + "quantity" : "all" + }, + { + "class" : "Alert", + "quantity" : "all" + }, + { + "quantity" : "all", + "class" : "View" + }, + { + "class" : "UserLastrecord", + "quantity" : "all" + }, + { + "quantity" : "all", + "class" : "Department" + }, + { + "class" : "File", + "quantity" : "all" + }, + { + "class" : "String", + "quantity" : "all" + }, + { + "quantity" : "all", + "class" : "Authentication" + }, + { + "quantity" : "all", + "class" : "LayoutDepend" + }, + { + "quantity" : "all", + "class" : "Metric" + }, + { + "class" : "Layout", + "quantity" : "all" + }, + { + "class" : "UserPermission", + "quantity" : "all" + }, + { + "class" : "FilteredValue", + "quantity" : "all" + }, + { + "quantity" : "all", + "class" : "Graph" + }, + { + "quantity" : "all", + "class" : "Topic" + }, + { + "class" : "GraphColor", + "quantity" : "all" + }, + { + "class" : "InstanceGroup", + "quantity" : "all" + }, + { + "class" : "InstanceRag", + "quantity" : "all" + }, + { + "class" : "Permission", + "quantity" : "all" + }, + { + "class" : "Group", + "quantity" : "all" + }, + { + "quantity" : "all", + "class" : "User" + }, + { + "class" : "Audit", + "quantity" : "all" + }, + { + "quantity" : "all", + "class" : "Import" + }, + { + "class" : "Rag", + "quantity" : "all" + }, + { + "class" : "Fileval", + "quantity" : "all" + } + ], + "belongs_to" : { + "fetch" : 0 + }, + "has_many" : { + "fetch" : 0 + } +} diff --git a/share/fixtures/110/conf/current.json b/share/fixtures/110/conf/current.json new file mode 100644 index 000000000..9fb298aae --- /dev/null +++ b/share/fixtures/110/conf/current.json @@ -0,0 +1,73 @@ +{ + "has_many" : { + "fetch" : 0 + }, + "might_have" : { + "fetch" : 0 + }, + "belongs_to" : { + "fetch" : 0 + }, + "sets" : [ + { + "class" : "Current", + "fetch" : [ + { + "rel": "records", + "quantity": "all", + "fetch": [ + { + "rel": "calcvals", + "quantity": "all" + }, + { + "rel": "curvals", + "quantity": "all" + }, + { + "rel": "dateranges", + "quantity": "all" + }, + { + "rel": "dates", + "quantity": "all" + }, + { + "rel": "enums", + "quantity": "all" + }, + { + "rel": "files", + "quantity": "all", + "fetch": [ + { + "rel": "value", + "quantity": "all" + } + ] + }, + { + "rel": "intgrs", + "quantity": "all" + }, + { + "rel": "people", + "quantity": "all" + }, + { + "rel": "ragvals", + "quantity": "all" + }, + { + "rel": "strings", + "quantity": "all" + } + ] + } + ], + "ids" : [ + "1766" + ] + } + ] +} diff --git a/share/fixtures/110/conf/graphs.json b/share/fixtures/110/conf/graphs.json new file mode 100644 index 000000000..6e742f676 --- /dev/null +++ b/share/fixtures/110/conf/graphs.json @@ -0,0 +1,17 @@ +{ + "has_many" : { + "fetch" : 0 + }, + "might_have" : { + "fetch" : 0 + }, + "belongs_to" : { + "fetch" : 0 + }, + "sets" : [ + { + "class" : "Graph", + "quantity" : "all" + } + ] +} diff --git a/share/fixtures/110/conf/layout.json b/share/fixtures/110/conf/layout.json new file mode 100644 index 000000000..557c20279 --- /dev/null +++ b/share/fixtures/110/conf/layout.json @@ -0,0 +1,53 @@ +{ + "has_many" : { + "fetch" : 0 + }, + "might_have" : { + "fetch" : 0 + }, + "belongs_to" : { + "fetch" : 0 + }, + "sets" : [ + { + "class" : "Calc", + "quantity" : "all" + }, + { + "class" : "Enumval", + "quantity" : "all" + }, + { + "quantity" : "all", + "class" : "CurvalField" + }, + { + "class" : "Instance", + "quantity" : "all" + }, + { + "quantity" : "all", + "class" : "LayoutGroup" + }, + { + "class" : "Layout", + "quantity" : "all" + }, + { + "quantity" : "all", + "class" : "FileOption" + }, + { + "quantity" : "all", + "class" : "LayoutDepend" + }, + { + "class" : "Rag", + "quantity" : "all" + }, + { + "quantity" : "all", + "class" : "Group" + } + ] +} diff --git a/share/fixtures/110/conf/permissions.json b/share/fixtures/110/conf/permissions.json new file mode 100644 index 000000000..c55636c86 --- /dev/null +++ b/share/fixtures/110/conf/permissions.json @@ -0,0 +1,17 @@ +{ + "might_have" : { + "fetch" : 0 + }, + "belongs_to" : { + "fetch" : 0 + }, + "has_many" : { + "fetch" : 0 + }, + "sets" : [ + { + "class" : "Permission", + "quantity" : "all" + } + ] +} diff --git a/share/fixtures/110/conf/views_global.json b/share/fixtures/110/conf/views_global.json new file mode 100644 index 000000000..7a675dce7 --- /dev/null +++ b/share/fixtures/110/conf/views_global.json @@ -0,0 +1,28 @@ +{ + "has_many" : { + "fetch" : 0 + }, + "might_have" : { + "fetch" : 0 + }, + "belongs_to" : { + "fetch" : 0 + }, + "sets" : [ + { + "class" : "View", + "quantity" : "all", + "cond": { "global": 1 }, + "fetch": [ + { + "rel": "view_layouts", + "quantity": "all" + }, + { + "rel": "sorts", + "quantity": "all" + } + ] + } + ] +} diff --git a/share/fixtures/110/permissions/_config_set b/share/fixtures/110/permissions/_config_set new file mode 100644 index 000000000..b737787ab --- /dev/null +++ b/share/fixtures/110/permissions/_config_set @@ -0,0 +1,17 @@ +$VAR1 = { + 'has_many' => { + 'fetch' => 0 + }, + 'might_have' => { + 'fetch' => 0 + }, + 'sets' => [ + { + 'class' => 'Permission', + 'quantity' => 'all' + } + ], + 'belongs_to' => { + 'fetch' => 0 + } + }; diff --git a/share/fixtures/110/permissions/_dumper_version b/share/fixtures/110/permissions/_dumper_version new file mode 100644 index 000000000..55eb15ebd --- /dev/null +++ b/share/fixtures/110/permissions/_dumper_version @@ -0,0 +1 @@ +1.001039 \ No newline at end of file diff --git a/share/fixtures/110/permissions/permission/10.fix b/share/fixtures/110/permissions/permission/10.fix new file mode 100644 index 000000000..dbcc7ff19 --- /dev/null +++ b/share/fixtures/110/permissions/permission/10.fix @@ -0,0 +1,7 @@ +$HASH1 = { + description + => 'User can access audit data', + id => 10, + name => 'audit', + order => 11 + }; diff --git a/share/fixtures/110/permissions/permission/12.fix b/share/fixtures/110/permissions/permission/12.fix new file mode 100644 index 000000000..902d83660 --- /dev/null +++ b/share/fixtures/110/permissions/permission/12.fix @@ -0,0 +1,7 @@ +$HASH1 = { + description + => 'Super-administrator', + id => 12, + name => 'superadmin', + order => undef + }; diff --git a/share/fixtures/110/permissions/permission/3.fix b/share/fixtures/110/permissions/permission/3.fix new file mode 100644 index 000000000..50be3fde3 --- /dev/null +++ b/share/fixtures/110/permissions/permission/3.fix @@ -0,0 +1,7 @@ +$HASH1 = { + description + => 'User can manage other user accounts', + id => 3, + name => 'useradmin', + order => 3 + }; diff --git a/share/migrations/MySQL/deploy/110/001-auto-__VERSION.sql b/share/migrations/MySQL/deploy/110/001-auto-__VERSION.sql new file mode 100644 index 000000000..5616aec0f --- /dev/null +++ b/share/migrations/MySQL/deploy/110/001-auto-__VERSION.sql @@ -0,0 +1,18 @@ +-- +-- Created by SQL::Translator::Producer::MySQL +-- Created on Sun Jan 4 22:32:07 2026 +-- +; +SET foreign_key_checks=0; +-- +-- Table: `dbix_class_deploymenthandler_versions` +-- +CREATE TABLE `dbix_class_deploymenthandler_versions` ( + `id` integer NOT NULL auto_increment, + `version` varchar(50) NOT NULL, + `ddl` text NULL, + `upgrade_sql` text NULL, + PRIMARY KEY (`id`), + UNIQUE `dbix_class_deploymenthandler_versions_version` (`version`) +); +SET foreign_key_checks=1; diff --git a/share/migrations/MySQL/deploy/110/001-auto.sql b/share/migrations/MySQL/deploy/110/001-auto.sql new file mode 100644 index 000000000..9efa9f787 --- /dev/null +++ b/share/migrations/MySQL/deploy/110/001-auto.sql @@ -0,0 +1,1279 @@ +-- +-- Created by SQL::Translator::Producer::MySQL +-- Created on Sun Jan 4 22:32:05 2026 +-- +; +SET foreign_key_checks=0; +-- +-- Table: `alert` +-- +CREATE TABLE `alert` ( + `id` integer NOT NULL auto_increment, + `view_id` bigint NOT NULL, + `user_id` bigint NOT NULL, + `frequency` integer NOT NULL DEFAULT 0, + INDEX `alert_idx_user_id` (`user_id`), + INDEX `alert_idx_view_id` (`view_id`), + PRIMARY KEY (`id`), + CONSTRAINT `alert_fk_user_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `alert_fk_view_id` FOREIGN KEY (`view_id`) REFERENCES `view` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `alert_cache` +-- +CREATE TABLE `alert_cache` ( + `id` bigint NOT NULL auto_increment, + `layout_id` integer NOT NULL, + `view_id` bigint NOT NULL, + `current_id` bigint NOT NULL, + `user_id` bigint NULL, + INDEX `alert_cache_idx_current_id` (`current_id`), + INDEX `alert_cache_idx_layout_id` (`layout_id`), + INDEX `alert_cache_idx_user_id` (`user_id`), + INDEX `alert_cache_idx_view_id` (`view_id`), + PRIMARY KEY (`id`), + CONSTRAINT `alert_cache_fk_current_id` FOREIGN KEY (`current_id`) REFERENCES `current` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `alert_cache_fk_layout_id` FOREIGN KEY (`layout_id`) REFERENCES `layout` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `alert_cache_fk_user_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `alert_cache_fk_view_id` FOREIGN KEY (`view_id`) REFERENCES `view` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `alert_column` +-- +CREATE TABLE `alert_column` ( + `id` integer NOT NULL auto_increment, + `layout_id` integer NOT NULL, + `instance_id` integer NOT NULL, + INDEX `alert_column_idx_instance_id` (`instance_id`), + INDEX `alert_column_idx_layout_id` (`layout_id`), + PRIMARY KEY (`id`), + CONSTRAINT `alert_column_fk_instance_id` FOREIGN KEY (`instance_id`) REFERENCES `instance` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `alert_column_fk_layout_id` FOREIGN KEY (`layout_id`) REFERENCES `layout` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `alert_send` +-- +CREATE TABLE `alert_send` ( + `id` bigint NOT NULL auto_increment, + `layout_id` integer NULL, + `alert_id` integer NOT NULL, + `current_id` bigint NOT NULL, + `status` char(7) NULL, + INDEX `alert_send_idx_alert_id` (`alert_id`), + INDEX `alert_send_idx_current_id` (`current_id`), + INDEX `alert_send_idx_layout_id` (`layout_id`), + PRIMARY KEY (`id`), + UNIQUE `alert_send_all` (`layout_id`, `alert_id`, `current_id`, `status`), + CONSTRAINT `alert_send_fk_alert_id` FOREIGN KEY (`alert_id`) REFERENCES `alert` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `alert_send_fk_current_id` FOREIGN KEY (`current_id`) REFERENCES `current` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `alert_send_fk_layout_id` FOREIGN KEY (`layout_id`) REFERENCES `layout` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `audit` +-- +CREATE TABLE `audit` ( + `id` bigint NOT NULL auto_increment, + `site_id` integer NULL, + `user_id` bigint NULL, + `type` varchar(45) NULL, + `datetime` datetime NULL, + `method` varchar(45) NULL, + `url` text NULL, + `description` text NULL, + `instance_id` integer NULL, + INDEX `audit_idx_instance_id` (`instance_id`), + INDEX `audit_idx_site_id` (`site_id`), + INDEX `audit_idx_user_id` (`user_id`), + INDEX `audit_idx_datetime` (`datetime`), + INDEX `audit_idx_user_instance_datetime` (`user_id`, `instance_id`, `datetime`), + PRIMARY KEY (`id`), + CONSTRAINT `audit_fk_instance_id` FOREIGN KEY (`instance_id`) REFERENCES `instance` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `audit_fk_site_id` FOREIGN KEY (`site_id`) REFERENCES `site` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `audit_fk_user_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `authentication` +-- +CREATE TABLE `authentication` ( + `id` bigint NOT NULL auto_increment, + `site_id` integer NULL, + `type` varchar(32) NULL, + `name` text NULL, + `xml` text NULL, + `saml2_firstname` text NULL, + `saml2_surname` text NULL, + `enabled` smallint NOT NULL DEFAULT 0, + `error_messages` text NULL, + INDEX `authentication_idx_site_id` (`site_id`), + PRIMARY KEY (`id`), + CONSTRAINT `authentication_fk_site_id` FOREIGN KEY (`site_id`) REFERENCES `site` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `calc` +-- +CREATE TABLE `calc` ( + `id` integer NOT NULL auto_increment, + `layout_id` integer NULL, + `calc` mediumtext NULL, + `code` mediumtext NULL, + `return_format` varchar(45) NULL, + `decimal_places` smallint NULL, + INDEX `calc_idx_layout_id` (`layout_id`), + PRIMARY KEY (`id`), + CONSTRAINT `calc_fk_layout_id` FOREIGN KEY (`layout_id`) REFERENCES `layout` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `calc_unique` +-- +CREATE TABLE `calc_unique` ( + `id` bigint NOT NULL auto_increment, + `layout_id` integer NOT NULL, + `value_text` text NULL, + `value_int` bigint NULL, + `value_date` date NULL, + `value_numeric` decimal(20, 5) NULL, + `value_date_from` datetime NULL, + `value_date_to` datetime NULL, + INDEX `calc_unique_idx_layout_id` (`layout_id`), + PRIMARY KEY (`id`), + UNIQUE `calc_unique_ux_layout_date` (`layout_id`, `value_date`), + UNIQUE `calc_unique_ux_layout_daterange` (`layout_id`, `value_date_from`, `value_date_to`), + UNIQUE `calc_unique_ux_layout_int` (`layout_id`, `value_int`), + UNIQUE `calc_unique_ux_layout_numeric` (`layout_id`, `value_numeric`), + UNIQUE `calc_unique_ux_layout_text` (`layout_id`, `value_text`), + CONSTRAINT `calc_unique_fk_layout_id` FOREIGN KEY (`layout_id`) REFERENCES `layout` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `calcval` +-- +CREATE TABLE `calcval` ( + `id` bigint NOT NULL auto_increment, + `record_id` bigint NOT NULL, + `layout_id` integer NOT NULL, + `value_text` text NULL, + `value_int` bigint NULL, + `value_date` date NULL, + `value_numeric` decimal(20, 5) NULL, + `value_date_from` datetime NULL, + `value_date_to` datetime NULL, + `purged_by` bigint NULL, + `purged_on` datetime NULL, + INDEX `calcval_idx_layout_id` (`layout_id`), + INDEX `calcval_idx_purged_by` (`purged_by`), + INDEX `calcval_idx_record_id` (`record_id`), + INDEX `calcval_idx_value_text` (`value_text`(64)), + INDEX `calcval_idx_value_numeric` (`value_numeric`), + INDEX `calcval_idx_value_int` (`value_int`), + INDEX `calcval_idx_value_date` (`value_date`), + PRIMARY KEY (`id`), + CONSTRAINT `calcval_fk_layout_id` FOREIGN KEY (`layout_id`) REFERENCES `layout` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `calcval_fk_purged_by` FOREIGN KEY (`purged_by`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `calcval_fk_record_id` FOREIGN KEY (`record_id`) REFERENCES `record` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `current` +-- +CREATE TABLE `current` ( + `id` bigint NOT NULL auto_increment, + `serial` bigint NULL, + `current_version_id` bigint NULL, + `parent_id` bigint NULL, + `instance_id` integer NULL, + `linked_id` bigint NULL, + `deleted` datetime NULL, + `deletedby` bigint NULL, + `draftuser_id` bigint NULL, + INDEX `current_idx_current_version_id` (`current_version_id`), + INDEX `current_idx_deletedby` (`deletedby`), + INDEX `current_idx_draftuser_id` (`draftuser_id`), + INDEX `current_idx_instance_id` (`instance_id`), + INDEX `current_idx_linked_id` (`linked_id`), + INDEX `current_idx_parent_id` (`parent_id`), + PRIMARY KEY (`id`), + UNIQUE `current_ux_instance_serial` (`instance_id`, `serial`), + CONSTRAINT `current_fk_current_version_id` FOREIGN KEY (`current_version_id`) REFERENCES `record` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `current_fk_deletedby` FOREIGN KEY (`deletedby`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `current_fk_draftuser_id` FOREIGN KEY (`draftuser_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `current_fk_instance_id` FOREIGN KEY (`instance_id`) REFERENCES `instance` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `current_fk_linked_id` FOREIGN KEY (`linked_id`) REFERENCES `current` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `current_fk_parent_id` FOREIGN KEY (`parent_id`) REFERENCES `current` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `curval` +-- +CREATE TABLE `curval` ( + `id` bigint NOT NULL auto_increment, + `record_id` bigint NULL, + `layout_id` integer NULL, + `child_unique` smallint NOT NULL DEFAULT 0, + `value` bigint NULL, + `purged_by` bigint NULL, + `purged_on` datetime NULL, + INDEX `curval_idx_layout_id` (`layout_id`), + INDEX `curval_idx_purged_by` (`purged_by`), + INDEX `curval_idx_record_id` (`record_id`), + INDEX `curval_idx_value` (`value`), + PRIMARY KEY (`id`), + CONSTRAINT `curval_fk_layout_id` FOREIGN KEY (`layout_id`) REFERENCES `layout` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `curval_fk_purged_by` FOREIGN KEY (`purged_by`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `curval_fk_record_id` FOREIGN KEY (`record_id`) REFERENCES `record` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `curval_fk_value` FOREIGN KEY (`value`) REFERENCES `current` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `curval_fields` +-- +CREATE TABLE `curval_fields` ( + `id` integer NOT NULL auto_increment, + `parent_id` integer NOT NULL, + `child_id` integer NOT NULL, + INDEX `curval_fields_idx_child_id` (`child_id`), + INDEX `curval_fields_idx_parent_id` (`parent_id`), + PRIMARY KEY (`id`), + CONSTRAINT `curval_fields_fk_child_id` FOREIGN KEY (`child_id`) REFERENCES `layout` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `curval_fields_fk_parent_id` FOREIGN KEY (`parent_id`) REFERENCES `layout` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `dashboard` +-- +CREATE TABLE `dashboard` ( + `id` integer NOT NULL auto_increment, + `site_id` integer NULL, + `instance_id` integer NULL, + `user_id` integer NULL, + INDEX `dashboard_idx_instance_id` (`instance_id`), + INDEX `dashboard_idx_site_id` (`site_id`), + INDEX `dashboard_idx_user_id` (`user_id`), + PRIMARY KEY (`id`), + CONSTRAINT `dashboard_fk_instance_id` FOREIGN KEY (`instance_id`) REFERENCES `instance` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `dashboard_fk_site_id` FOREIGN KEY (`site_id`) REFERENCES `site` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `dashboard_fk_user_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `date` +-- +CREATE TABLE `date` ( + `id` bigint NOT NULL auto_increment, + `record_id` bigint NOT NULL, + `layout_id` integer NOT NULL, + `child_unique` smallint NOT NULL DEFAULT 0, + `value` date NULL, + `purged_by` bigint NULL, + `purged_on` timestamp NULL, + INDEX `date_idx_layout_id` (`layout_id`), + INDEX `date_idx_purged_by` (`purged_by`), + INDEX `date_idx_record_id` (`record_id`), + INDEX `date_idx_value` (`value`), + PRIMARY KEY (`id`), + CONSTRAINT `date_fk_layout_id` FOREIGN KEY (`layout_id`) REFERENCES `layout` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `date_fk_purged_by` FOREIGN KEY (`purged_by`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `date_fk_record_id` FOREIGN KEY (`record_id`) REFERENCES `record` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `daterange` +-- +CREATE TABLE `daterange` ( + `id` bigint NOT NULL auto_increment, + `record_id` bigint NOT NULL, + `layout_id` integer NOT NULL, + `from` date NULL, + `to` date NULL, + `child_unique` smallint NOT NULL DEFAULT 0, + `value` varchar(45) NULL, + `purged_by` bigint NULL, + `purged_on` datetime NULL, + INDEX `daterange_idx_layout_id` (`layout_id`), + INDEX `daterange_idx_purged_by` (`purged_by`), + INDEX `daterange_idx_record_id` (`record_id`), + INDEX `daterange_idx_from` (`from`), + INDEX `daterange_idx_to` (`to`), + INDEX `daterange_idx_value` (`value`), + PRIMARY KEY (`id`), + CONSTRAINT `daterange_fk_layout_id` FOREIGN KEY (`layout_id`) REFERENCES `layout` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `daterange_fk_purged_by` FOREIGN KEY (`purged_by`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `daterange_fk_record_id` FOREIGN KEY (`record_id`) REFERENCES `record` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `department` +-- +CREATE TABLE `department` ( + `id` integer NOT NULL auto_increment, + `name` varchar(128) NULL, + `site_id` integer NULL, + `deleted` smallint NOT NULL DEFAULT 0, + INDEX `department_idx_site_id` (`site_id`), + PRIMARY KEY (`id`), + CONSTRAINT `department_fk_site_id` FOREIGN KEY (`site_id`) REFERENCES `site` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `display_field` +-- +CREATE TABLE `display_field` ( + `id` integer NOT NULL auto_increment, + `layout_id` integer NOT NULL, + `display_field_id` integer NOT NULL, + `regex` text NULL, + `operator` varchar(16) NULL, + INDEX `display_field_idx_display_field_id` (`display_field_id`), + INDEX `display_field_idx_layout_id` (`layout_id`), + PRIMARY KEY (`id`), + CONSTRAINT `display_field_fk_display_field_id` FOREIGN KEY (`display_field_id`) REFERENCES `layout` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `display_field_fk_layout_id` FOREIGN KEY (`layout_id`) REFERENCES `layout` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `enum` +-- +CREATE TABLE `enum` ( + `id` bigint NOT NULL auto_increment, + `record_id` bigint NULL, + `layout_id` integer NULL, + `child_unique` smallint NOT NULL DEFAULT 0, + `value` integer NULL, + `purged_by` bigint NULL, + `purged_on` datetime NULL, + INDEX `enum_idx_layout_id` (`layout_id`), + INDEX `enum_idx_purged_by` (`purged_by`), + INDEX `enum_idx_record_id` (`record_id`), + INDEX `enum_idx_value` (`value`), + PRIMARY KEY (`id`), + CONSTRAINT `enum_fk_layout_id` FOREIGN KEY (`layout_id`) REFERENCES `layout` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `enum_fk_purged_by` FOREIGN KEY (`purged_by`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `enum_fk_record_id` FOREIGN KEY (`record_id`) REFERENCES `record` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `enum_fk_value` FOREIGN KEY (`value`) REFERENCES `enumval` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `enumval` +-- +CREATE TABLE `enumval` ( + `id` integer NOT NULL auto_increment, + `value` text NULL, + `layout_id` integer NULL, + `deleted` smallint NOT NULL DEFAULT 0, + `parent` integer NULL, + `position` integer NULL, + INDEX `enumval_idx_layout_id` (`layout_id`), + INDEX `enumval_idx_parent` (`parent`), + INDEX `enumval_idx_value` (`value`(64)), + PRIMARY KEY (`id`), + CONSTRAINT `enumval_fk_layout_id` FOREIGN KEY (`layout_id`) REFERENCES `layout` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `enumval_fk_parent` FOREIGN KEY (`parent`) REFERENCES `enumval` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `export` +-- +CREATE TABLE `export` ( + `id` integer NOT NULL auto_increment, + `site_id` integer NULL, + `user_id` bigint NOT NULL, + `type` varchar(45) NULL, + `started` datetime NULL, + `completed` datetime NULL, + `result` text NULL, + `result_internal` text NULL, + `mimetype` text NULL, + `content` longblob NULL, + INDEX `export_idx_site_id` (`site_id`), + INDEX `export_idx_user_id` (`user_id`), + PRIMARY KEY (`id`), + CONSTRAINT `export_fk_site_id` FOREIGN KEY (`site_id`) REFERENCES `site` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `export_fk_user_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `file` +-- +CREATE TABLE `file` ( + `id` bigint NOT NULL auto_increment, + `record_id` bigint NULL, + `layout_id` integer NULL, + `child_unique` smallint NOT NULL DEFAULT 0, + `value` bigint NULL, + `purged_by` bigint NULL, + `purged_on` datetime NULL, + INDEX `file_idx_layout_id` (`layout_id`), + INDEX `file_idx_purged_by` (`purged_by`), + INDEX `file_idx_record_id` (`record_id`), + INDEX `file_idx_value` (`value`), + PRIMARY KEY (`id`), + CONSTRAINT `file_fk_layout_id` FOREIGN KEY (`layout_id`) REFERENCES `layout` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `file_fk_purged_by` FOREIGN KEY (`purged_by`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `file_fk_record_id` FOREIGN KEY (`record_id`) REFERENCES `record` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `file_fk_value` FOREIGN KEY (`value`) REFERENCES `fileval` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `file_option` +-- +CREATE TABLE `file_option` ( + `id` integer NOT NULL auto_increment, + `layout_id` integer NOT NULL, + `filesize` integer NULL, + INDEX `file_option_idx_layout_id` (`layout_id`), + PRIMARY KEY (`id`), + CONSTRAINT `file_option_fk_layout_id` FOREIGN KEY (`layout_id`) REFERENCES `layout` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `fileval` +-- +CREATE TABLE `fileval` ( + `id` bigint NOT NULL auto_increment, + `name` text NULL, + `mimetype` text NULL, + `is_independent` smallint NOT NULL DEFAULT 0, + `edit_user_id` bigint NULL, + INDEX `fileval_idx_edit_user_id` (`edit_user_id`), + INDEX `fileval_idx_name` (`name`(64)), + PRIMARY KEY (`id`), + CONSTRAINT `fileval_fk_edit_user_id` FOREIGN KEY (`edit_user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `filter` +-- +CREATE TABLE `filter` ( + `id` bigint NOT NULL auto_increment, + `view_id` bigint NOT NULL, + `layout_id` integer NOT NULL, + INDEX `filter_idx_layout_id` (`layout_id`), + INDEX `filter_idx_view_id` (`view_id`), + PRIMARY KEY (`id`), + CONSTRAINT `filter_fk_layout_id` FOREIGN KEY (`layout_id`) REFERENCES `layout` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `filter_fk_view_id` FOREIGN KEY (`view_id`) REFERENCES `view` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `filtered_value` +-- +CREATE TABLE `filtered_value` ( + `id` integer NOT NULL auto_increment, + `submission_id` integer NULL, + `layout_id` integer NULL, + `current_id` integer NULL, + INDEX `filtered_value_idx_current_id` (`current_id`), + INDEX `filtered_value_idx_layout_id` (`layout_id`), + INDEX `filtered_value_idx_submission_id` (`submission_id`), + PRIMARY KEY (`id`), + UNIQUE `ux_submission_layout_current` (`submission_id`, `layout_id`, `current_id`), + CONSTRAINT `filtered_value_fk_current_id` FOREIGN KEY (`current_id`) REFERENCES `current` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `filtered_value_fk_layout_id` FOREIGN KEY (`layout_id`) REFERENCES `layout` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `filtered_value_fk_submission_id` FOREIGN KEY (`submission_id`) REFERENCES `submission` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `graph` +-- +CREATE TABLE `graph` ( + `id` integer NOT NULL auto_increment, + `title` text NULL, + `description` text NULL, + `y_axis` integer NULL, + `y_axis_link` integer NULL, + `y_axis_stack` varchar(45) NULL, + `y_axis_label` text NULL, + `x_axis` integer NULL, + `x_axis_link` integer NULL, + `x_axis_grouping` varchar(45) NULL, + `group_by` integer NULL, + `stackseries` smallint NOT NULL DEFAULT 0, + `as_percent` smallint NOT NULL DEFAULT 0, + `type` varchar(45) NULL, + `metric_group` integer NULL, + `instance_id` integer NULL, + `is_shared` smallint NOT NULL DEFAULT 0, + `user_id` bigint NULL, + `group_id` integer NULL, + `trend` varchar(45) NULL, + `from` date NULL, + `to` date NULL, + `x_axis_range` varchar(45) NULL, + INDEX `graph_idx_group_id` (`group_id`), + INDEX `graph_idx_group_by` (`group_by`), + INDEX `graph_idx_instance_id` (`instance_id`), + INDEX `graph_idx_metric_group` (`metric_group`), + INDEX `graph_idx_user_id` (`user_id`), + INDEX `graph_idx_x_axis` (`x_axis`), + INDEX `graph_idx_x_axis_link` (`x_axis_link`), + INDEX `graph_idx_y_axis` (`y_axis`), + INDEX `graph_idx_y_axis_link` (`y_axis_link`), + PRIMARY KEY (`id`), + CONSTRAINT `graph_fk_group_id` FOREIGN KEY (`group_id`) REFERENCES `group` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `graph_fk_group_by` FOREIGN KEY (`group_by`) REFERENCES `layout` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `graph_fk_instance_id` FOREIGN KEY (`instance_id`) REFERENCES `instance` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `graph_fk_metric_group` FOREIGN KEY (`metric_group`) REFERENCES `metric_group` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `graph_fk_user_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `graph_fk_x_axis` FOREIGN KEY (`x_axis`) REFERENCES `layout` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `graph_fk_x_axis_link` FOREIGN KEY (`x_axis_link`) REFERENCES `layout` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `graph_fk_y_axis` FOREIGN KEY (`y_axis`) REFERENCES `layout` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `graph_fk_y_axis_link` FOREIGN KEY (`y_axis_link`) REFERENCES `layout` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `graph_color` +-- +CREATE TABLE `graph_color` ( + `id` bigint NOT NULL auto_increment, + `name` varchar(128) NULL, + `color` char(6) NULL, + PRIMARY KEY (`id`), + UNIQUE `ux_graph_color_name` (`name`) +); +-- +-- Table: `group` +-- +CREATE TABLE `group` ( + `id` integer NOT NULL auto_increment, + `name` varchar(128) NULL, + `default_read` smallint NOT NULL DEFAULT 0, + `default_write_new` smallint NOT NULL DEFAULT 0, + `default_write_existing` smallint NOT NULL DEFAULT 0, + `default_approve_new` smallint NOT NULL DEFAULT 0, + `default_approve_existing` smallint NOT NULL DEFAULT 0, + `default_write_new_no_approval` smallint NOT NULL DEFAULT 0, + `default_write_existing_no_approval` smallint NOT NULL DEFAULT 0, + `site_id` integer NULL, + INDEX `group_idx_site_id` (`site_id`), + PRIMARY KEY (`id`), + CONSTRAINT `group_fk_site_id` FOREIGN KEY (`site_id`) REFERENCES `site` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `import` +-- +CREATE TABLE `import` ( + `id` integer NOT NULL auto_increment, + `site_id` integer NULL, + `instance_id` integer NULL, + `user_id` bigint NOT NULL, + `type` varchar(45) NULL, + `row_count` integer NOT NULL DEFAULT 0, + `started` datetime NULL, + `completed` datetime NULL, + `written_count` integer NOT NULL DEFAULT 0, + `error_count` integer NOT NULL DEFAULT 0, + `skipped_count` integer NOT NULL DEFAULT 0, + `result` text NULL, + INDEX `import_idx_instance_id` (`instance_id`), + INDEX `import_idx_site_id` (`site_id`), + INDEX `import_idx_user_id` (`user_id`), + PRIMARY KEY (`id`), + CONSTRAINT `import_fk_instance_id` FOREIGN KEY (`instance_id`) REFERENCES `instance` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `import_fk_site_id` FOREIGN KEY (`site_id`) REFERENCES `site` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `import_fk_user_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `import_row` +-- +CREATE TABLE `import_row` ( + `id` bigint NOT NULL auto_increment, + `import_id` integer NOT NULL, + `status` varchar(45) NULL, + `content` text NULL, + `errors` text NULL, + `changes` text NULL, + INDEX `import_row_idx_import_id` (`import_id`), + PRIMARY KEY (`id`), + CONSTRAINT `import_row_fk_import_id` FOREIGN KEY (`import_id`) REFERENCES `import` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `instance` +-- +CREATE TABLE `instance` ( + `id` integer NOT NULL auto_increment, + `name` text NULL, + `name_short` varchar(64) NULL, + `site_id` integer NULL, + `sort_layout_id` integer NULL, + `sort_type` varchar(45) NULL, + `view_limit_id` integer NULL, + `default_view_limit_extra_id` integer NULL, + `homepage_text` text NULL, + `homepage_text2` text NULL, + `record_name` text NULL, + `forget_history` smallint NULL DEFAULT 0, + `no_overnight_update` smallint NULL DEFAULT 0, + `api_index_layout_id` integer NULL, + `forward_record_after_create` smallint NULL DEFAULT 0, + `no_hide_blank` smallint NOT NULL DEFAULT 0, + `no_download_pdf` smallint NOT NULL DEFAULT 0, + `no_copy_record` smallint NOT NULL DEFAULT 0, + `hide_in_selector` smallint NOT NULL DEFAULT 0, + `security_marking` text NULL, + INDEX `instance_idx_api_index_layout_id` (`api_index_layout_id`), + INDEX `instance_idx_default_view_limit_extra_id` (`default_view_limit_extra_id`), + INDEX `instance_idx_site_id` (`site_id`), + INDEX `instance_idx_sort_layout_id` (`sort_layout_id`), + INDEX `instance_idx_view_limit_id` (`view_limit_id`), + PRIMARY KEY (`id`), + CONSTRAINT `instance_fk_api_index_layout_id` FOREIGN KEY (`api_index_layout_id`) REFERENCES `layout` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `instance_fk_default_view_limit_extra_id` FOREIGN KEY (`default_view_limit_extra_id`) REFERENCES `view` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `instance_fk_site_id` FOREIGN KEY (`site_id`) REFERENCES `site` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `instance_fk_sort_layout_id` FOREIGN KEY (`sort_layout_id`) REFERENCES `layout` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `instance_fk_view_limit_id` FOREIGN KEY (`view_limit_id`) REFERENCES `view` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `instance_group` +-- +CREATE TABLE `instance_group` ( + `id` integer NOT NULL auto_increment, + `instance_id` integer NOT NULL, + `group_id` integer NOT NULL, + `permission` varchar(45) NOT NULL, + INDEX `instance_group_idx_group_id` (`group_id`), + INDEX `instance_group_idx_instance_id` (`instance_id`), + PRIMARY KEY (`id`), + UNIQUE `instance_group_ux_instance_group_permission` (`instance_id`, `group_id`, `permission`), + CONSTRAINT `instance_group_fk_group_id` FOREIGN KEY (`group_id`) REFERENCES `group` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `instance_group_fk_instance_id` FOREIGN KEY (`instance_id`) REFERENCES `instance` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `instance_rag` +-- +CREATE TABLE `instance_rag` ( + `id` integer NOT NULL auto_increment, + `instance_id` integer NOT NULL, + `rag` varchar(16) NOT NULL, + `enabled` smallint NOT NULL DEFAULT 0, + `description` text NULL, + INDEX `instance_rag_idx_instance_id` (`instance_id`), + PRIMARY KEY (`id`), + UNIQUE `instance_rag_ux_instance_rag` (`instance_id`, `rag`), + CONSTRAINT `instance_rag_fk_instance_id` FOREIGN KEY (`instance_id`) REFERENCES `instance` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `intgr` +-- +CREATE TABLE `intgr` ( + `id` bigint NOT NULL auto_increment, + `record_id` bigint NOT NULL, + `layout_id` integer NOT NULL, + `child_unique` smallint NOT NULL DEFAULT 0, + `value` bigint NULL, + `purged_by` bigint NULL, + `purged_on` datetime NULL, + INDEX `intgr_idx_layout_id` (`layout_id`), + INDEX `intgr_idx_purged_by` (`purged_by`), + INDEX `intgr_idx_record_id` (`record_id`), + INDEX `intgr_idx_value` (`value`), + PRIMARY KEY (`id`), + CONSTRAINT `intgr_fk_layout_id` FOREIGN KEY (`layout_id`) REFERENCES `layout` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `intgr_fk_purged_by` FOREIGN KEY (`purged_by`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `intgr_fk_record_id` FOREIGN KEY (`record_id`) REFERENCES `record` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `layout` +-- +CREATE TABLE `layout` ( + `id` integer NOT NULL auto_increment, + `name` text NULL, + `name_short` varchar(64) NULL, + `type` varchar(45) NULL, + `permission` integer NOT NULL DEFAULT 0, + `optional` smallint NOT NULL DEFAULT 0, + `remember` smallint NOT NULL DEFAULT 0, + `isunique` smallint NOT NULL DEFAULT 0, + `textbox` smallint NOT NULL DEFAULT 0, + `typeahead` smallint NOT NULL DEFAULT 0, + `force_regex` text NULL, + `position` integer NULL, + `ordering` varchar(45) NULL, + `end_node_only` smallint NOT NULL DEFAULT 0, + `multivalue` smallint NOT NULL DEFAULT 0, + `can_child` smallint NOT NULL DEFAULT 0, + `internal` smallint NOT NULL DEFAULT 0, + `description` text NULL, + `helptext` text NULL, + `options` text NULL, + `display_field` integer NULL, + `display_regex` text NULL, + `display_condition` char(3) NULL, + `display_matchtype` text NULL, + `instance_id` integer NULL, + `link_parent` integer NULL, + `related_field` integer NULL, + `width` integer NOT NULL DEFAULT 50, + `filter` text NULL, + `topic_id` integer NULL, + `aggregate` varchar(45) NULL, + `group_display` varchar(45) NULL, + `lookup_endpoint` text NULL, + `lookup_group` smallint NULL, + `notes` text NULL, + INDEX `layout_idx_display_field` (`display_field`), + INDEX `layout_idx_instance_id` (`instance_id`), + INDEX `layout_idx_link_parent` (`link_parent`), + INDEX `layout_idx_related_field` (`related_field`), + INDEX `layout_idx_topic_id` (`topic_id`), + PRIMARY KEY (`id`), + UNIQUE `layout_ux_instance_name_short` (`instance_id`, `name_short`), + CONSTRAINT `layout_fk_display_field` FOREIGN KEY (`display_field`) REFERENCES `layout` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `layout_fk_instance_id` FOREIGN KEY (`instance_id`) REFERENCES `instance` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `layout_fk_link_parent` FOREIGN KEY (`link_parent`) REFERENCES `layout` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `layout_fk_related_field` FOREIGN KEY (`related_field`) REFERENCES `layout` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `layout_fk_topic_id` FOREIGN KEY (`topic_id`) REFERENCES `topic` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `layout_depend` +-- +CREATE TABLE `layout_depend` ( + `id` integer NOT NULL auto_increment, + `layout_id` integer NOT NULL, + `depends_on` integer NOT NULL, + INDEX `layout_depend_idx_depends_on` (`depends_on`), + INDEX `layout_depend_idx_layout_id` (`layout_id`), + PRIMARY KEY (`id`), + CONSTRAINT `layout_depend_fk_depends_on` FOREIGN KEY (`depends_on`) REFERENCES `layout` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `layout_depend_fk_layout_id` FOREIGN KEY (`layout_id`) REFERENCES `layout` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `layout_group` +-- +CREATE TABLE `layout_group` ( + `id` integer NOT NULL auto_increment, + `layout_id` integer NOT NULL, + `group_id` integer NOT NULL, + `permission` varchar(45) NOT NULL, + INDEX `layout_group_idx_group_id` (`group_id`), + INDEX `layout_group_idx_layout_id` (`layout_id`), + INDEX `layout_group_idx_permission` (`permission`), + PRIMARY KEY (`id`), + UNIQUE `layout_group_ux_layout_group_permission` (`layout_id`, `group_id`, `permission`), + CONSTRAINT `layout_group_fk_group_id` FOREIGN KEY (`group_id`) REFERENCES `group` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `layout_group_fk_layout_id` FOREIGN KEY (`layout_id`) REFERENCES `layout` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `metric` +-- +CREATE TABLE `metric` ( + `id` integer NOT NULL auto_increment, + `metric_group` integer NOT NULL, + `x_axis_value` text NULL, + `target` bigint NULL, + `y_axis_grouping_value` text NULL, + INDEX `metric_idx_metric_group` (`metric_group`), + PRIMARY KEY (`id`), + CONSTRAINT `metric_fk_metric_group` FOREIGN KEY (`metric_group`) REFERENCES `metric_group` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `metric_group` +-- +CREATE TABLE `metric_group` ( + `id` integer NOT NULL auto_increment, + `name` text NULL, + `instance_id` integer NULL, + INDEX `metric_group_idx_instance_id` (`instance_id`), + PRIMARY KEY (`id`), + CONSTRAINT `metric_group_fk_instance_id` FOREIGN KEY (`instance_id`) REFERENCES `instance` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `oauthclient` +-- +CREATE TABLE `oauthclient` ( + `id` bigint NOT NULL auto_increment, + `client_id` varchar(64) NOT NULL, + `client_secret` varchar(64) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB; +-- +-- Table: `oauthtoken` +-- +CREATE TABLE `oauthtoken` ( + `token` varchar(128) NOT NULL, + `related_token` varchar(128) NOT NULL, + `oauthclient_id` integer NOT NULL, + `user_id` bigint NOT NULL, + `type` varchar(12) NOT NULL, + `expires` integer NULL, + INDEX `oauthtoken_idx_oauthclient_id` (`oauthclient_id`), + INDEX `oauthtoken_idx_user_id` (`user_id`), + PRIMARY KEY (`token`), + CONSTRAINT `oauthtoken_fk_oauthclient_id` FOREIGN KEY (`oauthclient_id`) REFERENCES `oauthclient` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `oauthtoken_fk_user_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `organisation` +-- +CREATE TABLE `organisation` ( + `id` integer NOT NULL auto_increment, + `name` varchar(128) NULL, + `site_id` integer NULL, + `deleted` smallint NOT NULL DEFAULT 0, + INDEX `organisation_idx_site_id` (`site_id`), + PRIMARY KEY (`id`), + CONSTRAINT `organisation_fk_site_id` FOREIGN KEY (`site_id`) REFERENCES `site` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `permission` +-- +CREATE TABLE `permission` ( + `id` integer NOT NULL auto_increment, + `name` varchar(128) NOT NULL, + `description` text NULL, + `order` integer NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB; +-- +-- Table: `person` +-- +CREATE TABLE `person` ( + `id` bigint NOT NULL auto_increment, + `record_id` bigint NULL, + `layout_id` integer NULL, + `child_unique` smallint NOT NULL DEFAULT 0, + `value` bigint NULL, + `purged_by` bigint NULL, + `purged_on` datetime NULL, + INDEX `person_idx_layout_id` (`layout_id`), + INDEX `person_idx_purged_by` (`purged_by`), + INDEX `person_idx_record_id` (`record_id`), + INDEX `person_idx_value` (`value`), + PRIMARY KEY (`id`), + CONSTRAINT `person_fk_layout_id` FOREIGN KEY (`layout_id`) REFERENCES `layout` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `person_fk_purged_by` FOREIGN KEY (`purged_by`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `person_fk_record_id` FOREIGN KEY (`record_id`) REFERENCES `record` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `person_fk_value` FOREIGN KEY (`value`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `rag` +-- +CREATE TABLE `rag` ( + `id` integer NOT NULL auto_increment, + `layout_id` integer NOT NULL, + `red` text NULL, + `amber` text NULL, + `green` text NULL, + `code` mediumtext NULL, + INDEX `rag_idx_layout_id` (`layout_id`), + PRIMARY KEY (`id`), + CONSTRAINT `rag_fk_layout_id` FOREIGN KEY (`layout_id`) REFERENCES `layout` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `ragval` +-- +CREATE TABLE `ragval` ( + `id` bigint NOT NULL auto_increment, + `record_id` bigint NOT NULL, + `layout_id` integer NOT NULL, + `value` varchar(16) NULL, + `purged_by` bigint NULL, + `purged_on` datetime NULL, + INDEX `ragval_idx_layout_id` (`layout_id`), + INDEX `ragval_idx_purged_by` (`purged_by`), + INDEX `ragval_idx_record_id` (`record_id`), + INDEX `ragval_idx_value` (`value`), + PRIMARY KEY (`id`), + UNIQUE `ragval_ux_record_layout` (`record_id`, `layout_id`), + CONSTRAINT `ragval_fk_layout_id` FOREIGN KEY (`layout_id`) REFERENCES `layout` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `ragval_fk_purged_by` FOREIGN KEY (`purged_by`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `ragval_fk_record_id` FOREIGN KEY (`record_id`) REFERENCES `record` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `record` +-- +CREATE TABLE `record` ( + `id` bigint NOT NULL auto_increment, + `created` datetime NOT NULL, + `current_id` bigint NOT NULL DEFAULT 0, + `createdby` bigint NULL, + `approvedby` bigint NULL, + `record_id` bigint NULL, + `approval` smallint NOT NULL DEFAULT 0, + INDEX `record_idx_approvedby` (`approvedby`), + INDEX `record_idx_createdby` (`createdby`), + INDEX `record_idx_current_id` (`current_id`), + INDEX `record_idx_record_id` (`record_id`), + INDEX `record_idx_approval` (`approval`), + PRIMARY KEY (`id`), + CONSTRAINT `record_fk_approvedby` FOREIGN KEY (`approvedby`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `record_fk_createdby` FOREIGN KEY (`createdby`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `record_fk_current_id` FOREIGN KEY (`current_id`) REFERENCES `current` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `record_fk_record_id` FOREIGN KEY (`record_id`) REFERENCES `record` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `report` +-- +CREATE TABLE `report` ( + `id` bigint NOT NULL auto_increment, + `name` text NOT NULL, + `title` text NULL, + `description` text NULL, + `user_id` bigint NULL, + `createdby` bigint NULL, + `created` datetime NULL, + `instance_id` bigint NULL, + `deleted` datetime NULL, + `security_marking` text NULL, + INDEX `report_idx_createdby` (`createdby`), + INDEX `report_idx_instance_id` (`instance_id`), + INDEX `report_idx_user_id` (`user_id`), + PRIMARY KEY (`id`), + CONSTRAINT `report_fk_createdby` FOREIGN KEY (`createdby`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `report_fk_instance_id` FOREIGN KEY (`instance_id`) REFERENCES `instance` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `report_fk_user_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `report_group` +-- +CREATE TABLE `report_group` ( + `id` integer NOT NULL auto_increment, + `report_id` integer NOT NULL, + `group_id` integer NOT NULL, + INDEX `report_group_idx_group_id` (`group_id`), + INDEX `report_group_idx_report_id` (`report_id`), + PRIMARY KEY (`id`), + CONSTRAINT `report_group_fk_group_id` FOREIGN KEY (`group_id`) REFERENCES `group` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `report_group_fk_report_id` FOREIGN KEY (`report_id`) REFERENCES `report` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `report_layout` +-- +CREATE TABLE `report_layout` ( + `id` integer NOT NULL auto_increment, + `report_id` integer NOT NULL, + `layout_id` bigint NOT NULL, + `order` integer NULL, + INDEX `report_layout_idx_layout_id` (`layout_id`), + INDEX `report_layout_idx_report_id` (`report_id`), + PRIMARY KEY (`id`), + CONSTRAINT `report_layout_fk_layout_id` FOREIGN KEY (`layout_id`) REFERENCES `layout` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `report_layout_fk_report_id` FOREIGN KEY (`report_id`) REFERENCES `report` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `site` +-- +CREATE TABLE `site` ( + `id` integer NOT NULL auto_increment, + `host` varchar(128) NULL, + `name` text NULL, + `created` datetime NULL, + `email_welcome_text` text NULL, + `email_welcome_subject` text NULL, + `email_delete_text` text NULL, + `email_delete_subject` text NULL, + `email_reject_text` text NULL, + `email_reject_subject` text NULL, + `register_text` text NULL, + `homepage_text` text NULL, + `homepage_text2` text NULL, + `register_title_help` text NULL, + `register_freetext1_help` text NULL, + `register_freetext2_help` text NULL, + `register_email_help` text NULL, + `register_organisation_help` text NULL, + `register_organisation_name` text NULL, + `register_organisation_mandatory` smallint NOT NULL DEFAULT 0, + `register_department_help` text NULL, + `register_department_name` text NULL, + `register_department_mandatory` smallint NOT NULL DEFAULT 0, + `register_team_help` text NULL, + `register_team_name` text NULL, + `register_team_mandatory` smallint NOT NULL DEFAULT 0, + `register_notes_help` text NULL, + `register_freetext1_name` text NULL, + `register_freetext2_name` text NULL, + `register_show_organisation` smallint NOT NULL DEFAULT 1, + `register_show_department` smallint NOT NULL DEFAULT 0, + `register_show_team` smallint NOT NULL DEFAULT 0, + `register_show_title` smallint NOT NULL DEFAULT 1, + `hide_account_request` smallint NOT NULL DEFAULT 0, + `remember_user_location` smallint NOT NULL DEFAULT 1, + `user_editable_fields` text NULL, + `register_freetext1_placeholder` text NULL, + `register_freetext2_placeholder` text NULL, + `account_request_notes_name` text NULL, + `account_request_notes_placeholder` text NULL, + `security_marking` text NULL, + `site_logo` longblob NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB; +-- +-- Table: `sort` +-- +CREATE TABLE `sort` ( + `id` integer NOT NULL auto_increment, + `view_id` bigint NOT NULL, + `layout_id` integer NULL, + `parent_id` integer NULL, + `type` varchar(45) NULL, + `order` integer NULL, + INDEX `sort_idx_layout_id` (`layout_id`), + INDEX `sort_idx_parent_id` (`parent_id`), + INDEX `sort_idx_view_id` (`view_id`), + PRIMARY KEY (`id`), + CONSTRAINT `sort_fk_layout_id` FOREIGN KEY (`layout_id`) REFERENCES `layout` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `sort_fk_parent_id` FOREIGN KEY (`parent_id`) REFERENCES `layout` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `sort_fk_view_id` FOREIGN KEY (`view_id`) REFERENCES `view` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `string` +-- +CREATE TABLE `string` ( + `id` bigint NOT NULL auto_increment, + `record_id` bigint NOT NULL, + `layout_id` integer NOT NULL, + `child_unique` smallint NOT NULL DEFAULT 0, + `value` text NULL, + `value_index` varchar(128) NULL, + `purged_by` bigint NULL, + `purged_on` datetime NULL, + INDEX `string_idx_layout_id` (`layout_id`), + INDEX `string_idx_purged_by` (`purged_by`), + INDEX `string_idx_record_id` (`record_id`), + INDEX `string_idx_value_index` (`value_index`), + PRIMARY KEY (`id`), + CONSTRAINT `string_fk_layout_id` FOREIGN KEY (`layout_id`) REFERENCES `layout` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `string_fk_purged_by` FOREIGN KEY (`purged_by`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `string_fk_record_id` FOREIGN KEY (`record_id`) REFERENCES `record` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `submission` +-- +CREATE TABLE `submission` ( + `id` integer NOT NULL auto_increment, + `token` varchar(64) NOT NULL, + `created` datetime NULL, + `submitted` smallint NOT NULL DEFAULT 0, + PRIMARY KEY (`id`), + UNIQUE `ux_submission_token` (`token`, `submitted`) +) ENGINE=InnoDB; +-- +-- Table: `team` +-- +CREATE TABLE `team` ( + `id` integer NOT NULL auto_increment, + `name` varchar(128) NULL, + `site_id` integer NULL, + `deleted` smallint NOT NULL DEFAULT 0, + INDEX `team_idx_site_id` (`site_id`), + PRIMARY KEY (`id`), + CONSTRAINT `team_fk_site_id` FOREIGN KEY (`site_id`) REFERENCES `site` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `title` +-- +CREATE TABLE `title` ( + `id` integer NOT NULL auto_increment, + `name` varchar(128) NULL, + `site_id` integer NULL, + `deleted` smallint NOT NULL DEFAULT 0, + INDEX `title_idx_site_id` (`site_id`), + PRIMARY KEY (`id`), + CONSTRAINT `title_fk_site_id` FOREIGN KEY (`site_id`) REFERENCES `site` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `topic` +-- +CREATE TABLE `topic` ( + `id` integer NOT NULL auto_increment, + `instance_id` integer NULL, + `name` text NULL, + `description` text NULL, + `initial_state` varchar(32) NULL, + `click_to_edit` smallint NOT NULL DEFAULT 0, + `prevent_edit_topic_id` integer NULL, + INDEX `topic_idx_instance_id` (`instance_id`), + INDEX `topic_idx_prevent_edit_topic_id` (`prevent_edit_topic_id`), + PRIMARY KEY (`id`), + CONSTRAINT `topic_fk_instance_id` FOREIGN KEY (`instance_id`) REFERENCES `instance` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `topic_fk_prevent_edit_topic_id` FOREIGN KEY (`prevent_edit_topic_id`) REFERENCES `topic` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `user` +-- +CREATE TABLE `user` ( + `id` bigint NOT NULL auto_increment, + `site_id` integer NULL, + `firstname` varchar(128) NULL, + `surname` varchar(128) NULL, + `email` text NULL, + `username` text NULL, + `title` integer NULL, + `organisation` integer NULL, + `department_id` integer NULL, + `team_id` integer NULL, + `freetext1` text NULL, + `freetext2` text NULL, + `password` varchar(128) NULL, + `pwchanged` datetime NULL, + `resetpw` varchar(32) NULL, + `deleted` datetime NULL, + `lastlogin` datetime NULL, + `lastfail` datetime NULL, + `failcount` integer NOT NULL DEFAULT 0, + `lastrecord` bigint NULL, + `lastview` bigint NULL, + `session_settings` text NULL, + `value` text NULL, + `account_request` smallint NULL DEFAULT 0, + `account_request_notes` text NULL, + `aup_accepted` datetime NULL, + `limit_to_view` bigint NULL, + `stylesheet` text NULL, + `created` datetime NULL, + `debug_login` smallint NULL DEFAULT 0, + INDEX `user_idx_department_id` (`department_id`), + INDEX `user_idx_lastrecord` (`lastrecord`), + INDEX `user_idx_lastview` (`lastview`), + INDEX `user_idx_limit_to_view` (`limit_to_view`), + INDEX `user_idx_organisation` (`organisation`), + INDEX `user_idx_site_id` (`site_id`), + INDEX `user_idx_team_id` (`team_id`), + INDEX `user_idx_title` (`title`), + INDEX `user_idx_value` (`value`(64)), + INDEX `user_idx_email` (`email`(64)), + INDEX `user_idx_username` (`username`(64)), + PRIMARY KEY (`id`), + CONSTRAINT `user_fk_department_id` FOREIGN KEY (`department_id`) REFERENCES `department` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `user_fk_lastrecord` FOREIGN KEY (`lastrecord`) REFERENCES `record` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `user_fk_lastview` FOREIGN KEY (`lastview`) REFERENCES `view` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `user_fk_limit_to_view` FOREIGN KEY (`limit_to_view`) REFERENCES `view` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `user_fk_organisation` FOREIGN KEY (`organisation`) REFERENCES `organisation` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `user_fk_site_id` FOREIGN KEY (`site_id`) REFERENCES `site` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `user_fk_team_id` FOREIGN KEY (`team_id`) REFERENCES `team` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `user_fk_title` FOREIGN KEY (`title`) REFERENCES `title` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `user_graph` +-- +CREATE TABLE `user_graph` ( + `id` bigint NOT NULL auto_increment, + `user_id` bigint NOT NULL, + `graph_id` integer NOT NULL, + INDEX `user_graph_idx_graph_id` (`graph_id`), + INDEX `user_graph_idx_user_id` (`user_id`), + PRIMARY KEY (`id`), + CONSTRAINT `user_graph_fk_graph_id` FOREIGN KEY (`graph_id`) REFERENCES `graph` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `user_graph_fk_user_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `user_group` +-- +CREATE TABLE `user_group` ( + `id` bigint NOT NULL auto_increment, + `user_id` bigint NOT NULL, + `group_id` integer NOT NULL, + INDEX `user_group_idx_group_id` (`group_id`), + INDEX `user_group_idx_user_id` (`user_id`), + PRIMARY KEY (`id`), + CONSTRAINT `user_group_fk_group_id` FOREIGN KEY (`group_id`) REFERENCES `group` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `user_group_fk_user_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `user_lastrecord` +-- +CREATE TABLE `user_lastrecord` ( + `id` bigint NOT NULL auto_increment, + `record_id` bigint NOT NULL, + `instance_id` integer NOT NULL, + `user_id` bigint NOT NULL, + INDEX `user_lastrecord_idx_instance_id` (`instance_id`), + INDEX `user_lastrecord_idx_record_id` (`record_id`), + INDEX `user_lastrecord_idx_user_id` (`user_id`), + PRIMARY KEY (`id`), + CONSTRAINT `user_lastrecord_fk_instance_id` FOREIGN KEY (`instance_id`) REFERENCES `instance` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `user_lastrecord_fk_record_id` FOREIGN KEY (`record_id`) REFERENCES `record` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `user_lastrecord_fk_user_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `user_permission` +-- +CREATE TABLE `user_permission` ( + `id` bigint NOT NULL auto_increment, + `user_id` bigint NOT NULL, + `permission_id` integer NOT NULL, + INDEX `user_permission_idx_permission_id` (`permission_id`), + INDEX `user_permission_idx_user_id` (`user_id`), + PRIMARY KEY (`id`), + CONSTRAINT `user_permission_fk_permission_id` FOREIGN KEY (`permission_id`) REFERENCES `permission` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `user_permission_fk_user_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `view` +-- +CREATE TABLE `view` ( + `id` bigint NOT NULL auto_increment, + `user_id` bigint NULL, + `group_id` integer NULL, + `name` varchar(128) NULL, + `global` smallint NOT NULL DEFAULT 0, + `is_admin` smallint NOT NULL DEFAULT 0, + `is_limit_extra` smallint NOT NULL DEFAULT 0, + `filter` text NULL, + `instance_id` integer NULL, + `created` datetime NULL, + `createdby` bigint NULL, + INDEX `view_idx_createdby` (`createdby`), + INDEX `view_idx_group_id` (`group_id`), + INDEX `view_idx_instance_id` (`instance_id`), + INDEX `view_idx_user_id` (`user_id`), + PRIMARY KEY (`id`), + CONSTRAINT `view_fk_createdby` FOREIGN KEY (`createdby`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `view_fk_group_id` FOREIGN KEY (`group_id`) REFERENCES `group` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `view_fk_instance_id` FOREIGN KEY (`instance_id`) REFERENCES `instance` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `view_fk_user_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `view_group` +-- +CREATE TABLE `view_group` ( + `id` integer NOT NULL auto_increment, + `view_id` bigint NOT NULL, + `layout_id` integer NULL, + `parent_id` integer NULL, + `order` integer NULL, + INDEX `view_group_idx_layout_id` (`layout_id`), + INDEX `view_group_idx_parent_id` (`parent_id`), + INDEX `view_group_idx_view_id` (`view_id`), + PRIMARY KEY (`id`), + CONSTRAINT `view_group_fk_layout_id` FOREIGN KEY (`layout_id`) REFERENCES `layout` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `view_group_fk_parent_id` FOREIGN KEY (`parent_id`) REFERENCES `layout` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `view_group_fk_view_id` FOREIGN KEY (`view_id`) REFERENCES `view` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `view_layout` +-- +CREATE TABLE `view_layout` ( + `id` integer NOT NULL auto_increment, + `view_id` bigint NOT NULL, + `layout_id` integer NOT NULL, + `order` integer NULL, + INDEX `view_layout_idx_layout_id` (`layout_id`), + INDEX `view_layout_idx_view_id` (`view_id`), + PRIMARY KEY (`id`), + CONSTRAINT `view_layout_fk_layout_id` FOREIGN KEY (`layout_id`) REFERENCES `layout` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `view_layout_fk_view_id` FOREIGN KEY (`view_id`) REFERENCES `view` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `view_limit` +-- +CREATE TABLE `view_limit` ( + `id` bigint NOT NULL auto_increment, + `view_id` bigint NOT NULL, + `user_id` bigint NOT NULL, + INDEX `view_limit_idx_user_id` (`user_id`), + INDEX `view_limit_idx_view_id` (`view_id`), + PRIMARY KEY (`id`), + CONSTRAINT `view_limit_fk_user_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `view_limit_fk_view_id` FOREIGN KEY (`view_id`) REFERENCES `view` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +-- +-- Table: `widget` +-- +CREATE TABLE `widget` ( + `id` integer NOT NULL auto_increment, + `grid_id` varchar(64) NULL, + `dashboard_id` integer NULL, + `type` varchar(16) NULL, + `title` text NULL, + `static` smallint NOT NULL DEFAULT 0, + `h` smallint NULL DEFAULT 0, + `w` smallint NULL DEFAULT 0, + `x` smallint NULL DEFAULT 0, + `y` smallint NULL DEFAULT 0, + `content` text NULL, + `view_id` integer NULL, + `graph_id` integer NULL, + `rows` integer NULL, + `tl_options` text NULL, + `globe_options` text NULL, + INDEX `widget_idx_dashboard_id` (`dashboard_id`), + INDEX `widget_idx_graph_id` (`graph_id`), + INDEX `widget_idx_view_id` (`view_id`), + PRIMARY KEY (`id`), + UNIQUE `widget_ux_dashboard_grid` (`dashboard_id`, `grid_id`), + CONSTRAINT `widget_fk_dashboard_id` FOREIGN KEY (`dashboard_id`) REFERENCES `dashboard` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `widget_fk_graph_id` FOREIGN KEY (`graph_id`) REFERENCES `graph` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT `widget_fk_view_id` FOREIGN KEY (`view_id`) REFERENCES `view` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; +SET foreign_key_checks=1; diff --git a/share/migrations/MySQL/downgrade/110-109/001-auto.sql b/share/migrations/MySQL/downgrade/110-109/001-auto.sql new file mode 100644 index 000000000..670c4000c --- /dev/null +++ b/share/migrations/MySQL/downgrade/110-109/001-auto.sql @@ -0,0 +1,19 @@ +-- Convert schema '/home/abeverley/git/GADS/bin/../share/migrations/_source/deploy/110/001-auto.yml' to '/home/abeverley/git/GADS/bin/../share/migrations/_source/deploy/109/001-auto.yml':; + +; +BEGIN; + +; +ALTER TABLE current DROP FOREIGN KEY current_fk_current_version_id, + DROP INDEX current_idx_current_version_id, + DROP COLUMN current_version_id; + +; +ALTER TABLE graph DROP FOREIGN KEY graph_fk_y_axis_link, + DROP INDEX graph_idx_y_axis_link, + DROP COLUMN y_axis_link; + +; + +COMMIT; + diff --git a/share/migrations/MySQL/upgrade/109-110/001-auto.sql b/share/migrations/MySQL/upgrade/109-110/001-auto.sql new file mode 100644 index 000000000..519735a68 --- /dev/null +++ b/share/migrations/MySQL/upgrade/109-110/001-auto.sql @@ -0,0 +1,19 @@ +-- Convert schema '/home/abeverley/git/GADS/bin/../share/migrations/_source/deploy/109/001-auto.yml' to '/home/abeverley/git/GADS/bin/../share/migrations/_source/deploy/110/001-auto.yml':; + +; +BEGIN; + +; +ALTER TABLE current ADD COLUMN current_version_id bigint NULL, + ADD INDEX current_idx_current_version_id (current_version_id), + ADD CONSTRAINT current_fk_current_version_id FOREIGN KEY (current_version_id) REFERENCES record (id) ON DELETE NO ACTION ON UPDATE NO ACTION; + +; +ALTER TABLE graph ADD COLUMN y_axis_link integer NULL, + ADD INDEX graph_idx_y_axis_link (y_axis_link), + ADD CONSTRAINT graph_fk_y_axis_link FOREIGN KEY (y_axis_link) REFERENCES layout (id) ON DELETE NO ACTION ON UPDATE NO ACTION; + +; + +COMMIT; + diff --git a/share/migrations/PostgreSQL/deploy/110/001-auto-__VERSION.sql b/share/migrations/PostgreSQL/deploy/110/001-auto-__VERSION.sql new file mode 100644 index 000000000..97f33b7d0 --- /dev/null +++ b/share/migrations/PostgreSQL/deploy/110/001-auto-__VERSION.sql @@ -0,0 +1,18 @@ +-- +-- Created by SQL::Translator::Producer::PostgreSQL +-- Created on Sun Jan 4 22:32:07 2026 +-- +; +-- +-- Table: dbix_class_deploymenthandler_versions +-- +CREATE TABLE "dbix_class_deploymenthandler_versions" ( + "id" serial NOT NULL, + "version" character varying(50) NOT NULL, + "ddl" text, + "upgrade_sql" text, + PRIMARY KEY ("id"), + CONSTRAINT "dbix_class_deploymenthandler_versions_version" UNIQUE ("version") +); + +; diff --git a/share/migrations/PostgreSQL/deploy/110/001-auto.sql b/share/migrations/PostgreSQL/deploy/110/001-auto.sql new file mode 100644 index 000000000..6a3abadbf --- /dev/null +++ b/share/migrations/PostgreSQL/deploy/110/001-auto.sql @@ -0,0 +1,1902 @@ +-- +-- Created by SQL::Translator::Producer::PostgreSQL +-- Created on Sun Jan 4 22:32:06 2026 +-- +; +-- +-- Table: alert +-- +CREATE TABLE "alert" ( + "id" serial NOT NULL, + "view_id" bigint NOT NULL, + "user_id" bigint NOT NULL, + "frequency" integer DEFAULT 0 NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "alert_idx_user_id" on "alert" ("user_id"); +CREATE INDEX "alert_idx_view_id" on "alert" ("view_id"); + +; +-- +-- Table: alert_cache +-- +CREATE TABLE "alert_cache" ( + "id" bigserial NOT NULL, + "layout_id" integer NOT NULL, + "view_id" bigint NOT NULL, + "current_id" bigint NOT NULL, + "user_id" bigint, + PRIMARY KEY ("id") +); +CREATE INDEX "alert_cache_idx_current_id" on "alert_cache" ("current_id"); +CREATE INDEX "alert_cache_idx_layout_id" on "alert_cache" ("layout_id"); +CREATE INDEX "alert_cache_idx_user_id" on "alert_cache" ("user_id"); +CREATE INDEX "alert_cache_idx_view_id" on "alert_cache" ("view_id"); + +; +-- +-- Table: alert_column +-- +CREATE TABLE "alert_column" ( + "id" serial NOT NULL, + "layout_id" integer NOT NULL, + "instance_id" integer NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "alert_column_idx_instance_id" on "alert_column" ("instance_id"); +CREATE INDEX "alert_column_idx_layout_id" on "alert_column" ("layout_id"); + +; +-- +-- Table: alert_send +-- +CREATE TABLE "alert_send" ( + "id" bigserial NOT NULL, + "layout_id" integer, + "alert_id" integer NOT NULL, + "current_id" bigint NOT NULL, + "status" character(7), + PRIMARY KEY ("id"), + CONSTRAINT "alert_send_all" UNIQUE ("layout_id", "alert_id", "current_id", "status") +); +CREATE INDEX "alert_send_idx_alert_id" on "alert_send" ("alert_id"); +CREATE INDEX "alert_send_idx_current_id" on "alert_send" ("current_id"); +CREATE INDEX "alert_send_idx_layout_id" on "alert_send" ("layout_id"); + +; +-- +-- Table: audit +-- +CREATE TABLE "audit" ( + "id" bigserial NOT NULL, + "site_id" integer, + "user_id" bigint, + "type" character varying(45), + "datetime" timestamp, + "method" character varying(45), + "url" text, + "description" text, + "instance_id" integer, + PRIMARY KEY ("id") +); +CREATE INDEX "audit_idx_instance_id" on "audit" ("instance_id"); +CREATE INDEX "audit_idx_site_id" on "audit" ("site_id"); +CREATE INDEX "audit_idx_user_id" on "audit" ("user_id"); +CREATE INDEX "audit_idx_datetime" on "audit" ("datetime"); +CREATE INDEX "audit_idx_user_instance_datetime" on "audit" ("user_id", "instance_id", "datetime"); + +; +-- +-- Table: authentication +-- +CREATE TABLE "authentication" ( + "id" bigserial NOT NULL, + "site_id" integer, + "type" character varying(32), + "name" text, + "xml" text, + "saml2_firstname" text, + "saml2_surname" text, + "enabled" smallint DEFAULT 0 NOT NULL, + "error_messages" text, + PRIMARY KEY ("id") +); +CREATE INDEX "authentication_idx_site_id" on "authentication" ("site_id"); + +; +-- +-- Table: calc +-- +CREATE TABLE "calc" ( + "id" serial NOT NULL, + "layout_id" integer, + "calc" text, + "code" text, + "return_format" character varying(45), + "decimal_places" smallint, + PRIMARY KEY ("id") +); +CREATE INDEX "calc_idx_layout_id" on "calc" ("layout_id"); + +; +-- +-- Table: calc_unique +-- +CREATE TABLE "calc_unique" ( + "id" bigserial NOT NULL, + "layout_id" integer NOT NULL, + "value_text" citext, + "value_int" bigint, + "value_date" date, + "value_numeric" numeric(20,5), + "value_date_from" timestamp, + "value_date_to" timestamp, + PRIMARY KEY ("id"), + CONSTRAINT "calc_unique_ux_layout_date" UNIQUE ("layout_id", "value_date"), + CONSTRAINT "calc_unique_ux_layout_daterange" UNIQUE ("layout_id", "value_date_from", "value_date_to"), + CONSTRAINT "calc_unique_ux_layout_int" UNIQUE ("layout_id", "value_int"), + CONSTRAINT "calc_unique_ux_layout_numeric" UNIQUE ("layout_id", "value_numeric"), + CONSTRAINT "calc_unique_ux_layout_text" UNIQUE ("layout_id", "value_text") +); +CREATE INDEX "calc_unique_idx_layout_id" on "calc_unique" ("layout_id"); + +; +-- +-- Table: calcval +-- +CREATE TABLE "calcval" ( + "id" bigserial NOT NULL, + "record_id" bigint NOT NULL, + "layout_id" integer NOT NULL, + "value_text" citext, + "value_int" bigint, + "value_date" date, + "value_numeric" numeric(20,5), + "value_date_from" timestamp, + "value_date_to" timestamp, + "purged_by" bigint, + "purged_on" timestamp, + PRIMARY KEY ("id") +); +CREATE INDEX "calcval_idx_layout_id" on "calcval" ("layout_id"); +CREATE INDEX "calcval_idx_purged_by" on "calcval" ("purged_by"); +CREATE INDEX "calcval_idx_record_id" on "calcval" ("record_id"); +CREATE INDEX "calcval_idx_value_text" on "calcval" ("value_text"); +CREATE INDEX "calcval_idx_value_numeric" on "calcval" ("value_numeric"); +CREATE INDEX "calcval_idx_value_int" on "calcval" ("value_int"); +CREATE INDEX "calcval_idx_value_date" on "calcval" ("value_date"); + +; +-- +-- Table: current +-- +CREATE TABLE "current" ( + "id" bigserial NOT NULL, + "serial" bigint, + "current_version_id" bigint, + "parent_id" bigint, + "instance_id" integer, + "linked_id" bigint, + "deleted" timestamp, + "deletedby" bigint, + "draftuser_id" bigint, + PRIMARY KEY ("id"), + CONSTRAINT "current_ux_instance_serial" UNIQUE ("instance_id", "serial") +); +CREATE INDEX "current_idx_current_version_id" on "current" ("current_version_id"); +CREATE INDEX "current_idx_deletedby" on "current" ("deletedby"); +CREATE INDEX "current_idx_draftuser_id" on "current" ("draftuser_id"); +CREATE INDEX "current_idx_instance_id" on "current" ("instance_id"); +CREATE INDEX "current_idx_linked_id" on "current" ("linked_id"); +CREATE INDEX "current_idx_parent_id" on "current" ("parent_id"); + +; +-- +-- Table: curval +-- +CREATE TABLE "curval" ( + "id" bigserial NOT NULL, + "record_id" bigint, + "layout_id" integer, + "child_unique" smallint DEFAULT 0 NOT NULL, + "value" bigint, + "purged_by" bigint, + "purged_on" timestamp, + PRIMARY KEY ("id") +); +CREATE INDEX "curval_idx_layout_id" on "curval" ("layout_id"); +CREATE INDEX "curval_idx_purged_by" on "curval" ("purged_by"); +CREATE INDEX "curval_idx_record_id" on "curval" ("record_id"); +CREATE INDEX "curval_idx_value" on "curval" ("value"); + +; +-- +-- Table: curval_fields +-- +CREATE TABLE "curval_fields" ( + "id" serial NOT NULL, + "parent_id" integer NOT NULL, + "child_id" integer NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "curval_fields_idx_child_id" on "curval_fields" ("child_id"); +CREATE INDEX "curval_fields_idx_parent_id" on "curval_fields" ("parent_id"); + +; +-- +-- Table: dashboard +-- +CREATE TABLE "dashboard" ( + "id" serial NOT NULL, + "site_id" integer, + "instance_id" integer, + "user_id" integer, + PRIMARY KEY ("id") +); +CREATE INDEX "dashboard_idx_instance_id" on "dashboard" ("instance_id"); +CREATE INDEX "dashboard_idx_site_id" on "dashboard" ("site_id"); +CREATE INDEX "dashboard_idx_user_id" on "dashboard" ("user_id"); + +; +-- +-- Table: date +-- +CREATE TABLE "date" ( + "id" bigserial NOT NULL, + "record_id" bigint NOT NULL, + "layout_id" integer NOT NULL, + "child_unique" smallint DEFAULT 0 NOT NULL, + "value" date, + "purged_by" bigint, + "purged_on" timestamp, + PRIMARY KEY ("id") +); +CREATE INDEX "date_idx_layout_id" on "date" ("layout_id"); +CREATE INDEX "date_idx_purged_by" on "date" ("purged_by"); +CREATE INDEX "date_idx_record_id" on "date" ("record_id"); +CREATE INDEX "date_idx_value" on "date" ("value"); + +; +-- +-- Table: daterange +-- +CREATE TABLE "daterange" ( + "id" bigserial NOT NULL, + "record_id" bigint NOT NULL, + "layout_id" integer NOT NULL, + "from" date, + "to" date, + "child_unique" smallint DEFAULT 0 NOT NULL, + "value" citext, + "purged_by" bigint, + "purged_on" timestamp, + PRIMARY KEY ("id") +); +CREATE INDEX "daterange_idx_layout_id" on "daterange" ("layout_id"); +CREATE INDEX "daterange_idx_purged_by" on "daterange" ("purged_by"); +CREATE INDEX "daterange_idx_record_id" on "daterange" ("record_id"); +CREATE INDEX "daterange_idx_from" on "daterange" ("from"); +CREATE INDEX "daterange_idx_to" on "daterange" ("to"); +CREATE INDEX "daterange_idx_value" on "daterange" ("value"); + +; +-- +-- Table: department +-- +CREATE TABLE "department" ( + "id" serial NOT NULL, + "name" citext, + "site_id" integer, + "deleted" smallint DEFAULT 0 NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "department_idx_site_id" on "department" ("site_id"); + +; +-- +-- Table: display_field +-- +CREATE TABLE "display_field" ( + "id" serial NOT NULL, + "layout_id" integer NOT NULL, + "display_field_id" integer NOT NULL, + "regex" text, + "operator" character varying(16), + PRIMARY KEY ("id") +); +CREATE INDEX "display_field_idx_display_field_id" on "display_field" ("display_field_id"); +CREATE INDEX "display_field_idx_layout_id" on "display_field" ("layout_id"); + +; +-- +-- Table: enum +-- +CREATE TABLE "enum" ( + "id" bigserial NOT NULL, + "record_id" bigint, + "layout_id" integer, + "child_unique" smallint DEFAULT 0 NOT NULL, + "value" integer, + "purged_by" bigint, + "purged_on" timestamp, + PRIMARY KEY ("id") +); +CREATE INDEX "enum_idx_layout_id" on "enum" ("layout_id"); +CREATE INDEX "enum_idx_purged_by" on "enum" ("purged_by"); +CREATE INDEX "enum_idx_record_id" on "enum" ("record_id"); +CREATE INDEX "enum_idx_value" on "enum" ("value"); + +; +-- +-- Table: enumval +-- +CREATE TABLE "enumval" ( + "id" serial NOT NULL, + "value" citext, + "layout_id" integer, + "deleted" smallint DEFAULT 0 NOT NULL, + "parent" integer, + "position" integer, + PRIMARY KEY ("id") +); +CREATE INDEX "enumval_idx_layout_id" on "enumval" ("layout_id"); +CREATE INDEX "enumval_idx_parent" on "enumval" ("parent"); +CREATE INDEX "enumval_idx_value" on "enumval" ("value"); + +; +-- +-- Table: export +-- +CREATE TABLE "export" ( + "id" serial NOT NULL, + "site_id" integer, + "user_id" bigint NOT NULL, + "type" character varying(45), + "started" timestamp, + "completed" timestamp, + "result" text, + "result_internal" text, + "mimetype" text, + "content" bytea, + PRIMARY KEY ("id") +); +CREATE INDEX "export_idx_site_id" on "export" ("site_id"); +CREATE INDEX "export_idx_user_id" on "export" ("user_id"); + +; +-- +-- Table: file +-- +CREATE TABLE "file" ( + "id" bigserial NOT NULL, + "record_id" bigint, + "layout_id" integer, + "child_unique" smallint DEFAULT 0 NOT NULL, + "value" bigint, + "purged_by" bigint, + "purged_on" timestamp, + PRIMARY KEY ("id") +); +CREATE INDEX "file_idx_layout_id" on "file" ("layout_id"); +CREATE INDEX "file_idx_purged_by" on "file" ("purged_by"); +CREATE INDEX "file_idx_record_id" on "file" ("record_id"); +CREATE INDEX "file_idx_value" on "file" ("value"); + +; +-- +-- Table: file_option +-- +CREATE TABLE "file_option" ( + "id" serial NOT NULL, + "layout_id" integer NOT NULL, + "filesize" integer, + PRIMARY KEY ("id") +); +CREATE INDEX "file_option_idx_layout_id" on "file_option" ("layout_id"); + +; +-- +-- Table: fileval +-- +CREATE TABLE "fileval" ( + "id" bigserial NOT NULL, + "name" text, + "mimetype" text, + "is_independent" smallint DEFAULT 0 NOT NULL, + "edit_user_id" bigint, + PRIMARY KEY ("id") +); +CREATE INDEX "fileval_idx_edit_user_id" on "fileval" ("edit_user_id"); +CREATE INDEX "fileval_idx_name" on "fileval" ("name"); + +; +-- +-- Table: filter +-- +CREATE TABLE "filter" ( + "id" bigserial NOT NULL, + "view_id" bigint NOT NULL, + "layout_id" integer NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "filter_idx_layout_id" on "filter" ("layout_id"); +CREATE INDEX "filter_idx_view_id" on "filter" ("view_id"); + +; +-- +-- Table: filtered_value +-- +CREATE TABLE "filtered_value" ( + "id" serial NOT NULL, + "submission_id" integer, + "layout_id" integer, + "current_id" integer, + PRIMARY KEY ("id"), + CONSTRAINT "ux_submission_layout_current" UNIQUE ("submission_id", "layout_id", "current_id") +); +CREATE INDEX "filtered_value_idx_current_id" on "filtered_value" ("current_id"); +CREATE INDEX "filtered_value_idx_layout_id" on "filtered_value" ("layout_id"); +CREATE INDEX "filtered_value_idx_submission_id" on "filtered_value" ("submission_id"); + +; +-- +-- Table: graph +-- +CREATE TABLE "graph" ( + "id" serial NOT NULL, + "title" text, + "description" text, + "y_axis" integer, + "y_axis_link" integer, + "y_axis_stack" character varying(45), + "y_axis_label" text, + "x_axis" integer, + "x_axis_link" integer, + "x_axis_grouping" character varying(45), + "group_by" integer, + "stackseries" smallint DEFAULT 0 NOT NULL, + "as_percent" smallint DEFAULT 0 NOT NULL, + "type" character varying(45), + "metric_group" integer, + "instance_id" integer, + "is_shared" smallint DEFAULT 0 NOT NULL, + "user_id" bigint, + "group_id" integer, + "trend" character varying(45), + "from" date, + "to" date, + "x_axis_range" character varying(45), + PRIMARY KEY ("id") +); +CREATE INDEX "graph_idx_group_id" on "graph" ("group_id"); +CREATE INDEX "graph_idx_group_by" on "graph" ("group_by"); +CREATE INDEX "graph_idx_instance_id" on "graph" ("instance_id"); +CREATE INDEX "graph_idx_metric_group" on "graph" ("metric_group"); +CREATE INDEX "graph_idx_user_id" on "graph" ("user_id"); +CREATE INDEX "graph_idx_x_axis" on "graph" ("x_axis"); +CREATE INDEX "graph_idx_x_axis_link" on "graph" ("x_axis_link"); +CREATE INDEX "graph_idx_y_axis" on "graph" ("y_axis"); +CREATE INDEX "graph_idx_y_axis_link" on "graph" ("y_axis_link"); + +; +-- +-- Table: graph_color +-- +CREATE TABLE "graph_color" ( + "id" bigserial NOT NULL, + "name" character varying(128), + "color" character(6), + PRIMARY KEY ("id"), + CONSTRAINT "ux_graph_color_name" UNIQUE ("name") +); + +; +-- +-- Table: group +-- +CREATE TABLE "group" ( + "id" serial NOT NULL, + "name" character varying(128), + "default_read" smallint DEFAULT 0 NOT NULL, + "default_write_new" smallint DEFAULT 0 NOT NULL, + "default_write_existing" smallint DEFAULT 0 NOT NULL, + "default_approve_new" smallint DEFAULT 0 NOT NULL, + "default_approve_existing" smallint DEFAULT 0 NOT NULL, + "default_write_new_no_approval" smallint DEFAULT 0 NOT NULL, + "default_write_existing_no_approval" smallint DEFAULT 0 NOT NULL, + "site_id" integer, + PRIMARY KEY ("id") +); +CREATE INDEX "group_idx_site_id" on "group" ("site_id"); + +; +-- +-- Table: import +-- +CREATE TABLE "import" ( + "id" serial NOT NULL, + "site_id" integer, + "instance_id" integer, + "user_id" bigint NOT NULL, + "type" character varying(45), + "row_count" integer DEFAULT 0 NOT NULL, + "started" timestamp, + "completed" timestamp, + "written_count" integer DEFAULT 0 NOT NULL, + "error_count" integer DEFAULT 0 NOT NULL, + "skipped_count" integer DEFAULT 0 NOT NULL, + "result" text, + PRIMARY KEY ("id") +); +CREATE INDEX "import_idx_instance_id" on "import" ("instance_id"); +CREATE INDEX "import_idx_site_id" on "import" ("site_id"); +CREATE INDEX "import_idx_user_id" on "import" ("user_id"); + +; +-- +-- Table: import_row +-- +CREATE TABLE "import_row" ( + "id" bigserial NOT NULL, + "import_id" integer NOT NULL, + "status" character varying(45), + "content" text, + "errors" text, + "changes" text, + PRIMARY KEY ("id") +); +CREATE INDEX "import_row_idx_import_id" on "import_row" ("import_id"); + +; +-- +-- Table: instance +-- +CREATE TABLE "instance" ( + "id" serial NOT NULL, + "name" text, + "name_short" character varying(64), + "site_id" integer, + "sort_layout_id" integer, + "sort_type" character varying(45), + "view_limit_id" integer, + "default_view_limit_extra_id" integer, + "homepage_text" text, + "homepage_text2" text, + "record_name" text, + "forget_history" smallint DEFAULT 0, + "no_overnight_update" smallint DEFAULT 0, + "api_index_layout_id" integer, + "forward_record_after_create" smallint DEFAULT 0, + "no_hide_blank" smallint DEFAULT 0 NOT NULL, + "no_download_pdf" smallint DEFAULT 0 NOT NULL, + "no_copy_record" smallint DEFAULT 0 NOT NULL, + "hide_in_selector" smallint DEFAULT 0 NOT NULL, + "security_marking" text, + PRIMARY KEY ("id") +); +CREATE INDEX "instance_idx_api_index_layout_id" on "instance" ("api_index_layout_id"); +CREATE INDEX "instance_idx_default_view_limit_extra_id" on "instance" ("default_view_limit_extra_id"); +CREATE INDEX "instance_idx_site_id" on "instance" ("site_id"); +CREATE INDEX "instance_idx_sort_layout_id" on "instance" ("sort_layout_id"); +CREATE INDEX "instance_idx_view_limit_id" on "instance" ("view_limit_id"); + +; +-- +-- Table: instance_group +-- +CREATE TABLE "instance_group" ( + "id" serial NOT NULL, + "instance_id" integer NOT NULL, + "group_id" integer NOT NULL, + "permission" character varying(45) NOT NULL, + PRIMARY KEY ("id"), + CONSTRAINT "instance_group_ux_instance_group_permission" UNIQUE ("instance_id", "group_id", "permission") +); +CREATE INDEX "instance_group_idx_group_id" on "instance_group" ("group_id"); +CREATE INDEX "instance_group_idx_instance_id" on "instance_group" ("instance_id"); + +; +-- +-- Table: instance_rag +-- +CREATE TABLE "instance_rag" ( + "id" serial NOT NULL, + "instance_id" integer NOT NULL, + "rag" character varying(16) NOT NULL, + "enabled" smallint DEFAULT 0 NOT NULL, + "description" text, + PRIMARY KEY ("id"), + CONSTRAINT "instance_rag_ux_instance_rag" UNIQUE ("instance_id", "rag") +); +CREATE INDEX "instance_rag_idx_instance_id" on "instance_rag" ("instance_id"); + +; +-- +-- Table: intgr +-- +CREATE TABLE "intgr" ( + "id" bigserial NOT NULL, + "record_id" bigint NOT NULL, + "layout_id" integer NOT NULL, + "child_unique" smallint DEFAULT 0 NOT NULL, + "value" bigint, + "purged_by" bigint, + "purged_on" timestamp, + PRIMARY KEY ("id") +); +CREATE INDEX "intgr_idx_layout_id" on "intgr" ("layout_id"); +CREATE INDEX "intgr_idx_purged_by" on "intgr" ("purged_by"); +CREATE INDEX "intgr_idx_record_id" on "intgr" ("record_id"); +CREATE INDEX "intgr_idx_value" on "intgr" ("value"); + +; +-- +-- Table: layout +-- +CREATE TABLE "layout" ( + "id" serial NOT NULL, + "name" text, + "name_short" character varying(64), + "type" character varying(45), + "permission" integer DEFAULT 0 NOT NULL, + "optional" smallint DEFAULT 0 NOT NULL, + "remember" smallint DEFAULT 0 NOT NULL, + "isunique" smallint DEFAULT 0 NOT NULL, + "textbox" smallint DEFAULT 0 NOT NULL, + "typeahead" smallint DEFAULT 0 NOT NULL, + "force_regex" text, + "position" integer, + "ordering" character varying(45), + "end_node_only" smallint DEFAULT 0 NOT NULL, + "multivalue" smallint DEFAULT 0 NOT NULL, + "can_child" smallint DEFAULT 0 NOT NULL, + "internal" smallint DEFAULT 0 NOT NULL, + "description" text, + "helptext" text, + "options" text, + "display_field" integer, + "display_regex" text, + "display_condition" character(3), + "display_matchtype" text, + "instance_id" integer, + "link_parent" integer, + "related_field" integer, + "width" integer DEFAULT 50 NOT NULL, + "filter" text, + "topic_id" integer, + "aggregate" character varying(45), + "group_display" character varying(45), + "lookup_endpoint" text, + "lookup_group" smallint, + "notes" text, + PRIMARY KEY ("id"), + CONSTRAINT "layout_ux_instance_name_short" UNIQUE ("instance_id", "name_short") +); +CREATE INDEX "layout_idx_display_field" on "layout" ("display_field"); +CREATE INDEX "layout_idx_instance_id" on "layout" ("instance_id"); +CREATE INDEX "layout_idx_link_parent" on "layout" ("link_parent"); +CREATE INDEX "layout_idx_related_field" on "layout" ("related_field"); +CREATE INDEX "layout_idx_topic_id" on "layout" ("topic_id"); + +; +-- +-- Table: layout_depend +-- +CREATE TABLE "layout_depend" ( + "id" serial NOT NULL, + "layout_id" integer NOT NULL, + "depends_on" integer NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "layout_depend_idx_depends_on" on "layout_depend" ("depends_on"); +CREATE INDEX "layout_depend_idx_layout_id" on "layout_depend" ("layout_id"); + +; +-- +-- Table: layout_group +-- +CREATE TABLE "layout_group" ( + "id" serial NOT NULL, + "layout_id" integer NOT NULL, + "group_id" integer NOT NULL, + "permission" character varying(45) NOT NULL, + PRIMARY KEY ("id"), + CONSTRAINT "layout_group_ux_layout_group_permission" UNIQUE ("layout_id", "group_id", "permission") +); +CREATE INDEX "layout_group_idx_group_id" on "layout_group" ("group_id"); +CREATE INDEX "layout_group_idx_layout_id" on "layout_group" ("layout_id"); +CREATE INDEX "layout_group_idx_permission" on "layout_group" ("permission"); + +; +-- +-- Table: metric +-- +CREATE TABLE "metric" ( + "id" serial NOT NULL, + "metric_group" integer NOT NULL, + "x_axis_value" text, + "target" bigint, + "y_axis_grouping_value" text, + PRIMARY KEY ("id") +); +CREATE INDEX "metric_idx_metric_group" on "metric" ("metric_group"); + +; +-- +-- Table: metric_group +-- +CREATE TABLE "metric_group" ( + "id" serial NOT NULL, + "name" text, + "instance_id" integer, + PRIMARY KEY ("id") +); +CREATE INDEX "metric_group_idx_instance_id" on "metric_group" ("instance_id"); + +; +-- +-- Table: oauthclient +-- +CREATE TABLE "oauthclient" ( + "id" bigserial NOT NULL, + "client_id" character varying(64) NOT NULL, + "client_secret" character varying(64) NOT NULL, + PRIMARY KEY ("id") +); + +; +-- +-- Table: oauthtoken +-- +CREATE TABLE "oauthtoken" ( + "token" character varying(128) NOT NULL, + "related_token" character varying(128) NOT NULL, + "oauthclient_id" integer NOT NULL, + "user_id" bigint NOT NULL, + "type" character varying(12) NOT NULL, + "expires" integer, + PRIMARY KEY ("token") +); +CREATE INDEX "oauthtoken_idx_oauthclient_id" on "oauthtoken" ("oauthclient_id"); +CREATE INDEX "oauthtoken_idx_user_id" on "oauthtoken" ("user_id"); + +; +-- +-- Table: organisation +-- +CREATE TABLE "organisation" ( + "id" serial NOT NULL, + "name" citext, + "site_id" integer, + "deleted" smallint DEFAULT 0 NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "organisation_idx_site_id" on "organisation" ("site_id"); + +; +-- +-- Table: permission +-- +CREATE TABLE "permission" ( + "id" serial NOT NULL, + "name" character varying(128) NOT NULL, + "description" text, + "order" integer, + PRIMARY KEY ("id") +); + +; +-- +-- Table: person +-- +CREATE TABLE "person" ( + "id" bigserial NOT NULL, + "record_id" bigint, + "layout_id" integer, + "child_unique" smallint DEFAULT 0 NOT NULL, + "value" bigint, + "purged_by" bigint, + "purged_on" timestamp, + PRIMARY KEY ("id") +); +CREATE INDEX "person_idx_layout_id" on "person" ("layout_id"); +CREATE INDEX "person_idx_purged_by" on "person" ("purged_by"); +CREATE INDEX "person_idx_record_id" on "person" ("record_id"); +CREATE INDEX "person_idx_value" on "person" ("value"); + +; +-- +-- Table: rag +-- +CREATE TABLE "rag" ( + "id" serial NOT NULL, + "layout_id" integer NOT NULL, + "red" text, + "amber" text, + "green" text, + "code" text, + PRIMARY KEY ("id") +); +CREATE INDEX "rag_idx_layout_id" on "rag" ("layout_id"); + +; +-- +-- Table: ragval +-- +CREATE TABLE "ragval" ( + "id" bigserial NOT NULL, + "record_id" bigint NOT NULL, + "layout_id" integer NOT NULL, + "value" character varying(16), + "purged_by" bigint, + "purged_on" timestamp, + PRIMARY KEY ("id"), + CONSTRAINT "ragval_ux_record_layout" UNIQUE ("record_id", "layout_id") +); +CREATE INDEX "ragval_idx_layout_id" on "ragval" ("layout_id"); +CREATE INDEX "ragval_idx_purged_by" on "ragval" ("purged_by"); +CREATE INDEX "ragval_idx_record_id" on "ragval" ("record_id"); +CREATE INDEX "ragval_idx_value" on "ragval" ("value"); + +; +-- +-- Table: record +-- +CREATE TABLE "record" ( + "id" bigserial NOT NULL, + "created" timestamp NOT NULL, + "current_id" bigint DEFAULT 0 NOT NULL, + "createdby" bigint, + "approvedby" bigint, + "record_id" bigint, + "approval" smallint DEFAULT 0 NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "record_idx_approvedby" on "record" ("approvedby"); +CREATE INDEX "record_idx_createdby" on "record" ("createdby"); +CREATE INDEX "record_idx_current_id" on "record" ("current_id"); +CREATE INDEX "record_idx_record_id" on "record" ("record_id"); +CREATE INDEX "record_idx_approval" on "record" ("approval"); + +; +-- +-- Table: report +-- +CREATE TABLE "report" ( + "id" bigserial NOT NULL, + "name" text NOT NULL, + "title" text, + "description" text, + "user_id" bigint, + "createdby" bigint, + "created" timestamp, + "instance_id" bigint, + "deleted" timestamp, + "security_marking" text, + PRIMARY KEY ("id") +); +CREATE INDEX "report_idx_createdby" on "report" ("createdby"); +CREATE INDEX "report_idx_instance_id" on "report" ("instance_id"); +CREATE INDEX "report_idx_user_id" on "report" ("user_id"); + +; +-- +-- Table: report_group +-- +CREATE TABLE "report_group" ( + "id" serial NOT NULL, + "report_id" integer NOT NULL, + "group_id" integer NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "report_group_idx_group_id" on "report_group" ("group_id"); +CREATE INDEX "report_group_idx_report_id" on "report_group" ("report_id"); + +; +-- +-- Table: report_layout +-- +CREATE TABLE "report_layout" ( + "id" serial NOT NULL, + "report_id" integer NOT NULL, + "layout_id" bigint NOT NULL, + "order" integer, + PRIMARY KEY ("id") +); +CREATE INDEX "report_layout_idx_layout_id" on "report_layout" ("layout_id"); +CREATE INDEX "report_layout_idx_report_id" on "report_layout" ("report_id"); + +; +-- +-- Table: site +-- +CREATE TABLE "site" ( + "id" serial NOT NULL, + "host" character varying(128), + "name" text, + "created" timestamp, + "email_welcome_text" text, + "email_welcome_subject" text, + "email_delete_text" text, + "email_delete_subject" text, + "email_reject_text" text, + "email_reject_subject" text, + "register_text" text, + "homepage_text" text, + "homepage_text2" text, + "register_title_help" text, + "register_freetext1_help" text, + "register_freetext2_help" text, + "register_email_help" text, + "register_organisation_help" text, + "register_organisation_name" text, + "register_organisation_mandatory" smallint DEFAULT 0 NOT NULL, + "register_department_help" text, + "register_department_name" text, + "register_department_mandatory" smallint DEFAULT 0 NOT NULL, + "register_team_help" text, + "register_team_name" text, + "register_team_mandatory" smallint DEFAULT 0 NOT NULL, + "register_notes_help" text, + "register_freetext1_name" text, + "register_freetext2_name" text, + "register_show_organisation" smallint DEFAULT 1 NOT NULL, + "register_show_department" smallint DEFAULT 0 NOT NULL, + "register_show_team" smallint DEFAULT 0 NOT NULL, + "register_show_title" smallint DEFAULT 1 NOT NULL, + "hide_account_request" smallint DEFAULT 0 NOT NULL, + "remember_user_location" smallint DEFAULT 1 NOT NULL, + "user_editable_fields" text, + "register_freetext1_placeholder" text, + "register_freetext2_placeholder" text, + "account_request_notes_name" text, + "account_request_notes_placeholder" text, + "security_marking" text, + "site_logo" bytea, + PRIMARY KEY ("id") +); + +; +-- +-- Table: sort +-- +CREATE TABLE "sort" ( + "id" serial NOT NULL, + "view_id" bigint NOT NULL, + "layout_id" integer, + "parent_id" integer, + "type" character varying(45), + "order" integer, + PRIMARY KEY ("id") +); +CREATE INDEX "sort_idx_layout_id" on "sort" ("layout_id"); +CREATE INDEX "sort_idx_parent_id" on "sort" ("parent_id"); +CREATE INDEX "sort_idx_view_id" on "sort" ("view_id"); + +; +-- +-- Table: string +-- +CREATE TABLE "string" ( + "id" bigserial NOT NULL, + "record_id" bigint NOT NULL, + "layout_id" integer NOT NULL, + "child_unique" smallint DEFAULT 0 NOT NULL, + "value" citext, + "value_index" character varying(128), + "purged_by" bigint, + "purged_on" timestamp, + PRIMARY KEY ("id") +); +CREATE INDEX "string_idx_layout_id" on "string" ("layout_id"); +CREATE INDEX "string_idx_purged_by" on "string" ("purged_by"); +CREATE INDEX "string_idx_record_id" on "string" ("record_id"); +CREATE INDEX "string_idx_value_index" on "string" ("value_index"); + +; +-- +-- Table: submission +-- +CREATE TABLE "submission" ( + "id" serial NOT NULL, + "token" character varying(64) NOT NULL, + "created" timestamp, + "submitted" smallint DEFAULT 0 NOT NULL, + PRIMARY KEY ("id"), + CONSTRAINT "ux_submission_token" UNIQUE ("token", "submitted") +); + +; +-- +-- Table: team +-- +CREATE TABLE "team" ( + "id" serial NOT NULL, + "name" citext, + "site_id" integer, + "deleted" smallint DEFAULT 0 NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "team_idx_site_id" on "team" ("site_id"); + +; +-- +-- Table: title +-- +CREATE TABLE "title" ( + "id" serial NOT NULL, + "name" character varying(128), + "site_id" integer, + "deleted" smallint DEFAULT 0 NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "title_idx_site_id" on "title" ("site_id"); + +; +-- +-- Table: topic +-- +CREATE TABLE "topic" ( + "id" serial NOT NULL, + "instance_id" integer, + "name" text, + "description" text, + "initial_state" character varying(32), + "click_to_edit" smallint DEFAULT 0 NOT NULL, + "prevent_edit_topic_id" integer, + PRIMARY KEY ("id") +); +CREATE INDEX "topic_idx_instance_id" on "topic" ("instance_id"); +CREATE INDEX "topic_idx_prevent_edit_topic_id" on "topic" ("prevent_edit_topic_id"); + +; +-- +-- Table: user +-- +CREATE TABLE "user" ( + "id" bigserial NOT NULL, + "site_id" integer, + "firstname" character varying(128), + "surname" character varying(128), + "email" citext, + "username" citext, + "title" integer, + "organisation" integer, + "department_id" integer, + "team_id" integer, + "freetext1" text, + "freetext2" text, + "password" character varying(128), + "pwchanged" timestamp, + "resetpw" character varying(32), + "deleted" timestamp, + "lastlogin" timestamp, + "lastfail" timestamp, + "failcount" integer DEFAULT 0 NOT NULL, + "lastrecord" bigint, + "lastview" bigint, + "session_settings" text, + "value" citext, + "account_request" smallint DEFAULT 0, + "account_request_notes" text, + "aup_accepted" timestamp, + "limit_to_view" bigint, + "stylesheet" text, + "created" timestamp, + "debug_login" smallint DEFAULT 0, + PRIMARY KEY ("id") +); +CREATE INDEX "user_idx_department_id" on "user" ("department_id"); +CREATE INDEX "user_idx_lastrecord" on "user" ("lastrecord"); +CREATE INDEX "user_idx_lastview" on "user" ("lastview"); +CREATE INDEX "user_idx_limit_to_view" on "user" ("limit_to_view"); +CREATE INDEX "user_idx_organisation" on "user" ("organisation"); +CREATE INDEX "user_idx_site_id" on "user" ("site_id"); +CREATE INDEX "user_idx_team_id" on "user" ("team_id"); +CREATE INDEX "user_idx_title" on "user" ("title"); +CREATE INDEX "user_idx_value" on "user" ("value"); +CREATE INDEX "user_idx_email" on "user" ("email"); +CREATE INDEX "user_idx_username" on "user" ("username"); + +; +-- +-- Table: user_graph +-- +CREATE TABLE "user_graph" ( + "id" bigserial NOT NULL, + "user_id" bigint NOT NULL, + "graph_id" integer NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "user_graph_idx_graph_id" on "user_graph" ("graph_id"); +CREATE INDEX "user_graph_idx_user_id" on "user_graph" ("user_id"); + +; +-- +-- Table: user_group +-- +CREATE TABLE "user_group" ( + "id" bigserial NOT NULL, + "user_id" bigint NOT NULL, + "group_id" integer NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "user_group_idx_group_id" on "user_group" ("group_id"); +CREATE INDEX "user_group_idx_user_id" on "user_group" ("user_id"); + +; +-- +-- Table: user_lastrecord +-- +CREATE TABLE "user_lastrecord" ( + "id" bigserial NOT NULL, + "record_id" bigint NOT NULL, + "instance_id" integer NOT NULL, + "user_id" bigint NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "user_lastrecord_idx_instance_id" on "user_lastrecord" ("instance_id"); +CREATE INDEX "user_lastrecord_idx_record_id" on "user_lastrecord" ("record_id"); +CREATE INDEX "user_lastrecord_idx_user_id" on "user_lastrecord" ("user_id"); + +; +-- +-- Table: user_permission +-- +CREATE TABLE "user_permission" ( + "id" bigserial NOT NULL, + "user_id" bigint NOT NULL, + "permission_id" integer NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "user_permission_idx_permission_id" on "user_permission" ("permission_id"); +CREATE INDEX "user_permission_idx_user_id" on "user_permission" ("user_id"); + +; +-- +-- Table: view +-- +CREATE TABLE "view" ( + "id" bigserial NOT NULL, + "user_id" bigint, + "group_id" integer, + "name" character varying(128), + "global" smallint DEFAULT 0 NOT NULL, + "is_admin" smallint DEFAULT 0 NOT NULL, + "is_limit_extra" smallint DEFAULT 0 NOT NULL, + "filter" text, + "instance_id" integer, + "created" timestamp, + "createdby" bigint, + PRIMARY KEY ("id") +); +CREATE INDEX "view_idx_createdby" on "view" ("createdby"); +CREATE INDEX "view_idx_group_id" on "view" ("group_id"); +CREATE INDEX "view_idx_instance_id" on "view" ("instance_id"); +CREATE INDEX "view_idx_user_id" on "view" ("user_id"); + +; +-- +-- Table: view_group +-- +CREATE TABLE "view_group" ( + "id" serial NOT NULL, + "view_id" bigint NOT NULL, + "layout_id" integer, + "parent_id" integer, + "order" integer, + PRIMARY KEY ("id") +); +CREATE INDEX "view_group_idx_layout_id" on "view_group" ("layout_id"); +CREATE INDEX "view_group_idx_parent_id" on "view_group" ("parent_id"); +CREATE INDEX "view_group_idx_view_id" on "view_group" ("view_id"); + +; +-- +-- Table: view_layout +-- +CREATE TABLE "view_layout" ( + "id" serial NOT NULL, + "view_id" bigint NOT NULL, + "layout_id" integer NOT NULL, + "order" integer, + PRIMARY KEY ("id") +); +CREATE INDEX "view_layout_idx_layout_id" on "view_layout" ("layout_id"); +CREATE INDEX "view_layout_idx_view_id" on "view_layout" ("view_id"); + +; +-- +-- Table: view_limit +-- +CREATE TABLE "view_limit" ( + "id" bigserial NOT NULL, + "view_id" bigint NOT NULL, + "user_id" bigint NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "view_limit_idx_user_id" on "view_limit" ("user_id"); +CREATE INDEX "view_limit_idx_view_id" on "view_limit" ("view_id"); + +; +-- +-- Table: widget +-- +CREATE TABLE "widget" ( + "id" serial NOT NULL, + "grid_id" character varying(64), + "dashboard_id" integer, + "type" character varying(16), + "title" text, + "static" smallint DEFAULT 0 NOT NULL, + "h" smallint DEFAULT 0, + "w" smallint DEFAULT 0, + "x" smallint DEFAULT 0, + "y" smallint DEFAULT 0, + "content" text, + "view_id" integer, + "graph_id" integer, + "rows" integer, + "tl_options" text, + "globe_options" text, + PRIMARY KEY ("id"), + CONSTRAINT "widget_ux_dashboard_grid" UNIQUE ("dashboard_id", "grid_id") +); +CREATE INDEX "widget_idx_dashboard_id" on "widget" ("dashboard_id"); +CREATE INDEX "widget_idx_graph_id" on "widget" ("graph_id"); +CREATE INDEX "widget_idx_view_id" on "widget" ("view_id"); + +; +-- +-- Foreign Key Definitions +-- + +; +ALTER TABLE "alert" ADD CONSTRAINT "alert_fk_user_id" FOREIGN KEY ("user_id") + REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "alert" ADD CONSTRAINT "alert_fk_view_id" FOREIGN KEY ("view_id") + REFERENCES "view" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "alert_cache" ADD CONSTRAINT "alert_cache_fk_current_id" FOREIGN KEY ("current_id") + REFERENCES "current" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "alert_cache" ADD CONSTRAINT "alert_cache_fk_layout_id" FOREIGN KEY ("layout_id") + REFERENCES "layout" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "alert_cache" ADD CONSTRAINT "alert_cache_fk_user_id" FOREIGN KEY ("user_id") + REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "alert_cache" ADD CONSTRAINT "alert_cache_fk_view_id" FOREIGN KEY ("view_id") + REFERENCES "view" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "alert_column" ADD CONSTRAINT "alert_column_fk_instance_id" FOREIGN KEY ("instance_id") + REFERENCES "instance" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "alert_column" ADD CONSTRAINT "alert_column_fk_layout_id" FOREIGN KEY ("layout_id") + REFERENCES "layout" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "alert_send" ADD CONSTRAINT "alert_send_fk_alert_id" FOREIGN KEY ("alert_id") + REFERENCES "alert" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "alert_send" ADD CONSTRAINT "alert_send_fk_current_id" FOREIGN KEY ("current_id") + REFERENCES "current" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "alert_send" ADD CONSTRAINT "alert_send_fk_layout_id" FOREIGN KEY ("layout_id") + REFERENCES "layout" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "audit" ADD CONSTRAINT "audit_fk_instance_id" FOREIGN KEY ("instance_id") + REFERENCES "instance" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "audit" ADD CONSTRAINT "audit_fk_site_id" FOREIGN KEY ("site_id") + REFERENCES "site" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "audit" ADD CONSTRAINT "audit_fk_user_id" FOREIGN KEY ("user_id") + REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "authentication" ADD CONSTRAINT "authentication_fk_site_id" FOREIGN KEY ("site_id") + REFERENCES "site" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "calc" ADD CONSTRAINT "calc_fk_layout_id" FOREIGN KEY ("layout_id") + REFERENCES "layout" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "calc_unique" ADD CONSTRAINT "calc_unique_fk_layout_id" FOREIGN KEY ("layout_id") + REFERENCES "layout" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "calcval" ADD CONSTRAINT "calcval_fk_layout_id" FOREIGN KEY ("layout_id") + REFERENCES "layout" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "calcval" ADD CONSTRAINT "calcval_fk_purged_by" FOREIGN KEY ("purged_by") + REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "calcval" ADD CONSTRAINT "calcval_fk_record_id" FOREIGN KEY ("record_id") + REFERENCES "record" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "current" ADD CONSTRAINT "current_fk_current_version_id" FOREIGN KEY ("current_version_id") + REFERENCES "record" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "current" ADD CONSTRAINT "current_fk_deletedby" FOREIGN KEY ("deletedby") + REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "current" ADD CONSTRAINT "current_fk_draftuser_id" FOREIGN KEY ("draftuser_id") + REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "current" ADD CONSTRAINT "current_fk_instance_id" FOREIGN KEY ("instance_id") + REFERENCES "instance" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "current" ADD CONSTRAINT "current_fk_linked_id" FOREIGN KEY ("linked_id") + REFERENCES "current" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "current" ADD CONSTRAINT "current_fk_parent_id" FOREIGN KEY ("parent_id") + REFERENCES "current" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "curval" ADD CONSTRAINT "curval_fk_layout_id" FOREIGN KEY ("layout_id") + REFERENCES "layout" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "curval" ADD CONSTRAINT "curval_fk_purged_by" FOREIGN KEY ("purged_by") + REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "curval" ADD CONSTRAINT "curval_fk_record_id" FOREIGN KEY ("record_id") + REFERENCES "record" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "curval" ADD CONSTRAINT "curval_fk_value" FOREIGN KEY ("value") + REFERENCES "current" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "curval_fields" ADD CONSTRAINT "curval_fields_fk_child_id" FOREIGN KEY ("child_id") + REFERENCES "layout" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "curval_fields" ADD CONSTRAINT "curval_fields_fk_parent_id" FOREIGN KEY ("parent_id") + REFERENCES "layout" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "dashboard" ADD CONSTRAINT "dashboard_fk_instance_id" FOREIGN KEY ("instance_id") + REFERENCES "instance" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "dashboard" ADD CONSTRAINT "dashboard_fk_site_id" FOREIGN KEY ("site_id") + REFERENCES "site" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "dashboard" ADD CONSTRAINT "dashboard_fk_user_id" FOREIGN KEY ("user_id") + REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "date" ADD CONSTRAINT "date_fk_layout_id" FOREIGN KEY ("layout_id") + REFERENCES "layout" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "date" ADD CONSTRAINT "date_fk_purged_by" FOREIGN KEY ("purged_by") + REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "date" ADD CONSTRAINT "date_fk_record_id" FOREIGN KEY ("record_id") + REFERENCES "record" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "daterange" ADD CONSTRAINT "daterange_fk_layout_id" FOREIGN KEY ("layout_id") + REFERENCES "layout" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "daterange" ADD CONSTRAINT "daterange_fk_purged_by" FOREIGN KEY ("purged_by") + REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "daterange" ADD CONSTRAINT "daterange_fk_record_id" FOREIGN KEY ("record_id") + REFERENCES "record" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "department" ADD CONSTRAINT "department_fk_site_id" FOREIGN KEY ("site_id") + REFERENCES "site" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "display_field" ADD CONSTRAINT "display_field_fk_display_field_id" FOREIGN KEY ("display_field_id") + REFERENCES "layout" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "display_field" ADD CONSTRAINT "display_field_fk_layout_id" FOREIGN KEY ("layout_id") + REFERENCES "layout" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "enum" ADD CONSTRAINT "enum_fk_layout_id" FOREIGN KEY ("layout_id") + REFERENCES "layout" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "enum" ADD CONSTRAINT "enum_fk_purged_by" FOREIGN KEY ("purged_by") + REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "enum" ADD CONSTRAINT "enum_fk_record_id" FOREIGN KEY ("record_id") + REFERENCES "record" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "enum" ADD CONSTRAINT "enum_fk_value" FOREIGN KEY ("value") + REFERENCES "enumval" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "enumval" ADD CONSTRAINT "enumval_fk_layout_id" FOREIGN KEY ("layout_id") + REFERENCES "layout" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "enumval" ADD CONSTRAINT "enumval_fk_parent" FOREIGN KEY ("parent") + REFERENCES "enumval" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "export" ADD CONSTRAINT "export_fk_site_id" FOREIGN KEY ("site_id") + REFERENCES "site" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "export" ADD CONSTRAINT "export_fk_user_id" FOREIGN KEY ("user_id") + REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "file" ADD CONSTRAINT "file_fk_layout_id" FOREIGN KEY ("layout_id") + REFERENCES "layout" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "file" ADD CONSTRAINT "file_fk_purged_by" FOREIGN KEY ("purged_by") + REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "file" ADD CONSTRAINT "file_fk_record_id" FOREIGN KEY ("record_id") + REFERENCES "record" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "file" ADD CONSTRAINT "file_fk_value" FOREIGN KEY ("value") + REFERENCES "fileval" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "file_option" ADD CONSTRAINT "file_option_fk_layout_id" FOREIGN KEY ("layout_id") + REFERENCES "layout" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "fileval" ADD CONSTRAINT "fileval_fk_edit_user_id" FOREIGN KEY ("edit_user_id") + REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "filter" ADD CONSTRAINT "filter_fk_layout_id" FOREIGN KEY ("layout_id") + REFERENCES "layout" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "filter" ADD CONSTRAINT "filter_fk_view_id" FOREIGN KEY ("view_id") + REFERENCES "view" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "filtered_value" ADD CONSTRAINT "filtered_value_fk_current_id" FOREIGN KEY ("current_id") + REFERENCES "current" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "filtered_value" ADD CONSTRAINT "filtered_value_fk_layout_id" FOREIGN KEY ("layout_id") + REFERENCES "layout" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "filtered_value" ADD CONSTRAINT "filtered_value_fk_submission_id" FOREIGN KEY ("submission_id") + REFERENCES "submission" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "graph" ADD CONSTRAINT "graph_fk_group_id" FOREIGN KEY ("group_id") + REFERENCES "group" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "graph" ADD CONSTRAINT "graph_fk_group_by" FOREIGN KEY ("group_by") + REFERENCES "layout" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "graph" ADD CONSTRAINT "graph_fk_instance_id" FOREIGN KEY ("instance_id") + REFERENCES "instance" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "graph" ADD CONSTRAINT "graph_fk_metric_group" FOREIGN KEY ("metric_group") + REFERENCES "metric_group" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "graph" ADD CONSTRAINT "graph_fk_user_id" FOREIGN KEY ("user_id") + REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "graph" ADD CONSTRAINT "graph_fk_x_axis" FOREIGN KEY ("x_axis") + REFERENCES "layout" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "graph" ADD CONSTRAINT "graph_fk_x_axis_link" FOREIGN KEY ("x_axis_link") + REFERENCES "layout" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "graph" ADD CONSTRAINT "graph_fk_y_axis" FOREIGN KEY ("y_axis") + REFERENCES "layout" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "graph" ADD CONSTRAINT "graph_fk_y_axis_link" FOREIGN KEY ("y_axis_link") + REFERENCES "layout" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "group" ADD CONSTRAINT "group_fk_site_id" FOREIGN KEY ("site_id") + REFERENCES "site" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "import" ADD CONSTRAINT "import_fk_instance_id" FOREIGN KEY ("instance_id") + REFERENCES "instance" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "import" ADD CONSTRAINT "import_fk_site_id" FOREIGN KEY ("site_id") + REFERENCES "site" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "import" ADD CONSTRAINT "import_fk_user_id" FOREIGN KEY ("user_id") + REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "import_row" ADD CONSTRAINT "import_row_fk_import_id" FOREIGN KEY ("import_id") + REFERENCES "import" ("id") ON DELETE CASCADE ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "instance" ADD CONSTRAINT "instance_fk_api_index_layout_id" FOREIGN KEY ("api_index_layout_id") + REFERENCES "layout" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "instance" ADD CONSTRAINT "instance_fk_default_view_limit_extra_id" FOREIGN KEY ("default_view_limit_extra_id") + REFERENCES "view" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "instance" ADD CONSTRAINT "instance_fk_site_id" FOREIGN KEY ("site_id") + REFERENCES "site" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "instance" ADD CONSTRAINT "instance_fk_sort_layout_id" FOREIGN KEY ("sort_layout_id") + REFERENCES "layout" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "instance" ADD CONSTRAINT "instance_fk_view_limit_id" FOREIGN KEY ("view_limit_id") + REFERENCES "view" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "instance_group" ADD CONSTRAINT "instance_group_fk_group_id" FOREIGN KEY ("group_id") + REFERENCES "group" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "instance_group" ADD CONSTRAINT "instance_group_fk_instance_id" FOREIGN KEY ("instance_id") + REFERENCES "instance" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "instance_rag" ADD CONSTRAINT "instance_rag_fk_instance_id" FOREIGN KEY ("instance_id") + REFERENCES "instance" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "intgr" ADD CONSTRAINT "intgr_fk_layout_id" FOREIGN KEY ("layout_id") + REFERENCES "layout" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "intgr" ADD CONSTRAINT "intgr_fk_purged_by" FOREIGN KEY ("purged_by") + REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "intgr" ADD CONSTRAINT "intgr_fk_record_id" FOREIGN KEY ("record_id") + REFERENCES "record" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "layout" ADD CONSTRAINT "layout_fk_display_field" FOREIGN KEY ("display_field") + REFERENCES "layout" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "layout" ADD CONSTRAINT "layout_fk_instance_id" FOREIGN KEY ("instance_id") + REFERENCES "instance" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "layout" ADD CONSTRAINT "layout_fk_link_parent" FOREIGN KEY ("link_parent") + REFERENCES "layout" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "layout" ADD CONSTRAINT "layout_fk_related_field" FOREIGN KEY ("related_field") + REFERENCES "layout" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "layout" ADD CONSTRAINT "layout_fk_topic_id" FOREIGN KEY ("topic_id") + REFERENCES "topic" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "layout_depend" ADD CONSTRAINT "layout_depend_fk_depends_on" FOREIGN KEY ("depends_on") + REFERENCES "layout" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "layout_depend" ADD CONSTRAINT "layout_depend_fk_layout_id" FOREIGN KEY ("layout_id") + REFERENCES "layout" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "layout_group" ADD CONSTRAINT "layout_group_fk_group_id" FOREIGN KEY ("group_id") + REFERENCES "group" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "layout_group" ADD CONSTRAINT "layout_group_fk_layout_id" FOREIGN KEY ("layout_id") + REFERENCES "layout" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "metric" ADD CONSTRAINT "metric_fk_metric_group" FOREIGN KEY ("metric_group") + REFERENCES "metric_group" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "metric_group" ADD CONSTRAINT "metric_group_fk_instance_id" FOREIGN KEY ("instance_id") + REFERENCES "instance" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "oauthtoken" ADD CONSTRAINT "oauthtoken_fk_oauthclient_id" FOREIGN KEY ("oauthclient_id") + REFERENCES "oauthclient" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "oauthtoken" ADD CONSTRAINT "oauthtoken_fk_user_id" FOREIGN KEY ("user_id") + REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "organisation" ADD CONSTRAINT "organisation_fk_site_id" FOREIGN KEY ("site_id") + REFERENCES "site" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "person" ADD CONSTRAINT "person_fk_layout_id" FOREIGN KEY ("layout_id") + REFERENCES "layout" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "person" ADD CONSTRAINT "person_fk_purged_by" FOREIGN KEY ("purged_by") + REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "person" ADD CONSTRAINT "person_fk_record_id" FOREIGN KEY ("record_id") + REFERENCES "record" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "person" ADD CONSTRAINT "person_fk_value" FOREIGN KEY ("value") + REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "rag" ADD CONSTRAINT "rag_fk_layout_id" FOREIGN KEY ("layout_id") + REFERENCES "layout" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "ragval" ADD CONSTRAINT "ragval_fk_layout_id" FOREIGN KEY ("layout_id") + REFERENCES "layout" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "ragval" ADD CONSTRAINT "ragval_fk_purged_by" FOREIGN KEY ("purged_by") + REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "ragval" ADD CONSTRAINT "ragval_fk_record_id" FOREIGN KEY ("record_id") + REFERENCES "record" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "record" ADD CONSTRAINT "record_fk_approvedby" FOREIGN KEY ("approvedby") + REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "record" ADD CONSTRAINT "record_fk_createdby" FOREIGN KEY ("createdby") + REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "record" ADD CONSTRAINT "record_fk_current_id" FOREIGN KEY ("current_id") + REFERENCES "current" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "record" ADD CONSTRAINT "record_fk_record_id" FOREIGN KEY ("record_id") + REFERENCES "record" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "report" ADD CONSTRAINT "report_fk_createdby" FOREIGN KEY ("createdby") + REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "report" ADD CONSTRAINT "report_fk_instance_id" FOREIGN KEY ("instance_id") + REFERENCES "instance" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "report" ADD CONSTRAINT "report_fk_user_id" FOREIGN KEY ("user_id") + REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "report_group" ADD CONSTRAINT "report_group_fk_group_id" FOREIGN KEY ("group_id") + REFERENCES "group" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "report_group" ADD CONSTRAINT "report_group_fk_report_id" FOREIGN KEY ("report_id") + REFERENCES "report" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "report_layout" ADD CONSTRAINT "report_layout_fk_layout_id" FOREIGN KEY ("layout_id") + REFERENCES "layout" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "report_layout" ADD CONSTRAINT "report_layout_fk_report_id" FOREIGN KEY ("report_id") + REFERENCES "report" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "sort" ADD CONSTRAINT "sort_fk_layout_id" FOREIGN KEY ("layout_id") + REFERENCES "layout" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "sort" ADD CONSTRAINT "sort_fk_parent_id" FOREIGN KEY ("parent_id") + REFERENCES "layout" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "sort" ADD CONSTRAINT "sort_fk_view_id" FOREIGN KEY ("view_id") + REFERENCES "view" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "string" ADD CONSTRAINT "string_fk_layout_id" FOREIGN KEY ("layout_id") + REFERENCES "layout" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "string" ADD CONSTRAINT "string_fk_purged_by" FOREIGN KEY ("purged_by") + REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "string" ADD CONSTRAINT "string_fk_record_id" FOREIGN KEY ("record_id") + REFERENCES "record" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "team" ADD CONSTRAINT "team_fk_site_id" FOREIGN KEY ("site_id") + REFERENCES "site" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "title" ADD CONSTRAINT "title_fk_site_id" FOREIGN KEY ("site_id") + REFERENCES "site" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "topic" ADD CONSTRAINT "topic_fk_instance_id" FOREIGN KEY ("instance_id") + REFERENCES "instance" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "topic" ADD CONSTRAINT "topic_fk_prevent_edit_topic_id" FOREIGN KEY ("prevent_edit_topic_id") + REFERENCES "topic" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "user" ADD CONSTRAINT "user_fk_department_id" FOREIGN KEY ("department_id") + REFERENCES "department" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "user" ADD CONSTRAINT "user_fk_lastrecord" FOREIGN KEY ("lastrecord") + REFERENCES "record" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "user" ADD CONSTRAINT "user_fk_lastview" FOREIGN KEY ("lastview") + REFERENCES "view" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "user" ADD CONSTRAINT "user_fk_limit_to_view" FOREIGN KEY ("limit_to_view") + REFERENCES "view" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "user" ADD CONSTRAINT "user_fk_organisation" FOREIGN KEY ("organisation") + REFERENCES "organisation" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "user" ADD CONSTRAINT "user_fk_site_id" FOREIGN KEY ("site_id") + REFERENCES "site" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "user" ADD CONSTRAINT "user_fk_team_id" FOREIGN KEY ("team_id") + REFERENCES "team" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "user" ADD CONSTRAINT "user_fk_title" FOREIGN KEY ("title") + REFERENCES "title" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "user_graph" ADD CONSTRAINT "user_graph_fk_graph_id" FOREIGN KEY ("graph_id") + REFERENCES "graph" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "user_graph" ADD CONSTRAINT "user_graph_fk_user_id" FOREIGN KEY ("user_id") + REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "user_group" ADD CONSTRAINT "user_group_fk_group_id" FOREIGN KEY ("group_id") + REFERENCES "group" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "user_group" ADD CONSTRAINT "user_group_fk_user_id" FOREIGN KEY ("user_id") + REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "user_lastrecord" ADD CONSTRAINT "user_lastrecord_fk_instance_id" FOREIGN KEY ("instance_id") + REFERENCES "instance" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "user_lastrecord" ADD CONSTRAINT "user_lastrecord_fk_record_id" FOREIGN KEY ("record_id") + REFERENCES "record" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "user_lastrecord" ADD CONSTRAINT "user_lastrecord_fk_user_id" FOREIGN KEY ("user_id") + REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "user_permission" ADD CONSTRAINT "user_permission_fk_permission_id" FOREIGN KEY ("permission_id") + REFERENCES "permission" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "user_permission" ADD CONSTRAINT "user_permission_fk_user_id" FOREIGN KEY ("user_id") + REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "view" ADD CONSTRAINT "view_fk_createdby" FOREIGN KEY ("createdby") + REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "view" ADD CONSTRAINT "view_fk_group_id" FOREIGN KEY ("group_id") + REFERENCES "group" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "view" ADD CONSTRAINT "view_fk_instance_id" FOREIGN KEY ("instance_id") + REFERENCES "instance" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "view" ADD CONSTRAINT "view_fk_user_id" FOREIGN KEY ("user_id") + REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "view_group" ADD CONSTRAINT "view_group_fk_layout_id" FOREIGN KEY ("layout_id") + REFERENCES "layout" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "view_group" ADD CONSTRAINT "view_group_fk_parent_id" FOREIGN KEY ("parent_id") + REFERENCES "layout" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "view_group" ADD CONSTRAINT "view_group_fk_view_id" FOREIGN KEY ("view_id") + REFERENCES "view" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "view_layout" ADD CONSTRAINT "view_layout_fk_layout_id" FOREIGN KEY ("layout_id") + REFERENCES "layout" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "view_layout" ADD CONSTRAINT "view_layout_fk_view_id" FOREIGN KEY ("view_id") + REFERENCES "view" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "view_limit" ADD CONSTRAINT "view_limit_fk_user_id" FOREIGN KEY ("user_id") + REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "view_limit" ADD CONSTRAINT "view_limit_fk_view_id" FOREIGN KEY ("view_id") + REFERENCES "view" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "widget" ADD CONSTRAINT "widget_fk_dashboard_id" FOREIGN KEY ("dashboard_id") + REFERENCES "dashboard" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "widget" ADD CONSTRAINT "widget_fk_graph_id" FOREIGN KEY ("graph_id") + REFERENCES "graph" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE "widget" ADD CONSTRAINT "widget_fk_view_id" FOREIGN KEY ("view_id") + REFERENCES "view" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; diff --git a/share/migrations/PostgreSQL/downgrade/110-109/001-auto.sql b/share/migrations/PostgreSQL/downgrade/110-109/001-auto.sql new file mode 100644 index 000000000..8b8f7272a --- /dev/null +++ b/share/migrations/PostgreSQL/downgrade/110-109/001-auto.sql @@ -0,0 +1,27 @@ +-- Convert schema '/home/abeverley/git/GADS/bin/../share/migrations/_source/deploy/110/001-auto.yml' to '/home/abeverley/git/GADS/bin/../share/migrations/_source/deploy/109/001-auto.yml':; + +; +BEGIN; + +; +ALTER TABLE current DROP CONSTRAINT current_fk_current_version_id; + +; +DROP INDEX current_idx_current_version_id; + +; +ALTER TABLE current DROP COLUMN current_version_id; + +; +ALTER TABLE graph DROP CONSTRAINT graph_fk_y_axis_link; + +; +DROP INDEX graph_idx_y_axis_link; + +; +ALTER TABLE graph DROP COLUMN y_axis_link; + +; + +COMMIT; + diff --git a/share/migrations/PostgreSQL/upgrade/109-110/001-auto.sql b/share/migrations/PostgreSQL/upgrade/109-110/001-auto.sql new file mode 100644 index 000000000..420c4e89a --- /dev/null +++ b/share/migrations/PostgreSQL/upgrade/109-110/001-auto.sql @@ -0,0 +1,29 @@ +-- Convert schema '/home/abeverley/git/GADS/bin/../share/migrations/_source/deploy/109/001-auto.yml' to '/home/abeverley/git/GADS/bin/../share/migrations/_source/deploy/110/001-auto.yml':; + +; +BEGIN; + +; +ALTER TABLE current ADD COLUMN current_version_id bigint; + +; +CREATE INDEX current_idx_current_version_id on current (current_version_id); + +; +ALTER TABLE current ADD CONSTRAINT current_fk_current_version_id FOREIGN KEY (current_version_id) + REFERENCES record (id) ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; +ALTER TABLE graph ADD COLUMN y_axis_link integer; + +; +CREATE INDEX graph_idx_y_axis_link on graph (y_axis_link); + +; +ALTER TABLE graph ADD CONSTRAINT graph_fk_y_axis_link FOREIGN KEY (y_axis_link) + REFERENCES layout (id) ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE; + +; + +COMMIT; + diff --git a/share/migrations/_common/upgrade/109-110/002-populate-current-versions.pl b/share/migrations/_common/upgrade/109-110/002-populate-current-versions.pl new file mode 100644 index 000000000..13c64dc5c --- /dev/null +++ b/share/migrations/_common/upgrade/109-110/002-populate-current-versions.pl @@ -0,0 +1,73 @@ +use strict; +use warnings; + +use feature 'say'; + +use DBIx::Class::Migration::RunScript; +use Log::Report; + +migrate { + my $schema = shift->schema; + # dbic_connect_attrs is ignored, so quote_names needs to be forced + $schema->storage->connect_info( + [sub {$schema->storage->dbh}, { quote_names => 1 }] + ); + + my $rec_class = $schema->class('Record'); + $rec_class->might_have( + record_later => 'Record', + sub { + my $args = shift; + return { + "$args->{foreign_alias}.current_id" => { -ident => "$args->{self_alias}.current_id" }, + -or => [ + { + "$args->{foreign_alias}.created" => { '>' => \"$args->{self_alias}.created" }, + }, + { + "$args->{foreign_alias}.created" => { '=' => \"$args->{self_alias}.created" }, + "$args->{foreign_alias}.id" => { '>' => \"$args->{self_alias}.id" }, + }, + ], + "$args->{foreign_alias}.approval" => 0, + }; + } + ); + + $schema->unregister_source('Record'); + $schema->register_class(Record => $rec_class); + + my $rs = $schema->resultset('Current')->search({ + 'records.approval' => 0, + 'record_later.current_id' => undef, + },{ + page => 1, + rows => 100, + order_by => 'me.id', + prefetch => { + records => 'record_later', + }, + }); + + my $pager = $rs->pager; + my $page = $pager->current_page; + my $last_page = $pager->last_page; + while ($page) + { + $rs = $rs->search( {}, { page => $page } ); + say "Writing record versions $page of $last_page"; + $pager->current_page($page); + foreach my $current ($rs->all) + { + my @records = $current->records; # Should only be one for latest version + @records == 1 + or error __x"Unexpected number of records for {count} for {current_id}", + count => scalar @records, current_id => $current->id; + my $latest = $records[0]->id; + $current->update({ + current_version_id => $latest, + }); + } + $page = $pager->next_page; + } +}; diff --git a/share/migrations/_source/deploy/110/001-auto-__VERSION.yml b/share/migrations/_source/deploy/110/001-auto-__VERSION.yml new file mode 100644 index 000000000..abd02b2a2 --- /dev/null +++ b/share/migrations/_source/deploy/110/001-auto-__VERSION.yml @@ -0,0 +1,92 @@ +--- +schema: + procedures: {} + tables: + dbix_class_deploymenthandler_versions: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - version + match_type: '' + name: dbix_class_deploymenthandler_versions_version + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + fields: + ddl: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: ddl + order: 3 + size: + - 0 + id: + data_type: int + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + upgrade_sql: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: upgrade_sql + order: 4 + size: + - 0 + version: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: version + order: 2 + size: + - 50 + indices: [] + name: dbix_class_deploymenthandler_versions + options: [] + order: 1 + triggers: {} + views: {} +translator: + add_drop_table: 0 + filename: ~ + no_comments: 0 + parser_args: + sources: + - __VERSION + parser_type: SQL::Translator::Parser::DBIx::Class + producer_args: + mysql_version: 5.7 + producer_type: SQL::Translator::Producer::YAML + show_warnings: 0 + trace: 0 + version: 1.63 diff --git a/share/migrations/_source/deploy/110/001-auto.yml b/share/migrations/_source/deploy/110/001-auto.yml new file mode 100644 index 000000000..5bb3aa596 --- /dev/null +++ b/share/migrations/_source/deploy/110/001-auto.yml @@ -0,0 +1,9765 @@ +--- +schema: + procedures: {} + tables: + alert: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - user_id + match_type: '' + name: alert_fk_user_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: user + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - view_id + match_type: '' + name: alert_fk_view_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: view + type: FOREIGN KEY + fields: + frequency: + data_type: integer + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: frequency + order: 4 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + user_id: + data_type: bigint + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: user_id + order: 3 + size: + - 0 + view_id: + data_type: bigint + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: view_id + order: 2 + size: + - 0 + indices: + - fields: + - user_id + name: alert_idx_user_id + options: [] + type: NORMAL + - fields: + - view_id + name: alert_idx_view_id + options: [] + type: NORMAL + name: alert + options: [] + order: 1 + alert_cache: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - current_id + match_type: '' + name: alert_cache_fk_current_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: current + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - layout_id + match_type: '' + name: alert_cache_fk_layout_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: layout + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - user_id + match_type: '' + name: alert_cache_fk_user_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: user + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - view_id + match_type: '' + name: alert_cache_fk_view_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: view + type: FOREIGN KEY + fields: + current_id: + data_type: bigint + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: current_id + order: 4 + size: + - 0 + id: + data_type: bigint + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + layout_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: layout_id + order: 2 + size: + - 0 + user_id: + data_type: bigint + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: user_id + order: 5 + size: + - 0 + view_id: + data_type: bigint + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: view_id + order: 3 + size: + - 0 + indices: + - fields: + - current_id + name: alert_cache_idx_current_id + options: [] + type: NORMAL + - fields: + - layout_id + name: alert_cache_idx_layout_id + options: [] + type: NORMAL + - fields: + - user_id + name: alert_cache_idx_user_id + options: [] + type: NORMAL + - fields: + - view_id + name: alert_cache_idx_view_id + options: [] + type: NORMAL + name: alert_cache + options: [] + order: 2 + alert_column: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - instance_id + match_type: '' + name: alert_column_fk_instance_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: instance + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - layout_id + match_type: '' + name: alert_column_fk_layout_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: layout + type: FOREIGN KEY + fields: + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + instance_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: instance_id + order: 3 + size: + - 0 + layout_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: layout_id + order: 2 + size: + - 0 + indices: + - fields: + - instance_id + name: alert_column_idx_instance_id + options: [] + type: NORMAL + - fields: + - layout_id + name: alert_column_idx_layout_id + options: [] + type: NORMAL + name: alert_column + options: [] + order: 3 + alert_send: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - layout_id + - alert_id + - current_id + - status + match_type: '' + name: alert_send_all + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + - deferrable: 1 + expression: '' + fields: + - alert_id + match_type: '' + name: alert_send_fk_alert_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: alert + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - current_id + match_type: '' + name: alert_send_fk_current_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: current + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - layout_id + match_type: '' + name: alert_send_fk_layout_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: layout + type: FOREIGN KEY + fields: + alert_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: alert_id + order: 3 + size: + - 0 + current_id: + data_type: bigint + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: current_id + order: 4 + size: + - 0 + id: + data_type: bigint + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + layout_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 1 + name: layout_id + order: 2 + size: + - 0 + status: + data_type: char + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 1 + name: status + order: 5 + size: + - 7 + indices: + - fields: + - alert_id + name: alert_send_idx_alert_id + options: [] + type: NORMAL + - fields: + - current_id + name: alert_send_idx_current_id + options: [] + type: NORMAL + - fields: + - layout_id + name: alert_send_idx_layout_id + options: [] + type: NORMAL + name: alert_send + options: [] + order: 4 + audit: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - instance_id + match_type: '' + name: audit_fk_instance_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: instance + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - site_id + match_type: '' + name: audit_fk_site_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: site + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - user_id + match_type: '' + name: audit_fk_user_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: user + type: FOREIGN KEY + fields: + datetime: + data_type: datetime + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: datetime + order: 5 + size: + - 0 + description: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: description + order: 8 + size: + - 0 + id: + data_type: bigint + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + instance_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: instance_id + order: 9 + size: + - 0 + method: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: method + order: 6 + size: + - 45 + site_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: site_id + order: 2 + size: + - 0 + type: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: type + order: 4 + size: + - 45 + url: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: url + order: 7 + size: + - 0 + user_id: + data_type: bigint + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: user_id + order: 3 + size: + - 0 + indices: + - fields: + - instance_id + name: audit_idx_instance_id + options: [] + type: NORMAL + - fields: + - site_id + name: audit_idx_site_id + options: [] + type: NORMAL + - fields: + - user_id + name: audit_idx_user_id + options: [] + type: NORMAL + - fields: + - datetime + name: audit_idx_datetime + options: [] + type: NORMAL + - fields: + - user_id + - instance_id + - datetime + name: audit_idx_user_instance_datetime + options: [] + type: NORMAL + name: audit + options: [] + order: 5 + authentication: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - site_id + match_type: '' + name: authentication_fk_site_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: site + type: FOREIGN KEY + fields: + enabled: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: enabled + order: 8 + size: + - 0 + error_messages: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: error_messages + order: 9 + size: + - 0 + id: + data_type: bigint + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + name: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: name + order: 4 + size: + - 0 + saml2_firstname: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: saml2_firstname + order: 6 + size: + - 0 + saml2_surname: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: saml2_surname + order: 7 + size: + - 0 + site_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: site_id + order: 2 + size: + - 0 + type: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: type + order: 3 + size: + - 32 + xml: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: xml + order: 5 + size: + - 0 + indices: + - fields: + - site_id + name: authentication_idx_site_id + options: [] + type: NORMAL + name: authentication + options: [] + order: 6 + calc: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - layout_id + match_type: '' + name: calc_fk_layout_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: layout + type: FOREIGN KEY + fields: + calc: + data_type: mediumtext + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: calc + order: 3 + size: + - 0 + code: + data_type: mediumtext + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: code + order: 4 + size: + - 0 + decimal_places: + data_type: smallint + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: decimal_places + order: 6 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + layout_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: layout_id + order: 2 + size: + - 0 + return_format: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: return_format + order: 5 + size: + - 45 + indices: + - fields: + - layout_id + name: calc_idx_layout_id + options: [] + type: NORMAL + name: calc + options: [] + order: 7 + calc_unique: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - layout_id + - value_date + match_type: '' + name: calc_unique_ux_layout_date + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + - deferrable: 1 + expression: '' + fields: + - layout_id + - value_date_from + - value_date_to + match_type: '' + name: calc_unique_ux_layout_daterange + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + - deferrable: 1 + expression: '' + fields: + - layout_id + - value_int + match_type: '' + name: calc_unique_ux_layout_int + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + - deferrable: 1 + expression: '' + fields: + - layout_id + - value_numeric + match_type: '' + name: calc_unique_ux_layout_numeric + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + - deferrable: 1 + expression: '' + fields: + - layout_id + - value_text + match_type: '' + name: calc_unique_ux_layout_text + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + - deferrable: 1 + expression: '' + fields: + - layout_id + match_type: '' + name: calc_unique_fk_layout_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: layout + type: FOREIGN KEY + fields: + id: + data_type: bigint + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + layout_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: layout_id + order: 2 + size: + - 0 + value_date: + data_type: date + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 1 + name: value_date + order: 5 + size: + - 0 + value_date_from: + data_type: datetime + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 1 + name: value_date_from + order: 7 + size: + - 0 + value_date_to: + data_type: datetime + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 1 + name: value_date_to + order: 8 + size: + - 0 + value_int: + data_type: bigint + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 1 + name: value_int + order: 4 + size: + - 0 + value_numeric: + data_type: decimal + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 1 + name: value_numeric + order: 6 + size: + - 20 + - 5 + value_text: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 1 + name: value_text + order: 3 + size: + - 0 + indices: + - fields: + - layout_id + name: calc_unique_idx_layout_id + options: [] + type: NORMAL + name: calc_unique + options: [] + order: 8 + calcval: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - layout_id + match_type: '' + name: calcval_fk_layout_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: layout + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - purged_by + match_type: '' + name: calcval_fk_purged_by + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: user + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - record_id + match_type: '' + name: calcval_fk_record_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: record + type: FOREIGN KEY + fields: + id: + data_type: bigint + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + layout_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: layout_id + order: 3 + size: + - 0 + purged_by: + data_type: bigint + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: purged_by + order: 10 + size: + - 0 + purged_on: + data_type: datetime + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: purged_on + order: 11 + size: + - 0 + record_id: + data_type: bigint + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: record_id + order: 2 + size: + - 0 + value_date: + data_type: date + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: value_date + order: 6 + size: + - 0 + value_date_from: + data_type: datetime + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: value_date_from + order: 8 + size: + - 0 + value_date_to: + data_type: datetime + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: value_date_to + order: 9 + size: + - 0 + value_int: + data_type: bigint + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: value_int + order: 5 + size: + - 0 + value_numeric: + data_type: decimal + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: value_numeric + order: 7 + size: + - 20 + - 5 + value_text: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: value_text + order: 4 + size: + - 0 + indices: + - fields: + - layout_id + name: calcval_idx_layout_id + options: [] + type: NORMAL + - fields: + - purged_by + name: calcval_idx_purged_by + options: [] + type: NORMAL + - fields: + - record_id + name: calcval_idx_record_id + options: [] + type: NORMAL + - fields: + - name: value_text + prefix_length: 64 + name: calcval_idx_value_text + options: [] + type: NORMAL + - fields: + - value_numeric + name: calcval_idx_value_numeric + options: [] + type: NORMAL + - fields: + - value_int + name: calcval_idx_value_int + options: [] + type: NORMAL + - fields: + - value_date + name: calcval_idx_value_date + options: [] + type: NORMAL + name: calcval + options: [] + order: 9 + current: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - instance_id + - serial + match_type: '' + name: current_ux_instance_serial + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + - deferrable: 1 + expression: '' + fields: + - current_version_id + match_type: '' + name: current_fk_current_version_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: record + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - deletedby + match_type: '' + name: current_fk_deletedby + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: user + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - draftuser_id + match_type: '' + name: current_fk_draftuser_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: user + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - instance_id + match_type: '' + name: current_fk_instance_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: instance + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - linked_id + match_type: '' + name: current_fk_linked_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: current + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - parent_id + match_type: '' + name: current_fk_parent_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: current + type: FOREIGN KEY + fields: + current_version_id: + data_type: bigint + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: current_version_id + order: 3 + size: + - 0 + deleted: + data_type: datetime + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: deleted + order: 7 + size: + - 0 + deletedby: + data_type: bigint + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: deletedby + order: 8 + size: + - 0 + draftuser_id: + data_type: bigint + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: draftuser_id + order: 9 + size: + - 0 + id: + data_type: bigint + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + instance_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 1 + name: instance_id + order: 5 + size: + - 0 + linked_id: + data_type: bigint + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: linked_id + order: 6 + size: + - 0 + parent_id: + data_type: bigint + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: parent_id + order: 4 + size: + - 0 + serial: + data_type: bigint + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 1 + name: serial + order: 2 + size: + - 0 + indices: + - fields: + - current_version_id + name: current_idx_current_version_id + options: [] + type: NORMAL + - fields: + - deletedby + name: current_idx_deletedby + options: [] + type: NORMAL + - fields: + - draftuser_id + name: current_idx_draftuser_id + options: [] + type: NORMAL + - fields: + - instance_id + name: current_idx_instance_id + options: [] + type: NORMAL + - fields: + - linked_id + name: current_idx_linked_id + options: [] + type: NORMAL + - fields: + - parent_id + name: current_idx_parent_id + options: [] + type: NORMAL + name: current + options: [] + order: 10 + curval: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - layout_id + match_type: '' + name: curval_fk_layout_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: layout + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - purged_by + match_type: '' + name: curval_fk_purged_by + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: user + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - record_id + match_type: '' + name: curval_fk_record_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: record + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - value + match_type: '' + name: curval_fk_value + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: current + type: FOREIGN KEY + fields: + child_unique: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: child_unique + order: 4 + size: + - 0 + id: + data_type: bigint + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + layout_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: layout_id + order: 3 + size: + - 0 + purged_by: + data_type: bigint + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: purged_by + order: 6 + size: + - 0 + purged_on: + data_type: datetime + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: purged_on + order: 7 + size: + - 0 + record_id: + data_type: bigint + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: record_id + order: 2 + size: + - 0 + value: + data_type: bigint + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: value + order: 5 + size: + - 0 + indices: + - fields: + - layout_id + name: curval_idx_layout_id + options: [] + type: NORMAL + - fields: + - purged_by + name: curval_idx_purged_by + options: [] + type: NORMAL + - fields: + - record_id + name: curval_idx_record_id + options: [] + type: NORMAL + - fields: + - value + name: curval_idx_value + options: [] + type: NORMAL + name: curval + options: [] + order: 11 + curval_fields: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - child_id + match_type: '' + name: curval_fields_fk_child_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: layout + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - parent_id + match_type: '' + name: curval_fields_fk_parent_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: layout + type: FOREIGN KEY + fields: + child_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: child_id + order: 3 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + parent_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: parent_id + order: 2 + size: + - 0 + indices: + - fields: + - child_id + name: curval_fields_idx_child_id + options: [] + type: NORMAL + - fields: + - parent_id + name: curval_fields_idx_parent_id + options: [] + type: NORMAL + name: curval_fields + options: [] + order: 12 + dashboard: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - instance_id + match_type: '' + name: dashboard_fk_instance_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: instance + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - site_id + match_type: '' + name: dashboard_fk_site_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: site + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - user_id + match_type: '' + name: dashboard_fk_user_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: user + type: FOREIGN KEY + fields: + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + instance_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: instance_id + order: 3 + size: + - 0 + site_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: site_id + order: 2 + size: + - 0 + user_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: user_id + order: 4 + size: + - 0 + indices: + - fields: + - instance_id + name: dashboard_idx_instance_id + options: [] + type: NORMAL + - fields: + - site_id + name: dashboard_idx_site_id + options: [] + type: NORMAL + - fields: + - user_id + name: dashboard_idx_user_id + options: [] + type: NORMAL + name: dashboard + options: [] + order: 13 + date: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - layout_id + match_type: '' + name: date_fk_layout_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: layout + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - purged_by + match_type: '' + name: date_fk_purged_by + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: user + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - record_id + match_type: '' + name: date_fk_record_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: record + type: FOREIGN KEY + fields: + child_unique: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: child_unique + order: 4 + size: + - 0 + id: + data_type: bigint + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + layout_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: layout_id + order: 3 + size: + - 0 + purged_by: + data_type: bigint + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: purged_by + order: 6 + size: + - 0 + purged_on: + data_type: timestamp + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: purged_on + order: 7 + size: + - 0 + record_id: + data_type: bigint + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: record_id + order: 2 + size: + - 0 + value: + data_type: date + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: value + order: 5 + size: + - 0 + indices: + - fields: + - layout_id + name: date_idx_layout_id + options: [] + type: NORMAL + - fields: + - purged_by + name: date_idx_purged_by + options: [] + type: NORMAL + - fields: + - record_id + name: date_idx_record_id + options: [] + type: NORMAL + - fields: + - value + name: date_idx_value + options: [] + type: NORMAL + name: date + options: [] + order: 14 + daterange: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - layout_id + match_type: '' + name: daterange_fk_layout_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: layout + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - purged_by + match_type: '' + name: daterange_fk_purged_by + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: user + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - record_id + match_type: '' + name: daterange_fk_record_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: record + type: FOREIGN KEY + fields: + child_unique: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: child_unique + order: 6 + size: + - 0 + from: + data_type: date + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: from + order: 4 + size: + - 0 + id: + data_type: bigint + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + layout_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: layout_id + order: 3 + size: + - 0 + purged_by: + data_type: bigint + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: purged_by + order: 8 + size: + - 0 + purged_on: + data_type: datetime + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: purged_on + order: 9 + size: + - 0 + record_id: + data_type: bigint + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: record_id + order: 2 + size: + - 0 + to: + data_type: date + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: to + order: 5 + size: + - 0 + value: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: value + order: 7 + size: + - 45 + indices: + - fields: + - layout_id + name: daterange_idx_layout_id + options: [] + type: NORMAL + - fields: + - purged_by + name: daterange_idx_purged_by + options: [] + type: NORMAL + - fields: + - record_id + name: daterange_idx_record_id + options: [] + type: NORMAL + - fields: + - from + name: daterange_idx_from + options: [] + type: NORMAL + - fields: + - to + name: daterange_idx_to + options: [] + type: NORMAL + - fields: + - value + name: daterange_idx_value + options: [] + type: NORMAL + name: daterange + options: [] + order: 15 + department: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - site_id + match_type: '' + name: department_fk_site_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: site + type: FOREIGN KEY + fields: + deleted: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: deleted + order: 4 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + name: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: name + order: 2 + size: + - 128 + site_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: site_id + order: 3 + size: + - 0 + indices: + - fields: + - site_id + name: department_idx_site_id + options: [] + type: NORMAL + name: department + options: [] + order: 16 + display_field: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - display_field_id + match_type: '' + name: display_field_fk_display_field_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: layout + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - layout_id + match_type: '' + name: display_field_fk_layout_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: layout + type: FOREIGN KEY + fields: + display_field_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: display_field_id + order: 3 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + layout_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: layout_id + order: 2 + size: + - 0 + operator: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: operator + order: 5 + size: + - 16 + regex: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: regex + order: 4 + size: + - 0 + indices: + - fields: + - display_field_id + name: display_field_idx_display_field_id + options: [] + type: NORMAL + - fields: + - layout_id + name: display_field_idx_layout_id + options: [] + type: NORMAL + name: display_field + options: [] + order: 17 + enum: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - layout_id + match_type: '' + name: enum_fk_layout_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: layout + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - purged_by + match_type: '' + name: enum_fk_purged_by + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: user + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - record_id + match_type: '' + name: enum_fk_record_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: record + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - value + match_type: '' + name: enum_fk_value + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: enumval + type: FOREIGN KEY + fields: + child_unique: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: child_unique + order: 4 + size: + - 0 + id: + data_type: bigint + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + layout_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: layout_id + order: 3 + size: + - 0 + purged_by: + data_type: bigint + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: purged_by + order: 6 + size: + - 0 + purged_on: + data_type: datetime + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: purged_on + order: 7 + size: + - 0 + record_id: + data_type: bigint + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: record_id + order: 2 + size: + - 0 + value: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: value + order: 5 + size: + - 0 + indices: + - fields: + - layout_id + name: enum_idx_layout_id + options: [] + type: NORMAL + - fields: + - purged_by + name: enum_idx_purged_by + options: [] + type: NORMAL + - fields: + - record_id + name: enum_idx_record_id + options: [] + type: NORMAL + - fields: + - value + name: enum_idx_value + options: [] + type: NORMAL + name: enum + options: [] + order: 18 + enumval: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - layout_id + match_type: '' + name: enumval_fk_layout_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: layout + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - parent + match_type: '' + name: enumval_fk_parent + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: enumval + type: FOREIGN KEY + fields: + deleted: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: deleted + order: 4 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + layout_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: layout_id + order: 3 + size: + - 0 + parent: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: parent + order: 5 + size: + - 0 + position: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: position + order: 6 + size: + - 0 + value: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: value + order: 2 + size: + - 0 + indices: + - fields: + - layout_id + name: enumval_idx_layout_id + options: [] + type: NORMAL + - fields: + - parent + name: enumval_idx_parent + options: [] + type: NORMAL + - fields: + - name: value + prefix_length: 64 + name: enumval_idx_value + options: [] + type: NORMAL + name: enumval + options: [] + order: 19 + export: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - site_id + match_type: '' + name: export_fk_site_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: site + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - user_id + match_type: '' + name: export_fk_user_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: user + type: FOREIGN KEY + fields: + completed: + data_type: datetime + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: completed + order: 6 + size: + - 0 + content: + data_type: longblob + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: content + order: 10 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + mimetype: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: mimetype + order: 9 + size: + - 0 + result: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: result + order: 7 + size: + - 0 + result_internal: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: result_internal + order: 8 + size: + - 0 + site_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: site_id + order: 2 + size: + - 0 + started: + data_type: datetime + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: started + order: 5 + size: + - 0 + type: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: type + order: 4 + size: + - 45 + user_id: + data_type: bigint + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: user_id + order: 3 + size: + - 0 + indices: + - fields: + - site_id + name: export_idx_site_id + options: [] + type: NORMAL + - fields: + - user_id + name: export_idx_user_id + options: [] + type: NORMAL + name: export + options: [] + order: 20 + file: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - layout_id + match_type: '' + name: file_fk_layout_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: layout + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - purged_by + match_type: '' + name: file_fk_purged_by + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: user + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - record_id + match_type: '' + name: file_fk_record_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: record + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - value + match_type: '' + name: file_fk_value + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: fileval + type: FOREIGN KEY + fields: + child_unique: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: child_unique + order: 4 + size: + - 0 + id: + data_type: bigint + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + layout_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: layout_id + order: 3 + size: + - 0 + purged_by: + data_type: bigint + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: purged_by + order: 6 + size: + - 0 + purged_on: + data_type: datetime + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: purged_on + order: 7 + size: + - 0 + record_id: + data_type: bigint + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: record_id + order: 2 + size: + - 0 + value: + data_type: bigint + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: value + order: 5 + size: + - 0 + indices: + - fields: + - layout_id + name: file_idx_layout_id + options: [] + type: NORMAL + - fields: + - purged_by + name: file_idx_purged_by + options: [] + type: NORMAL + - fields: + - record_id + name: file_idx_record_id + options: [] + type: NORMAL + - fields: + - value + name: file_idx_value + options: [] + type: NORMAL + name: file + options: [] + order: 21 + file_option: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - layout_id + match_type: '' + name: file_option_fk_layout_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: layout + type: FOREIGN KEY + fields: + filesize: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: filesize + order: 3 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + layout_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: layout_id + order: 2 + size: + - 0 + indices: + - fields: + - layout_id + name: file_option_idx_layout_id + options: [] + type: NORMAL + name: file_option + options: [] + order: 22 + fileval: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - edit_user_id + match_type: '' + name: fileval_fk_edit_user_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: user + type: FOREIGN KEY + fields: + edit_user_id: + data_type: bigint + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: edit_user_id + order: 5 + size: + - 0 + id: + data_type: bigint + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + is_independent: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: is_independent + order: 4 + size: + - 0 + mimetype: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: mimetype + order: 3 + size: + - 0 + name: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: name + order: 2 + size: + - 0 + indices: + - fields: + - edit_user_id + name: fileval_idx_edit_user_id + options: [] + type: NORMAL + - fields: + - name: name + prefix_length: 64 + name: fileval_idx_name + options: [] + type: NORMAL + name: fileval + options: [] + order: 23 + filter: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - layout_id + match_type: '' + name: filter_fk_layout_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: layout + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - view_id + match_type: '' + name: filter_fk_view_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: view + type: FOREIGN KEY + fields: + id: + data_type: bigint + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + layout_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: layout_id + order: 3 + size: + - 0 + view_id: + data_type: bigint + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: view_id + order: 2 + size: + - 0 + indices: + - fields: + - layout_id + name: filter_idx_layout_id + options: [] + type: NORMAL + - fields: + - view_id + name: filter_idx_view_id + options: [] + type: NORMAL + name: filter + options: [] + order: 24 + filtered_value: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - submission_id + - layout_id + - current_id + match_type: '' + name: ux_submission_layout_current + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + - deferrable: 1 + expression: '' + fields: + - current_id + match_type: '' + name: filtered_value_fk_current_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: current + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - layout_id + match_type: '' + name: filtered_value_fk_layout_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: layout + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - submission_id + match_type: '' + name: filtered_value_fk_submission_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: submission + type: FOREIGN KEY + fields: + current_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 1 + name: current_id + order: 4 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + layout_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 1 + name: layout_id + order: 3 + size: + - 0 + submission_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 1 + name: submission_id + order: 2 + size: + - 0 + indices: + - fields: + - current_id + name: filtered_value_idx_current_id + options: [] + type: NORMAL + - fields: + - layout_id + name: filtered_value_idx_layout_id + options: [] + type: NORMAL + - fields: + - submission_id + name: filtered_value_idx_submission_id + options: [] + type: NORMAL + name: filtered_value + options: [] + order: 25 + graph: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - group_id + match_type: '' + name: graph_fk_group_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: group + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - group_by + match_type: '' + name: graph_fk_group_by + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: layout + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - instance_id + match_type: '' + name: graph_fk_instance_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: instance + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - metric_group + match_type: '' + name: graph_fk_metric_group + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: metric_group + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - user_id + match_type: '' + name: graph_fk_user_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: user + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - x_axis + match_type: '' + name: graph_fk_x_axis + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: layout + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - x_axis_link + match_type: '' + name: graph_fk_x_axis_link + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: layout + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - y_axis + match_type: '' + name: graph_fk_y_axis + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: layout + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - y_axis_link + match_type: '' + name: graph_fk_y_axis_link + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: layout + type: FOREIGN KEY + fields: + as_percent: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: as_percent + order: 13 + size: + - 0 + description: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: description + order: 3 + size: + - 0 + from: + data_type: date + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: from + order: 21 + size: + - 0 + group_by: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: group_by + order: 11 + size: + - 0 + group_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: group_id + order: 19 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + instance_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: instance_id + order: 16 + size: + - 0 + is_shared: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: is_shared + order: 17 + size: + - 0 + metric_group: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: metric_group + order: 15 + size: + - 0 + stackseries: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: stackseries + order: 12 + size: + - 0 + title: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: title + order: 2 + size: + - 0 + to: + data_type: date + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: to + order: 22 + size: + - 0 + trend: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: trend + order: 20 + size: + - 45 + type: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: type + order: 14 + size: + - 45 + user_id: + data_type: bigint + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: user_id + order: 18 + size: + - 0 + x_axis: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: x_axis + order: 8 + size: + - 0 + x_axis_grouping: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: x_axis_grouping + order: 10 + size: + - 45 + x_axis_link: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: x_axis_link + order: 9 + size: + - 0 + x_axis_range: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: x_axis_range + order: 23 + size: + - 45 + y_axis: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: y_axis + order: 4 + size: + - 0 + y_axis_label: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: y_axis_label + order: 7 + size: + - 0 + y_axis_link: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: y_axis_link + order: 5 + size: + - 0 + y_axis_stack: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: y_axis_stack + order: 6 + size: + - 45 + indices: + - fields: + - group_id + name: graph_idx_group_id + options: [] + type: NORMAL + - fields: + - group_by + name: graph_idx_group_by + options: [] + type: NORMAL + - fields: + - instance_id + name: graph_idx_instance_id + options: [] + type: NORMAL + - fields: + - metric_group + name: graph_idx_metric_group + options: [] + type: NORMAL + - fields: + - user_id + name: graph_idx_user_id + options: [] + type: NORMAL + - fields: + - x_axis + name: graph_idx_x_axis + options: [] + type: NORMAL + - fields: + - x_axis_link + name: graph_idx_x_axis_link + options: [] + type: NORMAL + - fields: + - y_axis + name: graph_idx_y_axis + options: [] + type: NORMAL + - fields: + - y_axis_link + name: graph_idx_y_axis_link + options: [] + type: NORMAL + name: graph + options: [] + order: 26 + graph_color: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - name + match_type: '' + name: ux_graph_color_name + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + fields: + color: + data_type: char + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: color + order: 3 + size: + - 6 + id: + data_type: bigint + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + name: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 1 + name: name + order: 2 + size: + - 128 + indices: [] + name: graph_color + options: [] + order: 27 + group: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - site_id + match_type: '' + name: group_fk_site_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: site + type: FOREIGN KEY + fields: + default_approve_existing: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: default_approve_existing + order: 7 + size: + - 0 + default_approve_new: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: default_approve_new + order: 6 + size: + - 0 + default_read: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: default_read + order: 3 + size: + - 0 + default_write_existing: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: default_write_existing + order: 5 + size: + - 0 + default_write_existing_no_approval: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: default_write_existing_no_approval + order: 9 + size: + - 0 + default_write_new: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: default_write_new + order: 4 + size: + - 0 + default_write_new_no_approval: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: default_write_new_no_approval + order: 8 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + name: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: name + order: 2 + size: + - 128 + site_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: site_id + order: 10 + size: + - 0 + indices: + - fields: + - site_id + name: group_idx_site_id + options: [] + type: NORMAL + name: group + options: [] + order: 28 + import: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - instance_id + match_type: '' + name: import_fk_instance_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: instance + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - site_id + match_type: '' + name: import_fk_site_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: site + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - user_id + match_type: '' + name: import_fk_user_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: user + type: FOREIGN KEY + fields: + completed: + data_type: datetime + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: completed + order: 8 + size: + - 0 + error_count: + data_type: integer + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: error_count + order: 10 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + instance_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: instance_id + order: 3 + size: + - 0 + result: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: result + order: 12 + size: + - 0 + row_count: + data_type: integer + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: row_count + order: 6 + size: + - 0 + site_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: site_id + order: 2 + size: + - 0 + skipped_count: + data_type: integer + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: skipped_count + order: 11 + size: + - 0 + started: + data_type: datetime + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: started + order: 7 + size: + - 0 + type: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: type + order: 5 + size: + - 45 + user_id: + data_type: bigint + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: user_id + order: 4 + size: + - 0 + written_count: + data_type: integer + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: written_count + order: 9 + size: + - 0 + indices: + - fields: + - instance_id + name: import_idx_instance_id + options: [] + type: NORMAL + - fields: + - site_id + name: import_idx_site_id + options: [] + type: NORMAL + - fields: + - user_id + name: import_idx_user_id + options: [] + type: NORMAL + name: import + options: [] + order: 29 + import_row: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - import_id + match_type: '' + name: import_row_fk_import_id + on_delete: CASCADE + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: import + type: FOREIGN KEY + fields: + changes: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: changes + order: 6 + size: + - 0 + content: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: content + order: 4 + size: + - 0 + errors: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: errors + order: 5 + size: + - 0 + id: + data_type: bigint + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + import_id: + data_type: int + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: import_id + order: 2 + size: + - 0 + status: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: status + order: 3 + size: + - 45 + indices: + - fields: + - import_id + name: import_row_idx_import_id + options: [] + type: NORMAL + name: import_row + options: [] + order: 30 + instance: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - api_index_layout_id + match_type: '' + name: instance_fk_api_index_layout_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: layout + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - default_view_limit_extra_id + match_type: '' + name: instance_fk_default_view_limit_extra_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: view + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - site_id + match_type: '' + name: instance_fk_site_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: site + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - sort_layout_id + match_type: '' + name: instance_fk_sort_layout_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: layout + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - view_limit_id + match_type: '' + name: instance_fk_view_limit_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: view + type: FOREIGN KEY + fields: + api_index_layout_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: api_index_layout_id + order: 14 + size: + - 0 + default_view_limit_extra_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: default_view_limit_extra_id + order: 8 + size: + - 0 + forget_history: + data_type: smallint + default_value: 0 + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: forget_history + order: 12 + size: + - 0 + forward_record_after_create: + data_type: smallint + default_value: 0 + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: forward_record_after_create + order: 15 + size: + - 0 + hide_in_selector: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: hide_in_selector + order: 19 + size: + - 0 + homepage_text: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: homepage_text + order: 9 + size: + - 0 + homepage_text2: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: homepage_text2 + order: 10 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + name: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: name + order: 2 + size: + - 0 + name_short: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: name_short + order: 3 + size: + - 64 + no_copy_record: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: no_copy_record + order: 18 + size: + - 0 + no_download_pdf: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: no_download_pdf + order: 17 + size: + - 0 + no_hide_blank: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: no_hide_blank + order: 16 + size: + - 0 + no_overnight_update: + data_type: smallint + default_value: 0 + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: no_overnight_update + order: 13 + size: + - 0 + record_name: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: record_name + order: 11 + size: + - 0 + security_marking: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: security_marking + order: 20 + size: + - 0 + site_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: site_id + order: 4 + size: + - 0 + sort_layout_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: sort_layout_id + order: 5 + size: + - 0 + sort_type: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: sort_type + order: 6 + size: + - 45 + view_limit_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: view_limit_id + order: 7 + size: + - 0 + indices: + - fields: + - api_index_layout_id + name: instance_idx_api_index_layout_id + options: [] + type: NORMAL + - fields: + - default_view_limit_extra_id + name: instance_idx_default_view_limit_extra_id + options: [] + type: NORMAL + - fields: + - site_id + name: instance_idx_site_id + options: [] + type: NORMAL + - fields: + - sort_layout_id + name: instance_idx_sort_layout_id + options: [] + type: NORMAL + - fields: + - view_limit_id + name: instance_idx_view_limit_id + options: [] + type: NORMAL + name: instance + options: [] + order: 31 + instance_group: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - instance_id + - group_id + - permission + match_type: '' + name: instance_group_ux_instance_group_permission + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + - deferrable: 1 + expression: '' + fields: + - group_id + match_type: '' + name: instance_group_fk_group_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: group + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - instance_id + match_type: '' + name: instance_group_fk_instance_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: instance + type: FOREIGN KEY + fields: + group_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: group_id + order: 3 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + instance_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: instance_id + order: 2 + size: + - 0 + permission: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: permission + order: 4 + size: + - 45 + indices: + - fields: + - group_id + name: instance_group_idx_group_id + options: [] + type: NORMAL + - fields: + - instance_id + name: instance_group_idx_instance_id + options: [] + type: NORMAL + name: instance_group + options: [] + order: 32 + instance_rag: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - instance_id + - rag + match_type: '' + name: instance_rag_ux_instance_rag + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + - deferrable: 1 + expression: '' + fields: + - instance_id + match_type: '' + name: instance_rag_fk_instance_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: instance + type: FOREIGN KEY + fields: + description: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: description + order: 5 + size: + - 0 + enabled: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: enabled + order: 4 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + instance_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: instance_id + order: 2 + size: + - 0 + rag: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: rag + order: 3 + size: + - 16 + indices: + - fields: + - instance_id + name: instance_rag_idx_instance_id + options: [] + type: NORMAL + name: instance_rag + options: [] + order: 33 + intgr: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - layout_id + match_type: '' + name: intgr_fk_layout_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: layout + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - purged_by + match_type: '' + name: intgr_fk_purged_by + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: user + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - record_id + match_type: '' + name: intgr_fk_record_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: record + type: FOREIGN KEY + fields: + child_unique: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: child_unique + order: 4 + size: + - 0 + id: + data_type: bigint + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + layout_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: layout_id + order: 3 + size: + - 0 + purged_by: + data_type: bigint + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: purged_by + order: 6 + size: + - 0 + purged_on: + data_type: datetime + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: purged_on + order: 7 + size: + - 0 + record_id: + data_type: bigint + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: record_id + order: 2 + size: + - 0 + value: + data_type: bigint + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: value + order: 5 + size: + - 0 + indices: + - fields: + - layout_id + name: intgr_idx_layout_id + options: [] + type: NORMAL + - fields: + - purged_by + name: intgr_idx_purged_by + options: [] + type: NORMAL + - fields: + - record_id + name: intgr_idx_record_id + options: [] + type: NORMAL + - fields: + - value + name: intgr_idx_value + options: [] + type: NORMAL + name: intgr + options: [] + order: 34 + layout: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - instance_id + - name_short + match_type: '' + name: layout_ux_instance_name_short + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + - deferrable: 1 + expression: '' + fields: + - display_field + match_type: '' + name: layout_fk_display_field + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: layout + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - instance_id + match_type: '' + name: layout_fk_instance_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: instance + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - link_parent + match_type: '' + name: layout_fk_link_parent + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: layout + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - related_field + match_type: '' + name: layout_fk_related_field + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: layout + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - topic_id + match_type: '' + name: layout_fk_topic_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: topic + type: FOREIGN KEY + fields: + aggregate: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: aggregate + order: 31 + size: + - 45 + can_child: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: can_child + order: 16 + size: + - 0 + description: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: description + order: 18 + size: + - 0 + display_condition: + data_type: char + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: display_condition + order: 23 + size: + - 3 + display_field: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: display_field + order: 21 + size: + - 0 + display_matchtype: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: display_matchtype + order: 24 + size: + - 0 + display_regex: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: display_regex + order: 22 + size: + - 0 + end_node_only: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: end_node_only + order: 14 + size: + - 0 + filter: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: filter + order: 29 + size: + - 0 + force_regex: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: force_regex + order: 11 + size: + - 0 + group_display: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: group_display + order: 32 + size: + - 45 + helptext: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: helptext + order: 19 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + instance_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 1 + name: instance_id + order: 25 + size: + - 0 + internal: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: internal + order: 17 + size: + - 0 + isunique: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: isunique + order: 8 + size: + - 0 + link_parent: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: link_parent + order: 26 + size: + - 0 + lookup_endpoint: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: lookup_endpoint + order: 33 + size: + - 0 + lookup_group: + data_type: smallint + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: lookup_group + order: 34 + size: + - 0 + multivalue: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: multivalue + order: 15 + size: + - 0 + name: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: name + order: 2 + size: + - 0 + name_short: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 1 + name: name_short + order: 3 + size: + - 64 + notes: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: notes + order: 35 + size: + - 0 + optional: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: optional + order: 6 + size: + - 0 + options: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: options + order: 20 + size: + - 0 + ordering: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: ordering + order: 13 + size: + - 45 + permission: + data_type: integer + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: permission + order: 5 + size: + - 0 + position: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: position + order: 12 + size: + - 0 + related_field: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: related_field + order: 27 + size: + - 0 + remember: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: remember + order: 7 + size: + - 0 + textbox: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: textbox + order: 9 + size: + - 0 + topic_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: topic_id + order: 30 + size: + - 0 + type: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: type + order: 4 + size: + - 45 + typeahead: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: typeahead + order: 10 + size: + - 0 + width: + data_type: integer + default_value: 50 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: width + order: 28 + size: + - 0 + indices: + - fields: + - display_field + name: layout_idx_display_field + options: [] + type: NORMAL + - fields: + - instance_id + name: layout_idx_instance_id + options: [] + type: NORMAL + - fields: + - link_parent + name: layout_idx_link_parent + options: [] + type: NORMAL + - fields: + - related_field + name: layout_idx_related_field + options: [] + type: NORMAL + - fields: + - topic_id + name: layout_idx_topic_id + options: [] + type: NORMAL + name: layout + options: [] + order: 35 + layout_depend: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - depends_on + match_type: '' + name: layout_depend_fk_depends_on + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: layout + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - layout_id + match_type: '' + name: layout_depend_fk_layout_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: layout + type: FOREIGN KEY + fields: + depends_on: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: depends_on + order: 3 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + layout_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: layout_id + order: 2 + size: + - 0 + indices: + - fields: + - depends_on + name: layout_depend_idx_depends_on + options: [] + type: NORMAL + - fields: + - layout_id + name: layout_depend_idx_layout_id + options: [] + type: NORMAL + name: layout_depend + options: [] + order: 36 + layout_group: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - layout_id + - group_id + - permission + match_type: '' + name: layout_group_ux_layout_group_permission + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + - deferrable: 1 + expression: '' + fields: + - group_id + match_type: '' + name: layout_group_fk_group_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: group + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - layout_id + match_type: '' + name: layout_group_fk_layout_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: layout + type: FOREIGN KEY + fields: + group_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: group_id + order: 3 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + layout_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: layout_id + order: 2 + size: + - 0 + permission: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: permission + order: 4 + size: + - 45 + indices: + - fields: + - group_id + name: layout_group_idx_group_id + options: [] + type: NORMAL + - fields: + - layout_id + name: layout_group_idx_layout_id + options: [] + type: NORMAL + - fields: + - permission + name: layout_group_idx_permission + options: [] + type: NORMAL + name: layout_group + options: [] + order: 37 + metric: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - metric_group + match_type: '' + name: metric_fk_metric_group + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: metric_group + type: FOREIGN KEY + fields: + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + metric_group: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: metric_group + order: 2 + size: + - 0 + target: + data_type: bigint + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: target + order: 4 + size: + - 0 + x_axis_value: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: x_axis_value + order: 3 + size: + - 0 + y_axis_grouping_value: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: y_axis_grouping_value + order: 5 + size: + - 0 + indices: + - fields: + - metric_group + name: metric_idx_metric_group + options: [] + type: NORMAL + name: metric + options: [] + order: 38 + metric_group: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - instance_id + match_type: '' + name: metric_group_fk_instance_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: instance + type: FOREIGN KEY + fields: + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + instance_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: instance_id + order: 3 + size: + - 0 + name: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: name + order: 2 + size: + - 0 + indices: + - fields: + - instance_id + name: metric_group_idx_instance_id + options: [] + type: NORMAL + name: metric_group + options: [] + order: 39 + oauthclient: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + fields: + client_id: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: client_id + order: 2 + size: + - 64 + client_secret: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: client_secret + order: 3 + size: + - 64 + id: + data_type: bigint + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + indices: [] + name: oauthclient + options: [] + order: 40 + oauthtoken: + constraints: + - deferrable: 1 + expression: '' + fields: + - token + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - oauthclient_id + match_type: '' + name: oauthtoken_fk_oauthclient_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: oauthclient + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - user_id + match_type: '' + name: oauthtoken_fk_user_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: user + type: FOREIGN KEY + fields: + expires: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: expires + order: 6 + size: + - 0 + oauthclient_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: oauthclient_id + order: 3 + size: + - 0 + related_token: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: related_token + order: 2 + size: + - 128 + token: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: token + order: 1 + size: + - 128 + type: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: type + order: 5 + size: + - 12 + user_id: + data_type: bigint + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: user_id + order: 4 + size: + - 0 + indices: + - fields: + - oauthclient_id + name: oauthtoken_idx_oauthclient_id + options: [] + type: NORMAL + - fields: + - user_id + name: oauthtoken_idx_user_id + options: [] + type: NORMAL + name: oauthtoken + options: [] + order: 41 + organisation: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - site_id + match_type: '' + name: organisation_fk_site_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: site + type: FOREIGN KEY + fields: + deleted: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: deleted + order: 4 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + name: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: name + order: 2 + size: + - 128 + site_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: site_id + order: 3 + size: + - 0 + indices: + - fields: + - site_id + name: organisation_idx_site_id + options: [] + type: NORMAL + name: organisation + options: [] + order: 42 + permission: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + fields: + description: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: description + order: 3 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + name: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: name + order: 2 + size: + - 128 + order: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: order + order: 4 + size: + - 0 + indices: [] + name: permission + options: [] + order: 43 + person: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - layout_id + match_type: '' + name: person_fk_layout_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: layout + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - purged_by + match_type: '' + name: person_fk_purged_by + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: user + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - record_id + match_type: '' + name: person_fk_record_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: record + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - value + match_type: '' + name: person_fk_value + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: user + type: FOREIGN KEY + fields: + child_unique: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: child_unique + order: 4 + size: + - 0 + id: + data_type: bigint + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + layout_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: layout_id + order: 3 + size: + - 0 + purged_by: + data_type: bigint + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: purged_by + order: 6 + size: + - 0 + purged_on: + data_type: datetime + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: purged_on + order: 7 + size: + - 0 + record_id: + data_type: bigint + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: record_id + order: 2 + size: + - 0 + value: + data_type: bigint + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: value + order: 5 + size: + - 0 + indices: + - fields: + - layout_id + name: person_idx_layout_id + options: [] + type: NORMAL + - fields: + - purged_by + name: person_idx_purged_by + options: [] + type: NORMAL + - fields: + - record_id + name: person_idx_record_id + options: [] + type: NORMAL + - fields: + - value + name: person_idx_value + options: [] + type: NORMAL + name: person + options: [] + order: 44 + rag: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - layout_id + match_type: '' + name: rag_fk_layout_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: layout + type: FOREIGN KEY + fields: + amber: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: amber + order: 4 + size: + - 0 + code: + data_type: mediumtext + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: code + order: 6 + size: + - 0 + green: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: green + order: 5 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + layout_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: layout_id + order: 2 + size: + - 0 + red: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: red + order: 3 + size: + - 0 + indices: + - fields: + - layout_id + name: rag_idx_layout_id + options: [] + type: NORMAL + name: rag + options: [] + order: 45 + ragval: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - record_id + - layout_id + match_type: '' + name: ragval_ux_record_layout + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + - deferrable: 1 + expression: '' + fields: + - layout_id + match_type: '' + name: ragval_fk_layout_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: layout + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - purged_by + match_type: '' + name: ragval_fk_purged_by + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: user + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - record_id + match_type: '' + name: ragval_fk_record_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: record + type: FOREIGN KEY + fields: + id: + data_type: bigint + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + layout_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: layout_id + order: 3 + size: + - 0 + purged_by: + data_type: bigint + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: purged_by + order: 5 + size: + - 0 + purged_on: + data_type: datetime + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: purged_on + order: 6 + size: + - 0 + record_id: + data_type: bigint + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: record_id + order: 2 + size: + - 0 + value: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: value + order: 4 + size: + - 16 + indices: + - fields: + - layout_id + name: ragval_idx_layout_id + options: [] + type: NORMAL + - fields: + - purged_by + name: ragval_idx_purged_by + options: [] + type: NORMAL + - fields: + - record_id + name: ragval_idx_record_id + options: [] + type: NORMAL + - fields: + - value + name: ragval_idx_value + options: [] + type: NORMAL + name: ragval + options: [] + order: 46 + record: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - approvedby + match_type: '' + name: record_fk_approvedby + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: user + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - createdby + match_type: '' + name: record_fk_createdby + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: user + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - current_id + match_type: '' + name: record_fk_current_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: current + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - record_id + match_type: '' + name: record_fk_record_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: record + type: FOREIGN KEY + fields: + approval: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: approval + order: 7 + size: + - 0 + approvedby: + data_type: bigint + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: approvedby + order: 5 + size: + - 0 + created: + data_type: datetime + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: created + order: 2 + size: + - 0 + createdby: + data_type: bigint + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: createdby + order: 4 + size: + - 0 + current_id: + data_type: bigint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: current_id + order: 3 + size: + - 0 + id: + data_type: bigint + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + record_id: + data_type: bigint + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: record_id + order: 6 + size: + - 0 + indices: + - fields: + - approvedby + name: record_idx_approvedby + options: [] + type: NORMAL + - fields: + - createdby + name: record_idx_createdby + options: [] + type: NORMAL + - fields: + - current_id + name: record_idx_current_id + options: [] + type: NORMAL + - fields: + - record_id + name: record_idx_record_id + options: [] + type: NORMAL + - fields: + - approval + name: record_idx_approval + options: [] + type: NORMAL + name: record + options: [] + order: 47 + report: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - createdby + match_type: '' + name: report_fk_createdby + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: user + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - instance_id + match_type: '' + name: report_fk_instance_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: instance + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - user_id + match_type: '' + name: report_fk_user_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: user + type: FOREIGN KEY + fields: + created: + data_type: datetime + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: created + order: 7 + size: + - 0 + createdby: + data_type: bigint + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: createdby + order: 6 + size: + - 0 + deleted: + data_type: datetime + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: deleted + order: 9 + size: + - 0 + description: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: description + order: 4 + size: + - 128 + id: + data_type: bigint + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + instance_id: + data_type: bigint + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: instance_id + order: 8 + size: + - 0 + name: + data_type: text + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: name + order: 2 + size: + - 128 + security_marking: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: security_marking + order: 10 + size: + - 0 + title: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: title + order: 3 + size: + - 0 + user_id: + data_type: bigint + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: user_id + order: 5 + size: + - 0 + indices: + - fields: + - createdby + name: report_idx_createdby + options: [] + type: NORMAL + - fields: + - instance_id + name: report_idx_instance_id + options: [] + type: NORMAL + - fields: + - user_id + name: report_idx_user_id + options: [] + type: NORMAL + name: report + options: [] + order: 48 + report_group: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - group_id + match_type: '' + name: report_group_fk_group_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: group + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - report_id + match_type: '' + name: report_group_fk_report_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: report + type: FOREIGN KEY + fields: + group_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: group_id + order: 3 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + report_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: report_id + order: 2 + size: + - 0 + indices: + - fields: + - group_id + name: report_group_idx_group_id + options: [] + type: NORMAL + - fields: + - report_id + name: report_group_idx_report_id + options: [] + type: NORMAL + name: report_group + options: [] + order: 49 + report_layout: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - layout_id + match_type: '' + name: report_layout_fk_layout_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: layout + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - report_id + match_type: '' + name: report_layout_fk_report_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: report + type: FOREIGN KEY + fields: + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + layout_id: + data_type: bigint + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: layout_id + order: 3 + size: + - 0 + order: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: order + order: 4 + size: + - 0 + report_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: report_id + order: 2 + size: + - 0 + indices: + - fields: + - layout_id + name: report_layout_idx_layout_id + options: [] + type: NORMAL + - fields: + - report_id + name: report_layout_idx_report_id + options: [] + type: NORMAL + name: report_layout + options: [] + order: 50 + site: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + fields: + account_request_notes_name: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: account_request_notes_name + order: 39 + size: + - 0 + account_request_notes_placeholder: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: account_request_notes_placeholder + order: 40 + size: + - 0 + created: + data_type: datetime + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: created + order: 4 + size: + - 0 + email_delete_subject: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: email_delete_subject + order: 8 + size: + - 0 + email_delete_text: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: email_delete_text + order: 7 + size: + - 0 + email_reject_subject: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: email_reject_subject + order: 10 + size: + - 0 + email_reject_text: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: email_reject_text + order: 9 + size: + - 0 + email_welcome_subject: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: email_welcome_subject + order: 6 + size: + - 0 + email_welcome_text: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: email_welcome_text + order: 5 + size: + - 0 + hide_account_request: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: hide_account_request + order: 34 + size: + - 0 + homepage_text: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: homepage_text + order: 12 + size: + - 0 + homepage_text2: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: homepage_text2 + order: 13 + size: + - 0 + host: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: host + order: 2 + size: + - 128 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + name: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: name + order: 3 + size: + - 0 + register_department_help: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: register_department_help + order: 21 + size: + - 0 + register_department_mandatory: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: register_department_mandatory + order: 23 + size: + - 0 + register_department_name: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: register_department_name + order: 22 + size: + - 0 + register_email_help: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: register_email_help + order: 17 + size: + - 0 + register_freetext1_help: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: register_freetext1_help + order: 15 + size: + - 0 + register_freetext1_name: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: register_freetext1_name + order: 28 + size: + - 0 + register_freetext1_placeholder: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: register_freetext1_placeholder + order: 37 + size: + - 0 + register_freetext2_help: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: register_freetext2_help + order: 16 + size: + - 0 + register_freetext2_name: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: register_freetext2_name + order: 29 + size: + - 0 + register_freetext2_placeholder: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: register_freetext2_placeholder + order: 38 + size: + - 0 + register_notes_help: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: register_notes_help + order: 27 + size: + - 0 + register_organisation_help: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: register_organisation_help + order: 18 + size: + - 0 + register_organisation_mandatory: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: register_organisation_mandatory + order: 20 + size: + - 0 + register_organisation_name: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: register_organisation_name + order: 19 + size: + - 0 + register_show_department: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: register_show_department + order: 31 + size: + - 0 + register_show_organisation: + data_type: smallint + default_value: 1 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: register_show_organisation + order: 30 + size: + - 0 + register_show_team: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: register_show_team + order: 32 + size: + - 0 + register_show_title: + data_type: smallint + default_value: 1 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: register_show_title + order: 33 + size: + - 0 + register_team_help: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: register_team_help + order: 24 + size: + - 0 + register_team_mandatory: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: register_team_mandatory + order: 26 + size: + - 0 + register_team_name: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: register_team_name + order: 25 + size: + - 0 + register_text: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: register_text + order: 11 + size: + - 0 + register_title_help: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: register_title_help + order: 14 + size: + - 0 + remember_user_location: + data_type: smallint + default_value: 1 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: remember_user_location + order: 35 + size: + - 0 + security_marking: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: security_marking + order: 41 + size: + - 0 + site_logo: + data_type: longblob + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: site_logo + order: 42 + size: + - 0 + user_editable_fields: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: user_editable_fields + order: 36 + size: + - 0 + indices: [] + name: site + options: [] + order: 51 + sort: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - layout_id + match_type: '' + name: sort_fk_layout_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: layout + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - parent_id + match_type: '' + name: sort_fk_parent_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: layout + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - view_id + match_type: '' + name: sort_fk_view_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: view + type: FOREIGN KEY + fields: + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + layout_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: layout_id + order: 3 + size: + - 0 + order: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: order + order: 6 + size: + - 0 + parent_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: parent_id + order: 4 + size: + - 0 + type: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: type + order: 5 + size: + - 45 + view_id: + data_type: bigint + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: view_id + order: 2 + size: + - 0 + indices: + - fields: + - layout_id + name: sort_idx_layout_id + options: [] + type: NORMAL + - fields: + - parent_id + name: sort_idx_parent_id + options: [] + type: NORMAL + - fields: + - view_id + name: sort_idx_view_id + options: [] + type: NORMAL + name: sort + options: [] + order: 52 + string: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - layout_id + match_type: '' + name: string_fk_layout_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: layout + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - purged_by + match_type: '' + name: string_fk_purged_by + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: user + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - record_id + match_type: '' + name: string_fk_record_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: record + type: FOREIGN KEY + fields: + child_unique: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: child_unique + order: 4 + size: + - 0 + id: + data_type: bigint + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + layout_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: layout_id + order: 3 + size: + - 0 + purged_by: + data_type: bigint + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: purged_by + order: 7 + size: + - 0 + purged_on: + data_type: datetime + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: purged_on + order: 8 + size: + - 0 + record_id: + data_type: bigint + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: record_id + order: 2 + size: + - 0 + value: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: value + order: 5 + size: + - 0 + value_index: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: value_index + order: 6 + size: + - 128 + indices: + - fields: + - layout_id + name: string_idx_layout_id + options: [] + type: NORMAL + - fields: + - purged_by + name: string_idx_purged_by + options: [] + type: NORMAL + - fields: + - record_id + name: string_idx_record_id + options: [] + type: NORMAL + - fields: + - value_index + name: string_idx_value_index + options: [] + type: NORMAL + name: string + options: [] + order: 53 + submission: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - token + - submitted + match_type: '' + name: ux_submission_token + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + fields: + created: + data_type: datetime + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: created + order: 3 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + submitted: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: submitted + order: 4 + size: + - 0 + token: + data_type: varchar + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 1 + name: token + order: 2 + size: + - 64 + indices: [] + name: submission + options: [] + order: 54 + team: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - site_id + match_type: '' + name: team_fk_site_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: site + type: FOREIGN KEY + fields: + deleted: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: deleted + order: 4 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + name: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: name + order: 2 + size: + - 128 + site_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: site_id + order: 3 + size: + - 0 + indices: + - fields: + - site_id + name: team_idx_site_id + options: [] + type: NORMAL + name: team + options: [] + order: 55 + title: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - site_id + match_type: '' + name: title_fk_site_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: site + type: FOREIGN KEY + fields: + deleted: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: deleted + order: 4 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + name: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: name + order: 2 + size: + - 128 + site_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: site_id + order: 3 + size: + - 0 + indices: + - fields: + - site_id + name: title_idx_site_id + options: [] + type: NORMAL + name: title + options: [] + order: 56 + topic: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - instance_id + match_type: '' + name: topic_fk_instance_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: instance + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - prevent_edit_topic_id + match_type: '' + name: topic_fk_prevent_edit_topic_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: topic + type: FOREIGN KEY + fields: + click_to_edit: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: click_to_edit + order: 6 + size: + - 0 + description: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: description + order: 4 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + initial_state: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: initial_state + order: 5 + size: + - 32 + instance_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: instance_id + order: 2 + size: + - 0 + name: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: name + order: 3 + size: + - 0 + prevent_edit_topic_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: prevent_edit_topic_id + order: 7 + size: + - 0 + indices: + - fields: + - instance_id + name: topic_idx_instance_id + options: [] + type: NORMAL + - fields: + - prevent_edit_topic_id + name: topic_idx_prevent_edit_topic_id + options: [] + type: NORMAL + name: topic + options: [] + order: 57 + user: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - department_id + match_type: '' + name: user_fk_department_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: department + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - lastrecord + match_type: '' + name: user_fk_lastrecord + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: record + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - lastview + match_type: '' + name: user_fk_lastview + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: view + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - limit_to_view + match_type: '' + name: user_fk_limit_to_view + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: view + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - organisation + match_type: '' + name: user_fk_organisation + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: organisation + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - site_id + match_type: '' + name: user_fk_site_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: site + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - team_id + match_type: '' + name: user_fk_team_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: team + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - title + match_type: '' + name: user_fk_title + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: title + type: FOREIGN KEY + fields: + account_request: + data_type: smallint + default_value: 0 + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: account_request + order: 24 + size: + - 0 + account_request_notes: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: account_request_notes + order: 25 + size: + - 0 + aup_accepted: + data_type: datetime + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: aup_accepted + order: 26 + size: + - 0 + created: + data_type: datetime + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: created + order: 29 + size: + - 0 + debug_login: + data_type: smallint + default_value: 0 + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: debug_login + order: 30 + size: + - 0 + deleted: + data_type: datetime + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: deleted + order: 16 + size: + - 0 + department_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: department_id + order: 9 + size: + - 0 + email: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: email + order: 5 + size: + - 0 + failcount: + data_type: integer + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: failcount + order: 19 + size: + - 0 + firstname: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: firstname + order: 3 + size: + - 128 + freetext1: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: freetext1 + order: 11 + size: + - 0 + freetext2: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: freetext2 + order: 12 + size: + - 0 + id: + data_type: bigint + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + lastfail: + data_type: datetime + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: lastfail + order: 18 + size: + - 0 + lastlogin: + data_type: datetime + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: lastlogin + order: 17 + size: + - 0 + lastrecord: + data_type: bigint + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: lastrecord + order: 20 + size: + - 0 + lastview: + data_type: bigint + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: lastview + order: 21 + size: + - 0 + limit_to_view: + data_type: bigint + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: limit_to_view + order: 27 + size: + - 0 + organisation: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: organisation + order: 8 + size: + - 0 + password: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: password + order: 13 + size: + - 128 + pwchanged: + data_type: datetime + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: pwchanged + order: 14 + size: + - 0 + resetpw: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: resetpw + order: 15 + size: + - 32 + session_settings: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: session_settings + order: 22 + size: + - 0 + site_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: site_id + order: 2 + size: + - 0 + stylesheet: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: stylesheet + order: 28 + size: + - 0 + surname: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: surname + order: 4 + size: + - 128 + team_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: team_id + order: 10 + size: + - 0 + title: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: title + order: 7 + size: + - 0 + username: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: username + order: 6 + size: + - 0 + value: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: value + order: 23 + size: + - 0 + indices: + - fields: + - department_id + name: user_idx_department_id + options: [] + type: NORMAL + - fields: + - lastrecord + name: user_idx_lastrecord + options: [] + type: NORMAL + - fields: + - lastview + name: user_idx_lastview + options: [] + type: NORMAL + - fields: + - limit_to_view + name: user_idx_limit_to_view + options: [] + type: NORMAL + - fields: + - organisation + name: user_idx_organisation + options: [] + type: NORMAL + - fields: + - site_id + name: user_idx_site_id + options: [] + type: NORMAL + - fields: + - team_id + name: user_idx_team_id + options: [] + type: NORMAL + - fields: + - title + name: user_idx_title + options: [] + type: NORMAL + - fields: + - name: value + prefix_length: 64 + name: user_idx_value + options: [] + type: NORMAL + - fields: + - name: email + prefix_length: 64 + name: user_idx_email + options: [] + type: NORMAL + - fields: + - name: username + prefix_length: 64 + name: user_idx_username + options: [] + type: NORMAL + name: user + options: [] + order: 58 + user_graph: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - graph_id + match_type: '' + name: user_graph_fk_graph_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: graph + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - user_id + match_type: '' + name: user_graph_fk_user_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: user + type: FOREIGN KEY + fields: + graph_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: graph_id + order: 3 + size: + - 0 + id: + data_type: bigint + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + user_id: + data_type: bigint + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: user_id + order: 2 + size: + - 0 + indices: + - fields: + - graph_id + name: user_graph_idx_graph_id + options: [] + type: NORMAL + - fields: + - user_id + name: user_graph_idx_user_id + options: [] + type: NORMAL + name: user_graph + options: [] + order: 59 + user_group: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - group_id + match_type: '' + name: user_group_fk_group_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: group + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - user_id + match_type: '' + name: user_group_fk_user_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: user + type: FOREIGN KEY + fields: + group_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: group_id + order: 3 + size: + - 0 + id: + data_type: bigint + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + user_id: + data_type: bigint + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: user_id + order: 2 + size: + - 0 + indices: + - fields: + - group_id + name: user_group_idx_group_id + options: [] + type: NORMAL + - fields: + - user_id + name: user_group_idx_user_id + options: [] + type: NORMAL + name: user_group + options: [] + order: 60 + user_lastrecord: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - instance_id + match_type: '' + name: user_lastrecord_fk_instance_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: instance + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - record_id + match_type: '' + name: user_lastrecord_fk_record_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: record + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - user_id + match_type: '' + name: user_lastrecord_fk_user_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: user + type: FOREIGN KEY + fields: + id: + data_type: bigint + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + instance_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: instance_id + order: 3 + size: + - 0 + record_id: + data_type: bigint + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: record_id + order: 2 + size: + - 0 + user_id: + data_type: bigint + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: user_id + order: 4 + size: + - 0 + indices: + - fields: + - instance_id + name: user_lastrecord_idx_instance_id + options: [] + type: NORMAL + - fields: + - record_id + name: user_lastrecord_idx_record_id + options: [] + type: NORMAL + - fields: + - user_id + name: user_lastrecord_idx_user_id + options: [] + type: NORMAL + name: user_lastrecord + options: [] + order: 61 + user_permission: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - permission_id + match_type: '' + name: user_permission_fk_permission_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: permission + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - user_id + match_type: '' + name: user_permission_fk_user_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: user + type: FOREIGN KEY + fields: + id: + data_type: bigint + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + permission_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: permission_id + order: 3 + size: + - 0 + user_id: + data_type: bigint + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: user_id + order: 2 + size: + - 0 + indices: + - fields: + - permission_id + name: user_permission_idx_permission_id + options: [] + type: NORMAL + - fields: + - user_id + name: user_permission_idx_user_id + options: [] + type: NORMAL + name: user_permission + options: [] + order: 62 + view: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - createdby + match_type: '' + name: view_fk_createdby + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: user + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - group_id + match_type: '' + name: view_fk_group_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: group + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - instance_id + match_type: '' + name: view_fk_instance_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: instance + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - user_id + match_type: '' + name: view_fk_user_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: user + type: FOREIGN KEY + fields: + created: + data_type: datetime + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: created + order: 10 + size: + - 0 + createdby: + data_type: bigint + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: createdby + order: 11 + size: + - 0 + filter: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: filter + order: 8 + size: + - 0 + global: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: global + order: 5 + size: + - 0 + group_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: group_id + order: 3 + size: + - 0 + id: + data_type: bigint + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + instance_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: instance_id + order: 9 + size: + - 0 + is_admin: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: is_admin + order: 6 + size: + - 0 + is_limit_extra: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: is_limit_extra + order: 7 + size: + - 0 + name: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: name + order: 4 + size: + - 128 + user_id: + data_type: bigint + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: user_id + order: 2 + size: + - 0 + indices: + - fields: + - createdby + name: view_idx_createdby + options: [] + type: NORMAL + - fields: + - group_id + name: view_idx_group_id + options: [] + type: NORMAL + - fields: + - instance_id + name: view_idx_instance_id + options: [] + type: NORMAL + - fields: + - user_id + name: view_idx_user_id + options: [] + type: NORMAL + name: view + options: [] + order: 63 + view_group: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - layout_id + match_type: '' + name: view_group_fk_layout_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: layout + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - parent_id + match_type: '' + name: view_group_fk_parent_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: layout + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - view_id + match_type: '' + name: view_group_fk_view_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: view + type: FOREIGN KEY + fields: + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + layout_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: layout_id + order: 3 + size: + - 0 + order: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: order + order: 5 + size: + - 0 + parent_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: parent_id + order: 4 + size: + - 0 + view_id: + data_type: bigint + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: view_id + order: 2 + size: + - 0 + indices: + - fields: + - layout_id + name: view_group_idx_layout_id + options: [] + type: NORMAL + - fields: + - parent_id + name: view_group_idx_parent_id + options: [] + type: NORMAL + - fields: + - view_id + name: view_group_idx_view_id + options: [] + type: NORMAL + name: view_group + options: [] + order: 64 + view_layout: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - layout_id + match_type: '' + name: view_layout_fk_layout_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: layout + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - view_id + match_type: '' + name: view_layout_fk_view_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: view + type: FOREIGN KEY + fields: + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + layout_id: + data_type: integer + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: layout_id + order: 3 + size: + - 0 + order: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: order + order: 4 + size: + - 0 + view_id: + data_type: bigint + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: view_id + order: 2 + size: + - 0 + indices: + - fields: + - layout_id + name: view_layout_idx_layout_id + options: [] + type: NORMAL + - fields: + - view_id + name: view_layout_idx_view_id + options: [] + type: NORMAL + name: view_layout + options: [] + order: 65 + view_limit: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - user_id + match_type: '' + name: view_limit_fk_user_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: user + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - view_id + match_type: '' + name: view_limit_fk_view_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: view + type: FOREIGN KEY + fields: + id: + data_type: bigint + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + user_id: + data_type: bigint + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: user_id + order: 3 + size: + - 0 + view_id: + data_type: bigint + default_value: ~ + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: view_id + order: 2 + size: + - 0 + indices: + - fields: + - user_id + name: view_limit_idx_user_id + options: [] + type: NORMAL + - fields: + - view_id + name: view_limit_idx_view_id + options: [] + type: NORMAL + name: view_limit + options: [] + order: 66 + widget: + constraints: + - deferrable: 1 + expression: '' + fields: + - id + match_type: '' + name: '' + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: PRIMARY KEY + - deferrable: 1 + expression: '' + fields: + - dashboard_id + - grid_id + match_type: '' + name: widget_ux_dashboard_grid + on_delete: '' + on_update: '' + options: [] + reference_fields: [] + reference_table: '' + type: UNIQUE + - deferrable: 1 + expression: '' + fields: + - dashboard_id + match_type: '' + name: widget_fk_dashboard_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: dashboard + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - graph_id + match_type: '' + name: widget_fk_graph_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: graph + type: FOREIGN KEY + - deferrable: 1 + expression: '' + fields: + - view_id + match_type: '' + name: widget_fk_view_id + on_delete: NO ACTION + on_update: NO ACTION + options: [] + reference_fields: + - id + reference_table: view + type: FOREIGN KEY + fields: + content: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: content + order: 11 + size: + - 0 + dashboard_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 1 + name: dashboard_id + order: 3 + size: + - 0 + globe_options: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: globe_options + order: 16 + size: + - 0 + graph_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: graph_id + order: 13 + size: + - 0 + grid_id: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 1 + name: grid_id + order: 2 + size: + - 64 + h: + data_type: smallint + default_value: 0 + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: h + order: 7 + size: + - 0 + id: + data_type: integer + default_value: ~ + is_auto_increment: 1 + is_nullable: 0 + is_primary_key: 1 + is_unique: 0 + name: id + order: 1 + size: + - 0 + rows: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: rows + order: 14 + size: + - 0 + static: + data_type: smallint + default_value: 0 + is_nullable: 0 + is_primary_key: 0 + is_unique: 0 + name: static + order: 6 + size: + - 0 + title: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: title + order: 5 + size: + - 0 + tl_options: + data_type: text + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: tl_options + order: 15 + size: + - 0 + type: + data_type: varchar + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: type + order: 4 + size: + - 16 + view_id: + data_type: integer + default_value: ~ + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: view_id + order: 12 + size: + - 0 + w: + data_type: smallint + default_value: 0 + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: w + order: 8 + size: + - 0 + x: + data_type: smallint + default_value: 0 + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: x + order: 9 + size: + - 0 + y: + data_type: smallint + default_value: 0 + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: y + order: 10 + size: + - 0 + indices: + - fields: + - dashboard_id + name: widget_idx_dashboard_id + options: [] + type: NORMAL + - fields: + - graph_id + name: widget_idx_graph_id + options: [] + type: NORMAL + - fields: + - view_id + name: widget_idx_view_id + options: [] + type: NORMAL + name: widget + options: [] + order: 67 + triggers: {} + views: {} +translator: + add_drop_table: 0 + filename: ~ + no_comments: 0 + parser_args: + sources: + - Alert + - AlertCache + - AlertColumn + - AlertSend + - Audit + - Authentication + - Calc + - CalcUnique + - Calcval + - Changed + - Current + - Curval + - CurvalField + - Dashboard + - Date + - Daterange + - Department + - DisplayField + - Enum + - Enumval + - Export + - File + - FileOption + - Fileval + - Filter + - FilteredValue + - Graph + - GraphColor + - Group + - Import + - ImportRow + - Instance + - InstanceGroup + - InstanceRag + - Intgr + - Layout + - LayoutDepend + - LayoutGroup + - Metric + - MetricGroup + - Oauthclient + - Oauthtoken + - Organisation + - Permission + - Person + - Rag + - Ragval + - Record + - Report + - ReportGroup + - ReportLayout + - Site + - Sort + - String + - Submission + - Team + - Title + - Topic + - User + - UserGraph + - UserGroup + - UserLastrecord + - UserPermission + - View + - ViewGroup + - ViewLayout + - ViewLimit + - Widget + parser_type: SQL::Translator::Parser::DBIx::Class + producer_args: + mysql_version: 5.7 + producer_type: SQL::Translator::Producer::YAML + show_warnings: 0 + trace: 0 + version: 1.63 diff --git a/t/003_search.t b/t/003_search.t index 29ceeb3c0..1b1684d69 100644 --- a/t/003_search.t +++ b/t/003_search.t @@ -116,7 +116,7 @@ my $calc_int = GADS::Column::Calc->new( layout => $layout, name => 'calc_int', return_type => 'integer', - code => "function evaluate (L1integer1) return L1integer1 end", + code => "function evaluate (L1integer1) return L1integer1[1] end", set_permissions => { $sheet->group->id => $sheet->default_permissions, }, diff --git a/t/004_aggregate.t b/t/004_aggregate.t index fe4caf9e8..dfcefa1c2 100644 --- a/t/004_aggregate.t +++ b/t/004_aggregate.t @@ -38,7 +38,7 @@ my $data = [ my $sheet = Test::GADS::DataSheet->new( data => $data, multivalue => 1, - calc_code => "function evaluate (L1integer1, L1integer2) \n return (L1integer1 / L1integer2) * 100 \n end", + calc_code => "function evaluate (L1integer1, L1integer2) \n return (L1integer1[1] / L1integer2[1]) * 100 \n end", column_count => { integer => 2 }, ); my $schema = $sheet->schema; diff --git a/t/004_group.t b/t/004_group.t index 9b200e450..4813046c0 100644 --- a/t/004_group.t +++ b/t/004_group.t @@ -80,13 +80,16 @@ foreach my $multivalue (0..1) }, ]; - my $curval_sheet = Test::GADS::DataSheet->new(instance_id => 2, user_permission_override => 0); + my $curval_sheet = Test::GADS::DataSheet->new(instance_id => 2, user_permission_override => 0, multivalue => $multivalue); $curval_sheet->create_records; my $schema = $curval_sheet->schema; + my $calc_code = $multivalue + ? "function evaluate (L1integer1) \n return L1integer1[1] * 2 \n end" + : "function evaluate (L1integer1) \n return L1integer1 * 2 \n end"; my $sheet = Test::GADS::DataSheet->new( data => $data, - calc_code => "function evaluate (L1integer1) \n return L1integer1 * 2 \n end", + calc_code => $calc_code, schema => $schema, curval => 2, curval_field_ids => [$curval_sheet->columns->{string1}->id], @@ -131,8 +134,9 @@ foreach my $multivalue (0..1) ); $view->set_groups([$string1->id]); # Also add a sort, to check that doesn't result in unwanted multi-value - # field joins - $view->set_sorts({fields => [$enum1->id], types => ['asc']}); + # field joins (needs to be a sort that has an actual value, not a unique + # count) + $view->set_sorts({fields => [$integer1->id], types => ['asc']}); $view->write; my $records = GADS::Records->new( @@ -162,9 +166,10 @@ foreach my $multivalue (0..1) # Remove grouped column from view and check still gets added as required $view->columns([$integer1->id]); + $view->set_sorts({fields => [$string1->id], types => ['asc']}); $view->write; - @expected = (@$expected); + @expected = sort { $a->{string1} cmp $b->{string1} } @$expected; $records->clear; $records = GADS::Records->new( view => $view, @@ -195,6 +200,7 @@ foreach my $multivalue (0..1) user => $sheet->user, ); $view->set_groups([$col->id]); + $view->set_sorts({fields => [$col->id], types => ['asc']}); $view->write; $records = GADS::Records->new( @@ -204,6 +210,7 @@ foreach my $multivalue (0..1) schema => $schema, ); + # We expect the first value in ascending order of that column my $expected = { string1 => 'foo1', integer1 => 25, @@ -212,7 +219,7 @@ foreach my $multivalue (0..1) date1 => '2008-10-10', rag1 => 'b_red', calc1 => 50, - curval1 => 'Foo', + curval1 => 'Bar', daterange1 => '2000-01-02 to 2001-03-03', person1 => 'User1, User1', }; @@ -296,6 +303,7 @@ foreach my $multivalue (0..1) schema => $schema, user => $sheet->user, ); + $view->set_sorts({fields => [$columns->{curval1}->id."_".$curval_sheet->columns->{string1}->id], types => ['desc']}); $view->set_groups([$columns->{curval1}->id."_".$curval_sheet->columns->{string1}->id]); $view->write; @@ -305,7 +313,38 @@ foreach my $multivalue (0..1) user => $sheet->user, schema => $schema, ); + @results = @{$records->results}; + is(@results, 2, "Correct number of rows for group by curval subfield"); + is($results[0]->fields->{$integer1->id}, '75', "Group by curval subfield first result correct"); + is($results[1]->fields->{$integer1->id}, '130', "Group by curval subfield second result correct"); + # Try also sorting directly on the Records object + # First with invalid subfield without parent - should error + $records = GADS::Records->new( + sort => { + type => 'desc', + id => $curval_sheet->columns->{string1}->id, + }, + view => $view, + layout => $layout, + user => $sheet->user, + schema => $schema, + ); + try { $records->results }; + like($@, qr/from different table without parent/, "Error when using subfield without parent"); + + # Then with correct parent + $records = GADS::Records->new( + sort => { + type => 'desc', + id => $curval_sheet->columns->{string1}->id, + parent_id => $columns->{curval1}->id, + }, + view => $view, + layout => $layout, + user => $sheet->user, + schema => $schema, + ); @results = @{$records->results}; is(@results, 2, "Correct number of rows for group by curval subfield"); is($results[0]->fields->{$integer1->id}, '75', "Group by curval subfield first result correct"); @@ -400,6 +439,7 @@ foreach my $multivalue (0..1) user => $sheet->user, ); $view->set_groups([$string1->id]); + $view->set_sorts({fields => [$string1->id], types => ['asc']}); $view->write; my $records = GADS::Records->new( @@ -499,7 +539,7 @@ foreach my $multivalue (0..1) my $sheet = Test::GADS::DataSheet->new( data => $data, multivalue => 1, - calc_code => "function evaluate (L1integer1, L1integer2) \n return (L1integer1 / L1integer2) * 100 \n end", + calc_code => "function evaluate (L1integer1, L1integer2) \n return (L1integer1[1] / L1integer2[1]) * 100 \n end", column_count => { integer => 2 }, ); my $schema = $sheet->schema; @@ -528,6 +568,7 @@ foreach my $multivalue (0..1) user => $sheet->user, ); $view->set_groups([$string1->id]); + $view->set_sorts({fields => [$string1->id], types => ['asc']}); $view->write; my $records = GADS::Records->new( diff --git a/t/012_graph_historical.t b/t/012_graph_historical.t index 61e796cd2..fc99f0fd4 100644 --- a/t/012_graph_historical.t +++ b/t/012_graph_historical.t @@ -16,312 +16,404 @@ use Test::GADS::DataSheet; set_fixed_time('06/14/2019 01:00:00', '%m/%d/%Y %H:%M:%S'); -my @records = ( - [ - { - created => '2018-02-01T11:00', - data => { - enum1 => 1, - integer1 => 12, - } - }, - { - created => '2018-10-01T12:00', - data => { - enum1 => 2, - integer1 => 1, - } - }, - { - created => '2019-03-15T18:00', - data => { - enum1 => 3, - integer1 => 4, - } - }, +foreach my $multivalue (0, 1) +{ + my @records = ( + [ + { + created => '2018-02-01T11:00', + data => { + enum1 => 7, + integer1 => 12, + curval_int => 110, + } + }, + { + created => '2018-10-01T12:00', + data => { + enum1 => 8, + integer1 => 1, + curval_int => 125, + } + }, + { + created => '2019-03-15T18:00', + data => { + enum1 => 9, + integer1 => 4, + curval_int => 155, + } + }, + { + created => '2019-06-14T01:00', + data => { + enum1 => 8, + integer1 => 10, + curval_int => 140, + } + }, + ], + [ + { + created => '2018-06-20T20:00', + data => { + enum1 => 8, + integer1 => 23, + curval_int => 280, + } + }, + { + created => '2018-07-31T00:00', + data => { + enum1 => 9, + integer1 => 5, + curval_int => 220, + } + }, + { + created => '2018-11-12T23:59', + data => { + enum1 => 7, + integer1 => 7, + curval_int => 245, + } + }, + { + created => '2019-04-01T14:50', + data => { + enum1 => 7, + integer1 => 19, + curval_int => 265, + } + }, + ], + [ + { + created => '2017-05-13T16:00', + data => { + enum1 => 9, + integer1 => 1, + curval_int => 310, + } + }, + { + created => '2018-10-01T19:00', + data => { + enum1 => 7, + integer1 => 0, + curval_int => 330, + } + }, + { + created => '2019-06-02T22:00', + data => { + enum1 => 9, + integer1 => 54, + curval_int => 365, + } + }, + { + created => '2019-06-02T23:00', + data => { + enum1 => 7, + integer1 => 37, + curval_int => 380, + } + }, + ], + ); + + my $curval_sheet = Test::GADS::DataSheet->new(instance_id => 2, multivalue => $multivalue, data => []); + $curval_sheet->create_records; + my $schema = $curval_sheet->schema; + + my $sheet = Test::GADS::DataSheet->new( + data => [], + schema => $schema, + multivalue => $multivalue, + curval => 2, + curval_field_ids => [ $curval_sheet->columns->{string1}->id ], + ); + my $layout = $sheet->layout; + my $columns = $sheet->columns; + $sheet->create_records; + + my $curval = $columns->{curval1}; + $curval->show_add(1); + $curval->value_selector('noshow'); + $curval->write(no_alerts => 1);#, force => 1); + my $curval_int = $curval_sheet->columns->{integer1}; + + foreach my $rec (@records) + { + my $record = GADS::Record->new( + user => $sheet->user, + layout => $layout, + schema => $schema, + ); + $record->initialise; + foreach my $version (@$rec) { - created => '2019-06-14T01:00', - data => { - enum1 => 2, - integer1 => 10, - } - }, - ], - [ + my $created = DateTime::Format::ISO8601->parse_datetime($version->{created}); + my $data = $version->{data}; + + my $curval_datum = $record->fields->{$curval->id}; + my ($cid) = @{$curval_datum->ids}; + + my $curval_record = GADS::Record->new( + user => $sheet->user, + layout => $curval_sheet->layout, + schema => $schema, + ); + $cid ? $curval_record->find_current_id($cid) : $curval_record->initialise; + $curval_record->fields->{$curval_int->id}->set_value($data->{curval_int}); + $curval_record->write(version_datetime => $created, no_alerts => 1); + + $record->fields->{$columns->{enum1}->id}->set_value($data->{enum1}); + $record->fields->{$columns->{integer1}->id}->set_value($data->{integer1}); + $record->fields->{$curval->id}->set_value([$curval_record->current_id]); + $record->write(version_datetime => $created, no_alerts => 1); + } + } + + my $crs = $schema->resultset('Current')->search({ instance_id => 1 }); + is($crs->count, 3, "Correct number of records created"); + is($crs->search({},{ join => 'records' })->count, 12, "Correct number of versions created"); + + my $graphs = [ { - created => '2018-06-20T20:00', - data => { - enum1 => 2, - integer1 => 23, - } + name => 'String x-axis with count - standard 12 month range', + type => 'bar', + x_axis => $columns->{enum1}->id, + x_axis_range => '-12', + y_axis_stack => 'count', + labels => [qw/foo3 foo2 foo1/], + data => [ + [1,2,2,2,1,0,0,0,0,1,1,1,0], + [1,0,0,0,1,1,1,1,1,0,0,0,1], + [1,1,1,1,1,2,2,2,2,2,2,2,2], + ], + xlabels => [ + 'June 2018', 'July 2018', 'August 2018', 'September 2018', + 'October 2018', 'November 2018', 'December 2018', 'January 2019', + 'February 2019', 'March 2019', 'April 2019', 'May 2019', 'June 2019' + ], }, { - created => '2018-07-31T00:00', - data => { - enum1 => 3, - integer1 => 5, - } + name => 'Including quick search', + type => 'bar', + x_axis => $columns->{enum1}->id, + x_axis_range => '-12', + y_axis_stack => 'count', + labels => [qw/foo3 foo2 foo1/], + search => 'foo2', + data => [ + [0,0,0,0,0,0,0,0,0,1,1,1,0], + [0,0,0,0,1,1,1,1,1,0,0,0,1], + [1,1,1,1,0,0,0,0,0,0,0,0,0], + ], + xlabels => [ + 'June 2018', 'July 2018', 'August 2018', 'September 2018', + 'October 2018', 'November 2018', 'December 2018', 'January 2019', + 'February 2019', 'March 2019', 'April 2019', 'May 2019', 'June 2019' + ], }, { - created => '2018-11-12T23:59', - data => { - enum1 => 1, - integer1 => 7, - } + name => 'Quick search with curval value', + type => 'bar', + x_axis => $columns->{enum1}->id, + x_axis_range => '-12', + y_axis => $curval_int->id, + y_axis_link => $curval->id, + y_axis_stack => 'sum', + labels => [qw/foo3 foo2 foo1/], + search => 'foo1', + data => [ + [310,530,530,530,220,0,0,0,0,0,0,0,0], + [280,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,330,575,575,575,575,575,595,595,645], + ], + xlabels => [ + 'June 2018', 'July 2018', 'August 2018', 'September 2018', + 'October 2018', 'November 2018', 'December 2018', 'January 2019', + 'February 2019', 'March 2019', 'April 2019', 'May 2019', 'June 2019' + ], }, { - created => '2019-04-01T14:50', - data => { - enum1 => 1, - integer1 => 19, - } + name => 'Including filter', # Should use same record IDs for each period + type => 'bar', + x_axis => $columns->{enum1}->id, + x_axis_range => '-12', + y_axis_stack => 'count', + labels => [qw/foo3 foo2 foo1/], + view => { + column => $columns->{integer1}->id, + value => '10', + }, + data => [ + [0,0,0,0,0,0,0,0,0,1,1,1,0], + [0,0,0,0,1,1,1,1,1,0,0,0,1], + [1,1,1,1,0,0,0,0,0,0,0,0,0], + ], + xlabels => [ + 'June 2018', 'July 2018', 'August 2018', 'September 2018', + 'October 2018', 'November 2018', 'December 2018', 'January 2019', + 'February 2019', 'March 2019', 'April 2019', 'May 2019', 'June 2019' + ], }, - ], - [ { - created => '2017-05-13T16:00', - data => { - enum1 => 3, - integer1 => 1, - } + name => 'Curval values with filter', # Should use same record IDs for each period + type => 'bar', + x_axis => $columns->{enum1}->id, + x_axis_range => '-12', + y_axis => $curval_int->id, + y_axis_link => $curval->id, + y_axis_stack => 'sum', + labels => [qw/foo3 foo2 foo1/], + view => { + column => $columns->{integer1}->id, + value => '10', + operator => 'greater', + }, + data => [ + [310,530,530,530,220,0,0,0,0,0,0,0,0], + [280,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,330,575,575,575,575,575,595,595,645], + ], + xlabels => [ + 'June 2018', 'July 2018', 'August 2018', 'September 2018', + 'October 2018', 'November 2018', 'December 2018', 'January 2019', + 'February 2019', 'March 2019', 'April 2019', 'May 2019', 'June 2019' + ], }, { - created => '2018-10-01T19:00', - data => { - enum1 => 1, - integer1 => 0, - } + name => 'String x-axis with y-axis sum - standard 12 month range', + type => 'bar', + x_axis => $columns->{enum1}->id, + x_axis_range => '-12', + y_axis => $columns->{integer1}->id, + y_axis_stack => 'sum', + labels => [qw/foo3 foo2 foo1/], + data => [ + [1,6,6,6,5,0,0,0,0,4,4,4,0], + [23,0,0,0,1,1,1,1,1,0,0,0,10], + [12,12,12,12,0,7,7,7,7,7,19,19,56], + ], + xlabels => [ + 'June 2018', 'July 2018', 'August 2018', 'September 2018', + 'October 2018', 'November 2018', 'December 2018', 'January 2019', + 'February 2019', 'March 2019', 'April 2019', 'May 2019', 'June 2019' + ], }, { - created => '2019-06-02T22:00', - data => { - enum1 => 3, - integer1 => 54, - } + name => 'String x-axis with y-axis sum - 1 month range', + type => 'bar', + x_axis => $columns->{enum1}->id, + x_axis_range => '-1', + y_axis => $columns->{integer1}->id, + y_axis_stack => 'sum', + labels => [qw/foo3 foo2 foo1/], + data => [ + [(4) x 31, 0], + [(0) x 31, 10], + [(19) x 19, (56) x 13], + ], + xlabels => [ + '14 May 2019', '15 May 2019', '16 May 2019', '17 May 2019', '18 May 2019', '19 May 2019', + '20 May 2019', '21 May 2019', '22 May 2019', '23 May 2019', '24 May 2019', '25 May 2019', + '26 May 2019', '27 May 2019', '28 May 2019', '29 May 2019', '30 May 2019', '31 May 2019', + '01 June 2019', '02 June 2019', '03 June 2019', '04 June 2019', '05 June 2019', '06 June 2019', + '07 June 2019', '08 June 2019', '09 June 2019', '10 June 2019', '11 June 2019', '12 June 2019', + '13 June 2019', '14 June 2019' + ] }, { - created => '2019-06-02T23:00', - data => { - enum1 => 1, - integer1 => 37, - } + name => 'String x-axis with y-axis count - custom range', + type => 'bar', + x_axis => $columns->{enum1}->id, + x_axis_range => 'custom', + x_axis_grouping => 'month', + from => DateTime->new(year => 2018, month => 1, day => 5), + to => DateTime->new(year => 2018, month => 3, day => 10), + y_axis => $columns->{integer1}->id, + y_axis_stack => 'count', + labels => [qw/foo3 foo1/], + data => [ + [1,1,1], + [0,1,1], + ], + xlabels => [ + 'January 2018', 'February 2018', 'March 2018', + ], }, - ], -); - -my $sheet = Test::GADS::DataSheet->new(data => []); -my $schema = $sheet->schema; -my $layout = $sheet->layout; -my $columns = $sheet->columns; -$sheet->create_records; - -foreach my $rec (@records) -{ - my $record = GADS::Record->new( - user => $sheet->user, - layout => $layout, - schema => $schema, - ); - $record->initialise; - foreach my $version (@$rec) - { - my $created = DateTime::Format::ISO8601->parse_datetime($version->{created}); - my $data = $version->{data}; - $record->fields->{$columns->{enum1}->id}->set_value($data->{enum1}); - $record->fields->{$columns->{integer1}->id}->set_value($data->{integer1}); - $record->write(version_datetime => $created, no_alerts => 1); - } -} + ]; -is($schema->resultset('Current')->count, 3, "Correct number of records created"); -is($schema->resultset('Record')->count, 12, "Correct number of versions created"); - -my $graphs = [ - { - name => 'String x-axis with count - standard 12 month range', - type => 'bar', - x_axis => $columns->{enum1}->id, - x_axis_range => '-12', - y_axis_stack => 'count', - labels => [qw/foo3 foo2 foo1/], - data => [ - [1,2,2,2,1,0,0,0,0,1,1,1,0], - [1,0,0,0,1,1,1,1,1,0,0,0,1], - [1,1,1,1,1,2,2,2,2,2,2,2,2], - ], - xlabels => [ - 'June 2018', 'July 2018', 'August 2018', 'September 2018', - 'October 2018', 'November 2018', 'December 2018', 'January 2019', - 'February 2019', 'March 2019', 'April 2019', 'May 2019', 'June 2019' - ], - }, - { - name => 'Including quick search', - type => 'bar', - x_axis => $columns->{enum1}->id, - x_axis_range => '-12', - y_axis_stack => 'count', - labels => [qw/foo3 foo2 foo1/], - search => 'foo2', - data => [ - [0,0,0,0,0,0,0,0,0,1,1,1,0], - [0,0,0,0,1,1,1,1,1,0,0,0,1], - [1,1,1,1,0,0,0,0,0,0,0,0,0], - ], - xlabels => [ - 'June 2018', 'July 2018', 'August 2018', 'September 2018', - 'October 2018', 'November 2018', 'December 2018', 'January 2019', - 'February 2019', 'March 2019', 'April 2019', 'May 2019', 'June 2019' - ], - }, - { - name => 'Including filter', # Should use same record IDs for each period - type => 'bar', - x_axis => $columns->{enum1}->id, - x_axis_range => '-12', - y_axis_stack => 'count', - labels => [qw/foo3 foo2 foo1/], - view => { - column => $columns->{integer1}->id, - value => '10', - }, - data => [ - [0,0,0,0,0,0,0,0,0,1,1,1,0], - [0,0,0,0,1,1,1,1,1,0,0,0,1], - [1,1,1,1,0,0,0,0,0,0,0,0,0], - ], - xlabels => [ - 'June 2018', 'July 2018', 'August 2018', 'September 2018', - 'October 2018', 'November 2018', 'December 2018', 'January 2019', - 'February 2019', 'March 2019', 'April 2019', 'May 2019', 'June 2019' - ], - }, + foreach my $g (@$graphs) { - name => 'String x-axis with y-axis sum - standard 12 month range', - type => 'bar', - x_axis => $columns->{enum1}->id, - x_axis_range => '-12', - y_axis => $columns->{integer1}->id, - y_axis_stack => 'sum', - labels => [qw/foo3 foo2 foo1/], - data => [ - [1,6,6,6,5,0,0,0,0,4,4,4,0], - [23,0,0,0,1,1,1,1,1,0,0,0,10], - [12,12,12,12,0,7,7,7,7,7,19,19,56], - ], - xlabels => [ - 'June 2018', 'July 2018', 'August 2018', 'September 2018', - 'October 2018', 'November 2018', 'December 2018', 'January 2019', - 'February 2019', 'March 2019', 'April 2019', 'May 2019', 'June 2019' - ], - }, - { - name => 'String x-axis with y-axis sum - 1 month range', - type => 'bar', - x_axis => $columns->{enum1}->id, - x_axis_range => '-1', - y_axis => $columns->{integer1}->id, - y_axis_stack => 'sum', - labels => [qw/foo3 foo2 foo1/], - data => [ - [(4) x 31, 0], - [(0) x 31, 10], - [(19) x 19, (56) x 13], - ], - xlabels => [ - '14 May 2019', '15 May 2019', '16 May 2019', '17 May 2019', '18 May 2019', '19 May 2019', - '20 May 2019', '21 May 2019', '22 May 2019', '23 May 2019', '24 May 2019', '25 May 2019', - '26 May 2019', '27 May 2019', '28 May 2019', '29 May 2019', '30 May 2019', '31 May 2019', - '01 June 2019', '02 June 2019', '03 June 2019', '04 June 2019', '05 June 2019', '06 June 2019', - '07 June 2019', '08 June 2019', '09 June 2019', '10 June 2019', '11 June 2019', '12 June 2019', - '13 June 2019', '14 June 2019' - ] - }, - { - name => 'String x-axis with y-axis count - custom range', - type => 'bar', - x_axis => $columns->{enum1}->id, - x_axis_range => 'custom', - x_axis_grouping => 'month', - from => DateTime->new(year => 2018, month => 1, day => 5), - to => DateTime->new(year => 2018, month => 3, day => 10), - y_axis => $columns->{integer1}->id, - y_axis_stack => 'count', - labels => [qw/foo3 foo1/], - data => [ - [1,1,1], - [0,1,1], - ], - xlabels => [ - 'January 2018', 'February 2018', 'March 2018', - ], - }, -]; + my $graph = GADS::Graph->new( + layout => $layout, + schema => $schema, + current_user => $sheet->user, + ); + $graph->title($g->{name}); + $graph->type($g->{type}); + $graph->trend('aggregate'); + $graph->x_axis_range($g->{x_axis_range}); + $graph->from($g->{from}); + $graph->to($g->{to}); + $graph->x_axis($g->{x_axis}); + $graph->x_axis_grouping($g->{x_axis_grouping}) + if $g->{x_axis_grouping}; + $graph->y_axis($g->{y_axis}); + $graph->y_axis_link($g->{y_axis_link}); + $graph->y_axis_stack($g->{y_axis_stack}); + $graph->group_by($g->{group_by}) + if $g->{group_by}; + $graph->write; -foreach my $g (@$graphs) -{ - my $graph = GADS::Graph->new( - layout => $layout, - schema => $schema, - current_user => $sheet->user, - ); - $graph->title($g->{name}); - $graph->type($g->{type}); - $graph->trend('aggregate'); - $graph->x_axis_range($g->{x_axis_range}); - $graph->from($g->{from}); - $graph->to($g->{to}); - $graph->x_axis($g->{x_axis}); - $graph->x_axis_grouping($g->{x_axis_grouping}) - if $g->{x_axis_grouping}; - $graph->y_axis($g->{y_axis}); - $graph->y_axis_stack($g->{y_axis_stack}); - $graph->group_by($g->{group_by}) - if $g->{group_by}; - $graph->write; + my $view; + if (my $v = $g->{view}) + { + my $rules = GADS::Filter->new( + as_hash => { + rules => [{ + id => $v->{column}, + type => 'string', + value => $v->{value}, + operator => $v->{operator} || 'equal', + }], + }, + ); + $view = GADS::View->new( + name => 'Test view', + filter => $rules, + columns => [$columns->{integer1}->id], + instance_id => $layout->instance_id, + layout => $layout, + schema => $schema, + user => $sheet->user, + ); + $view->write; + } - my $view; - if (my $v = $g->{view}) - { - my $rules = GADS::Filter->new( - as_hash => { - rules => [{ - id => $v->{column}, - type => 'string', - value => $v->{value}, - operator => 'equal', - }], - }, + my $records = GADS::RecordsGraph->new( + user => $sheet->user, + layout => $layout, + schema => $schema, + search => $g->{search}, ); - $view = GADS::View->new( - name => 'Test view', - filter => $rules, - columns => [$columns->{integer1}->id], - instance_id => $layout->instance_id, - layout => $layout, - schema => $schema, - user => $sheet->user, + my $graph_data = GADS::Graph::Data->new( + id => $graph->id, + records => $records, + schema => $schema, + view => $view, ); - $view->write; - } - my $records = GADS::RecordsGraph->new( - user => $sheet->user, - layout => $layout, - schema => $schema, - search => $g->{search}, - ); - my $graph_data = GADS::Graph::Data->new( - id => $graph->id, - records => $records, - schema => $schema, - view => $view, - ); - - is_deeply($graph_data->points, $g->{data}, "Graph data for $g->{name} is correct"); - is_deeply($graph_data->xlabels, $g->{xlabels}, "Graph xlabels for $g->{name} is correct"); - my @labels = map { $_->{label} } @{$graph_data->labels}; - is_deeply([@labels], $g->{labels}, "Graph labels for $g->{name} is correct"); + is_deeply($graph_data->points, $g->{data}, "Graph data for $g->{name} is correct"); + is_deeply($graph_data->xlabels, $g->{xlabels}, "Graph xlabels for $g->{name} is correct"); + my @labels = map { $_->{label} } @{$graph_data->labels}; + is_deeply([@labels], $g->{labels}, "Graph labels for $g->{name} is correct"); + } } done_testing(); diff --git a/t/025_approval.t b/t/025_approval.t index 28945031d..85f569167 100644 --- a/t/025_approval.t +++ b/t/025_approval.t @@ -89,4 +89,20 @@ is($records->count, 4, "Correct number of records to begin"); is(@{$records->results}, 4, "Correct number of records to begin"); is($records->results->[0]->current_id, 2, "Correct first record"); +# Check record retrieved from GADS::Records +my $live_version = $records->results->[3]; +is($live_version->current_id, 1, "Live version in correct location of sort"); +is($live_version->fields->{$string1->id}->as_string, 'Foo5', "Correct written data"); +is($live_version->fields->{$date1->id}->as_string, '2004-01-01', "Unapproved data still previous version"); + +# Check record retrieved from GADS::Record +$live_version = GADS::Record->new( + user => $sheet->user, + layout => $layout, + schema => $schema, +); +$live_version->find_current_id(1); +is($live_version->fields->{$string1->id}->as_string, 'Foo5', "Correct written data"); +is($live_version->fields->{$date1->id}->as_string, '2004-01-01', "Unapproved data still previous version"); + done_testing(); diff --git a/t/026_purge.t b/t/026_purge.t index df11125b0..5be78409e 100644 --- a/t/026_purge.t +++ b/t/026_purge.t @@ -9,8 +9,6 @@ use GADS::Record; use lib 't/lib'; use Test::GADS::DataSheet; -use Test::Simple tests => 384; - my $sheet = Test::GADS::DataSheet->new( column_count => { string => 2, @@ -101,7 +99,6 @@ foreach my $col (@cols) $record->find_current_id(1); - if($col->{new}) { $record->fields->{ $test_col->id }->set_value($col->{new}); $record->write(no_alerts => 1); @@ -159,4 +156,16 @@ foreach my $col (@cols) } } +# Test purge of whole record version +$record->find_current_id(1); +is($record->versions, 8, "Correct number of versions of record"); +my $crs = $schema->resultset('Current')->find($record->current_id); +is($crs->records->get_column('id')->max, 8, "Correct current version number"); +is($crs->current_version_id, 8, "Correct version number in parent"); +$record->purge; +$crs->discard_changes; +is($record->versions, 7, "Correct number of versions of record"); +is($crs->records->get_column('id')->max, 7, "Correct version number after rollback"); +is($crs->current_version_id, 7, "Correct version number in parent"); + done_testing(); diff --git a/t/lib/Test/GADS/DataSheet.pm b/t/lib/Test/GADS/DataSheet.pm index 0fb1159eb..3e2819f3a 100644 --- a/t/lib/Test/GADS/DataSheet.pm +++ b/t/lib/Test/GADS/DataSheet.pm @@ -479,6 +479,7 @@ has multivalue_columns => ( daterange => 1, string => 1, calc => 1, + integer => 1, }; }, ); @@ -615,6 +616,7 @@ sub __build_columns $integer->type('intgr'); $integer->name("integer$count"); $integer->name_short("L${instance_id}integer$count"); + $integer->multivalue(1) if $self->multivalue && $self->multivalue_columns->{integer}; $integer->set_permissions({$self->group->id => $permissions}) if $self->group; try { $integer->write }; diff --git a/views/data_table.tt b/views/data_table.tt index b04dac77c..1e141fb24 100755 --- a/views/data_table.tt +++ b/views/data_table.tt @@ -68,7 +68,7 @@ END; table_columns.push({ - name = col.id, + name = col.full_id, title = col.name, type = col.type, orderable = 1,