postgres_upsert 2.0.0 → 3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 363018cec57166d2976cbeedc60fad9dc17e5ac7
4
- data.tar.gz: 280a43ba9f6dea9a72111031c5c7e82089185f72
3
+ metadata.gz: 8b0a956bd60011cf247a58c3031d5157be3c6f7f
4
+ data.tar.gz: 918a0d163efa3915f8b3d76421ab69e67e2469d8
5
5
  SHA512:
6
- metadata.gz: 195008d31407158e4cecf27fbd1aec45b6b3c17a078efe5dcd567e4ec8d023f187d597cf0b1a5a1e46e53c901e957a7c70b6ceccdd1aa27231f1cd2f727b194d
7
- data.tar.gz: fbf6e4e15fc23ab1c344a1a8bdd9ba80733cc77c776b6eed98c05936a0dd6cd4889f387e43f028c8c380a2e7d4beb9f3ecc58ef5374183ff3891821077e0fb37
6
+ metadata.gz: d1dda03e61a25fb875bbaf8eab001d0f8b780dbcb329f8be1c0aabbb03c4be4bb66c6adf2dbfbf21d3edb55135be2fc01826dcc79259b928b64c7bb1748c0369
7
+ data.tar.gz: ca59859938a0671ffed159495d10a08328a498500f8c18610c4d50f9d452901b55c5e81e63e62eb35dc8c74b532a713e4f2285db690721be5f4de9b3aed3f8ad
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- postgres_upsert (1.1.0)
4
+ postgres_upsert (3.0.0)
5
5
  activerecord (>= 3.0.0)
6
6
  pg (~> 0.17.0)
7
7
  rails (>= 3.0.0)
@@ -9,26 +9,26 @@ PATH
9
9
  GEM
10
10
  remote: https://rubygems.org/
11
11
  specs:
12
- actionmailer (4.0.3)
13
- actionpack (= 4.0.3)
14
- mail (~> 2.5.4)
15
- actionpack (4.0.3)
16
- activesupport (= 4.0.3)
12
+ actionmailer (4.0.11)
13
+ actionpack (= 4.0.11)
14
+ mail (~> 2.5, >= 2.5.4)
15
+ actionpack (4.0.11)
16
+ activesupport (= 4.0.11)
17
17
  builder (~> 3.1.0)
18
18
  erubis (~> 2.7.0)
19
19
  rack (~> 1.5.2)
20
20
  rack-test (~> 0.6.2)
21
- activemodel (4.0.3)
22
- activesupport (= 4.0.3)
21
+ activemodel (4.0.11)
22
+ activesupport (= 4.0.11)
23
23
  builder (~> 3.1.0)
24
- activerecord (4.0.3)
25
- activemodel (= 4.0.3)
24
+ activerecord (4.0.11)
25
+ activemodel (= 4.0.11)
26
26
  activerecord-deprecated_finders (~> 1.0.2)
27
- activesupport (= 4.0.3)
27
+ activesupport (= 4.0.11)
28
28
  arel (~> 4.0.0)
29
29
  activerecord-deprecated_finders (1.0.3)
30
- activesupport (4.0.3)
31
- i18n (~> 0.6, >= 0.6.4)
30
+ activesupport (4.0.11)
31
+ i18n (~> 0.6, >= 0.6.9)
32
32
  minitest (~> 4.2)
33
33
  multi_json (~> 1.3)
34
34
  thread_safe (~> 0.1)
@@ -41,15 +41,13 @@ GEM
41
41
  hike (1.2.3)
42
42
  i18n (0.6.11)
43
43
  json (1.7.6)
44
- mail (2.5.4)
45
- mime-types (~> 1.16)
46
- treetop (~> 1.4.8)
44
+ mail (2.6.3)
45
+ mime-types (>= 1.16, < 3)
47
46
  method_source (0.8.2)
48
- mime-types (1.25.1)
47
+ mime-types (2.4.3)
49
48
  minitest (4.7.5)
50
49
  multi_json (1.10.1)
51
50
  pg (0.17.1)
52
- polyglot (0.3.5)
53
51
  pry (0.10.1)
54
52
  coderay (~> 1.1.0)
55
53
  method_source (~> 0.8.1)
@@ -59,17 +57,17 @@ GEM
59
57
  rack (1.5.2)
60
58
  rack-test (0.6.2)
61
59
  rack (>= 1.0)
62
- rails (4.0.3)
63
- actionmailer (= 4.0.3)
64
- actionpack (= 4.0.3)
65
- activerecord (= 4.0.3)
66
- activesupport (= 4.0.3)
60
+ rails (4.0.11)
61
+ actionmailer (= 4.0.11)
62
+ actionpack (= 4.0.11)
63
+ activerecord (= 4.0.11)
64
+ activesupport (= 4.0.11)
67
65
  bundler (>= 1.3.0, < 2.0)
68
- railties (= 4.0.3)
69
- sprockets-rails (~> 2.0.0)
70
- railties (4.0.3)
71
- actionpack (= 4.0.3)
72
- activesupport (= 4.0.3)
66
+ railties (= 4.0.11)
67
+ sprockets-rails (~> 2.0)
68
+ railties (4.0.11)
69
+ actionpack (= 4.0.11)
70
+ activesupport (= 4.0.11)
73
71
  rake (>= 0.8.7)
74
72
  thor (>= 0.18.1, < 2.0)
75
73
  rake (10.3.2)
@@ -84,22 +82,19 @@ GEM
84
82
  diff-lcs (~> 1.1.3)
85
83
  rspec-mocks (2.12.2)
86
84
  slop (3.6.0)
87
- sprockets (2.11.0)
85
+ sprockets (2.12.3)
88
86
  hike (~> 1.2)
89
87
  multi_json (~> 1.0)
90
88
  rack (~> 1.0)
91
89
  tilt (~> 1.1, != 1.3.0)
92
- sprockets-rails (2.0.1)
90
+ sprockets-rails (2.2.0)
93
91
  actionpack (>= 3.0)
94
92
  activesupport (>= 3.0)
95
- sprockets (~> 2.8)
93
+ sprockets (>= 2.8, < 4.0)
96
94
  thor (0.19.1)
97
95
  thread_safe (0.3.4)
98
96
  tilt (1.4.1)
99
- treetop (1.4.15)
100
- polyglot
101
- polyglot (>= 0.3.1)
102
- tzinfo (0.3.40)
97
+ tzinfo (0.3.42)
103
98
 
104
99
  PLATFORMS
105
100
  ruby
@@ -7,7 +7,7 @@ module ActiveRecord
7
7
  # * You can map fields from the file to different fields in the table using a map in the options hash
8
8
  # * For further details on usage take a look at the README.md
9
9
  def self.pg_upsert path_or_io, options = {}
10
- PostgresUpsert::Writer.new(self, path_or_io, options).write
10
+ PostgresUpsert::Writer.new(table_name, path_or_io, options).write
11
11
  end
12
12
  end
13
13
  end
@@ -2,13 +2,13 @@ module PostgresUpsert
2
2
 
3
3
  class Writer
4
4
 
5
- def initialize(klass, source, options = {})
6
- @klass = klass
5
+ def initialize(table_name, source, options = {})
6
+ @table_name = table_name
7
7
  @options = options.reverse_merge({
8
8
  :delimiter => ",",
9
9
  :format => :csv,
10
10
  :header => true,
11
- :key_column => @klass.primary_key,
11
+ :key_column => primary_key,
12
12
  :update_only => false})
13
13
  @source = source.instance_of?(String) ? File.open(source, 'r') : source
14
14
  @columns_list = get_columns
@@ -23,7 +23,6 @@ module PostgresUpsert
23
23
  csv_options = @options[:format] == :binary ? "BINARY" : "DELIMITER '#{@options[:delimiter]}' CSV"
24
24
 
25
25
  copy_table = @temp_table_name
26
- destination_table = get_table_name
27
26
 
28
27
  columns_string = columns_string_for_copy
29
28
  create_temp_table
@@ -36,14 +35,40 @@ module PostgresUpsert
36
35
  end
37
36
  end
38
37
 
39
- if destination_table
40
- upsert_from_temp_table
41
- drop_temp_table
42
- end
38
+ upsert_from_temp_table
39
+ drop_temp_table
43
40
  end
44
41
 
45
42
  private
46
43
 
44
+ def primary_key
45
+ @primary_key ||= begin
46
+ query = <<-sql
47
+ SELECT
48
+ pg_attribute.attname,
49
+ format_type(pg_attribute.atttypid, pg_attribute.atttypmod)
50
+ FROM pg_index, pg_class, pg_attribute
51
+ WHERE
52
+ pg_class.oid = '#{@table_name}'::regclass AND
53
+ indrelid = pg_class.oid AND
54
+ pg_attribute.attrelid = pg_class.oid AND
55
+ pg_attribute.attnum = any(pg_index.indkey)
56
+ AND indisprimary
57
+ sql
58
+
59
+ pg_result = ActiveRecord::Base.connection.execute query
60
+ pg_result.each{ |row| return row['attname'] }
61
+ end
62
+ end
63
+
64
+ def column_names
65
+ @column_names ||= begin
66
+ query = "SELECT * FROM information_schema.columns WHERE TABLE_NAME = '#{@table_name}'"
67
+ pg_result = ActiveRecord::Base.connection.execute query
68
+ pg_result.map{ |row| row['column_name'] }
69
+ end
70
+ end
71
+
47
72
  def get_columns
48
73
  columns_list = @options[:columns] || []
49
74
  if @options[:format] != :binary && @options[:header]
@@ -64,23 +89,23 @@ module PostgresUpsert
64
89
 
65
90
  def columns_string_for_select
66
91
  columns = @columns_list.clone
67
- columns << "created_at" if @klass.column_names.include?("created_at")
68
- columns << "updated_at" if @klass.column_names.include?("updated_at")
92
+ columns << "created_at" if column_names.include?("created_at")
93
+ columns << "updated_at" if column_names.include?("updated_at")
69
94
  str = get_columns_string(columns)
70
95
  end
71
96
 
72
97
  def columns_string_for_insert
73
98
  columns = @columns_list.clone
74
- columns << "created_at" if @klass.column_names.include?("created_at")
75
- columns << "updated_at" if @klass.column_names.include?("updated_at")
99
+ columns << "created_at" if column_names.include?("created_at")
100
+ columns << "updated_at" if column_names.include?("updated_at")
76
101
  str = get_columns_string(columns)
77
102
  end
78
103
 
79
104
  def select_string_for_insert
80
105
  columns = @columns_list.clone
81
106
  str = get_columns_string(columns)
82
- str << ",'#{DateTime.now.utc}'" if @klass.column_names.include?("created_at")
83
- str << ",'#{DateTime.now.utc}'" if @klass.column_names.include?("updated_at")
107
+ str << ",'#{DateTime.now.utc}'" if column_names.include?("created_at")
108
+ str << ",'#{DateTime.now.utc}'" if column_names.include?("updated_at")
84
109
  str
85
110
  end
86
111
 
@@ -95,16 +120,12 @@ module PostgresUpsert
95
120
  columns.size > 0 ? "\"#{columns.join('","')}\"" : ""
96
121
  end
97
122
 
98
- def get_table_name
99
- if @options[:table]
100
- connection.quote_table_name(@options[:table])
101
- else
102
- @klass.quoted_table_name
103
- end
123
+ def quoted_table_name
124
+ @quoted_table_name ||= ActiveRecord::Base.connection.quote_table_name(@table_name)
104
125
  end
105
126
 
106
127
  def generate_temp_table_name
107
- @temp_table_name = "#{@klass.table_name}_temp_#{rand(1000)}"
128
+ @temp_table_name = "#{@table_name}_temp_#{rand(1000)}"
108
129
  end
109
130
 
110
131
  def read_input_line
@@ -126,7 +147,7 @@ module PostgresUpsert
126
147
 
127
148
  def update_from_temp_table
128
149
  ActiveRecord::Base.connection.execute <<-SQL
129
- UPDATE #{get_table_name} AS d
150
+ UPDATE #{quoted_table_name} AS d
130
151
  #{update_set_clause}
131
152
  FROM #{@temp_table_name} as t
132
153
  WHERE t.#{@options[:key_column]} = d.#{@options[:key_column]}
@@ -138,7 +159,7 @@ module PostgresUpsert
138
159
  command = @columns_list.map do |col|
139
160
  "\"#{col}\" = t.\"#{col}\""
140
161
  end
141
- command << "\"updated_at\" = '#{DateTime.now.utc}'" if @klass.column_names.include?("updated_at")
162
+ command << "\"updated_at\" = '#{DateTime.now.utc}'" if column_names.include?("updated_at")
142
163
  "SET #{command.join(',')}"
143
164
  end
144
165
 
@@ -146,12 +167,12 @@ module PostgresUpsert
146
167
  columns_string = columns_string_for_insert
147
168
  select_string = select_string_for_insert
148
169
  ActiveRecord::Base.connection.execute <<-SQL
149
- INSERT INTO #{get_table_name} (#{columns_string})
170
+ INSERT INTO #{quoted_table_name} (#{columns_string})
150
171
  SELECT #{select_string}
151
172
  FROM #{@temp_table_name} as t
152
173
  WHERE NOT EXISTS
153
174
  (SELECT 1
154
- FROM #{get_table_name} as d
175
+ FROM #{quoted_table_name} as d
155
176
  WHERE d.#{@options[:key_column]} = t.#{@options[:key_column]})
156
177
  AND t.#{@options[:key_column]} IS NOT NULL;
157
178
  SQL
@@ -164,7 +185,7 @@ module PostgresUpsert
164
185
  DROP TABLE IF EXISTS #{@temp_table_name};
165
186
 
166
187
  CREATE TEMP TABLE #{@temp_table_name}
167
- AS SELECT #{columns_string} FROM #{get_table_name} WHERE 0 = 1;
188
+ AS SELECT #{columns_string} FROM #{quoted_table_name} WHERE 0 = 1;
168
189
  SQL
169
190
  end
170
191
 
@@ -5,7 +5,7 @@ $:.unshift lib unless $:.include?(lib)
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "postgres_upsert"
8
- s.version = "2.0.0"
8
+ s.version = "3.0.0"
9
9
 
10
10
  s.platform = Gem::Platform::RUBY
11
11
  s.required_ruby_version = ">= 1.8.7"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: postgres_upsert
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steve Mitchell