bulk-insert-active-record 0.0.1

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 50a047ec99ae044e95e2ece35f7ed6a98f774369
4
+ data.tar.gz: c81b2276e7d97ba319cbfed840c28eff00b0db12
5
+ SHA512:
6
+ metadata.gz: 6bf3fca5d20ee03cbc94ea6de6de28e7940074c17106ecc36eb8ebbb0a31e63d96debcb3a46456055591e768e3b5e024a84abd6a4f0f91dacedbd8cf7a39b14a
7
+ data.tar.gz: 72bad9ef5d4e3ca8f1990fd95ccaad3c4ea7bd2984fcc48c1a3e704a5c46b67e348426c333941a1b0c9c65ccb8cd3a00172d8d3363d193eae6dfed391a6dda2a
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
@@ -0,0 +1 @@
1
+ bulk-insert-active-record
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source('https://rubygems.org')
2
+
3
+ gemspec
@@ -0,0 +1,39 @@
1
+ # Bulk Insert Active Record (for ActiveRecord 3 or higher)
2
+
3
+ This gem extends Active Record and allows you to insert multiple records in one SQL statement,
4
+ dramatically increasing performance.
5
+
6
+ ## Current status
7
+
8
+ This gem is currently actively in development, but because it's already useful, I've decided to
9
+ publish it in its premature state. Right now it has been manually tested with MySQL and SQL Server
10
+ via JDBC.
11
+
12
+ ## Usage
13
+
14
+ Installation is done by adding the gem your *Gemfile* and running Bundler. After loading Active
15
+ Record an extra class method is available for your models.
16
+
17
+ ## Examples
18
+
19
+ Suppose you want to insert multiple Post records in the database. This can be done in different
20
+ ways:
21
+
22
+ # suppose it has 3 columns (`id`, `author` and `text`)
23
+ class Post < ActiveRecord::Base
24
+ end
25
+
26
+ # create an array of arrays
27
+ posts = [
28
+ # author, # text
29
+ ['John Doe', 'An article about me'],
30
+ ['John Smith', 'Something interesting']
31
+ ]
32
+
33
+ # call class method bulk_insert with two arguments (the posts and the column names)
34
+ Post.bulk_insert(posts, ['author', 'name])
35
+
36
+
37
+ # Copyright
38
+
39
+ &copy; 2014 Walter Horstman, [IT on Rails](http://itonrails.com)
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,22 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'bulk-insert-active-record'
7
+ spec.summary = 'Lightweight bulk insert mechanism for ActiveRecord 3 or higher'
8
+ spec.description = 'This gem allows you to insert multiple rows as once, dramatically increasing performance.'
9
+ spec.version = '0.0.1'
10
+ spec.required_ruby_version = '>= 1.9.2'
11
+
12
+ spec.author = 'Walter Horstman'
13
+ spec.email = 'walter.horstman@itonrails.com'
14
+ spec.homepage = 'https://github.com/walterhorstman/bulk-insert-active-record'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_path = 'lib'
20
+
21
+ spec.add_dependency('activerecord', '>= 3')
22
+ end
@@ -0,0 +1,45 @@
1
+ require_relative('inserters')
2
+
3
+ module BulkInsertActiveRecord
4
+
5
+ def self.included(base)
6
+ base.class_eval do
7
+
8
+ def self.bulk_insert(records, column_names = self.column_names)
9
+ fail('No connection with the database') unless self.connection.active?
10
+
11
+ inserter = Inserters::factory(self)
12
+ self.transaction do
13
+ if inserter.nil?
14
+ self.insert_one_by_one(records, column_names)
15
+ else
16
+ sql = inserter.statement(records, column_names)
17
+ self.connection.insert(sql)
18
+ end
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def self.insert_one_by_one(records, column_names)
25
+ self.transaction do
26
+ records.each do |record|
27
+ if record.is_a?(self)
28
+ record.save
29
+ else
30
+ item = self.new
31
+ column_names.each_with_index do |column_name, index|
32
+ item[column_name] = record[index]
33
+ end
34
+ item.save
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ ActiveSupport.on_load(:active_record) do
44
+ include(BulkInsertActiveRecord)
45
+ end
@@ -0,0 +1,16 @@
1
+ Dir[File.expand_path('../inserters/*.rb', __FILE__)].each { |file_name| require(file_name) }
2
+
3
+ module BulkInsertActiveRecord
4
+ module Inserters
5
+
6
+ def self.factory(active_record_class, options = {})
7
+ inserter_class = case active_record_class.connection.adapter_name.downcase
8
+ when 'mssql', 'mysql', 'sqlserver' then Base
9
+ when 'oracle' then Oracle
10
+ else nil
11
+ end
12
+
13
+ inserter_class.nil? ? nil : inserter_class.new(active_record_class, options)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,36 @@
1
+ # This base implementation works for MySQL and SQLServer
2
+ module BulkInsertActiveRecord
3
+ module Inserters
4
+ class Base
5
+
6
+ def initialize(active_record_class, options = {})
7
+ @connection = active_record_class.connection
8
+ @quoted_table_name = active_record_class.quoted_table_name
9
+
10
+ # basic bulk insert statement
11
+ @statement = options[:statement] || 'INSERT INTO %{table_name}(%{columns_clause}) VALUES %{values_clause}'
12
+ # character(s) used to separate columns in the columns_clause of the statement
13
+ @column_separator = options[:column_separator] || ','
14
+ # character(s) used to separate records in the values_clause of the statement
15
+ @record_separator = options[:record_separator] || ','
16
+ # sql fragment for individual records in the values_clause of the statement
17
+ @record_statement = options[:record_statement] || '(%{value_clause})'
18
+ # character(s) used to separate values in the value_clause of the record statement
19
+ @value_separator = options[:value_separator] || ','
20
+ end
21
+
22
+ # returns bulk insert statement
23
+ def statement(records, column_names)
24
+ @statement % {
25
+ table_name: @quoted_table_name,
26
+ columns_clause: column_names.map { |column_name| @connection.quote_column_name(column_name) }.join(@column_separator),
27
+ values_clause: records.map do |record|
28
+ @record_statement % {
29
+ value_clause: record.map { |value| @connection.quote(value) }.join(@value_separator)
30
+ }
31
+ end.join(@record_separator)
32
+ }
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,16 @@
1
+ require_relative('base')
2
+
3
+ module BulkInsertActiveRecord
4
+ module Inserters
5
+ class Oracle < Base
6
+
7
+ def initialize(active_record_class, options = {})
8
+ super(active_record_class, {
9
+ statement: 'INSERT INTO %{table_name}(%{columns_clause}) %{values_clause}',
10
+ record_statement: 'SELECT %{value_clause} FROM dual',
11
+ record_separator: ' UNION '
12
+ }.merge(options))
13
+ end
14
+ end
15
+ end
16
+ end
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bulk-insert-active-record
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Walter Horstman
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-03-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activerecord
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '3'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '3'
27
+ description: This gem allows you to insert multiple rows as once, dramatically increasing
28
+ performance.
29
+ email: walter.horstman@itonrails.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - ".gitignore"
35
+ - ".ruby-gemset"
36
+ - Gemfile
37
+ - README.md
38
+ - Rakefile
39
+ - bulk-insert-active-record.gemspec
40
+ - lib/bulk-insert-active-record.rb
41
+ - lib/inserters.rb
42
+ - lib/inserters/base.rb
43
+ - lib/inserters/oracle.rb
44
+ homepage: https://github.com/walterhorstman/bulk-insert-active-record
45
+ licenses: []
46
+ metadata: {}
47
+ post_install_message:
48
+ rdoc_options: []
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: 1.9.2
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ requirements: []
62
+ rubyforge_project:
63
+ rubygems_version: 2.2.2
64
+ signing_key:
65
+ specification_version: 4
66
+ summary: Lightweight bulk insert mechanism for ActiveRecord 3 or higher
67
+ test_files: []