GFunk911-dataload 0.9.1 → 0.9.2
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.
- data/VERSION.yml +1 -1
- data/lib/dataload.rb +9 -2
- data/lib/dataload/batch_insert.rb +29 -3
- data/lib/dataload/master_loader.rb +5 -0
- data/lib/dataload/sqlserver_ext.rb +40 -0
- data/lib/dataload/table_loader.rb +14 -4
- metadata +3 -1
data/VERSION.yml
CHANGED
data/lib/dataload.rb
CHANGED
@@ -22,13 +22,20 @@ class Dataload
|
|
22
22
|
end
|
23
23
|
|
24
24
|
class DataloadLogger
|
25
|
+
fattr(:first) { true }
|
25
26
|
def log(str)
|
26
|
-
File.
|
27
|
+
File.create(current_filename,"") if first
|
28
|
+
File.append(timestamp_filename,"#{Time.now.short_dt} #{str}\n")
|
29
|
+
File.append(current_filename,"#{Time.now.short_dt} #{str}\n")
|
30
|
+
self.first = false
|
27
31
|
end
|
28
|
-
fattr(:
|
32
|
+
fattr(:timestamp_filename) do
|
29
33
|
t = Time.now.strftime("%Y%m%d%H%M%S")
|
30
34
|
res = File.expand_path("dataload_#{t}.log")
|
31
35
|
puts "Logging to #{res}"
|
32
36
|
res
|
33
37
|
end
|
38
|
+
fattr(:current_filename) do
|
39
|
+
File.expand_path("dataload.log")
|
40
|
+
end
|
34
41
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
class StandardBatchInsert
|
2
2
|
include FromHash
|
3
|
-
attr_accessor :rows, :table_name
|
3
|
+
attr_accessor :rows, :table_name, :ar_class, :block_size
|
4
4
|
fattr(:column_names) { rows.first.sorted_column_names }
|
5
5
|
fattr(:values_sql) do
|
6
6
|
"VALUES " + rows.map { |x| x.insert_values_sql }.join(", ")
|
@@ -15,6 +15,28 @@ class StandardBatchInsert
|
|
15
15
|
ActiveRecord::Base.connection.execute(insert_sql)
|
16
16
|
end
|
17
17
|
end
|
18
|
+
|
19
|
+
class SqlServerBatchInsert < StandardBatchInsert
|
20
|
+
fattr(:load_file_str) do
|
21
|
+
cols = ar_class.columns.map { |x| x.name }
|
22
|
+
rows.map do |row|
|
23
|
+
#raise cols.inspect + "|" + row.inspect
|
24
|
+
cols.map { |c| row[c.to_sym] }.join("|")
|
25
|
+
end.join("______")
|
26
|
+
end
|
27
|
+
fattr(:load_file_path) { File.expand_path("temp_load_file.txt") }
|
28
|
+
def write_load_file!
|
29
|
+
File.create(load_file_path,load_file_str)
|
30
|
+
Dataload.log "Temp file for bulk insert created at #{load_file_path}"
|
31
|
+
end
|
32
|
+
def insert_sql
|
33
|
+
"BULK INSERT #{table_name} FROM '#{load_file_path}' WITH (FIELDTERMINATOR = '|', ROWTERMINATOR = '______', BATCHSIZE = #{block_size})"
|
34
|
+
end
|
35
|
+
def insert!
|
36
|
+
write_load_file!
|
37
|
+
ActiveRecord::Base.connection.execute(insert_sql)
|
38
|
+
end
|
39
|
+
end
|
18
40
|
|
19
41
|
class OracleBatchInsert < StandardBatchInsert
|
20
42
|
fattr(:insert_sql) do
|
@@ -28,10 +50,14 @@ end
|
|
28
50
|
|
29
51
|
class BatchInsert
|
30
52
|
def self.get_class
|
31
|
-
|
53
|
+
adapter = MasterLoader.instance.db_ops[:adapter].to_s
|
54
|
+
if %w(oci oci8 oracle).include?(adapter)
|
32
55
|
OracleBatchInsert
|
56
|
+
elsif adapter == 'sqlserver'
|
57
|
+
SqlServerBatchInsert
|
33
58
|
else
|
34
59
|
StandardBatchInsert
|
35
60
|
end
|
36
61
|
end
|
37
|
-
end
|
62
|
+
end
|
63
|
+
|
@@ -29,6 +29,11 @@ class MasterLoader
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
def connect!
|
32
|
+
if db_ops[:adapter].to_s == 'sqlserver'
|
33
|
+
gem 'activerecord-sqlserver-adapter'
|
34
|
+
require 'active_record/connection_adapters/sqlserver_adapter'
|
35
|
+
require File.dirname(__FILE__) + "/sqlserver_ext"
|
36
|
+
end
|
32
37
|
ActiveRecord::Base.establish_connection(db_ops)
|
33
38
|
Dataload.log "Established Connection"
|
34
39
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
#Dir["C:/Ruby/lib/ruby/gems/1.8/gems/activerecord-sqlserver-adapter*/**/*.rb"].each { |x| puts x; require x }
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
class Base
|
5
|
+
class << self
|
6
|
+
alias_method :orig_sqlserver_connection, :sqlserver_connection
|
7
|
+
#puts "redeffing sqlserver_connection"
|
8
|
+
def sqlserver_connection(config) #:nodoc:
|
9
|
+
#puts "in redeffed sqlserver connection"
|
10
|
+
require_library_or_gem 'dbi' unless self.class.const_defined?(:DBI)
|
11
|
+
|
12
|
+
config = config.symbolize_keys
|
13
|
+
|
14
|
+
mode = config[:mode] ? config[:mode].to_s.upcase : 'ADO'
|
15
|
+
username = config[:username] ? config[:username].to_s : 'sa'
|
16
|
+
password = config[:password] ? config[:password].to_s : ''
|
17
|
+
autocommit = config.key?(:autocommit) ? config[:autocommit] : true
|
18
|
+
if mode == "ODBC"
|
19
|
+
raise ArgumentError, "Missing DSN. Argument ':dsn' must be set in order for this adapter to work." unless config.has_key?(:dsn)
|
20
|
+
dsn = config[:dsn]
|
21
|
+
driver_url = "DBI:ODBC:#{dsn}"
|
22
|
+
else
|
23
|
+
raise ArgumentError, "Missing Database. Argument ':database' must be set in order for this adapter to work." unless config.has_key?(:database)
|
24
|
+
database = config[:database]
|
25
|
+
host = config[:host] ? config[:host].to_s : 'localhost'
|
26
|
+
if username =~ /PCI/
|
27
|
+
driver_url = "DBI:ADO:Provider=SQLOLEDB;Data Source=#{host};Initial Catalog=#{database};Integrated Security=SSPI;"
|
28
|
+
else
|
29
|
+
driver_url = "DBI:ADO:Provider=SQLOLEDB;Data Source=#{host};Initial Catalog=#{database};User ID=#{username};Password=#{password};"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
#puts "DriverURL: #{driver_url}"
|
33
|
+
conn = DBI.connect(driver_url, username, password)
|
34
|
+
conn["AutoCommit"] = autocommit
|
35
|
+
ConnectionAdapters::SQLServerAdapter.new(conn, logger, [driver_url, username, password])
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
@@ -23,10 +23,20 @@ class TableLoader
|
|
23
23
|
attr_accessor_nn :source_filename
|
24
24
|
fattr(:delimiter) { "," }
|
25
25
|
fattr(:block_size) { 1000 }
|
26
|
+
def master
|
27
|
+
MasterLoader.instance
|
28
|
+
end
|
29
|
+
def effective_block_size
|
30
|
+
if master.db_ops[:adapter].to_s == 'sqlserver'
|
31
|
+
100000
|
32
|
+
else
|
33
|
+
block_size
|
34
|
+
end
|
35
|
+
end
|
26
36
|
fattr(:columns) { [] }
|
27
37
|
fattr(:source_row_groups) do
|
28
38
|
e = enum(FasterCSV,:foreach,source_filename,:headers => true, :col_sep => delimiter)
|
29
|
-
enum(e,:each_by,
|
39
|
+
enum(e,:each_by,effective_block_size)
|
30
40
|
end
|
31
41
|
def target_hash_for_row(row)
|
32
42
|
columns.inject({}) { |h,col| h.merge(col.target_name => col.target_value(row)) }
|
@@ -36,7 +46,7 @@ class TableLoader
|
|
36
46
|
end
|
37
47
|
def target_hash_groups
|
38
48
|
source_row_groups.each_with_index do |rows,i|
|
39
|
-
yield(target_hashes(rows),i*
|
49
|
+
yield(target_hashes(rows),i*effective_block_size+rows.size)
|
40
50
|
end
|
41
51
|
end
|
42
52
|
def load!
|
@@ -44,8 +54,8 @@ class TableLoader
|
|
44
54
|
Dataload.log "Starting load of table '#{table_name}'"
|
45
55
|
total = 0
|
46
56
|
target_hash_groups do |hs,num_inserted|
|
47
|
-
BatchInsert.get_class.new(:rows => hs, :table_name => table_name).insert!
|
48
|
-
Dataload.log "Inserted #{
|
57
|
+
BatchInsert.get_class.new(:rows => hs, :table_name => table_name, :ar_class => ar_cls, :block_size => block_size).insert!
|
58
|
+
Dataload.log "Inserted #{num_inserted - total} rows into table '#{table_name}'. Total of #{num_inserted} rows inserted."
|
49
59
|
total = num_inserted
|
50
60
|
end
|
51
61
|
Dataload.log "Finished load of table '#{table_name}'. Loaded #{total} rows."
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: GFunk911-dataload
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Harris
|
@@ -61,6 +61,7 @@ files:
|
|
61
61
|
- lib/dataload/ext/faster_csv.rb
|
62
62
|
- lib/dataload/master_loader.rb
|
63
63
|
- lib/dataload/migration.rb
|
64
|
+
- lib/dataload/sqlserver_ext.rb
|
64
65
|
- lib/dataload/table_loader.rb
|
65
66
|
- lib/dataload/table_manager.rb
|
66
67
|
- lib/dataload/table_module.rb
|
@@ -73,6 +74,7 @@ files:
|
|
73
74
|
- LICENSE
|
74
75
|
- README.rdoc
|
75
76
|
- VERSION.yml
|
77
|
+
- tmp
|
76
78
|
has_rdoc: true
|
77
79
|
homepage: http://github.com/GFunk911/dataload
|
78
80
|
post_install_message:
|