postgres-copy 0.4.0 → 0.5.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.
- data/Gemfile +1 -0
- data/Gemfile.lock +66 -60
- data/README.md +33 -3
- data/VERSION +1 -1
- data/lib/postgres-copy/active_record.rb +46 -15
- data/postgres-copy.gemspec +9 -3
- data/spec/fixtures/2_col_binary_data.dat +0 -0
- data/spec/pg_copy_from_binary_spec.rb +22 -0
- data/spec/pg_copy_to_binary_spec.rb +33 -0
- data/spec/spec_helper.rb +9 -3
- metadata +81 -19
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,100 +1,106 @@
|
|
|
1
1
|
GEM
|
|
2
2
|
remote: http://rubygems.org/
|
|
3
3
|
specs:
|
|
4
|
-
actionmailer (3.
|
|
5
|
-
actionpack (= 3.
|
|
6
|
-
mail (~> 2.
|
|
7
|
-
actionpack (3.
|
|
8
|
-
activemodel (= 3.
|
|
9
|
-
activesupport (= 3.
|
|
4
|
+
actionmailer (3.2.9)
|
|
5
|
+
actionpack (= 3.2.9)
|
|
6
|
+
mail (~> 2.4.4)
|
|
7
|
+
actionpack (3.2.9)
|
|
8
|
+
activemodel (= 3.2.9)
|
|
9
|
+
activesupport (= 3.2.9)
|
|
10
10
|
builder (~> 3.0.0)
|
|
11
11
|
erubis (~> 2.7.0)
|
|
12
|
-
|
|
13
|
-
rack (~> 1.
|
|
14
|
-
rack-cache (~> 1.
|
|
15
|
-
rack-mount (~> 0.8.2)
|
|
12
|
+
journey (~> 1.0.4)
|
|
13
|
+
rack (~> 1.4.0)
|
|
14
|
+
rack-cache (~> 1.2)
|
|
16
15
|
rack-test (~> 0.6.1)
|
|
17
|
-
sprockets (~> 2.
|
|
18
|
-
activemodel (3.
|
|
19
|
-
activesupport (= 3.
|
|
16
|
+
sprockets (~> 2.2.1)
|
|
17
|
+
activemodel (3.2.9)
|
|
18
|
+
activesupport (= 3.2.9)
|
|
20
19
|
builder (~> 3.0.0)
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
arel (~> 2.2.1)
|
|
20
|
+
activerecord (3.2.9)
|
|
21
|
+
activemodel (= 3.2.9)
|
|
22
|
+
activesupport (= 3.2.9)
|
|
23
|
+
arel (~> 3.0.2)
|
|
26
24
|
tzinfo (~> 0.3.29)
|
|
27
|
-
activeresource (3.
|
|
28
|
-
activemodel (= 3.
|
|
29
|
-
activesupport (= 3.
|
|
30
|
-
activesupport (3.
|
|
25
|
+
activeresource (3.2.9)
|
|
26
|
+
activemodel (= 3.2.9)
|
|
27
|
+
activesupport (= 3.2.9)
|
|
28
|
+
activesupport (3.2.9)
|
|
29
|
+
i18n (~> 0.6)
|
|
31
30
|
multi_json (~> 1.0)
|
|
32
|
-
arel (
|
|
33
|
-
builder (3.0.
|
|
34
|
-
diff-lcs (1.1.
|
|
31
|
+
arel (3.0.2)
|
|
32
|
+
builder (3.0.4)
|
|
33
|
+
diff-lcs (1.1.3)
|
|
35
34
|
erubis (2.7.0)
|
|
35
|
+
git (1.2.5)
|
|
36
36
|
hike (1.2.1)
|
|
37
|
-
i18n (0.6.
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
i18n (0.6.1)
|
|
38
|
+
jeweler (1.8.4)
|
|
39
|
+
bundler (~> 1.0)
|
|
40
|
+
git (>= 1.2.5)
|
|
41
|
+
rake
|
|
42
|
+
rdoc
|
|
43
|
+
journey (1.0.4)
|
|
44
|
+
json (1.7.5)
|
|
45
|
+
mail (2.4.4)
|
|
40
46
|
i18n (>= 0.4.0)
|
|
41
47
|
mime-types (~> 1.16)
|
|
42
48
|
treetop (~> 1.4.8)
|
|
43
|
-
mime-types (1.
|
|
44
|
-
multi_json (1.0
|
|
45
|
-
pg (0.
|
|
49
|
+
mime-types (1.19)
|
|
50
|
+
multi_json (1.5.0)
|
|
51
|
+
pg (0.14.1)
|
|
46
52
|
polyglot (0.3.3)
|
|
47
|
-
rack (1.
|
|
48
|
-
rack-cache (1.
|
|
53
|
+
rack (1.4.1)
|
|
54
|
+
rack-cache (1.2)
|
|
49
55
|
rack (>= 0.4)
|
|
50
|
-
rack-mount (0.8.3)
|
|
51
|
-
rack (>= 1.0.0)
|
|
52
56
|
rack-ssl (1.3.2)
|
|
53
57
|
rack
|
|
54
|
-
rack-test (0.6.
|
|
58
|
+
rack-test (0.6.2)
|
|
55
59
|
rack (>= 1.0)
|
|
56
|
-
rails (3.
|
|
57
|
-
actionmailer (= 3.
|
|
58
|
-
actionpack (= 3.
|
|
59
|
-
activerecord (= 3.
|
|
60
|
-
activeresource (= 3.
|
|
61
|
-
activesupport (= 3.
|
|
60
|
+
rails (3.2.9)
|
|
61
|
+
actionmailer (= 3.2.9)
|
|
62
|
+
actionpack (= 3.2.9)
|
|
63
|
+
activerecord (= 3.2.9)
|
|
64
|
+
activeresource (= 3.2.9)
|
|
65
|
+
activesupport (= 3.2.9)
|
|
62
66
|
bundler (~> 1.0)
|
|
63
|
-
railties (= 3.
|
|
64
|
-
railties (3.
|
|
65
|
-
actionpack (= 3.
|
|
66
|
-
activesupport (= 3.
|
|
67
|
+
railties (= 3.2.9)
|
|
68
|
+
railties (3.2.9)
|
|
69
|
+
actionpack (= 3.2.9)
|
|
70
|
+
activesupport (= 3.2.9)
|
|
67
71
|
rack-ssl (~> 1.3.2)
|
|
68
72
|
rake (>= 0.8.7)
|
|
69
73
|
rdoc (~> 3.4)
|
|
70
|
-
thor (
|
|
71
|
-
rake (0.
|
|
74
|
+
thor (>= 0.14.6, < 2.0)
|
|
75
|
+
rake (10.0.2)
|
|
72
76
|
rdoc (3.12)
|
|
73
77
|
json (~> 1.4)
|
|
74
|
-
rspec (2.
|
|
75
|
-
rspec-core (~> 2.
|
|
76
|
-
rspec-expectations (~> 2.
|
|
77
|
-
rspec-mocks (~> 2.
|
|
78
|
-
rspec-core (2.
|
|
79
|
-
rspec-expectations (2.
|
|
80
|
-
diff-lcs (~> 1.1.
|
|
81
|
-
rspec-mocks (2.
|
|
82
|
-
sprockets (2.
|
|
78
|
+
rspec (2.12.0)
|
|
79
|
+
rspec-core (~> 2.12.0)
|
|
80
|
+
rspec-expectations (~> 2.12.0)
|
|
81
|
+
rspec-mocks (~> 2.12.0)
|
|
82
|
+
rspec-core (2.12.1)
|
|
83
|
+
rspec-expectations (2.12.0)
|
|
84
|
+
diff-lcs (~> 1.1.3)
|
|
85
|
+
rspec-mocks (2.12.0)
|
|
86
|
+
sprockets (2.2.2)
|
|
83
87
|
hike (~> 1.2)
|
|
88
|
+
multi_json (~> 1.0)
|
|
84
89
|
rack (~> 1.0)
|
|
85
90
|
tilt (~> 1.1, != 1.3.0)
|
|
86
|
-
thor (0.
|
|
91
|
+
thor (0.16.0)
|
|
87
92
|
tilt (1.3.3)
|
|
88
|
-
treetop (1.4.
|
|
93
|
+
treetop (1.4.12)
|
|
89
94
|
polyglot
|
|
90
95
|
polyglot (>= 0.3.1)
|
|
91
|
-
tzinfo (0.3.
|
|
96
|
+
tzinfo (0.3.35)
|
|
92
97
|
|
|
93
98
|
PLATFORMS
|
|
94
99
|
ruby
|
|
95
100
|
|
|
96
101
|
DEPENDENCIES
|
|
97
102
|
activerecord
|
|
103
|
+
jeweler
|
|
98
104
|
pg
|
|
99
105
|
rails
|
|
100
106
|
rake
|
data/README.md
CHANGED
|
@@ -62,11 +62,25 @@ Which will generate the following SQL command:
|
|
|
62
62
|
|
|
63
63
|
COPY (SELECT name FROM "users" WHERE "users"."id" IN (1, 2, 3)) TO '/tmp/users.csv' WITH DELIMITER ',' CSV HEADER
|
|
64
64
|
|
|
65
|
+
The COPY command also supports exporting the data in binary format.
|
|
66
|
+
|
|
67
|
+
User.select("name").where(:id => [1,2,3]).pg_copy_to "/tmp/users.dat", :format => :binary
|
|
68
|
+
|
|
69
|
+
Which will generate the following SQL command:
|
|
70
|
+
|
|
71
|
+
COPY (SELECT name FROM "users" WHERE "users"."id" IN (1, 2, 3)) TO '/tmp/users.dat' WITH BINARY
|
|
72
|
+
|
|
73
|
+
The copy_to_string method also supports this
|
|
74
|
+
|
|
75
|
+
puts User.pg_copy_to_string(:format => :binary)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
|
|
65
79
|
### Using pg_copy_from
|
|
66
80
|
|
|
67
81
|
Now, if you want to copy data from a CSV file into the database, you can use the pg_copy_from method.
|
|
68
|
-
It will allow you to copy data from an arbritary IO object or from a file in the database server (when you pass the path as string).
|
|
69
|
-
Let's first copy from a file in the database server, assuming again that we have a users table and
|
|
82
|
+
It will allow you to copy data from an arbritary IO object or from a file in the database server (when you pass the path as string).
|
|
83
|
+
Let's first copy from a file in the database server, assuming again that we have a users table and
|
|
70
84
|
that we are in the Rails console:
|
|
71
85
|
|
|
72
86
|
User.pg_copy_from "/tmp/users.csv"
|
|
@@ -86,8 +100,24 @@ You can also manipulate and modify the values of the file being imported before
|
|
|
86
100
|
The above extample will always change the value of the first column to "fixed string" before storing it into the database.
|
|
87
101
|
For each iteration of the block row receives an array with the same order as the columns in the CSV file.
|
|
88
102
|
|
|
103
|
+
|
|
104
|
+
To copy a binary formatted data file or IO object you can specify the format as binary
|
|
105
|
+
|
|
106
|
+
User.pg_copy_from "/tmp/users.dat", :format => :binary
|
|
107
|
+
|
|
108
|
+
NOTE: Columns must line up with the table unless you specify how they map to table columns.
|
|
109
|
+
|
|
110
|
+
To specify how the columns will map to the table you can specify the :columns option
|
|
111
|
+
|
|
112
|
+
User.pg_copy_from "/tmp/users.dat", :format => :binary, :columns => [:id, :name]
|
|
113
|
+
|
|
114
|
+
Which will generate the following SQL command:
|
|
115
|
+
|
|
116
|
+
COPY users (id, name) FROM '/tmp/users.dat' WITH BINARY
|
|
117
|
+
|
|
118
|
+
|
|
89
119
|
## Note on Patches/Pull Requests
|
|
90
|
-
|
|
120
|
+
|
|
91
121
|
* Fork the project.
|
|
92
122
|
* Make your feature addition or bug fix.
|
|
93
123
|
* Add tests for it. This is important so I don't break it in a
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.5.0
|
|
@@ -2,23 +2,32 @@ module ActiveRecord
|
|
|
2
2
|
class Base
|
|
3
3
|
# Copy data to a file passed as a string (the file path) or to lines that are passed to a block
|
|
4
4
|
def self.pg_copy_to path = nil, options = {}
|
|
5
|
-
options = {:delimiter => ","}.merge(options)
|
|
5
|
+
options = {:delimiter => ",", :format => :csv, :header => true}.merge(options)
|
|
6
|
+
options_string = if options[:format] == :binary
|
|
7
|
+
"BINARY"
|
|
8
|
+
else
|
|
9
|
+
"DELIMITER '#{options[:delimiter]}' CSV #{options[:header] ? 'HEADER' : ''}"
|
|
10
|
+
end
|
|
11
|
+
|
|
6
12
|
if path
|
|
7
13
|
raise "You have to choose between exporting to a file or receiving the lines inside a block" if block_given?
|
|
8
|
-
connection.execute "COPY (#{self.scoped.to_sql}) TO #{sanitize(path)} WITH
|
|
14
|
+
connection.execute "COPY (#{self.scoped.to_sql}) TO #{sanitize(path)} WITH #{options_string}"
|
|
9
15
|
else
|
|
10
|
-
connection.execute "COPY (#{self.scoped.to_sql}) TO STDOUT WITH
|
|
16
|
+
connection.execute "COPY (#{self.scoped.to_sql}) TO STDOUT WITH #{options_string}"
|
|
11
17
|
while line = connection.raw_connection.get_copy_data do
|
|
12
18
|
yield(line) if block_given?
|
|
13
19
|
end
|
|
14
20
|
end
|
|
15
21
|
return self
|
|
16
22
|
end
|
|
17
|
-
|
|
23
|
+
|
|
18
24
|
# Copy all data to a single string
|
|
19
25
|
def self.pg_copy_to_string options = {}
|
|
20
26
|
data = ''
|
|
21
27
|
self.pg_copy_to(nil, options){|l| data += l }
|
|
28
|
+
if options[:format] == :binary
|
|
29
|
+
data.force_encoding("ASCII-8BIT")
|
|
30
|
+
end
|
|
22
31
|
data
|
|
23
32
|
end
|
|
24
33
|
|
|
@@ -27,21 +36,43 @@ module ActiveRecord
|
|
|
27
36
|
# * You can map fields from the file to different fields in the table using a map in the options hash
|
|
28
37
|
# * For further details on usage take a look at the README.md
|
|
29
38
|
def self.pg_copy_from path_or_io, options = {}
|
|
30
|
-
options = {:delimiter => ","}.merge(options)
|
|
39
|
+
options = {:delimiter => ",", :format => :csv}.merge(options)
|
|
40
|
+
options_string = if options[:format] == :binary
|
|
41
|
+
"BINARY"
|
|
42
|
+
else
|
|
43
|
+
"DELIMITER '#{options[:delimiter]}' CSV"
|
|
44
|
+
end
|
|
31
45
|
io = path_or_io.instance_of?(String) ? File.open(path_or_io, 'r') : path_or_io
|
|
32
46
|
# The first line should be always the HEADER.
|
|
33
|
-
|
|
34
|
-
|
|
47
|
+
if options[:format] == :binary
|
|
48
|
+
columns_list = options[:columns] || []
|
|
49
|
+
else
|
|
50
|
+
line = io.gets
|
|
51
|
+
columns_list = options[:columns] || line.strip.split(options[:delimiter])
|
|
52
|
+
end
|
|
53
|
+
|
|
35
54
|
columns_list = columns_list.map{|c| options[:map][c.to_s] } if options[:map]
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
55
|
+
columns_string = columns_list.size > 0 ? "(\"#{columns_list.join('","')}\")" : ""
|
|
56
|
+
connection.execute %{COPY #{quoted_table_name} #{columns_string} FROM STDIN WITH #{options_string}}
|
|
57
|
+
if options[:format] == :binary
|
|
58
|
+
bytes = 0
|
|
59
|
+
begin
|
|
60
|
+
while line = io.readpartial(10240)
|
|
61
|
+
connection.raw_connection.put_copy_data line
|
|
62
|
+
bytes += line.bytesize
|
|
63
|
+
end
|
|
64
|
+
rescue EOFError
|
|
65
|
+
end
|
|
66
|
+
else
|
|
67
|
+
while line = io.gets do
|
|
68
|
+
next if line.strip.size == 0
|
|
69
|
+
if block_given?
|
|
70
|
+
row = line.strip.split(options[:delimiter])
|
|
71
|
+
yield(row)
|
|
72
|
+
line = row.join(options[:delimiter]) + "\n"
|
|
73
|
+
end
|
|
74
|
+
connection.raw_connection.put_copy_data line
|
|
43
75
|
end
|
|
44
|
-
connection.raw_connection.put_copy_data line
|
|
45
76
|
end
|
|
46
77
|
connection.raw_connection.put_copy_end
|
|
47
78
|
end
|
data/postgres-copy.gemspec
CHANGED
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
|
|
6
6
|
Gem::Specification.new do |s|
|
|
7
7
|
s.name = "postgres-copy"
|
|
8
|
-
s.version = "0.
|
|
8
|
+
s.version = "0.5.0"
|
|
9
9
|
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
|
11
11
|
s.authors = ["Diogo Biazus"]
|
|
12
|
-
s.date = "2012-
|
|
12
|
+
s.date = "2012-12-12"
|
|
13
13
|
s.description = "Now you can use the super fast COPY for import/export data directly from your AR models."
|
|
14
14
|
s.email = "diogob@gmail.com"
|
|
15
15
|
s.extra_rdoc_files = [
|
|
@@ -30,6 +30,7 @@ Gem::Specification.new do |s|
|
|
|
30
30
|
"lib/postgres-copy/csv_responder.rb",
|
|
31
31
|
"lib/postgres-copy/zip_responder.rb",
|
|
32
32
|
"postgres-copy.gemspec",
|
|
33
|
+
"spec/fixtures/2_col_binary_data.dat",
|
|
33
34
|
"spec/fixtures/comma_with_header.csv",
|
|
34
35
|
"spec/fixtures/extra_field.rb",
|
|
35
36
|
"spec/fixtures/reserved_word_model.rb",
|
|
@@ -43,20 +44,23 @@ Gem::Specification.new do |s|
|
|
|
43
44
|
"spec/fixtures/tab_with_header.csv",
|
|
44
45
|
"spec/fixtures/tab_with_two_lines.csv",
|
|
45
46
|
"spec/fixtures/test_model.rb",
|
|
47
|
+
"spec/pg_copy_from_binary_spec.rb",
|
|
46
48
|
"spec/pg_copy_from_spec.rb",
|
|
49
|
+
"spec/pg_copy_to_binary_spec.rb",
|
|
47
50
|
"spec/pg_copy_to_spec.rb",
|
|
48
51
|
"spec/spec.opts",
|
|
49
52
|
"spec/spec_helper.rb"
|
|
50
53
|
]
|
|
51
54
|
s.homepage = "http://github.com/diogob/postgres-copy"
|
|
52
55
|
s.require_paths = ["lib"]
|
|
53
|
-
s.rubygems_version = "1.8.
|
|
56
|
+
s.rubygems_version = "1.8.24"
|
|
54
57
|
s.summary = "Put COPY command functionality in ActiveRecord's model class"
|
|
55
58
|
|
|
56
59
|
if s.respond_to? :specification_version then
|
|
57
60
|
s.specification_version = 3
|
|
58
61
|
|
|
59
62
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
|
63
|
+
s.add_runtime_dependency(%q<jeweler>, [">= 0"])
|
|
60
64
|
s.add_runtime_dependency(%q<pg>, [">= 0"])
|
|
61
65
|
s.add_runtime_dependency(%q<activerecord>, [">= 0"])
|
|
62
66
|
s.add_runtime_dependency(%q<rails>, [">= 0"])
|
|
@@ -66,6 +70,7 @@ Gem::Specification.new do |s|
|
|
|
66
70
|
s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
|
|
67
71
|
s.add_runtime_dependency(%q<activerecord>, [">= 3.0.0"])
|
|
68
72
|
else
|
|
73
|
+
s.add_dependency(%q<jeweler>, [">= 0"])
|
|
69
74
|
s.add_dependency(%q<pg>, [">= 0"])
|
|
70
75
|
s.add_dependency(%q<activerecord>, [">= 0"])
|
|
71
76
|
s.add_dependency(%q<rails>, [">= 0"])
|
|
@@ -76,6 +81,7 @@ Gem::Specification.new do |s|
|
|
|
76
81
|
s.add_dependency(%q<activerecord>, [">= 3.0.0"])
|
|
77
82
|
end
|
|
78
83
|
else
|
|
84
|
+
s.add_dependency(%q<jeweler>, [">= 0"])
|
|
79
85
|
s.add_dependency(%q<pg>, [">= 0"])
|
|
80
86
|
s.add_dependency(%q<activerecord>, [">= 0"])
|
|
81
87
|
s.add_dependency(%q<rails>, [">= 0"])
|
|
Binary file
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
|
2
|
+
|
|
3
|
+
describe "COPY FROM BINARY" do
|
|
4
|
+
before(:each) do
|
|
5
|
+
ActiveRecord::Base.connection.execute %{
|
|
6
|
+
TRUNCATE TABLE test_models;
|
|
7
|
+
SELECT setval('test_models_id_seq', 1, false);
|
|
8
|
+
}
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "should import from file if path is passed without field_map" do
|
|
12
|
+
TestModel.pg_copy_from File.expand_path('spec/fixtures/2_col_binary_data.dat'), :format => :binary, columns: [:id, :data]
|
|
13
|
+
TestModel.order(:id).all.map{|r| r.attributes}.should == [{'id' => 1, 'data' => 'text'}]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "should import from file if columns are not specified" do
|
|
17
|
+
TestModel.pg_copy_from File.expand_path('spec/fixtures/2_col_binary_data.dat'), :format => :binary
|
|
18
|
+
TestModel.order(:id).all.map{|r| r.attributes}.should == [{'id' => 1, 'data' => 'text'}]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
end
|
|
22
|
+
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
|
2
|
+
|
|
3
|
+
describe "COPY TO BINARY" do
|
|
4
|
+
before(:all) do
|
|
5
|
+
ActiveRecord::Base.connection.execute %{
|
|
6
|
+
TRUNCATE TABLE test_models;
|
|
7
|
+
SELECT setval('test_models_id_seq', 1, false);
|
|
8
|
+
}
|
|
9
|
+
TestModel.create :data => 'text'
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
describe "should allow binary output to string" do
|
|
13
|
+
context "with only binary option" do
|
|
14
|
+
subject{ TestModel.pg_copy_to_string(:format => :binary) }
|
|
15
|
+
it{ should == File.open('spec/fixtures/2_col_binary_data.dat', 'r:ASCII-8BIT').read }
|
|
16
|
+
end
|
|
17
|
+
context "with custom select" do
|
|
18
|
+
subject{ TestModel.select("id, data").pg_copy_to_string(:format => :binary) }
|
|
19
|
+
it{ should == File.open('spec/fixtures/2_col_binary_data.dat', 'r:ASCII-8BIT').read }
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
describe "should allow binary output to file" do
|
|
24
|
+
it "should copy to disk if block is not given and a path is passed" do
|
|
25
|
+
TestModel.pg_copy_to '/tmp/export.dat', :format => :binary
|
|
26
|
+
str = File.open('/tmp/export.dat', 'r:ASCII-8BIT').read
|
|
27
|
+
|
|
28
|
+
str.should == File.open('spec/fixtures/2_col_binary_data.dat', 'r:ASCII-8BIT').read
|
|
29
|
+
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -14,13 +14,16 @@ RSpec.configure do |config|
|
|
|
14
14
|
ActiveRecord::Base.establish_connection(
|
|
15
15
|
:adapter => "postgresql",
|
|
16
16
|
:host => "localhost",
|
|
17
|
+
:username => "postgres",
|
|
18
|
+
:password => "postgres",
|
|
19
|
+
:port => 5432,
|
|
17
20
|
:database => "ar_pg_copy_test"
|
|
18
21
|
)
|
|
19
22
|
ActiveRecord::Base.connection.execute %{
|
|
20
23
|
SET client_min_messages TO warning;
|
|
21
|
-
DROP TABLE IF EXISTS test_models;
|
|
22
|
-
DROP TABLE IF EXISTS extra_fields;
|
|
23
|
-
DROP TABLE IF EXISTS reserved_word_models;
|
|
24
|
+
DROP TABLE IF EXISTS test_models;
|
|
25
|
+
DROP TABLE IF EXISTS extra_fields;
|
|
26
|
+
DROP TABLE IF EXISTS reserved_word_models;
|
|
24
27
|
CREATE TABLE test_models (id serial PRIMARY KEY, data text);
|
|
25
28
|
CREATE TABLE reserved_word_models (id serial PRIMARY KEY, "select" text, "group" text);
|
|
26
29
|
CREATE TABLE extra_fields (id serial PRIMARY KEY, data text, created_at timestamp, updated_at timestamp);
|
|
@@ -30,6 +33,9 @@ RSpec.configure do |config|
|
|
|
30
33
|
ActiveRecord::Base.establish_connection(
|
|
31
34
|
:adapter => "postgresql",
|
|
32
35
|
:host => "localhost",
|
|
36
|
+
:username => "postgres",
|
|
37
|
+
:password => "postgres",
|
|
38
|
+
:port => 5432,
|
|
33
39
|
:database => "postgres"
|
|
34
40
|
)
|
|
35
41
|
ActiveRecord::Base.connection.execute "CREATE DATABASE ar_pg_copy_test"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: postgres-copy
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.5.0
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
@@ -9,11 +9,27 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2012-
|
|
12
|
+
date: 2012-12-12 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
|
+
- !ruby/object:Gem::Dependency
|
|
15
|
+
name: jeweler
|
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
|
17
|
+
none: false
|
|
18
|
+
requirements:
|
|
19
|
+
- - ! '>='
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '0'
|
|
22
|
+
type: :runtime
|
|
23
|
+
prerelease: false
|
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
+
none: false
|
|
26
|
+
requirements:
|
|
27
|
+
- - ! '>='
|
|
28
|
+
- !ruby/object:Gem::Version
|
|
29
|
+
version: '0'
|
|
14
30
|
- !ruby/object:Gem::Dependency
|
|
15
31
|
name: pg
|
|
16
|
-
requirement:
|
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
|
17
33
|
none: false
|
|
18
34
|
requirements:
|
|
19
35
|
- - ! '>='
|
|
@@ -21,10 +37,15 @@ dependencies:
|
|
|
21
37
|
version: '0'
|
|
22
38
|
type: :runtime
|
|
23
39
|
prerelease: false
|
|
24
|
-
version_requirements:
|
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
41
|
+
none: false
|
|
42
|
+
requirements:
|
|
43
|
+
- - ! '>='
|
|
44
|
+
- !ruby/object:Gem::Version
|
|
45
|
+
version: '0'
|
|
25
46
|
- !ruby/object:Gem::Dependency
|
|
26
47
|
name: activerecord
|
|
27
|
-
requirement:
|
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
|
28
49
|
none: false
|
|
29
50
|
requirements:
|
|
30
51
|
- - ! '>='
|
|
@@ -32,10 +53,15 @@ dependencies:
|
|
|
32
53
|
version: '0'
|
|
33
54
|
type: :runtime
|
|
34
55
|
prerelease: false
|
|
35
|
-
version_requirements:
|
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
57
|
+
none: false
|
|
58
|
+
requirements:
|
|
59
|
+
- - ! '>='
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '0'
|
|
36
62
|
- !ruby/object:Gem::Dependency
|
|
37
63
|
name: rails
|
|
38
|
-
requirement:
|
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
|
39
65
|
none: false
|
|
40
66
|
requirements:
|
|
41
67
|
- - ! '>='
|
|
@@ -43,10 +69,15 @@ dependencies:
|
|
|
43
69
|
version: '0'
|
|
44
70
|
type: :runtime
|
|
45
71
|
prerelease: false
|
|
46
|
-
version_requirements:
|
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
73
|
+
none: false
|
|
74
|
+
requirements:
|
|
75
|
+
- - ! '>='
|
|
76
|
+
- !ruby/object:Gem::Version
|
|
77
|
+
version: '0'
|
|
47
78
|
- !ruby/object:Gem::Dependency
|
|
48
79
|
name: rake
|
|
49
|
-
requirement:
|
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
|
50
81
|
none: false
|
|
51
82
|
requirements:
|
|
52
83
|
- - ! '>='
|
|
@@ -54,10 +85,15 @@ dependencies:
|
|
|
54
85
|
version: '0'
|
|
55
86
|
type: :runtime
|
|
56
87
|
prerelease: false
|
|
57
|
-
version_requirements:
|
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
89
|
+
none: false
|
|
90
|
+
requirements:
|
|
91
|
+
- - ! '>='
|
|
92
|
+
- !ruby/object:Gem::Version
|
|
93
|
+
version: '0'
|
|
58
94
|
- !ruby/object:Gem::Dependency
|
|
59
95
|
name: rspec
|
|
60
|
-
requirement:
|
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
|
61
97
|
none: false
|
|
62
98
|
requirements:
|
|
63
99
|
- - ~>
|
|
@@ -65,10 +101,15 @@ dependencies:
|
|
|
65
101
|
version: '2.6'
|
|
66
102
|
type: :runtime
|
|
67
103
|
prerelease: false
|
|
68
|
-
version_requirements:
|
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
105
|
+
none: false
|
|
106
|
+
requirements:
|
|
107
|
+
- - ~>
|
|
108
|
+
- !ruby/object:Gem::Version
|
|
109
|
+
version: '2.6'
|
|
69
110
|
- !ruby/object:Gem::Dependency
|
|
70
111
|
name: rspec-core
|
|
71
|
-
requirement:
|
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
113
|
none: false
|
|
73
114
|
requirements:
|
|
74
115
|
- - ~>
|
|
@@ -76,10 +117,15 @@ dependencies:
|
|
|
76
117
|
version: '2.6'
|
|
77
118
|
type: :runtime
|
|
78
119
|
prerelease: false
|
|
79
|
-
version_requirements:
|
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
121
|
+
none: false
|
|
122
|
+
requirements:
|
|
123
|
+
- - ~>
|
|
124
|
+
- !ruby/object:Gem::Version
|
|
125
|
+
version: '2.6'
|
|
80
126
|
- !ruby/object:Gem::Dependency
|
|
81
127
|
name: rspec
|
|
82
|
-
requirement:
|
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
|
83
129
|
none: false
|
|
84
130
|
requirements:
|
|
85
131
|
- - ! '>='
|
|
@@ -87,10 +133,15 @@ dependencies:
|
|
|
87
133
|
version: 1.2.9
|
|
88
134
|
type: :development
|
|
89
135
|
prerelease: false
|
|
90
|
-
version_requirements:
|
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
137
|
+
none: false
|
|
138
|
+
requirements:
|
|
139
|
+
- - ! '>='
|
|
140
|
+
- !ruby/object:Gem::Version
|
|
141
|
+
version: 1.2.9
|
|
91
142
|
- !ruby/object:Gem::Dependency
|
|
92
143
|
name: activerecord
|
|
93
|
-
requirement:
|
|
144
|
+
requirement: !ruby/object:Gem::Requirement
|
|
94
145
|
none: false
|
|
95
146
|
requirements:
|
|
96
147
|
- - ! '>='
|
|
@@ -98,7 +149,12 @@ dependencies:
|
|
|
98
149
|
version: 3.0.0
|
|
99
150
|
type: :runtime
|
|
100
151
|
prerelease: false
|
|
101
|
-
version_requirements:
|
|
152
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
153
|
+
none: false
|
|
154
|
+
requirements:
|
|
155
|
+
- - ! '>='
|
|
156
|
+
- !ruby/object:Gem::Version
|
|
157
|
+
version: 3.0.0
|
|
102
158
|
description: Now you can use the super fast COPY for import/export data directly from
|
|
103
159
|
your AR models.
|
|
104
160
|
email: diogob@gmail.com
|
|
@@ -121,6 +177,7 @@ files:
|
|
|
121
177
|
- lib/postgres-copy/csv_responder.rb
|
|
122
178
|
- lib/postgres-copy/zip_responder.rb
|
|
123
179
|
- postgres-copy.gemspec
|
|
180
|
+
- spec/fixtures/2_col_binary_data.dat
|
|
124
181
|
- spec/fixtures/comma_with_header.csv
|
|
125
182
|
- spec/fixtures/extra_field.rb
|
|
126
183
|
- spec/fixtures/reserved_word_model.rb
|
|
@@ -134,7 +191,9 @@ files:
|
|
|
134
191
|
- spec/fixtures/tab_with_header.csv
|
|
135
192
|
- spec/fixtures/tab_with_two_lines.csv
|
|
136
193
|
- spec/fixtures/test_model.rb
|
|
194
|
+
- spec/pg_copy_from_binary_spec.rb
|
|
137
195
|
- spec/pg_copy_from_spec.rb
|
|
196
|
+
- spec/pg_copy_to_binary_spec.rb
|
|
138
197
|
- spec/pg_copy_to_spec.rb
|
|
139
198
|
- spec/spec.opts
|
|
140
199
|
- spec/spec_helper.rb
|
|
@@ -150,6 +209,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
150
209
|
- - ! '>='
|
|
151
210
|
- !ruby/object:Gem::Version
|
|
152
211
|
version: '0'
|
|
212
|
+
segments:
|
|
213
|
+
- 0
|
|
214
|
+
hash: 4043975197351030400
|
|
153
215
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
154
216
|
none: false
|
|
155
217
|
requirements:
|
|
@@ -158,7 +220,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
158
220
|
version: '0'
|
|
159
221
|
requirements: []
|
|
160
222
|
rubyforge_project:
|
|
161
|
-
rubygems_version: 1.8.
|
|
223
|
+
rubygems_version: 1.8.24
|
|
162
224
|
signing_key:
|
|
163
225
|
specification_version: 3
|
|
164
226
|
summary: Put COPY command functionality in ActiveRecord's model class
|