json2sql 1.0.1 → 1.0.3

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: 3caea0aaaaac6b6bdc5fe29341cf711d7ce2c34a0752fd06bfd246eacfc4c1df
4
- data.tar.gz: 49341acb1ed445eaf48ed6dd0cee2fff492105f3f823d7e4d415671acf4208d0
3
+ metadata.gz: '081df2cfbe162d78f93d112d4566e0639af9770ba8f26b4cba40e98d518cf749'
4
+ data.tar.gz: 45c1664023f707fe8c09a18a2d184d6af26ac199534ce92f6cb1b969a234a7e7
5
5
  SHA512:
6
- metadata.gz: '09d2615939602fe80edcec47e521ddf58678aab8c048336795129fdda56061d6a38d109bfc0a4321cfc05298c83df0884a79d097b4e5655e4b544b0f0a4d343b'
7
- data.tar.gz: c46959b88dd70ea6f8981ab7ae6484281e77ec75d82dc06a197af7f9cdefdd5566522a1e050e5a910ab0f7463fbd5fdc12ef5705d1a08358d571596b98f7ebf5
6
+ metadata.gz: 7fac86cfbbd4aca360ae717528e4bbb43a3d98e9e452e4e339f30a07d9cb19f11498cbd7ae9640509ce934dc2efc0aec401685e43bfd82e9e9ef4e17d768376f
7
+ data.tar.gz: 01b3370c8936fde70bf803cb257095ae778e008fa63ca98b0eac8f28c2a0b430a0dfc8492aec4ec49eafa4adddd49464e63306d752426e1058a9ec21ed0a258a
@@ -61,20 +61,20 @@ module Json2sql
61
61
  build_offset(params)
62
62
  end
63
63
 
64
- # SELECT JSON_ARRAYAGG(JSON_OBJECT(...)) AS `table`
64
+ # SELECT COALESCE(JSON_ARRAYAGG(JSON_OBJECT(...)), JSON_ARRAY()) AS `table`
65
65
  # FROM LATERAL (SELECT * FROM `table` WHERE ... ORDER ... LIMIT ...) AS `table`
66
66
 
67
67
  def build_query_array(params)
68
68
 
69
69
  @sep = false
70
70
 
71
- @sql << "SELECT JSON_ARRAYAGG(JSON_OBJECT("
71
+ @sql << "SELECT COALESCE(JSON_ARRAYAGG(JSON_OBJECT("
72
72
 
73
73
  build_columns_json(params)
74
74
  build_columns_array(params)
75
75
  build_columns_object(params)
76
76
 
77
- @sql << ")) AS "
77
+ @sql << ")), JSON_ARRAY()) AS "
78
78
 
79
79
  @sql << Sanitizer.keyword_wrap(@table)
80
80
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Json2sql
4
- VERSION = "1.0.1"
4
+ VERSION = "1.0.3"
5
5
  end
@@ -41,26 +41,24 @@ module Json2sql
41
41
 
42
42
  return unless has_relation || has_where_and || has_where_or
43
43
 
44
- @sql << " WHERE "
44
+ parts = []
45
45
 
46
- if has_relation
46
+ parts << with_buffer { @relation.build_table_relation(@sql, @table) } if has_relation
47
47
 
48
- @relation.build_table_relation(@sql, @table)
48
+ scope = has_where_and ? " AND " : " OR "
49
+
50
+ group = params["and"] || params["or"]
49
51
 
50
- @sql << " AND " if has_where_and || has_where_or
51
- end
52
-
53
- if has_where_and
52
+ if group
54
53
 
55
- build_column_group(params["and"], " AND ")
54
+ frag = build_column_group(group, scope)
56
55
 
57
- return
56
+ parts << frag unless frag.empty?
58
57
  end
59
58
 
60
- if has_where_or
59
+ return if parts.empty?
61
60
 
62
- build_column_group(params["or"], " OR ")
63
- end
61
+ @sql << " WHERE " << parts.join(" AND ")
64
62
  end
65
63
 
66
64
  private
@@ -71,20 +69,16 @@ module Json2sql
71
69
 
72
70
  def build_column_group(params, scope)
73
71
 
74
- @sql << "("
75
-
76
- glue = false
72
+ fragments = params.filter_map do |key, value|
77
73
 
78
- params.each do |key, value|
74
+ frag = with_buffer { build_column_types(value, scope, key.to_s) }
79
75
 
80
- @sql << scope if glue
81
-
82
- glue = true
83
-
84
- build_column_types(value, scope, key.to_s)
76
+ frag.empty? ? nil : frag
85
77
  end
86
78
 
87
- @sql << ")"
79
+ return "" if fragments.empty?
80
+
81
+ "(" + fragments.join(scope) + ")"
88
82
  end
89
83
 
90
84
  # Dispatch by Ruby type of the value.
@@ -92,6 +86,7 @@ module Json2sql
92
86
  def build_column_types(params, scope, column)
93
87
 
94
88
  case params
89
+
95
90
  when TrueClass, FalseClass
96
91
 
97
92
  build_action_types(params, column, "=")
@@ -108,15 +103,23 @@ module Json2sql
108
103
 
109
104
  if column == "and"
110
105
 
111
- build_column_group(params, " AND ")
106
+ frag = build_column_group(params, " AND ")
107
+
108
+ @sql << frag unless frag.empty?
112
109
 
113
- elsif column == "or"
110
+ return
111
+ end
112
+
113
+ if column == "or"
114
+
115
+ frag = build_column_group(params, " OR ")
114
116
 
115
- build_column_group(params, " OR ")
117
+ @sql << frag unless frag.empty?
116
118
 
117
- else
118
- build_action_group(params, scope, column)
119
+ return
119
120
  end
121
+
122
+ build_action_group(params, scope, column)
120
123
  end
121
124
  end
122
125
 
@@ -126,16 +129,14 @@ module Json2sql
126
129
 
127
130
  def build_action_group(params, scope, column)
128
131
 
129
- glue = false
130
-
131
- params.each do |key, value|
132
+ fragments = params.filter_map do |key, value|
132
133
 
133
- @sql << scope if glue
134
+ frag = with_buffer { build_action_types(value, column, key.to_s) }
134
135
 
135
- glue = true
136
-
137
- build_action_types(value, column, key.to_s)
136
+ frag.empty? ? nil : frag
138
137
  end
138
+
139
+ @sql << fragments.join(scope) unless fragments.empty?
139
140
  end
140
141
 
141
142
  def build_action_types(params, column, action)
@@ -164,20 +165,20 @@ module Json2sql
164
165
  def build_action_values(params, column, action) # rubocop:disable Metrics/MethodLength
165
166
 
166
167
  case params
168
+
167
169
  when TrueClass, FalseClass
168
170
 
169
171
  # Only "null" → IS NULL / IS NOT NULL. Boolean equality is not emitted
170
172
  # (matches C++ behaviour — use integer 1/0 for boolean equality).
171
- if action == "null"
173
+ return unless action == "null"
172
174
 
173
- action_str = params ? " IS " : " IS NOT "
175
+ action_str = params ? " IS " : " IS NOT "
174
176
 
175
- @sql << Sanitizer.keyword_wrap(@table) << "."
177
+ @sql << Sanitizer.keyword_wrap(@table) << "."
176
178
 
177
- @sql << Sanitizer.keyword_wrap(column)
179
+ @sql << Sanitizer.keyword_wrap(column)
178
180
 
179
- @sql << action_str << "NULL"
180
- end
181
+ @sql << action_str << "NULL"
181
182
 
182
183
  when Integer
183
184
 
@@ -238,6 +239,7 @@ module Json2sql
238
239
  action_name = get_action(action)
239
240
 
240
241
  case action_name
242
+
241
243
  when "last"
242
244
 
243
245
  @sql << Sanitizer.keyword_wrap(@table) << "."
@@ -264,26 +266,20 @@ module Json2sql
264
266
 
265
267
  else
266
268
 
267
- if params.start_with?("$.")
269
+ @sql << Sanitizer.keyword_wrap(@table) << "."
268
270
 
269
- @sql << Sanitizer.keyword_wrap(@table) << "."
271
+ @sql << Sanitizer.keyword_wrap(column)
270
272
 
271
- @sql << Sanitizer.keyword_wrap(column)
273
+ @sql << " #{action_name} "
272
274
 
273
- @sql << " #{action_name} "
275
+ if params.start_with?("$.")
274
276
 
275
277
  @sql << Sanitizer.reference(params)
276
278
 
277
- else
278
-
279
- @sql << Sanitizer.keyword_wrap(@table) << "."
280
-
281
- @sql << Sanitizer.keyword_wrap(column)
282
-
283
- @sql << " #{action_name} "
284
-
285
- @sql << Sanitizer.value_wrap(params)
279
+ return
286
280
  end
281
+
282
+ @sql << Sanitizer.value_wrap(params)
287
283
  end
288
284
  end
289
285
 
@@ -347,6 +343,26 @@ module Json2sql
347
343
  end
348
344
  end
349
345
 
346
+ # -------------------------------------------------------------------------
347
+ # Buffer helper — temporarily swap @sql for a fresh string so that any
348
+ # downstream << calls are captured in isolation. Returns the captured fragment.
349
+ # -------------------------------------------------------------------------
350
+
351
+ def with_buffer
352
+
353
+ saved = @sql
354
+
355
+ @sql = +""
356
+
357
+ yield
358
+
359
+ @sql
360
+
361
+ ensure
362
+
363
+ @sql = saved
364
+ end
365
+
350
366
  # -------------------------------------------------------------------------
351
367
  # Operator mapping
352
368
  # -------------------------------------------------------------------------
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: json2sql
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tiago da Silva