activerecord-bulkwrite 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/activerecord/bulkwrite.rb +63 -0
  3. metadata +64 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: baa1dc1f6bd651873a0746548960ef3a70d12d6c
4
+ data.tar.gz: 13c6220a44d36c96e7b6d2a0187b655f7e567fed
5
+ SHA512:
6
+ metadata.gz: 31fbe026d454d4f940e7e647d09613450d6300e95e537883fe0d286208ab27ed07547561e626206be456c00c377760328b3b10e4188f27cc051ab96611aed2ba
7
+ data.tar.gz: 19c1612d0e2988b0796971ff99ff7186e73ea5229eb8df075e551cffc5926fd4dc2a3b7f707f59ef5d516f7e32e3c609328068b59829567f36b2263459dc6889
@@ -0,0 +1,63 @@
1
+ require 'active_record'
2
+
3
+ module ActiveRecord
4
+ class Base
5
+ # Insert or update a batch of rows.
6
+ # When upsert is nil, insert only. Otherwise insert or update on conflict.
7
+ #
8
+ # Parameters:
9
+ # fields: an array of field names to insert value
10
+ # rows: an array of array of values to insert. The element, values array,
11
+ # must correspond with the fields parameter.
12
+ # upsert:
13
+ # A hash with the following keys::
14
+ # conflict: an array of field names on which a unique constrain may fail the
15
+ # insert
16
+ # update: an array of field names to update when conflict happens. If
17
+ # omitted, it will be "fields - upsert[:conflict]".
18
+ # where: where clause to determine if a row will be updated when
19
+ # conflict happens. "EXCLUDED" is used for referencing the row
20
+ # that failed in insert. If omitted, update all rows that have
21
+ # conflict.
22
+ #
23
+ # Return:
24
+ # The number of affected rows
25
+ def self.bulk_write(fields, rows, upsert = nil)
26
+ return 0 if rows.empty?
27
+
28
+ columns = fields.map {|name| column_for_attribute(name) }
29
+ rows = rows.map do |row|
30
+ values = row.map.with_index do |val, i|
31
+ # NOTE: Here quote method treats val as a Ruby value from
32
+ # Value#type_cast_from_user, and thus won't convert a String time to
33
+ # Time object before passing the string time to database.
34
+ # That's OK for a time string in UTC, but NOT FOR LOCAL TIME, since
35
+ # ActiveRecord saves time as type "DATETIME WITHOUT TIMEZONE" in database!
36
+ connection.quote(val, columns[i])
37
+ end.join ', '
38
+ "(#{ values })"
39
+ end
40
+ field_list = fields.map{|e| %Q("#{e}") }.join ', '
41
+ sql = "INSERT INTO #{ table_name } (#{ field_list }) VALUES #{ rows.join ', ' }"
42
+ if upsert
43
+ if !upsert[:update]
44
+ update = fields.map(&:to_s) - upsert[:conflict].map(&:to_s)
45
+ else
46
+ update = upsert[:update]
47
+ end
48
+ update = update.map {|field| "#{ field } = EXCLUDED.#{ field }" }
49
+ sql += " ON CONFLICT (#{ upsert[:conflict].join ', ' }) DO UPDATE SET #{ update.join ', ' }"
50
+ if upsert[:where]
51
+ sql += " WHERE #{ upsert[:where] }"
52
+ end
53
+ end
54
+ # res is a PG::Result object. See
55
+ # https://deveiate.org/code/pg/PG/Result.html
56
+ # for its details.
57
+ res = connection.execute(sql)
58
+ res.cmd_tuples
59
+ end
60
+
61
+ end
62
+ end
63
+
metadata ADDED
@@ -0,0 +1,64 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: activerecord-bulkwrite
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Robert Zhang
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-10-02 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: '4.0'
20
+ - - "~>"
21
+ - !ruby/object:Gem::Version
22
+ version: '5.0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '4.0'
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '5.0'
33
+ description:
34
+ email: louirobert@gmail.com
35
+ executables: []
36
+ extensions: []
37
+ extra_rdoc_files: []
38
+ files:
39
+ - lib/activerecord/bulkwrite.rb
40
+ homepage: https://github.com/coin8086/activerecord-bulkwrite
41
+ licenses:
42
+ - MIT
43
+ metadata: {}
44
+ post_install_message:
45
+ rdoc_options: []
46
+ require_paths:
47
+ - lib
48
+ required_ruby_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ requirements: []
59
+ rubyforge_project:
60
+ rubygems_version: 2.5.1
61
+ signing_key:
62
+ specification_version: 4
63
+ summary: Bulk write/upsert for ActiveRecord
64
+ test_files: []