postgres-copy 1.5.0 → 1.6.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ad654ff2a933f1e41f23e6347f0b20daa3e16455caea9a6107ce4d50c39598f8
4
- data.tar.gz: e972e684f928c0afdd7fdd096ade3d28d293604ef20f42a959097234f37f7317
3
+ metadata.gz: bfe11c5653d850edd47a3df54bcbb83600f820b35a297f05d363b6e89b8b27ff
4
+ data.tar.gz: 25a187d205ca18ad00e9a35de9a3fabc400137a56af61fce58eac5f7713491af
5
5
  SHA512:
6
- metadata.gz: e57d3d4d0bd7a0bef175dad625c77013f2616222ef9ef086c449cdcbd8f58e4bbde77625e6f70ab55149683becac6e15d8c2cbf84c09c707f1a39cbef0417b05
7
- data.tar.gz: b8768a3cf765aa7d6c01eb5138439e20c1140f6b2e772e96d169635832fe14a2780e438732503f719eba7f0b9bcf0e6cf6da4c7241d3d42e734d4433f65799e6
6
+ metadata.gz: bf7bdfb2fc14b24ede0973c7e573ed30507c77c205cfe87aa13f9302ad31d988360bcebec83b5ee1c83d266c14d8b42728fb17d5a07c222babc3aab5438562ce
7
+ data.tar.gz: b0f085dbbd1fbd684a00d97eda965f7074d52b8e8f0fe07657f33a5a5fcbd9ab4041a71956e640c5b40140c125675f20479044e1aea5b7bea1d1aba9d51e4227
@@ -33,6 +33,10 @@ jobs:
33
33
  --health-retries 5
34
34
 
35
35
  runs-on: ubuntu-latest
36
+ name: test (ruby v${{ matrix.ruby }})
37
+ strategy:
38
+ matrix:
39
+ ruby: ["2.7", "3.0", "3.1"]
36
40
 
37
41
  steps:
38
42
  - uses: actions/checkout@v2
@@ -41,7 +45,8 @@ jobs:
41
45
  # change this to (see https://github.com/ruby/setup-ruby#versioning):
42
46
  uses: ruby/setup-ruby@v1
43
47
  with:
44
- ruby-version: 2.7
48
+ ruby-version: ${{ matrix.ruby }}
49
+ bundler-cache: true
45
50
  - name: Install dependencies
46
51
  run: bundle install
47
52
  - name: Run tests
data/Gemfile.lock CHANGED
@@ -1,73 +1,31 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- postgres-copy (1.5.0)
4
+ postgres-copy (1.6.1)
5
5
  activerecord (>= 5.1)
6
6
  pg (>= 0.17)
7
- responders
8
7
 
9
8
  GEM
10
9
  remote: https://rubygems.org/
11
10
  specs:
12
- actionpack (6.0.3.2)
13
- actionview (= 6.0.3.2)
14
- activesupport (= 6.0.3.2)
15
- rack (~> 2.0, >= 2.0.8)
16
- rack-test (>= 0.6.3)
17
- rails-dom-testing (~> 2.0)
18
- rails-html-sanitizer (~> 1.0, >= 1.2.0)
19
- actionview (6.0.3.2)
20
- activesupport (= 6.0.3.2)
21
- builder (~> 3.1)
22
- erubi (~> 1.4)
23
- rails-dom-testing (~> 2.0)
24
- rails-html-sanitizer (~> 1.1, >= 1.2.0)
25
- activemodel (6.0.3.2)
26
- activesupport (= 6.0.3.2)
27
- activerecord (6.0.3.2)
28
- activemodel (= 6.0.3.2)
29
- activesupport (= 6.0.3.2)
30
- activesupport (6.0.3.2)
11
+ activemodel (7.0.4)
12
+ activesupport (= 7.0.4)
13
+ activerecord (7.0.4)
14
+ activemodel (= 7.0.4)
15
+ activesupport (= 7.0.4)
16
+ activesupport (7.0.4)
31
17
  concurrent-ruby (~> 1.0, >= 1.0.2)
32
- i18n (>= 0.7, < 2)
33
- minitest (~> 5.1)
34
- tzinfo (~> 1.1)
35
- zeitwerk (~> 2.2, >= 2.2.2)
36
- builder (3.2.4)
37
- concurrent-ruby (1.1.6)
38
- crass (1.0.6)
18
+ i18n (>= 1.6, < 2)
19
+ minitest (>= 5.1)
20
+ tzinfo (~> 2.0)
21
+ concurrent-ruby (1.1.10)
39
22
  diff-lcs (1.4.4)
40
- erubi (1.9.0)
41
- i18n (1.8.3)
23
+ i18n (1.12.0)
42
24
  concurrent-ruby (~> 1.0)
43
- loofah (2.6.0)
44
- crass (~> 1.0.2)
45
- nokogiri (>= 1.5.9)
46
- method_source (1.0.0)
47
- mini_portile2 (2.4.0)
48
- minitest (5.14.1)
49
- nokogiri (1.10.10)
50
- mini_portile2 (~> 2.4.0)
51
- pg (1.2.3)
52
- rack (2.2.3)
53
- rack-test (1.1.0)
54
- rack (>= 1.0, < 3)
55
- rails-dom-testing (2.0.3)
56
- activesupport (>= 4.2.0)
57
- nokogiri (>= 1.6)
58
- rails-html-sanitizer (1.3.0)
59
- loofah (~> 2.3)
60
- railties (6.0.3.2)
61
- actionpack (= 6.0.3.2)
62
- activesupport (= 6.0.3.2)
63
- method_source
64
- rake (>= 0.8.7)
65
- thor (>= 0.20.3, < 2.0)
25
+ minitest (5.16.3)
26
+ pg (1.4.3)
66
27
  rake (11.2.2)
67
28
  rdoc (6.2.1)
68
- responders (3.0.1)
69
- actionpack (>= 5.0)
70
- railties (>= 5.0)
71
29
  rspec (2.99.0)
72
30
  rspec-core (~> 2.99.0)
73
31
  rspec-expectations (~> 2.99.0)
@@ -76,11 +34,8 @@ GEM
76
34
  rspec-expectations (2.99.2)
77
35
  diff-lcs (>= 1.1.3, < 2.0)
78
36
  rspec-mocks (2.99.4)
79
- thor (1.0.1)
80
- thread_safe (0.3.6)
81
- tzinfo (1.2.7)
82
- thread_safe (~> 0.1)
83
- zeitwerk (2.4.0)
37
+ tzinfo (2.0.5)
38
+ concurrent-ruby (~> 1.0)
84
39
 
85
40
  PLATFORMS
86
41
  ruby
@@ -93,4 +48,4 @@ DEPENDENCIES
93
48
  rspec (~> 2.12)
94
49
 
95
50
  BUNDLED WITH
96
- 2.1.2
51
+ 2.2.22
data/README.md CHANGED
@@ -200,6 +200,13 @@ Which will generate the following SQL command:
200
200
  COPY users (id, name) FROM '/tmp/users.dat' WITH BINARY
201
201
  ```
202
202
 
203
+ To specify the encoding with which to read the file, set the :encoding option.
204
+ This is useful for removing byte order marks when matching column headers.
205
+
206
+ ```ruby
207
+ User.copy_from "/tmp/users_with_byte_order_mark.csv", :encoding => 'bom|utf-8'
208
+ ```
209
+
203
210
 
204
211
  ### Using the CSV Responder
205
212
  If you want to make the result of a COPY command available to download this gem provides a CSV responder that, in conjunction with [inherited_resources](https://github.com/josevalim/inherited_resources), is a very powerfull tool. BTW, do not try to use the responder without inherited_resources.
@@ -1,5 +1,13 @@
1
1
  require 'csv'
2
2
 
3
+ def get_file_mode mode, encoding = nil
4
+ if encoding
5
+ "#{mode}:#{encoding}"
6
+ else
7
+ mode
8
+ end
9
+ end
10
+
3
11
  module PostgresCopy
4
12
  module ActsAsCopyTarget
5
13
  extend ActiveSupport::Concern
@@ -10,7 +18,7 @@ module PostgresCopy
10
18
  module CopyMethods
11
19
  # Copy data to a file passed as a string (the file path) or to lines that are passed to a block
12
20
  def copy_to path = nil, options = {}
13
- options = {:delimiter => ",", :format => :csv, :header => true}.merge(options)
21
+ options = { delimiter: ",", format: :csv, header: true }.merge(options)
14
22
  options_string = if options[:format] == :binary
15
23
  "BINARY"
16
24
  else
@@ -72,7 +80,7 @@ module PostgresCopy
72
80
  # * You can map fields from the file to different fields in the table using a map in the options hash
73
81
  # * For further details on usage take a look at the README.md
74
82
  def copy_from path_or_io, options = {}
75
- options = {:delimiter => ",", :format => :csv, :header => true, :quote => '"'}.merge(options)
83
+ options = { delimiter: ",", format: :csv, header: true, quote: '"' }.merge(options)
76
84
  options[:delimiter] = "\t" if options[:format] == :tsv
77
85
  options_string = if options[:format] == :binary
78
86
  "BINARY"
@@ -83,7 +91,7 @@ module PostgresCopy
83
91
  delimiter = options[:format] == :tsv ? "E'\t'" : "'#{options[:delimiter]}'"
84
92
  "WITH (" + ["DELIMITER #{delimiter}", "QUOTE '#{quote}'", null, force_null, "FORMAT CSV"].compact.join(', ') + ")"
85
93
  end
86
- io = path_or_io.instance_of?(String) ? File.open(path_or_io, 'r') : path_or_io
94
+ io = path_or_io.instance_of?(String) ? File.open(path_or_io, get_file_mode('r', options[:encoding])) : path_or_io
87
95
 
88
96
  if options[:format] == :binary
89
97
  columns_list = options[:columns] || []
@@ -100,7 +108,7 @@ module PostgresCopy
100
108
  quoted_table_name
101
109
  end
102
110
 
103
- columns_list = columns_list.map{|c| options[:map][c.to_s] } if options[:map]
111
+ columns_list = columns_list.map{|c| options[:map][c.to_s] || c.to_s } if options[:map]
104
112
  columns_string = columns_list.size > 0 ? "(\"#{columns_list.join('","')}\")" : ""
105
113
  connection.raw_connection.copy_data %{COPY #{table} #{columns_string} FROM STDIN #{options_string}} do
106
114
  if options[:format] == :binary
@@ -124,10 +132,10 @@ module PostgresCopy
124
132
  if line_buffer =~ /\n$/ || line_buffer =~ /\Z/
125
133
  if block_given?
126
134
  begin
127
- row = CSV.parse_line(line_buffer.strip, {:col_sep => options[:delimiter]})
135
+ row = CSV.parse_line(line_buffer.strip, col_sep: options[:delimiter])
128
136
  yield(row)
129
- next if row.all?{|f| f.nil? }
130
- line_buffer = CSV.generate_line(row, {:col_sep => options[:delimiter]})
137
+ next if row.all?(&:nil?)
138
+ line_buffer = CSV.generate_line(row, col_sep: options[:delimiter])
131
139
  rescue CSV::MalformedCSVError
132
140
  next
133
141
  end
@@ -5,7 +5,7 @@ $:.unshift lib unless $:.include?(lib)
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "postgres-copy"
8
- s.version = "1.5.0"
8
+ s.version = "1.6.1"
9
9
  s.platform = Gem::Platform::RUBY
10
10
  s.required_ruby_version = ">= 1.9.3"
11
11
  s.authors = ["Diogo Biazus"]
@@ -22,7 +22,6 @@ Gem::Specification.new do |s|
22
22
 
23
23
  s.add_dependency "pg", ">= 0.17"
24
24
  s.add_dependency "activerecord", '>= 5.1'
25
- s.add_dependency "responders"
26
25
  s.add_development_dependency "bundler"
27
26
  s.add_development_dependency "rdoc"
28
27
  s.add_development_dependency "rspec", "~> 2.12"
@@ -14,6 +14,12 @@ describe "COPY FROM" do
14
14
  TestModel.order(:id).map{|r| r.attributes}.should == [{'id' => 1, 'data' => 'test data 1'}]
15
15
  end
16
16
 
17
+ it "should import from file if path is with a field_map" do
18
+ TestModel.copy_from File.expand_path('spec/fixtures/comma_with_header_to_map.csv'), map: {'ref' => 'id'}
19
+ TestModel.order(:id).map{|r| r.attributes}.should == [{'id' => 1, 'data' => 'test data 1'}]
20
+ end
21
+
22
+
17
23
  it "should import from IO without field_map" do
18
24
  TestModel.copy_from File.open(File.expand_path('spec/fixtures/comma_with_header.csv'), 'r')
19
25
  TestModel.order(:id).map{|r| r.attributes}.should == [{'id' => 1, 'data' => 'test data 1'}]
@@ -173,4 +179,10 @@ describe "COPY FROM" do
173
179
  TestModel.order(:id).first.attributes.should == {'id' => 1, 'data' => 'changed this data'}
174
180
  TestModel.count.should == 2
175
181
  end
182
+
183
+ it "should import csv headers with BOM when provided encoding option" do
184
+ TestModel.copy_from File.expand_path("spec/fixtures/comma_with_bom.csv"), :encoding => "bom|utf-8"
185
+ TestModel.order(:id).map{|r| r.attributes}.should == [{'id' => 1, 'data' => 'test data 1'}]
186
+ end
187
+
176
188
  end
@@ -0,0 +1,2 @@
1
+ id,data
2
+ 1,"test data 1"
@@ -0,0 +1,2 @@
1
+ ref,data
2
+ 1,test data 1
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: postgres-copy
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.0
4
+ version: 1.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Diogo Biazus
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-18 00:00:00.000000000 Z
11
+ date: 2022-10-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pg
@@ -38,20 +38,6 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '5.1'
41
- - !ruby/object:Gem::Dependency
42
- name: responders
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :runtime
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- version: '0'
55
41
  - !ruby/object:Gem::Dependency
56
42
  name: bundler
57
43
  requirement: !ruby/object:Gem::Requirement
@@ -134,12 +120,14 @@ files:
134
120
  - spec/copy_to_spec.rb
135
121
  - spec/fixtures/2_col_binary_data.dat
136
122
  - spec/fixtures/comma_inside_field.csv
123
+ - spec/fixtures/comma_with_bom.csv
137
124
  - spec/fixtures/comma_with_carriage_returns.csv
138
125
  - spec/fixtures/comma_with_empty_string.csv
139
126
  - spec/fixtures/comma_with_header.csv
140
127
  - spec/fixtures/comma_with_header_and_scope.csv
141
128
  - spec/fixtures/comma_with_header_empty_values_at_the_end.csv
142
129
  - spec/fixtures/comma_with_header_multi.csv
130
+ - spec/fixtures/comma_with_header_to_map.csv
143
131
  - spec/fixtures/comma_without_header.csv
144
132
  - spec/fixtures/extra_field.rb
145
133
  - spec/fixtures/reserved_word_model.rb
@@ -179,7 +167,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
179
167
  - !ruby/object:Gem::Version
180
168
  version: '0'
181
169
  requirements: []
182
- rubygems_version: 3.1.2
170
+ rubygems_version: 3.1.6
183
171
  signing_key:
184
172
  specification_version: 4
185
173
  summary: Put COPY command functionality in ActiveRecord's model class