marty 2.5.9 → 2.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/db/migrate/501_create_dg_plpgsql_v1_fns.rb +22 -0
- data/db/sql/lookup_grid_distinct_v1.sql +175 -0
- data/db/sql/query_grid_dir_v1.sql +100 -0
- data/lib/marty/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5793ffa9b322a289ab5cf900d733f296127f4840586baf8a95afe8793e9752cd
|
4
|
+
data.tar.gz: 6e1e78d9cbb3472ac5ed1f99a5592cc1718ab706eb1d878265a5682408d9b130
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
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.
|
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-
|
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
|