real_data_tests 0.3.6 → 0.3.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/lib/real_data_tests/rspec_helper.rb +68 -66
- data/lib/real_data_tests/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f325960594ac352b4fbaae4adafb38256bde54feed249140838971e61c5fcef1
|
4
|
+
data.tar.gz: d977dda68eac4fa8d13c82dc5a00bba7dd3b27e9c876ab5847a3b3b254cc7d4f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 40c69c54f989318441e697487673f7c019907cddcea3d81fa9b5775964fc2a6a76994b97093465d57f26521813780292f58d28f11ed75638222b458a75e514f8
|
7
|
+
data.tar.gz: bce1cd39d64e2501b222135477c7e10d38769ae26b47827c3c76efb8d2651cdffae689ad3c8e2bb9bd0bdd1315e9f2dbfcdd3dd576079589c75d3d7585c2668c
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [0.3.7] - 2025-01-14
|
4
|
+
### Fixed
|
5
|
+
- Corrected SQL value handling in native loader
|
6
|
+
- Fixed boolean value handling, particularly at the end of VALUES clauses
|
7
|
+
- Improved handling of NULL values and numbers
|
8
|
+
- Added proper whitespace cleaning for values
|
9
|
+
- Enhanced value type detection for correct quoting
|
10
|
+
|
3
11
|
## [0.3.6] - 2025-01-14
|
4
12
|
### Fixed
|
5
13
|
- Further enhanced SQL statement handling in native loader
|
@@ -103,81 +103,83 @@ module RealDataTests
|
|
103
103
|
statements
|
104
104
|
end
|
105
105
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
values.each_with_index do |value, i|
|
121
|
-
# Skip if already properly quoted
|
122
|
-
next if value.start_with?("'") && value.end_with?("'")
|
123
|
-
|
124
|
-
# Quote UUIDs
|
125
|
-
if value.match?(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i)
|
126
|
-
values[i] = "'#{value}'"
|
127
|
-
# Quote any non-NULL string values that contain spaces or special characters
|
128
|
-
elsif !['NULL', 'true', 'false'].include?(value) &&
|
129
|
-
!value.match?(/^\d+$/) && # not a number
|
130
|
-
!value.start_with?("'{") && # not a JSON object
|
131
|
-
!value.start_with?("'") # not already quoted
|
132
|
-
values[i] = "'#{value}'"
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
# Reassemble the statement with any trailing ON CONFLICT clause
|
137
|
-
remainder = values_part.match(/\)\s*(ON\s+CONFLICT.*?)(;?\s*$)/i)
|
138
|
-
statement = parts[0] + 'VALUES (' + values.join(', ') + ')'
|
139
|
-
statement += " #{remainder[1]};" if remainder
|
140
|
-
end
|
106
|
+
def clean_sql_statement(statement)
|
107
|
+
# Extract the ON CONFLICT clause if it exists
|
108
|
+
statement, conflict_clause = extract_conflict_clause(statement)
|
109
|
+
|
110
|
+
# Handle VALUES clause formatting
|
111
|
+
if statement.include?('VALUES')
|
112
|
+
# Split into pre-VALUES and VALUES parts
|
113
|
+
parts = statement.split(/VALUES\s*\(/i, 2)
|
114
|
+
if parts.length == 2
|
115
|
+
# Clean and process the values
|
116
|
+
values = clean_values(parts[1].split(/\)\s*$/)[0])
|
117
|
+
|
118
|
+
# Reassemble the statement
|
119
|
+
statement = "#{parts[0]}VALUES (#{values})"
|
141
120
|
end
|
121
|
+
end
|
122
|
+
|
123
|
+
# Add back the conflict clause if it existed
|
124
|
+
statement += " #{conflict_clause}" if conflict_clause
|
125
|
+
statement += ";"
|
126
|
+
|
127
|
+
statement
|
128
|
+
end
|
142
129
|
|
143
|
-
|
130
|
+
def extract_conflict_clause(statement)
|
131
|
+
if statement =~ /(.+?)(\s+ON\s+CONFLICT\s+.*?)(?:;?\s*$)/i
|
132
|
+
[$1, $2.strip]
|
133
|
+
else
|
134
|
+
[statement.sub(/;?\s*$/, ''), nil]
|
144
135
|
end
|
136
|
+
end
|
145
137
|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
next
|
170
|
-
end
|
138
|
+
def clean_values(values_str)
|
139
|
+
values = []
|
140
|
+
current_value = ''
|
141
|
+
in_quotes = false
|
142
|
+
nested_level = 0
|
143
|
+
|
144
|
+
values_str.chars.each do |char|
|
145
|
+
case char
|
146
|
+
when "'"
|
147
|
+
in_quotes = !in_quotes
|
148
|
+
current_value << char
|
149
|
+
when '{'
|
150
|
+
nested_level += 1
|
151
|
+
current_value << char
|
152
|
+
when '}'
|
153
|
+
nested_level -= 1
|
154
|
+
current_value << char
|
155
|
+
when ','
|
156
|
+
if !in_quotes && nested_level == 0
|
157
|
+
values << clean_value(current_value.strip)
|
158
|
+
current_value = ''
|
159
|
+
else
|
160
|
+
current_value << char
|
171
161
|
end
|
162
|
+
else
|
172
163
|
current_value << char
|
173
164
|
end
|
165
|
+
end
|
166
|
+
|
167
|
+
values << clean_value(current_value.strip)
|
168
|
+
values.join(', ')
|
169
|
+
end
|
174
170
|
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
171
|
+
def clean_value(value)
|
172
|
+
return value if value.start_with?("'") # Already quoted
|
173
|
+
return value if value.start_with?("'{") # JSON object
|
174
|
+
return 'NULL' if value.upcase == 'NULL'
|
175
|
+
return value.downcase if ['true', 'false'].include?(value.downcase)
|
176
|
+
return value if value.match?(/^\d+$/) # Numbers
|
179
177
|
|
180
|
-
|
178
|
+
if value.match?(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i)
|
179
|
+
"'#{value}'" # UUID
|
180
|
+
else
|
181
|
+
"'#{value}'" # Other strings
|
181
182
|
end
|
183
|
+
end
|
182
184
|
end
|
183
185
|
end
|