diff --git a/lib/sql_query.rb b/lib/sql_query.rb index 23b7b04..3795851 100644 --- a/lib/sql_query.rb +++ b/lib/sql_query.rb @@ -78,8 +78,16 @@ def initialize def prepare_query(for_logs) query_template = File.read(file_path) - query_template = query_template.gsub(/(\n|\s)+/, ' ') if for_logs - ERB.new(query_template).result(binding) + rendered_sql = ERB.new(query_template).result(binding) + + return rendered_sql unless for_logs + + # Normalize whitespace while preserving SQL quoted strings + # Matches: 'single-quoted' OR "double-quoted" OR (whitespace) + # Only captures whitespace when NOT inside quotes + rendered_sql.gsub(/'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|(\s+)/) do |match| + ::Regexp.last_match(1) ? ' ' : match # Replace whitespace with space, preserve quoted strings + end end def split_to_path_and_name(file) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 67a4845..0349788 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -33,23 +33,13 @@ def BigDecimal.new(...) mocks.verify_partial_doubles = true end - connection_config = if ENV['CI'] - { - adapter: 'postgresql', - host: 'localhost', - username: 'postgres', - password: 'postgres', - database: 'sqlquery_test' - } - else - { - adapter: 'postgresql', - host: 'localhost', - username: 'sqlquery', - password: 'sqlquery', - database: 'sqlquery' - } - end + connection_config = { + adapter: 'postgresql', + host: 'localhost', + username: 'postgres', + password: 'postgres', + database: 'sqlquery_test' + } ActiveRecord::Base.establish_connection(connection_config) diff --git a/spec/sql_queries/multiline_erb.sql.erb b/spec/sql_queries/multiline_erb.sql.erb new file mode 100644 index 0000000..8ba41f7 --- /dev/null +++ b/spec/sql_queries/multiline_erb.sql.erb @@ -0,0 +1,9 @@ +<% + field1 = @field1 || 'default1' + field2 = @field2 || 'default2' +%> +SELECT + <%= quote field1 %> as field1, + <%= quote field2 %> as field2 +FROM players +WHERE email = <%= quote @email %> diff --git a/spec/sql_query_spec.rb b/spec/sql_query_spec.rb index 390153b..11cbb70 100644 --- a/spec/sql_query_spec.rb +++ b/spec/sql_query_spec.rb @@ -211,6 +211,22 @@ class Model < ActiveRecord::Base .to eq("SELECT * FROM players WHERE email = ' e@mail.dev ' ") end end + + context 'when template has multiline ERB blocks' do + let(:file_name) { :multiline_erb } + let(:options) { { email: 'test@dev.com', field1: 'val1', field2: 'val2' } } + let(:query) { described_class.new(file_name, options) } + + it 'processes multiline ERB correctly without syntax errors' do + expect { query.prepared_for_logs }.not_to raise_error + end + + it 'includes rendered values in prepared_for_logs output' do + result = query.prepared_for_logs + expect(result).to include("'val1' as field1") + expect(result).to include("'val2' as field2") + end + end end describe '.config' do