bulk-insert-active-record 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []