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 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