-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsql_script.rb
More file actions
61 lines (54 loc) · 1.95 KB
/
sql_script.rb
File metadata and controls
61 lines (54 loc) · 1.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# Produce a script of insert statements wrapped in a transaction.
#
# Example:
#
# script = SqlScript.new(:postgresql)
# row = SqlRow.new(SqlRowType.new('lists', :id => :integer, :text => :string, :num => :numeric, :dt => :date, :tm => :time))
# row[:id] = 12
# row[:text] = 'A String'
# row[:num] = 12.123
# row[:dt] = Date.parse('2015-01-01')
# row[:tm] = Time.parse('2015-01-01 10:01:22')
# script.rows << row
# puts script.to_script #=>
# BEGIN;
# INSERT INTO lists (id, text, num, dt, tm)
# VALUES (12, 'A String', 12.123, '2015-01-01', '2015-01-01T10:01:22+02:00');
# COMMIT;
#
class SqlScript
attr_reader :db_type
attr_accessor :rows
TRANSACTION_START = {:sql_server => 'BEGIN TRANSACTION', :postgresql => 'BEGIN;'}
TRANSACTION_END = {:sql_server => "COMMIT TRANSACTION", :postgresql => 'COMMIT;'}
# Create an SqlScript. The db_type parameter must be :sql_server or :postgresql.
def initialize(db_type)
raise ArgumentError, "Unknown database type: #{db_type}" unless [:sql_server, :postgresql].include? db_type
@db_type = db_type
@rows = []
end
# Get insert_sql from rows (SqlRow) and wrap in a transaction.
# Returns String - SQL script.
def to_script
s = TRANSACTION_START[db_type].dup
s << "\n"
rows.each {|r| s << r.insert_sql(db_type) }
s << "#{TRANSACTION_END[db_type]}\n"
s
end
# Get bulk insert_sql from rows (SqlRow) and wrap in a transaction.
# For homogenous rows - does a bulk insert for every 500 rows.
# Returns String - SQL script.
def to_bulk_insert_script
s = TRANSACTION_START[db_type].dup
s << "\n"
insert_command = rows.first.bulk_insert_str
rows.each_slice(500) do |sliced_rows|
s << insert_command
s << sliced_rows.map {|row| row.bulk_insert_values_str(db_type) }.join(",\n")
s << "#{SqlRow::STATEMENT_TERMINATOR[db_type]}\n"
end
s << "#{TRANSACTION_END[db_type]}\n"
s
end
end