real_data_tests 0.3.15 → 0.3.17
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1 -41
- data/lib/real_data_tests/rspec_helper.rb +94 -25
- 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: 52310e31cdfaa0e019824607ff10a0b06a99381ab559cbe50f5922a9f7f8cea1
|
4
|
+
data.tar.gz: 777d70960ae3d1905cff453d7b6ea96ffc581492907691bd38a9a9d205ed63cb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 042425555c4a9b6d538217aefb9faa2502cbd7753ccdb68169ff4a45d08cc1af1b0258737d3c79e5c4be19f1754e8efe11764eac5d0130ab0ed6606b0823b0aa
|
7
|
+
data.tar.gz: 49c59d9646ccdafbad9ab00c18261f5fee1310059e4e10ffc2505a1fc65913c4918d6e22ef94a8fb727cf4e7bfcfba8eecd813945bf09fbda80801c723fef4e8
|
data/CHANGELOG.md
CHANGED
@@ -1,46 +1,6 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
-
## [0.3.
|
4
|
-
### Fixed
|
5
|
-
- Enhanced SQL statement parsing in native loader
|
6
|
-
- Improved handling of complex ON CONFLICT clauses with multiple closing parentheses
|
7
|
-
- Fixed spacing issues between VALUES and ON CONFLICT clauses
|
8
|
-
- Enhanced regex pattern for more precise conflict clause extraction
|
9
|
-
- Added proper statement reassembly for complex SQL structures
|
10
|
-
|
11
|
-
## [0.3.9] - 2025-01-14
|
12
|
-
### Fixed
|
13
|
-
- Enhanced SQL statement parsing in native loader
|
14
|
-
- Improved handling of complex ON CONFLICT clauses with multiple closing parentheses
|
15
|
-
- Fixed spacing issues between VALUES and ON CONFLICT clauses
|
16
|
-
- Enhanced regex pattern for more precise conflict clause extraction
|
17
|
-
- Added proper statement reassembly for complex SQL structures
|
18
|
-
|
19
|
-
## [0.3.8] - 2025-01-14
|
20
|
-
### Fixed
|
21
|
-
- Enhanced SQL statement parsing in native loader
|
22
|
-
- Improved handling of complex ON CONFLICT clauses with multiple closing parentheses
|
23
|
-
- Fixed spacing issues between VALUES and ON CONFLICT clauses
|
24
|
-
- Enhanced regex pattern for more precise conflict clause extraction
|
25
|
-
- Added proper statement reassembly for complex SQL structures
|
26
|
-
|
27
|
-
## [0.3.7] - 2025-01-14
|
28
|
-
### Fixed
|
29
|
-
- Corrected SQL value handling in native loader
|
30
|
-
- Fixed boolean value handling, particularly at the end of VALUES clauses
|
31
|
-
- Improved handling of NULL values and numbers
|
32
|
-
- Added proper whitespace cleaning for values
|
33
|
-
- Enhanced value type detection for correct quoting
|
34
|
-
|
35
|
-
## [0.3.6] - 2025-01-14
|
36
|
-
### Fixed
|
37
|
-
- Further enhanced SQL statement handling in native loader
|
38
|
-
- Fixed handling of SQL statements with ON CONFLICT clauses
|
39
|
-
- Improved quoting for company names containing spaces
|
40
|
-
- Added proper handling of trailing semicolons
|
41
|
-
- Enhanced detection and preservation of SQL statement structure
|
42
|
-
|
43
|
-
## [0.3.5] - 2025-01-14
|
3
|
+
## [0.3.5 - 0.3.17] - 2025-01-14
|
44
4
|
### Fixed
|
45
5
|
- Enhanced SQL statement handling in native loader
|
46
6
|
- Added proper UUID value quoting in VALUES clauses
|
@@ -90,36 +90,80 @@ module RealDataTests
|
|
90
90
|
options.join(" ")
|
91
91
|
end
|
92
92
|
|
93
|
+
class SqlBlock
|
94
|
+
attr_reader :type, :content, :table_name
|
95
|
+
|
96
|
+
def initialize(content)
|
97
|
+
@content = content.strip
|
98
|
+
@type = determine_block_type
|
99
|
+
@table_name = extract_table_name if @type == :insert
|
100
|
+
end
|
101
|
+
|
102
|
+
private
|
103
|
+
|
104
|
+
def determine_block_type
|
105
|
+
if @content.match?(/\AINSERT INTO/i)
|
106
|
+
:insert
|
107
|
+
elsif @content.match?(/\ACOPY.*FROM stdin/i)
|
108
|
+
:copy
|
109
|
+
elsif @content.match?(/\AALTER TABLE/i)
|
110
|
+
:alter
|
111
|
+
elsif @content.match?(/\ASET/i)
|
112
|
+
:set
|
113
|
+
else
|
114
|
+
:other
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def extract_table_name
|
119
|
+
if @content =~ /INSERT INTO\s+"?([^\s"(]+)"?\s/i
|
120
|
+
$1
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
93
125
|
def parse_sql_blocks(content)
|
94
126
|
blocks = []
|
95
127
|
current_block = []
|
96
128
|
in_copy_block = false
|
97
129
|
|
98
130
|
content.each_line do |line|
|
99
|
-
line = line.
|
100
|
-
|
131
|
+
line = line.chomp
|
132
|
+
|
133
|
+
# Skip empty lines and comments unless in COPY block
|
134
|
+
next if !in_copy_block && (line.empty? || line.start_with?('--'))
|
101
135
|
|
102
|
-
|
136
|
+
# Handle start of COPY block
|
137
|
+
if !in_copy_block && line.upcase.match?(/\ACOPY.*FROM stdin/i)
|
138
|
+
current_block = [line]
|
103
139
|
in_copy_block = true
|
140
|
+
next
|
141
|
+
end
|
142
|
+
|
143
|
+
# Handle end of COPY block
|
144
|
+
if in_copy_block && line == '\\.'
|
104
145
|
current_block << line
|
105
|
-
|
146
|
+
blocks << SqlBlock.new(current_block.join("\n"))
|
147
|
+
current_block = []
|
106
148
|
in_copy_block = false
|
149
|
+
next
|
150
|
+
end
|
151
|
+
|
152
|
+
# Accumulate lines in COPY block
|
153
|
+
if in_copy_block
|
107
154
|
current_block << line
|
155
|
+
next
|
156
|
+
end
|
157
|
+
|
158
|
+
# Handle regular SQL statements
|
159
|
+
current_block << line
|
160
|
+
if line.end_with?(';')
|
108
161
|
blocks << SqlBlock.new(current_block.join("\n"))
|
109
162
|
current_block = []
|
110
|
-
elsif in_copy_block
|
111
|
-
current_block << line
|
112
|
-
else
|
113
|
-
# Handle regular SQL statements
|
114
|
-
current_block << line
|
115
|
-
if line.end_with?(';') && !in_copy_block
|
116
|
-
blocks << SqlBlock.new(current_block.join("\n"))
|
117
|
-
current_block = []
|
118
|
-
end
|
119
163
|
end
|
120
164
|
end
|
121
165
|
|
122
|
-
#
|
166
|
+
# Handle any remaining block
|
123
167
|
blocks << SqlBlock.new(current_block.join("\n")) unless current_block.empty?
|
124
168
|
blocks
|
125
169
|
end
|
@@ -136,29 +180,54 @@ module RealDataTests
|
|
136
180
|
end
|
137
181
|
|
138
182
|
def execute_insert_block(block, index, total)
|
139
|
-
puts "Executing INSERT block #{index}/#{total} for table: #{block.table_name}"
|
140
|
-
|
141
|
-
|
183
|
+
# puts "Executing INSERT block #{index}/#{total} for table: #{block.table_name}"
|
184
|
+
# Don't modify statements that already end with semicolon
|
185
|
+
statement = if block.content.strip.end_with?(';')
|
186
|
+
block.content
|
187
|
+
else
|
188
|
+
"#{block.content};"
|
189
|
+
end
|
190
|
+
|
191
|
+
begin
|
192
|
+
ActiveRecord::Base.connection.execute(statement)
|
193
|
+
rescue ActiveRecord::StatementInvalid => e
|
194
|
+
if e.message.include?('syntax error at or near "ON"')
|
195
|
+
# Try alternative formatting for ON CONFLICT
|
196
|
+
modified_statement = statement.gsub(/\)\s+ON\s+CONFLICT/, ') ON CONFLICT')
|
197
|
+
ActiveRecord::Base.connection.execute(modified_statement)
|
198
|
+
else
|
199
|
+
raise
|
200
|
+
end
|
201
|
+
end
|
142
202
|
end
|
143
203
|
|
144
204
|
def execute_copy_block(block, index, total)
|
145
|
-
puts "Executing COPY block #{index}/#{total}"
|
205
|
+
# puts "Executing COPY block #{index}/#{total}"
|
146
206
|
ActiveRecord::Base.connection.execute(block.content)
|
147
207
|
end
|
148
208
|
|
149
209
|
def execute_regular_block(block, index, total)
|
150
|
-
puts "Executing block #{index}/#{total} of type: #{block.type}"
|
210
|
+
# puts "Executing block #{index}/#{total} of type: #{block.type}"
|
151
211
|
ActiveRecord::Base.connection.execute(block.content)
|
152
212
|
end
|
153
213
|
|
154
214
|
def normalize_insert_statement(statement)
|
155
|
-
#
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
215
|
+
# First clean up any excess whitespace around parentheses
|
216
|
+
statement = statement.gsub(/\(\s+/, '(')
|
217
|
+
.gsub(/\s+\)/, ')')
|
218
|
+
.gsub(/\)\s+ON\s+CONFLICT/, ') ON CONFLICT')
|
219
|
+
|
220
|
+
# Ensure proper spacing around ON CONFLICT
|
221
|
+
if statement =~ /(.*?)\s*ON\s+CONFLICT\s+(.*?)\s*(?:DO\s+.*?)?\s*;\s*\z/i
|
222
|
+
base = $1.strip
|
223
|
+
conflict_part = $2.strip
|
224
|
+
action_part = $3&.strip || 'DO NOTHING'
|
225
|
+
|
226
|
+
# Rebuild the statement with consistent formatting
|
227
|
+
"#{base} ON CONFLICT #{conflict_part} #{action_part};"
|
160
228
|
else
|
161
|
-
|
229
|
+
# If no ON CONFLICT clause, just clean up the spacing
|
230
|
+
statement.strip.sub(/;?\s*$/, ';')
|
162
231
|
end
|
163
232
|
end
|
164
233
|
|