real_data_tests 0.3.6 → 0.3.7
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/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
|