real_data_tests 0.3.15 → 0.3.17

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: 9b6d2be28f1fa0fc3982e0d8bb4927ea8f25eb1701d0c77059ec6a4059cb33ee
4
- data.tar.gz: 19f5865fbb86760845c079a5b46ba49231533a33a91596e2b7c73438ca3941eb
3
+ metadata.gz: 52310e31cdfaa0e019824607ff10a0b06a99381ab559cbe50f5922a9f7f8cea1
4
+ data.tar.gz: 777d70960ae3d1905cff453d7b6ea96ffc581492907691bd38a9a9d205ed63cb
5
5
  SHA512:
6
- metadata.gz: 6d68fbb46440b6950ec57363bbd995ea64503c41c9c66955ad1ad28b9338f51798a7aad945238e0a61c7654651a365b80056b3108e4dff1d2486b5c77cfad91c
7
- data.tar.gz: e82c24d4082fb0d5e4e56e6de6cfd0e7130029057f2fa993e4f9bffdc2c5583bde94ee7c224535890f7e74ae01d8dd08ad670e2daef20041d572bf9845955fe8
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.10] - 2025-01-14
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.strip
100
- next if line.empty? || line.start_with?('--')
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
- if line.upcase.start_with?('COPY') && line.upcase.include?('FROM stdin')
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
- elsif line == '\.' && in_copy_block
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
- # Add any remaining block
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
- statement = normalize_insert_statement(block.content)
141
- ActiveRecord::Base.connection.execute(statement)
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
- # Handle ON CONFLICT clauses properly
156
- if statement =~ /(.*?)\s+(ON\s+CONFLICT.*?)\s*;\s*\z/i
157
- main_insert = $1
158
- conflict_clause = $2
159
- "#{main_insert} #{conflict_clause};"
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
- statement
229
+ # If no ON CONFLICT clause, just clean up the spacing
230
+ statement.strip.sub(/;?\s*$/, ';')
162
231
  end
163
232
  end
164
233
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RealDataTests
4
- VERSION = "0.3.15"
4
+ VERSION = "0.3.17"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: real_data_tests
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.15
4
+ version: 0.3.17
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin Dias