activerecord-bulkwrite 1.0.0
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.
- checksums.yaml +7 -0
- data/lib/activerecord/bulkwrite.rb +63 -0
- 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: []
|