marty 2.5.9 → 2.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ec3679621406e9c0a3d3a343f38bc89cd467a9e39c353b7a2a4911877482194d
4
- data.tar.gz: fde0d9513d1f964b7a9a7022d964971a6aa486785027e7e96ddb1da11c815807
3
+ metadata.gz: 5793ffa9b322a289ab5cf900d733f296127f4840586baf8a95afe8793e9752cd
4
+ data.tar.gz: 6e1e78d9cbb3472ac5ed1f99a5592cc1718ab706eb1d878265a5682408d9b130
5
5
  SHA512:
6
- metadata.gz: d520244f0c0e98a1ae3c779660f049663514f2062eabd837e3167bb6098754476abef431e5f9c22fdd460567c56791a7d08095b852af0c807a628c6998148cfc
7
- data.tar.gz: f6d70ee23ab6b1a571a5bb913ffc10e453169731b4e5736a8ac22ff830262b65d19e9cf81361f8e54f54fd774d64b6149f6d572c524249af8c80a9315537da95
6
+ metadata.gz: 3e47115835ddf8cff33b27b6582f73cd77f5e802099c776981aa47311bae1f11047bbba797fe5def8c8188c5ae10de6e213dff1fe37dd51c974e1d326a2c22dc
7
+ data.tar.gz: 731b6b6799978cbd72416461ca55c1243eac694b324b8df497a5193d2416569b901c610d862e84a19d58810031c38d4b22d2206280bf9ceaa2ad917b7365ab65
@@ -0,0 +1,22 @@
1
+ class CreateDgPlpgsqlV1Fns < ActiveRecord::Migration[4.2]
2
+ def up
3
+ marty_path = Gem.loaded_specs["marty"].full_gem_path
4
+ Dir.glob("#{marty_path}/db/sql/*_v1.sql") do |f|
5
+ connection.execute(File.read(f))
6
+ end
7
+
8
+ connection.execute('DROP FUNCTION IF EXISTS errinfo(err jsonb);')
9
+ end
10
+
11
+ def down
12
+ connection.execute <<-SQL
13
+ -- required to utilize plv8 extension
14
+ CREATE EXTENSION IF NOT EXISTS plv8;
15
+ SQL
16
+
17
+ marty_path = Gem.loaded_specs["marty"].full_gem_path
18
+ Dir.glob("#{marty_path}/db/js/*_v1.js") do |f|
19
+ connection.execute(Marty::Migrations.get_plv8_migration(f))
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,175 @@
1
+ CREATE OR REPLACE FUNCTION public.lookup_grid_distinct(h jsonb, row_info jsonb, return_grid_data boolean DEFAULT false, dis boolean DEFAULT false) RETURNS jsonb
2
+ LANGUAGE plpgsql
3
+ AS $_$
4
+
5
+ -- Finds a data grid metadata, calculates the SQL query for it's vertical and horizontal attributes
6
+ -- Fetches vertical and horizontal indexes and uses them to fetch value from data grid data
7
+
8
+ DECLARE
9
+ directions TEXT[] = ARRAY['h', 'v'];
10
+ direction TEXT;
11
+
12
+ data_grid_info JSONB;
13
+ data_grid_metadata JSONB;
14
+ data_grid_lenient BOOLEAN;
15
+ data_grid_data JSONB;
16
+ data_grid_name TEXT;
17
+ data_grid_group_id TEXT;
18
+ data_grid_metadata_h JSONB[];
19
+ data_grid_metadata_v JSONB[];
20
+ data_grid_metadata_current JSONB[];
21
+
22
+ horizontal_indexes JSONB = '[]'::JSONB;
23
+ horizontal_index INTEGER;
24
+
25
+ vertical_indexes JSONB = '[]'::JSONB;
26
+ vertical_index INTEGER;
27
+
28
+ query_dir_result JSONB;
29
+ query_index_result JSONB = '[]'::JSONB;
30
+ metadata_record JSONB;
31
+
32
+ all_results JSONB[];
33
+ sql_scripts_arr text[];
34
+
35
+ result JSONB;
36
+ return_json JSONB;
37
+
38
+ error_extra JSONB;
39
+
40
+ target RECORD;
41
+ BEGIN
42
+ EXECUTE 'SELECT metadata, lenient, name, data, group_id FROM marty_data_grids WHERE id = $1::INTEGER'
43
+ INTO data_grid_metadata, data_grid_lenient, data_grid_name, data_grid_data, data_grid_group_id
44
+ USING row_info ->> 'id';
45
+
46
+
47
+ data_grid_metadata := COALESCE(data_grid_metadata, '[]'::JSONB);
48
+
49
+ FOR i IN 0 .. (jsonb_array_length(data_grid_metadata) - 1) LOOP
50
+ metadata_record := data_grid_metadata -> i;
51
+ IF (metadata_record ->> 'dir') = 'h' THEN
52
+ data_grid_metadata_h := data_grid_metadata_h || metadata_record;
53
+ ELSIF (metadata_record ->> 'dir') = 'v' THEN
54
+ data_grid_metadata_v := data_grid_metadata_v || metadata_record;
55
+ END IF;
56
+ END LOOP;
57
+
58
+ FOREACH direction IN ARRAY directions LOOP
59
+
60
+ IF direction = 'h' THEN
61
+ data_grid_metadata_current := data_grid_metadata_h;
62
+ ELSE
63
+ data_grid_metadata_current := data_grid_metadata_v;
64
+ END IF;
65
+
66
+
67
+ IF COALESCE(array_length(data_grid_metadata_current, 1), 0) = 0 THEN
68
+ IF direction = 'h' THEN
69
+ horizontal_indexes := '[0]'::JSONB;
70
+ ELSE
71
+ vertical_indexes := '[0]'::JSONB;
72
+ END IF;
73
+ CONTINUE;
74
+ END IF;
75
+
76
+ -- fetch the resulting SQL query and it's arguments for current direction
77
+ EXECUTE 'SELECT public.query_grid_dir($1, $2, $3)'
78
+ INTO query_dir_result
79
+ USING h, data_grid_metadata_current, row_info;
80
+
81
+ IF query_dir_result ->> 0 IS NULL THEN
82
+ CONTINUE;
83
+ END IF;
84
+
85
+ sql_scripts_arr := sql_scripts_arr || (query_dir_result ->> 0);
86
+
87
+ query_index_result := '[]'::JSONB;
88
+
89
+ -- execute the SQL query that has been received before and
90
+ -- add it's (possibly multiple) results to query_index_result variable
91
+ FOR target IN EXECUTE query_dir_result ->> 0 USING query_dir_result -> 1 LOOP
92
+ query_index_result := query_index_result || to_jsonb(target.index);
93
+ END LOOP;
94
+
95
+ all_results := all_results || query_index_result;
96
+ query_index_result := '[]'::JSONB || query_index_result; -- Use empty JSONB array in case of NULL results
97
+
98
+ IF direction = 'h' THEN
99
+ horizontal_indexes := query_index_result;
100
+ ELSE
101
+ vertical_indexes := query_index_result;
102
+ END IF;
103
+
104
+
105
+ IF dis AND jsonb_array_length(query_index_result) > 1 THEN
106
+ RAISE EXCEPTION 'matches > 1';
107
+ END IF;
108
+
109
+ END LOOP;
110
+
111
+ vertical_indexes := COALESCE(vertical_indexes, '[]'::JSONB);
112
+ horizontal_indexes := COALESCE(horizontal_indexes, '[]'::JSONB);
113
+
114
+ IF ((jsonb_array_length(vertical_indexes)) = 0
115
+ OR (jsonb_array_length(horizontal_indexes)) = 0)
116
+ AND NOT data_grid_lenient
117
+ AND NOT return_grid_data THEN
118
+
119
+ RAISE EXCEPTION 'Data Grid lookup failed';
120
+ END IF;
121
+
122
+ -- Get the smalles vertical index
123
+ IF jsonb_array_length(vertical_indexes) > 0 THEN
124
+ FOR i IN 0 .. (jsonb_array_length(vertical_indexes) - 1) LOOP
125
+ vertical_index := LEAST(vertical_index, (vertical_indexes ->> i)::INTEGER);
126
+ END LOOP;
127
+ END IF;
128
+
129
+ -- Get the smalles horizontal index
130
+ IF jsonb_array_length(horizontal_indexes) > 0 THEN
131
+ FOR i IN 0 .. (jsonb_array_length(vertical_indexes) - 1) LOOP
132
+ horizontal_index := LEAST(horizontal_index, (horizontal_indexes ->> i)::INTEGER);
133
+ END LOOP;
134
+ END IF;
135
+
136
+ IF vertical_index IS NOT NULL and horizontal_index IS NOT NULL THEN
137
+ result := data_grid_data -> vertical_index -> horizontal_index;
138
+ END IF;
139
+
140
+ IF NOT return_grid_data THEN
141
+ data_grid_data := NULL;
142
+ data_grid_metadata := NULL;
143
+ END IF;
144
+
145
+ return_json := jsonb_build_object(
146
+ 'result', result,
147
+ 'name', data_grid_name,
148
+ 'data', data_grid_data,
149
+ 'metadata', data_grid_metadata
150
+ );
151
+
152
+ RETURN return_json;
153
+
154
+ EXCEPTION WHEN OTHERS THEN
155
+ error_extra := jsonb_build_object(
156
+ 'error', SQLERRM,
157
+ 'sql', sql_scripts_arr,
158
+ 'results', all_results,
159
+ 'params', h,
160
+ 'dg', jsonb_build_object(
161
+ 'name', data_grid_name,
162
+ 'data', data_grid_data,
163
+ 'metadata', data_grid_metadata,
164
+ 'group_id', data_grid_group_id,
165
+ 'lenient', data_grid_lenient
166
+ )
167
+ );
168
+
169
+ RETURN jsonb_build_object(
170
+ 'error', SQLERRM,
171
+ 'error_extra', error_extra
172
+ );
173
+ END
174
+
175
+ $_$;
@@ -0,0 +1,100 @@
1
+ CREATE OR REPLACE FUNCTION public.query_grid_dir(h jsonb, infos jsonb[], row_info jsonb) returns jsonb
2
+ LANGUAGE plpgsql
3
+ AS $$
4
+
5
+ -- Iterates through infos and and builds a one big SQL query
6
+ -- with one SELECT per info and INTERSECT between those SELECTs
7
+ -- in order to find the cells that multiple vertical or horizontal headers are pointing to.
8
+ -- Return JSONB array with resulting SQL query and JSONB array of it's arguments.
9
+ -- Each of the argument is references via it's index in JSONB array. Example: ($1 ->> 0)
10
+
11
+ DECLARE
12
+ args text[];
13
+ sqlidx integer = 0;
14
+ i integer;
15
+
16
+ attr_type text;
17
+ attr_name text;
18
+ attr_value text;
19
+ h_key_exists boolean;
20
+
21
+ table_name text;
22
+ sql_script text;
23
+ sql_scripts_arr text[];
24
+ sql_scripts_arr_intersect text;
25
+ sql_filter text;
26
+
27
+ BEGIN
28
+ FOR i IN 1 .. COALESCE(array_upper(infos, 1), 0)
29
+ LOOP
30
+ attr_type := infos[i] ->> 'type';
31
+ attr_name := infos[i] ->> 'attr';
32
+ attr_value := h ->> attr_name;
33
+ h_key_exists := h ? attr_name;
34
+
35
+ IF NOT h_key_exists THEN
36
+ CONTINUE;
37
+ END IF;
38
+
39
+ CASE attr_type
40
+ WHEN 'boolean' THEN
41
+ table_name := 'marty_grid_index_' || attr_type || 's';
42
+ WHEN 'numrange' THEN
43
+ table_name := 'marty_grid_index_' || attr_type || 's';
44
+ WHEN 'int4range' THEN
45
+ table_name := 'marty_grid_index_' || attr_type || 's';
46
+ WHEN 'integer' THEN
47
+ table_name := 'marty_grid_index_' || attr_type || 's';
48
+ ELSE
49
+ table_name := 'marty_grid_index_strings';
50
+ END CASE;
51
+
52
+ sql_script = 'SELECT DISTINCT index from ' || table_name ||
53
+ -- Convertion to FLOAT is neeed to make numbers like 2005.0 work
54
+ ' WHERE data_grid_id = ($1 ->> ' || sqlidx || ')::FLOAT::INTEGER' ||
55
+ ' AND created_dt = ($1 ->> ' || (sqlidx + 1) || ')::TIMESTAMP' ||
56
+ ' AND attr = $1 ->> ' || (sqlidx + 2) || ' ';
57
+
58
+ sqlidx := sqlidx + 3;
59
+
60
+ args := args || (row_info ->> 'group_id');
61
+ args := args || (row_info ->> 'created_dt');
62
+ args := args || attr_name;
63
+
64
+ IF attr_value IS NULL THEN
65
+ sql_filter := '';
66
+ ELSE
67
+ CASE attr_type
68
+ WHEN 'boolean' THEN
69
+ sql_filter := 'key = ($1 ->> ' || sqlidx || ')::BOOLEAN OR ';
70
+ WHEN 'numrange' THEN
71
+ sql_filter := 'key @> ($1 ->> ' || sqlidx || ')::NUMERIC OR ';
72
+ WHEN 'int4range' THEN
73
+ -- Convertion to FLOAT is neeed to make numbers like 2005.0 work
74
+ sql_filter := 'key @> ($1 ->> ' || sqlidx || ')::FLOAT::INTEGER OR ';
75
+ WHEN 'integer' THEN
76
+ -- Convertion to FLOAT is neeed to make numbers like 2005.0 work
77
+ sql_filter := 'key @> ARRAY[($1 ->> ' || sqlidx || ')::FLOAT::INTEGER] OR ';
78
+ ELSE
79
+ sql_filter := 'key @> ARRAY[($1 ->> ' || sqlidx || ')::TEXT] OR ';
80
+ END CASE;
81
+
82
+ sqlidx := sqlidx + 1;
83
+ args := args || attr_value;
84
+ END IF;
85
+
86
+ sql_script := sql_script || ' AND (' || sql_filter || 'key is NULL) ';
87
+
88
+ sql_scripts_arr := sql_scripts_arr || sql_script;
89
+ END LOOP;
90
+
91
+ IF array_length(sql_scripts_arr, 1) = 0 THEN
92
+ RETURN NULL;
93
+ END IF;
94
+
95
+ sql_scripts_arr_intersect := array_to_string(sql_scripts_arr, ' INTERSECT ');
96
+
97
+ RETURN json_build_array(sql_scripts_arr_intersect, args);
98
+ END;
99
+
100
+ $$;
data/lib/marty/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Marty
2
- VERSION = '2.5.9'
2
+ VERSION = '2.6.0'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: marty
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.5.9
4
+ version: 2.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Arman Bostani
@@ -14,7 +14,7 @@ authors:
14
14
  autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
- date: 2019-03-12 00:00:00.000000000 Z
17
+ date: 2019-03-25 00:00:00.000000000 Z
18
18
  dependencies:
19
19
  - !ruby/object:Gem::Dependency
20
20
  name: pg
@@ -379,7 +379,10 @@ files:
379
379
  - db/migrate/410_jsonb_promise_result.rb
380
380
  - db/migrate/411_create_vw_promises.rb
381
381
  - db/migrate/500_add_api_class_to_marty_api_config.rb
382
+ - db/migrate/501_create_dg_plpgsql_v1_fns.rb
382
383
  - db/seeds.rb
384
+ - db/sql/lookup_grid_distinct_v1.sql
385
+ - db/sql/query_grid_dir_v1.sql
383
386
  - delorean/blame_report.dl
384
387
  - delorean/diagnostics.dl
385
388
  - delorean/marty_fields.dl