real_data_tests 0.3.4 → 0.3.6
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 +16 -0
- data/lib/real_data_tests/rspec_helper.rb +82 -2
- 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: 179a591f6a485c397255c0cbec27e18757e2f7fdc450f7292f279cd681f91e0b
|
4
|
+
data.tar.gz: bb9b9f4f60b609f2ea8a901689b4b9b8d5ddfdc7d36e867c18ebbe24855cb5aa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a47d49d690958e70cd324ede48dadce7d3e9e7bd39471ee052879d6fe5646ad308aebbf05f79cb92ebe3c9b7ede94b0163c74efdddf3f518ef47518a489a2ee6
|
7
|
+
data.tar.gz: a4c6a97cff1bd02096064fd1da67580dd9307ce29f4e7d5a8be4d82c9f352b97009ef1fc22eb555dc39b1b87599947680a61bc2bc376c2cd14a7f8cc5397892d
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,21 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [0.3.6] - 2025-01-14
|
4
|
+
### Fixed
|
5
|
+
- Further enhanced SQL statement handling in native loader
|
6
|
+
- Fixed handling of SQL statements with ON CONFLICT clauses
|
7
|
+
- Improved quoting for company names containing spaces
|
8
|
+
- Added proper handling of trailing semicolons
|
9
|
+
- Enhanced detection and preservation of SQL statement structure
|
10
|
+
|
11
|
+
## [0.3.5] - 2025-01-14
|
12
|
+
### Fixed
|
13
|
+
- Enhanced SQL statement handling in native loader
|
14
|
+
- Added proper UUID value quoting in VALUES clauses
|
15
|
+
- Fixed string value formatting in SQL statements
|
16
|
+
- Improved error reporting with detailed SQL statement context
|
17
|
+
- Added robust SQL statement cleaning and normalization
|
18
|
+
|
3
19
|
## [0.3.4] - 2025-01-14
|
4
20
|
### Added
|
5
21
|
- Alternative native SQL loading method for CI environments
|
@@ -39,9 +39,12 @@ module RealDataTests
|
|
39
39
|
statements.each do |statement|
|
40
40
|
next if statement.strip.empty?
|
41
41
|
begin
|
42
|
-
|
42
|
+
# Clean up any formatting issues that might cause syntax errors
|
43
|
+
cleaned_statement = clean_sql_statement(statement)
|
44
|
+
connection.execute(cleaned_statement)
|
43
45
|
rescue ActiveRecord::StatementInvalid => e
|
44
|
-
|
46
|
+
# Provide detailed error information
|
47
|
+
raise Error, "Failed to execute SQL statement: #{e.message}\nStatement: #{cleaned_statement}"
|
45
48
|
end
|
46
49
|
end
|
47
50
|
ensure
|
@@ -99,5 +102,82 @@ module RealDataTests
|
|
99
102
|
|
100
103
|
statements
|
101
104
|
end
|
105
|
+
|
106
|
+
def clean_sql_statement(statement)
|
107
|
+
# Handle VALUES clause formatting
|
108
|
+
if statement.include?('VALUES')
|
109
|
+
# Split into pre-VALUES and VALUES parts
|
110
|
+
parts = statement.split(/VALUES\s*\(/i, 2)
|
111
|
+
if parts.length == 2
|
112
|
+
# Get the column names from the first part
|
113
|
+
column_names = parts[0].scan(/\((.*?)\)/).flatten.first&.split(',')&.map(&:strip) || []
|
114
|
+
|
115
|
+
# Split values into individual items
|
116
|
+
values_part = parts[1]
|
117
|
+
values = split_values(values_part)
|
118
|
+
|
119
|
+
# Process each value according to its column and position
|
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
|
141
|
+
end
|
142
|
+
|
143
|
+
statement
|
144
|
+
end
|
145
|
+
|
146
|
+
def split_values(values_part)
|
147
|
+
values = []
|
148
|
+
current_value = ''
|
149
|
+
in_quotes = false
|
150
|
+
in_json = false
|
151
|
+
depth = 0
|
152
|
+
|
153
|
+
values_part.chars.each_with_index do |char, i|
|
154
|
+
case char
|
155
|
+
when "'"
|
156
|
+
# Toggle quote state if not escaped
|
157
|
+
if i == 0 || values_part[i-1] != '\\'
|
158
|
+
in_quotes = !in_quotes
|
159
|
+
end
|
160
|
+
when '{'
|
161
|
+
depth += 1 unless in_quotes
|
162
|
+
in_json = true unless in_quotes
|
163
|
+
when '}'
|
164
|
+
depth -= 1 unless in_quotes
|
165
|
+
when ','
|
166
|
+
if !in_quotes && depth == 0
|
167
|
+
values << current_value.strip
|
168
|
+
current_value = ''
|
169
|
+
next
|
170
|
+
end
|
171
|
+
end
|
172
|
+
current_value << char
|
173
|
+
end
|
174
|
+
|
175
|
+
# Add the last value (remove trailing ';' or ')')
|
176
|
+
last_value = current_value.strip
|
177
|
+
last_value = last_value[0..-2] if last_value.end_with?(';', ')')
|
178
|
+
values << last_value
|
179
|
+
|
180
|
+
values
|
181
|
+
end
|
102
182
|
end
|
103
183
|
end
|