rdb_csv 0.3.0 → 0.4.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 +4 -4
- data/.gitignore +12 -0
- data/.rspec +3 -0
- data/.travis.yml +7 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +34 -0
- data/LICENSE +9 -0
- data/README.md +96 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/rdb_csv.rb +123 -0
- data/lib/rdb_csv/reader.rb +73 -0
- data/lib/rdb_csv/row.rb +121 -0
- data/lib/rdb_csv/version.rb +3 -0
- data/rdb_csv.gemspec +21 -0
- data/spec/fixtures/mysql.csv +7 -0
- data/spec/fixtures/mysql.tsv +6 -0
- data/spec/fixtures/normal.csv +4 -0
- data/spec/fixtures/normal.tsv +4 -0
- data/spec/fixtures/postgresql.csv +8 -0
- data/spec/fixtures/postgresql.tsv +8 -0
- data/spec/load/README.md +37 -0
- data/spec/load/create_table.mysql.sql +1 -0
- data/spec/load/create_table.postgresql.sql +1 -0
- data/spec/load/docker/docker-compose.mysql.yml +16 -0
- data/spec/load/docker/docker-compose.postgresql.yml +10 -0
- data/spec/load/load.mysql.csv.sql +1 -0
- data/spec/load/load.mysql.tsv.sql +1 -0
- data/spec/load/load.postgresql.csv.sql +1 -0
- data/spec/load/load.postgresql.tsv.sql +1 -0
- data/spec/rdb_csv_spec.rb +512 -0
- data/spec/spec_helper.rb +14 -0
- metadata +35 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 49500956b9723214a17c58ea2511214c3b8d35f0734ed92609b14336e987cca6
|
4
|
+
data.tar.gz: 41896be81f877579013ce1d98410b413ad12b205e417817d6abd391f29a7feb2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fb447a0deab272668e546f3f067ad08957e2e7c6d1257b7fe76d22895a77e5f85ffb51ea61370ca3402f390b73555702ef1c8f24956ff7fed8e17ca5b9056e13
|
7
|
+
data.tar.gz: 4a9b3d811aa1ff10abded0c5e857c367cc50e9c28404d9138774ac47d5e50c86fc0021c8b9b0a3699057c8f7e1be51c23e7a781a8796116ac9714aaebd8ea1a0
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
rdb_csv (0.4.0)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
diff-lcs (1.3)
|
10
|
+
rake (12.3.2)
|
11
|
+
rspec (3.8.0)
|
12
|
+
rspec-core (~> 3.8.0)
|
13
|
+
rspec-expectations (~> 3.8.0)
|
14
|
+
rspec-mocks (~> 3.8.0)
|
15
|
+
rspec-core (3.8.0)
|
16
|
+
rspec-support (~> 3.8.0)
|
17
|
+
rspec-expectations (3.8.3)
|
18
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
19
|
+
rspec-support (~> 3.8.0)
|
20
|
+
rspec-mocks (3.8.0)
|
21
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
22
|
+
rspec-support (~> 3.8.0)
|
23
|
+
rspec-support (3.8.0)
|
24
|
+
|
25
|
+
PLATFORMS
|
26
|
+
ruby
|
27
|
+
|
28
|
+
DEPENDENCIES
|
29
|
+
rake
|
30
|
+
rdb_csv!
|
31
|
+
rspec
|
32
|
+
|
33
|
+
BUNDLED WITH
|
34
|
+
2.0.1
|
data/LICENSE
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2019 longicorn
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
6
|
+
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
8
|
+
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
# RdbCSV
|
2
|
+
|
3
|
+
RDB dumped csv/tsv can be read and write.
|
4
|
+
|
5
|
+
Rdbcsv supoorts mainly MySQL and PostgreSQL within reasonable range.
|
6
|
+
|
7
|
+
## Requirements
|
8
|
+
- Ruby 2.4+
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
|
12
|
+
```
|
13
|
+
gem install rdb_csv
|
14
|
+
```
|
15
|
+
|
16
|
+
or, add this line in your Gemfile
|
17
|
+
|
18
|
+
```
|
19
|
+
gem 'rdb_csv'
|
20
|
+
```
|
21
|
+
|
22
|
+
## Usage
|
23
|
+
|
24
|
+
`RdbCSV` is similar to the standard CSV class.
|
25
|
+
|
26
|
+
database type: argment `db`. The default is to use standard CSV class.
|
27
|
+
|
28
|
+
delimiter type: argment `delimiter` The default is to use `\t`, because the dafault delimiter for dump data is `\t`.
|
29
|
+
|
30
|
+
### MySQL
|
31
|
+
|
32
|
+
Use `INTO OUTFILE` to safely dump CSV,TSV on MySQL.
|
33
|
+
|
34
|
+
```ruby
|
35
|
+
require 'rdb_csv'
|
36
|
+
|
37
|
+
# TSV
|
38
|
+
tsv_path = "your_dump_file_path.tsv"
|
39
|
+
RdbCSV.open(tsv_path, db: :mysql, delimiter: "\t") do |tsv|
|
40
|
+
tsv.each do |row|
|
41
|
+
p row
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# CSV
|
46
|
+
csv_path = "your_dump_file_path.tsv"
|
47
|
+
RdbCSV.open(csv_path, db: :mysql, delimiter: ",") do |csv|
|
48
|
+
csv.each do |row|
|
49
|
+
p row
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# Use foreach
|
54
|
+
RdbCSV.foreach(csv_path, db: :mysql, delimiter: ",") do |row|
|
55
|
+
p row
|
56
|
+
end
|
57
|
+
```
|
58
|
+
|
59
|
+
### PostgreSQl
|
60
|
+
Use `COPY` to safely dump CSV,TSV on PostgreSQL.
|
61
|
+
|
62
|
+
```ruby
|
63
|
+
require 'rdb_csv'
|
64
|
+
|
65
|
+
# TSV
|
66
|
+
tsv_path = "your_dump_file_path.tsv"
|
67
|
+
RdbCSV.foreach(tsv_path, db: :postgresql, delimiter: "\t") do |row|
|
68
|
+
p row
|
69
|
+
end
|
70
|
+
|
71
|
+
# CSV
|
72
|
+
csv_path = "your_dump_file_path.csv"
|
73
|
+
RdbCSV.foreach(csv_path, db: :postgresql, delimiter: ",") do |row|
|
74
|
+
p row
|
75
|
+
end
|
76
|
+
```
|
77
|
+
|
78
|
+
### Convert MySQL to PostgreSQl
|
79
|
+
|
80
|
+
```ruby
|
81
|
+
require 'rdb_csv'
|
82
|
+
|
83
|
+
mysql_rows = []
|
84
|
+
|
85
|
+
mysql_tsv_path = "your_mysql_dump_file_path.tsv"
|
86
|
+
RdbCSV.foreach(mysql_tsv_path, db: :mysql, delimiter: "\t") do |row|
|
87
|
+
mysql_rows << row
|
88
|
+
end
|
89
|
+
|
90
|
+
postgres_tsv_path = "your_postgres_dump_file_path.tsv"
|
91
|
+
RdbCSV.open(postgres_tsv_path, "w", db: :postgresql, delimiter: "\t") do |tsv|
|
92
|
+
mysql_rows.each do |mysql_row|
|
93
|
+
tsv << mysql_row
|
94
|
+
end
|
95
|
+
end
|
96
|
+
```
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "rdb_csv"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/lib/rdb_csv.rb
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
require 'csv'
|
2
|
+
require 'rdb_csv/reader'
|
3
|
+
require 'rdb_csv/row'
|
4
|
+
|
5
|
+
class RdbCSV
|
6
|
+
class CSV
|
7
|
+
include RdbCSVReader
|
8
|
+
include RdbCSVRow
|
9
|
+
|
10
|
+
def initialize(f, mode, options)
|
11
|
+
@f = f
|
12
|
+
@mode = options[:mode]
|
13
|
+
@db = options[:db]
|
14
|
+
@delimiter = options[:delimiter] || "\t"
|
15
|
+
@escape = "\\"
|
16
|
+
@linefeed = "\n"
|
17
|
+
quote = options[:quote] || '"'
|
18
|
+
|
19
|
+
# quote option is valid only mysql
|
20
|
+
@quote = options[:db] == :mysql ? quote : '"'
|
21
|
+
end
|
22
|
+
|
23
|
+
def each
|
24
|
+
raise IOError if @mode == 'w'
|
25
|
+
|
26
|
+
reader = Reader.new(@f, @db, @delimiter, escape: @escape, linefeed: @linefeed, quote: @quote)
|
27
|
+
|
28
|
+
reader.each_line do |row|
|
29
|
+
yield row.unescape(@escape, @db, @delimiter)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
WRITE_BUFFER_SIZE = 1000
|
34
|
+
|
35
|
+
def <<(array)
|
36
|
+
raise IOError if @mode == 'r'
|
37
|
+
|
38
|
+
@lines ||= []
|
39
|
+
|
40
|
+
row = Row.new(array)
|
41
|
+
line = row.join(@escape, @db, @delimiter)
|
42
|
+
@lines << line + @linefeed
|
43
|
+
buffer_write if @lines.size >= WRITE_BUFFER_SIZE
|
44
|
+
end
|
45
|
+
|
46
|
+
def buffer_write
|
47
|
+
return if @lines.nil? || @lines.size.zero?
|
48
|
+
|
49
|
+
@f.write(@lines.join)
|
50
|
+
@lines = []
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.open(file, mode = 'r', options)
|
55
|
+
db = options[:db] || :default
|
56
|
+
delimiter = options[:delimiter] || "\t"
|
57
|
+
quote = options[:delimiter] || '"'
|
58
|
+
|
59
|
+
case mode
|
60
|
+
when 'r'
|
61
|
+
if db == :default
|
62
|
+
::CSV.open(file, mode, col_sep: delimiter) do |csv|
|
63
|
+
yield csv
|
64
|
+
end
|
65
|
+
else
|
66
|
+
File.open(file) do |f|
|
67
|
+
csv = CSV.new(f, mode, db: db, delimiter: delimiter, quote: quote)
|
68
|
+
yield csv
|
69
|
+
end
|
70
|
+
end
|
71
|
+
when 'w'
|
72
|
+
if db == :default
|
73
|
+
::CSV.open(file, mode, col_sep: delimiter) do |csv|
|
74
|
+
yield csv
|
75
|
+
end
|
76
|
+
else
|
77
|
+
File.open(file, 'w') do |f|
|
78
|
+
csv = CSV.new(f, mode, db: db, delimiter: delimiter, quote: quote)
|
79
|
+
yield csv
|
80
|
+
|
81
|
+
csv.buffer_write
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def self.foreach(file, options)
|
88
|
+
open(file, options) do |csv|
|
89
|
+
csv.each do |row|
|
90
|
+
yield row
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def self.parse(str, options)
|
96
|
+
db = options[:db] || :default
|
97
|
+
delimiter = options[:delimiter] || "\t"
|
98
|
+
quote = options[:delimiter] || '"'
|
99
|
+
|
100
|
+
if options.key?(:db)
|
101
|
+
reader = CSV.new(str, 'r', db: db, delimiter: delimiter, quote: quote)
|
102
|
+
else
|
103
|
+
reader = ::CSV.parse(str, col_sep: delimiter)
|
104
|
+
end
|
105
|
+
|
106
|
+
rows = []
|
107
|
+
reader.each do |row|
|
108
|
+
if block_given?
|
109
|
+
yield row
|
110
|
+
else
|
111
|
+
rows << row
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
return rows unless block_given?
|
116
|
+
end
|
117
|
+
|
118
|
+
def self.parse_line(line, options)
|
119
|
+
ary = nil
|
120
|
+
parse(line, options).each{|row| ary = row; break}
|
121
|
+
return ary
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module RdbCSVReader
|
2
|
+
class Reader
|
3
|
+
def initialize(fp, db, delimiter, options)
|
4
|
+
@fp = fp
|
5
|
+
@db = db
|
6
|
+
@delimiter = delimiter
|
7
|
+
@escape = options[:escape] || "\\" # 1 char
|
8
|
+
@linefeed = options[:linefeed] || "\n"
|
9
|
+
@quote = options[:quote] || '"'
|
10
|
+
end
|
11
|
+
|
12
|
+
def each_line
|
13
|
+
str = ''
|
14
|
+
row = []
|
15
|
+
quote_num = 0
|
16
|
+
|
17
|
+
each_char do |char|
|
18
|
+
if quote_num > 0
|
19
|
+
if str[-1] == @quote && char == @quote
|
20
|
+
quote_num -= 1
|
21
|
+
elsif str[-1] != @quote && char == @quote
|
22
|
+
quote_num -= 1
|
23
|
+
elsif char == @quote
|
24
|
+
quote_num += 1
|
25
|
+
end
|
26
|
+
str += char
|
27
|
+
else
|
28
|
+
if char == @delimiter
|
29
|
+
row << str
|
30
|
+
str = ''
|
31
|
+
elsif char == @linefeed
|
32
|
+
row << str
|
33
|
+
yield RdbCSV::CSV::Row.new(row)
|
34
|
+
row = []
|
35
|
+
str = ''
|
36
|
+
else
|
37
|
+
quote_num += 1 if (str.size == 0 || str[0] == @quote) && char == @quote
|
38
|
+
str += char
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def each_char
|
47
|
+
str = ''
|
48
|
+
@fp.each_char do |char|
|
49
|
+
if str[-1] == @escape
|
50
|
+
str += char
|
51
|
+
yield str
|
52
|
+
str = ''
|
53
|
+
next
|
54
|
+
end
|
55
|
+
|
56
|
+
str += char
|
57
|
+
|
58
|
+
if str[@linefeed.size-1..-1] == @linefeed
|
59
|
+
yield str
|
60
|
+
str = ''
|
61
|
+
next
|
62
|
+
end
|
63
|
+
|
64
|
+
if str[-1] != @escape
|
65
|
+
yield str
|
66
|
+
str = ''
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
yield str unless str.empty?
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
data/lib/rdb_csv/row.rb
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
module RdbCSVRow
|
2
|
+
class Row < Array
|
3
|
+
def unescape(escape_char, db, delimiter)
|
4
|
+
send("unescape_#{db}").map{|v|v.to_i.to_s == v ? v.to_i : v rescue v}
|
5
|
+
end
|
6
|
+
|
7
|
+
def join(escape_char, db, delimiter)
|
8
|
+
escape(escape_char, db, delimiter).to_a.join(delimiter)
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def unescape_default
|
14
|
+
self
|
15
|
+
end
|
16
|
+
|
17
|
+
def unescape_mysql
|
18
|
+
row = self
|
19
|
+
if @quote
|
20
|
+
row = row.map{|v|v.match?(/^#{@quote}.*?#{@quote}$/m) ? v[1..-2].gsub(/#{@quote}#{@quote}/o, @quote) : v}
|
21
|
+
end
|
22
|
+
row.map{|v|v.nil? ? nil : v.gsub(/\\\\/o, '\\')
|
23
|
+
.gsub(/\\n/o, "\n")
|
24
|
+
.gsub(/\\\n/o, "\n")
|
25
|
+
.gsub(/\\r/o, "\r")
|
26
|
+
.gsub(/\\t/o, "\t")
|
27
|
+
.gsub(/\\0/o, "\0")
|
28
|
+
.gsub(/\\,/o, ",")
|
29
|
+
}
|
30
|
+
.map{|v|v=="\\N" ? nil : v}
|
31
|
+
.map{|v|v=="NULL" ? nil : v}
|
32
|
+
end
|
33
|
+
|
34
|
+
def unescape_postgresql
|
35
|
+
self.map{|v|v.gsub(/\\0/o, "\0")}
|
36
|
+
.map{|v|v.match?(/^".*?"$/om) ? v[1..-2].gsub(/""/, '"') : (v == '' ? nil : v)}
|
37
|
+
end
|
38
|
+
|
39
|
+
def escape(escape_char, db, delimiter)
|
40
|
+
send("escape_#{db}", escape_char, delimiter)
|
41
|
+
end
|
42
|
+
|
43
|
+
def escape_default(escape_char, delimiter)
|
44
|
+
self
|
45
|
+
end
|
46
|
+
|
47
|
+
def escape_mysql(escape_char, delimiter)
|
48
|
+
case delimiter
|
49
|
+
when "\t" # tsv
|
50
|
+
self.map do |column|
|
51
|
+
case column
|
52
|
+
when nil
|
53
|
+
"NULL"
|
54
|
+
when String
|
55
|
+
str = ""
|
56
|
+
column.each_char do |char|
|
57
|
+
case char
|
58
|
+
when escape_char
|
59
|
+
str += char*2
|
60
|
+
when "\n"
|
61
|
+
str += "#{escape_char}n"
|
62
|
+
when "\t"
|
63
|
+
str += "#{escape_char}t"
|
64
|
+
when "\0"
|
65
|
+
str += "#{escape_char}0"
|
66
|
+
else
|
67
|
+
str += char
|
68
|
+
end
|
69
|
+
end
|
70
|
+
str
|
71
|
+
else
|
72
|
+
column
|
73
|
+
end
|
74
|
+
end
|
75
|
+
when "," # csv
|
76
|
+
self.map do |column|
|
77
|
+
case column
|
78
|
+
when nil
|
79
|
+
"#{escape_char}N"
|
80
|
+
when String
|
81
|
+
str = ""
|
82
|
+
column.each_char do |char|
|
83
|
+
case char
|
84
|
+
when escape_char
|
85
|
+
str += char*2
|
86
|
+
when "\n"
|
87
|
+
str += "#{escape_char}\n"
|
88
|
+
when "\0"
|
89
|
+
str += "#{escape_char}0"
|
90
|
+
when delimiter
|
91
|
+
str += "#{escape_char}#{delimiter}"
|
92
|
+
else
|
93
|
+
str += char
|
94
|
+
end
|
95
|
+
end
|
96
|
+
str
|
97
|
+
else
|
98
|
+
column
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def escape_postgresql(escape_char, delimiter)
|
105
|
+
self.map do |v|
|
106
|
+
if v == ''
|
107
|
+
'""'
|
108
|
+
elsif v.nil?
|
109
|
+
''
|
110
|
+
elsif v.kind_of?(String)
|
111
|
+
v = v.gsub(/\0/o, "#{escape_char}#{escape_char}0")
|
112
|
+
v = v.gsub(/"/o, '""') if v.include?('"')
|
113
|
+
v = "\"#{v}\"" if v.match?(/"|\r|\n|#{delimiter}/)
|
114
|
+
v
|
115
|
+
else
|
116
|
+
v
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
data/rdb_csv.gemspec
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
lib = File.expand_path("../lib", __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require "rdb_csv/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "rdb_csv"
|
7
|
+
spec.version = RdbCSV::VERSION
|
8
|
+
spec.authors = ["longicorn"]
|
9
|
+
spec.email = ["longicorn.c@gmail.com"]
|
10
|
+
|
11
|
+
spec.summary = %q{RDB dumped csv/tsv can be read and write.}
|
12
|
+
spec.description = %q{Rdbcsv supoorts mainly MySQL and PostgreSQL within reasonable range.}
|
13
|
+
spec.homepage = "https://github.com/longicorn/rdb_csv"
|
14
|
+
spec.license = 'MIT'
|
15
|
+
|
16
|
+
spec.require_paths = ["lib"]
|
17
|
+
spec.files = `git ls-files`.split($/)
|
18
|
+
|
19
|
+
spec.add_development_dependency "rspec"
|
20
|
+
spec.add_development_dependency "rake"
|
21
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
1,abcdefg,ABCNDEFG,1,1,2018-12-12 02:26:06,2018-12-12 02:26:06,2018-12-12 02:26:06
|
2
|
+
2,abc\
|
3
|
+
|
4
|
+
3,abc defg,ABC\,DEFG,\N,-1,2018-12-12 02:26:06,2018-12-12 02:26:06,2018-12-12 02:26:06
|
5
|
+
4,abc\\defg,ABC"DEFG,\N,-1,2018-12-12 02:26:06,2018-12-12 02:26:06,2018-12-12 02:26:06
|
6
|
+
5,'abcdefg,ABC'DEFG,\N,-1,2018-12-12 02:26:06,2018-12-12 02:26:06,2018-12-12 02:26:06
|
7
|
+
6,\N,,\N,\N,2018-12-12 02:26:06,2018-12-12 02:26:06,2018-12-12 02:26:06
|
@@ -0,0 +1,6 @@
|
|
1
|
+
1 abcdefg ABCNDEFG 1 1 2018-12-12 02:26:06 2018-12-12 02:26:06 2018-12-12 02:26:06
|
2
|
+
2 abc\n
|
3
|
+
3 abc\tdefg ABC,DEFG NULL -1 2018-12-12 02:26:06 2018-12-12 02:26:06 2018-12-12 02:26:06
|
4
|
+
4 abc\\defg ABC"DEFG NULL -1 2018-12-12 02:26:06 2018-12-12 02:26:06 2018-12-12 02:26:06
|
5
|
+
5 'abcdefg ABC'DEFG NULL -1 2018-12-12 02:26:06 2018-12-12 02:26:06 2018-12-12 02:26:06
|
6
|
+
6 NULL NULL NULL 2018-12-12 02:26:06 2018-12-12 02:26:06 2018-12-12 02:26:06
|
@@ -0,0 +1,8 @@
|
|
1
|
+
id,text0,text1,flag,point,inserted_at,created_at,updated_at
|
2
|
+
1,abcdefg,ABCNDEFG,t,1,2018-12-18 04:18:24.181256,2018-12-18 04:18:24.18319,2018-12-18 04:18:24.18319
|
3
|
+
2,"abc
|
4
|
+
|
5
|
+
3,abc defg,"ABC,DEFG",,-1,2018-12-18 04:18:24.202638,2018-12-18 04:18:24.203768,2018-12-18 04:18:24.203768
|
6
|
+
4,abc\defg,"ABC""DEFG",,-1,2018-12-18 04:18:24.207705,2018-12-18 04:18:24.20904,2018-12-18 04:18:24.20904
|
7
|
+
5,'abcdefg,ABC'DEFG,,-1,2018-12-18 04:18:24.207705,2018-12-18 04:18:24.20904,2018-12-18 04:18:24.20904
|
8
|
+
6,,"",,,2018-12-18 04:18:24.213643,2018-12-18 04:18:24.215238,2018-12-18 04:18:24.215238
|
@@ -0,0 +1,8 @@
|
|
1
|
+
id text0 text1 flag point inserted_at created_at updated_at
|
2
|
+
1 abcdefg ABCNDEFG t 1 2018-12-18 04:18:24.181256 2018-12-18 04:18:24.18319 2018-12-18 04:18:24.18319
|
3
|
+
2 "abc
|
4
|
+
|
5
|
+
3 "abc defg" ABC,DEFG -1 2018-12-18 04:18:24.202638 2018-12-18 04:18:24.203768 2018-12-18 04:18:24.203768
|
6
|
+
4 abc\defg "ABC""DEFG" -1 2018-12-18 04:18:24.207705 2018-12-18 04:18:24.20904 2018-12-18 04:18:24.20904
|
7
|
+
5 'abcdefg ABC'DEFG -1 2018-12-18 04:18:24.207705 2018-12-18 04:18:24.20904 2018-12-18 04:18:24.20904
|
8
|
+
6 "" 2018-12-18 04:18:24.213643 2018-12-18 04:18:24.215238 2018-12-18 04:18:24.215238
|
data/spec/load/README.md
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# Load test
|
2
|
+
|
3
|
+
## MySQL
|
4
|
+
```
|
5
|
+
$ cp spec/load/docker/docker-compose.mysql.yml docker-compose.yml
|
6
|
+
$ sudo docker-compose up -d
|
7
|
+
$ mysql -h 127.0.0.1 -P 3306 -u docker -p < spec/load/create_table.mysql.sql
|
8
|
+
```
|
9
|
+
|
10
|
+
load csv
|
11
|
+
```
|
12
|
+
$ mysql -h 127.0.0.1 -P 3306 -u docker -p < spec/load/load.mysql.csv.sql
|
13
|
+
```
|
14
|
+
|
15
|
+
load tsv
|
16
|
+
```
|
17
|
+
$ mysql -h 127.0.0.1 -P 3306 -u docker -p < spec/load/load.mysql.tsv.sql
|
18
|
+
```
|
19
|
+
|
20
|
+
## PostgreSQL
|
21
|
+
```
|
22
|
+
$ cp spec/load/docker/docker-compose.postgresql.yml docker-compose.yml
|
23
|
+
$ sudo docker-compose up -d
|
24
|
+
$ mysql -h 127.0.0.1 -P 3306 -u docker -p < spec/load/create_table.postgresql.sql
|
25
|
+
```
|
26
|
+
|
27
|
+
load csv
|
28
|
+
```
|
29
|
+
$ sudo docker cp spec/fixtures/postgresql.csv <CONTAINER ID>:/tmp/postgresql.csv
|
30
|
+
$ psql -h 127.0.0.1 -p 5432 -U docker < spec/load/load.postgresql.csv.sql
|
31
|
+
```
|
32
|
+
|
33
|
+
load tsv
|
34
|
+
```
|
35
|
+
$ sudo docker cp spec/fixtures/postgresql.tsv <CONTAINER ID>:/tmp/postgresql.csv
|
36
|
+
$ psql -h 127.0.0.1 -p 5432 -U docker < spec/load/load.postgresql.tsv.sql
|
37
|
+
```
|
@@ -0,0 +1 @@
|
|
1
|
+
create table test (id int, text0 varchar(255), text1 varchar(255), flag tinyint(1), point int, inserted_at datetime, created_at datetime, updated_at datetime) CHARSET=utf8mb4;
|
@@ -0,0 +1 @@
|
|
1
|
+
create table test (id int, text0 varchar(255), text1 varchar(255), flag boolean, point int, inserted_at timestamp, created_at timestamp, updated_at timestamp);
|
@@ -0,0 +1,16 @@
|
|
1
|
+
version: '3'
|
2
|
+
|
3
|
+
services:
|
4
|
+
db:
|
5
|
+
image: mysql:5.7
|
6
|
+
container_name: rdb_csv_mysql
|
7
|
+
environment:
|
8
|
+
MYSQL_ROOT_PASSWORD: root
|
9
|
+
MYSQL_DATABASE: test
|
10
|
+
MYSQL_USER: docker
|
11
|
+
MYSQL_PASSWORD: password
|
12
|
+
command:
|
13
|
+
- --character-set-server=utf8mb4
|
14
|
+
- --collation-server=utf8mb4_unicode_ci
|
15
|
+
ports:
|
16
|
+
- 3306:3306
|
@@ -0,0 +1 @@
|
|
1
|
+
LOAD DATA LOCAL INFILE "./spec/fixtures/mysql.csv" INTO TABLE test FIELDS TERMINATED BY ',';
|
@@ -0,0 +1 @@
|
|
1
|
+
LOAD DATA LOCAL INFILE "./spec/fixtures/mysql.tsv" INTO TABLE test FIELDS TERMINATED BY '\t';
|
@@ -0,0 +1 @@
|
|
1
|
+
COPY test FROM '/tmp/postgresql.csv' WITH CSV HEADER;
|
@@ -0,0 +1 @@
|
|
1
|
+
COPY test FROM '/tmp/postgresql.tsv' WITH CSV HEADER DELIMITER E'\t';
|
@@ -0,0 +1,512 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'csv'
|
3
|
+
|
4
|
+
RSpec.describe RdbCSV do
|
5
|
+
before do
|
6
|
+
FileUtils.mkdir_p("tmp")
|
7
|
+
end
|
8
|
+
|
9
|
+
after do
|
10
|
+
FileUtils.rm_rf("tmp")
|
11
|
+
end
|
12
|
+
|
13
|
+
it "Check version number" do
|
14
|
+
expect(RdbCSV::VERSION).to eq "0.4.0"
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "normal data" do
|
18
|
+
let(:check_rows) {[["abcdefg","hijkmnl","opqrstu","vwxyz"],
|
19
|
+
["あいうえお","かきくけこ","さしすせそ","たちつてと"],
|
20
|
+
["あいうえお\nかきくけこ","さしすせそ","たちつてと"]
|
21
|
+
]}
|
22
|
+
|
23
|
+
describe "Read csv" do
|
24
|
+
it "open" do
|
25
|
+
read_rows = []
|
26
|
+
path = "spec/fixtures/normal.csv"
|
27
|
+
|
28
|
+
RdbCSV.open(path, delimiter: ",") do |csv|
|
29
|
+
csv.each do |row|
|
30
|
+
read_rows << row
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
expect(read_rows).to eq check_rows
|
35
|
+
end
|
36
|
+
|
37
|
+
it "foreach" do
|
38
|
+
read_rows = []
|
39
|
+
path = "spec/fixtures/normal.csv"
|
40
|
+
|
41
|
+
RdbCSV.foreach(path, delimiter: ",") do |row|
|
42
|
+
read_rows << row
|
43
|
+
end
|
44
|
+
|
45
|
+
expect(read_rows).to eq check_rows
|
46
|
+
end
|
47
|
+
|
48
|
+
it "parse without block" do
|
49
|
+
read_rows = []
|
50
|
+
path = "spec/fixtures/normal.csv"
|
51
|
+
|
52
|
+
str = File.read(path)
|
53
|
+
read_rows = RdbCSV.parse(str, delimiter: ",")
|
54
|
+
|
55
|
+
expect(read_rows).to eq check_rows
|
56
|
+
end
|
57
|
+
|
58
|
+
it "parse with block" do
|
59
|
+
read_rows = []
|
60
|
+
path = "spec/fixtures/normal.csv"
|
61
|
+
|
62
|
+
str = File.read(path)
|
63
|
+
RdbCSV.parse(str, delimiter: ",").each do |row|
|
64
|
+
read_rows << row
|
65
|
+
end
|
66
|
+
|
67
|
+
expect(read_rows).to eq check_rows
|
68
|
+
end
|
69
|
+
|
70
|
+
it "parse_line" do
|
71
|
+
read_rows = []
|
72
|
+
path = "spec/fixtures/normal.csv"
|
73
|
+
|
74
|
+
str = File.read(path)
|
75
|
+
read_rows = RdbCSV.parse_line(str, delimiter: ",")
|
76
|
+
|
77
|
+
expect(read_rows).to eq check_rows[0]
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "Read tsv" do
|
82
|
+
it "open" do
|
83
|
+
read_rows = []
|
84
|
+
path = "spec/fixtures/normal.tsv"
|
85
|
+
|
86
|
+
RdbCSV.open(path, delimiter: "\t") do |tsv|
|
87
|
+
tsv.each do |row|
|
88
|
+
read_rows << row
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
expect(read_rows).to eq check_rows
|
93
|
+
end
|
94
|
+
|
95
|
+
it "foreach" do
|
96
|
+
read_rows = []
|
97
|
+
path = "spec/fixtures/normal.tsv"
|
98
|
+
|
99
|
+
RdbCSV.foreach(path, delimiter: "\t") do |row|
|
100
|
+
read_rows << row
|
101
|
+
end
|
102
|
+
|
103
|
+
expect(read_rows).to eq check_rows
|
104
|
+
end
|
105
|
+
|
106
|
+
it "parse without block" do
|
107
|
+
read_rows = []
|
108
|
+
path = "spec/fixtures/normal.tsv"
|
109
|
+
|
110
|
+
str = File.read(path)
|
111
|
+
read_rows = RdbCSV.parse(str, delimiter: "\t")
|
112
|
+
|
113
|
+
expect(read_rows).to eq check_rows
|
114
|
+
end
|
115
|
+
|
116
|
+
it "parse with block" do
|
117
|
+
read_rows = []
|
118
|
+
path = "spec/fixtures/normal.tsv"
|
119
|
+
|
120
|
+
str = File.read(path)
|
121
|
+
RdbCSV.parse(str, delimiter: "\t").each do |row|
|
122
|
+
read_rows << row
|
123
|
+
end
|
124
|
+
|
125
|
+
expect(read_rows).to eq check_rows
|
126
|
+
end
|
127
|
+
|
128
|
+
it "parse_line" do
|
129
|
+
read_rows = []
|
130
|
+
path = "spec/fixtures/normal.tsv"
|
131
|
+
|
132
|
+
str = File.read(path)
|
133
|
+
read_rows = RdbCSV.parse_line(str, delimiter: "\t")
|
134
|
+
|
135
|
+
expect(read_rows).to eq check_rows[0]
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
it "Write csv" do
|
140
|
+
read_rows = []
|
141
|
+
path = "tmp/normal.csv"
|
142
|
+
|
143
|
+
RdbCSV.open(path, 'w', delimiter: ",") do |csv|
|
144
|
+
check_rows.each do |row|
|
145
|
+
csv << row
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
RdbCSV.open(path, delimiter: ",") do |csv|
|
150
|
+
csv.each do |row|
|
151
|
+
read_rows << row
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
expect(read_rows).to eq check_rows
|
156
|
+
end
|
157
|
+
|
158
|
+
it "Write csv" do
|
159
|
+
read_rows = []
|
160
|
+
path = "tmp/normal.csv"
|
161
|
+
|
162
|
+
RdbCSV.open(path, 'w', delimiter: "\t") do |csv|
|
163
|
+
check_rows.each do |row|
|
164
|
+
csv << row
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
RdbCSV.open(path, delimiter: "\t") do |csv|
|
169
|
+
csv.each do |row|
|
170
|
+
read_rows << row
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
expect(read_rows).to eq check_rows
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
describe "MySQL data" do
|
179
|
+
let(:check_rows) {[[1, "abcdefg", "ABCNDEFG", 1, 1, "2018-12-12 02:26:06", "2018-12-12 02:26:06", "2018-12-12 02:26:06"],
|
180
|
+
[2, "abc\n\rdefg", "ABC\u0000DEFG", 0, 0, "2018-12-12 02:26:06", "2018-12-12 02:26:06", "2018-12-12 02:26:06"],
|
181
|
+
[3, "abc\tdefg", "ABC,DEFG", nil, -1, "2018-12-12 02:26:06", "2018-12-12 02:26:06", "2018-12-12 02:26:06"],
|
182
|
+
[4, "abc\\defg", "ABC\"DEFG", nil, -1, "2018-12-12 02:26:06", "2018-12-12 02:26:06", "2018-12-12 02:26:06"],
|
183
|
+
[5, "'abcdefg", "ABC'DEFG", nil, -1, "2018-12-12 02:26:06", "2018-12-12 02:26:06", "2018-12-12 02:26:06"],
|
184
|
+
[6, nil, "", nil, nil, "2018-12-12 02:26:06", "2018-12-12 02:26:06", "2018-12-12 02:26:06"]
|
185
|
+
]}
|
186
|
+
|
187
|
+
describe "Read csv" do
|
188
|
+
it "open" do
|
189
|
+
read_rows = []
|
190
|
+
path = "spec/fixtures/mysql.csv"
|
191
|
+
|
192
|
+
RdbCSV.open(path, db: :mysql, delimiter: ",") do |csv|
|
193
|
+
csv.each do |row|
|
194
|
+
read_rows << row
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
expect(read_rows).to eq check_rows
|
199
|
+
end
|
200
|
+
|
201
|
+
it "foreach" do
|
202
|
+
read_rows = []
|
203
|
+
path = "spec/fixtures/mysql.csv"
|
204
|
+
|
205
|
+
RdbCSV.foreach(path, db: :mysql, delimiter: ",") do |row|
|
206
|
+
read_rows << row
|
207
|
+
end
|
208
|
+
|
209
|
+
expect(read_rows).to eq check_rows
|
210
|
+
end
|
211
|
+
|
212
|
+
it "parse without block" do
|
213
|
+
read_rows = []
|
214
|
+
path = "spec/fixtures/mysql.csv"
|
215
|
+
|
216
|
+
str = File.read(path)
|
217
|
+
read_rows = RdbCSV.parse(str, db: :mysql, delimiter: ",")
|
218
|
+
|
219
|
+
expect(read_rows).to eq check_rows
|
220
|
+
end
|
221
|
+
|
222
|
+
it "parse with block" do
|
223
|
+
read_rows = []
|
224
|
+
path = "spec/fixtures/mysql.csv"
|
225
|
+
|
226
|
+
str = File.read(path)
|
227
|
+
RdbCSV.parse(str, db: :mysql, delimiter: ",").each do |row|
|
228
|
+
read_rows << row
|
229
|
+
end
|
230
|
+
|
231
|
+
expect(read_rows).to eq check_rows
|
232
|
+
end
|
233
|
+
|
234
|
+
it "parse_line" do
|
235
|
+
read_rows = []
|
236
|
+
path = "spec/fixtures/mysql.csv"
|
237
|
+
|
238
|
+
str = File.read(path)
|
239
|
+
read_rows = RdbCSV.parse_line(str, db: :mysql, delimiter: ",")
|
240
|
+
|
241
|
+
expect(read_rows).to eq check_rows[0]
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
describe "Read tsv" do
|
246
|
+
it "open" do
|
247
|
+
read_rows = []
|
248
|
+
path = "spec/fixtures/mysql.tsv"
|
249
|
+
|
250
|
+
RdbCSV.open(path, db: :mysql, delimiter: "\t") do |tsv|
|
251
|
+
tsv.each do |row|
|
252
|
+
read_rows << row
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
expect(read_rows).to eq check_rows
|
257
|
+
end
|
258
|
+
|
259
|
+
it "foreach" do
|
260
|
+
read_rows = []
|
261
|
+
path = "spec/fixtures/mysql.tsv"
|
262
|
+
|
263
|
+
RdbCSV.foreach(path, db: :mysql, delimiter: "\t") do |row|
|
264
|
+
read_rows << row
|
265
|
+
end
|
266
|
+
|
267
|
+
expect(read_rows).to eq check_rows
|
268
|
+
end
|
269
|
+
|
270
|
+
it "parse without block" do
|
271
|
+
read_rows = []
|
272
|
+
path = "spec/fixtures/mysql.tsv"
|
273
|
+
|
274
|
+
str = File.read(path)
|
275
|
+
read_rows = RdbCSV.parse(str, db: :mysql, delimiter: "\t")
|
276
|
+
|
277
|
+
expect(read_rows).to eq check_rows
|
278
|
+
end
|
279
|
+
|
280
|
+
it "parse with block" do
|
281
|
+
read_rows = []
|
282
|
+
path = "spec/fixtures/mysql.tsv"
|
283
|
+
|
284
|
+
str = File.read(path)
|
285
|
+
RdbCSV.parse(str, db: :mysql, delimiter: "\t").each do |row|
|
286
|
+
read_rows << row
|
287
|
+
end
|
288
|
+
|
289
|
+
expect(read_rows).to eq check_rows
|
290
|
+
end
|
291
|
+
|
292
|
+
it "parse_line" do
|
293
|
+
read_rows = []
|
294
|
+
path = "spec/fixtures/mysql.tsv"
|
295
|
+
|
296
|
+
str = File.read(path)
|
297
|
+
read_rows = RdbCSV.parse_line(str, db: :mysql, delimiter: "\t")
|
298
|
+
|
299
|
+
expect(read_rows).to eq check_rows[0]
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
it "Write csv" do
|
304
|
+
read_rows = []
|
305
|
+
path = "tmp/mysql.csv"
|
306
|
+
|
307
|
+
RdbCSV.open(path, 'w', db: :mysql, delimiter: ",") do |csv|
|
308
|
+
check_rows.each do |row|
|
309
|
+
csv << row
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
RdbCSV.open(path, db: :mysql, delimiter: ",") do |csv|
|
314
|
+
csv.each do |row|
|
315
|
+
read_rows << row
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
expect(read_rows).to eq check_rows
|
320
|
+
end
|
321
|
+
|
322
|
+
it "Write tsv" do
|
323
|
+
read_rows = []
|
324
|
+
path = "tmp/mysql.tsv"
|
325
|
+
|
326
|
+
RdbCSV.open(path, 'w', db: :mysql, delimiter: "\t") do |tsv|
|
327
|
+
check_rows.each do |row|
|
328
|
+
tsv << row
|
329
|
+
end
|
330
|
+
end
|
331
|
+
|
332
|
+
RdbCSV.open(path, db: :mysql, delimiter: "\t") do |tsv|
|
333
|
+
tsv.each do |row|
|
334
|
+
read_rows << row
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
expect(read_rows).to eq check_rows
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
describe "PostgreSQL data" do
|
343
|
+
let(:check_rows) {[["id", "text0", "text1", "flag", "point", "inserted_at", "created_at", "updated_at"],
|
344
|
+
[1, "abcdefg", "ABCNDEFG", "t", 1, "2018-12-18 04:18:24.181256",
|
345
|
+
"2018-12-18 04:18:24.18319", "2018-12-18 04:18:24.18319"],
|
346
|
+
[2, "abc\n\rdefg", "ABC\u0000DEFG", "f", 0,
|
347
|
+
"2018-12-18 04:18:24.19734", "2018-12-18 04:18:24.198651", "2018-12-18 04:18:24.198651"],
|
348
|
+
[3, "abc\tdefg", "ABC,DEFG", nil, -1,
|
349
|
+
"2018-12-18 04:18:24.202638", "2018-12-18 04:18:24.203768", "2018-12-18 04:18:24.203768"],
|
350
|
+
[4, "abc\\defg", "ABC\"DEFG", nil, -1,
|
351
|
+
"2018-12-18 04:18:24.207705", "2018-12-18 04:18:24.20904", "2018-12-18 04:18:24.20904"],
|
352
|
+
[5, "'abcdefg", "ABC'DEFG", nil, -1,
|
353
|
+
"2018-12-18 04:18:24.207705", "2018-12-18 04:18:24.20904", "2018-12-18 04:18:24.20904"],
|
354
|
+
[6, nil, "", nil, nil,
|
355
|
+
"2018-12-18 04:18:24.213643", "2018-12-18 04:18:24.215238", "2018-12-18 04:18:24.215238"]
|
356
|
+
]}
|
357
|
+
|
358
|
+
describe "Read csv" do
|
359
|
+
it "open" do
|
360
|
+
read_rows = []
|
361
|
+
path = "spec/fixtures/postgresql.csv"
|
362
|
+
|
363
|
+
RdbCSV.open(path, db: :postgresql, delimiter: ",") do |csv|
|
364
|
+
csv.each do |row|
|
365
|
+
read_rows << row
|
366
|
+
end
|
367
|
+
end
|
368
|
+
|
369
|
+
expect(read_rows).to eq check_rows
|
370
|
+
end
|
371
|
+
|
372
|
+
it "foreach" do
|
373
|
+
read_rows = []
|
374
|
+
path = "spec/fixtures/postgresql.csv"
|
375
|
+
|
376
|
+
RdbCSV.foreach(path, db: :postgresql, delimiter: ",") do |row|
|
377
|
+
read_rows << row
|
378
|
+
end
|
379
|
+
|
380
|
+
expect(read_rows).to eq check_rows
|
381
|
+
end
|
382
|
+
|
383
|
+
it "parse without block" do
|
384
|
+
read_rows = []
|
385
|
+
path = "spec/fixtures/postgresql.csv"
|
386
|
+
|
387
|
+
str = File.read(path)
|
388
|
+
read_rows = RdbCSV.parse(str, db: :postgresql, delimiter: ",")
|
389
|
+
|
390
|
+
expect(read_rows).to eq check_rows
|
391
|
+
end
|
392
|
+
|
393
|
+
it "parse with block" do
|
394
|
+
read_rows = []
|
395
|
+
path = "spec/fixtures/postgresql.csv"
|
396
|
+
|
397
|
+
str = File.read(path)
|
398
|
+
RdbCSV.parse(str, db: :postgresql, delimiter: ",").each do |row|
|
399
|
+
read_rows << row
|
400
|
+
end
|
401
|
+
|
402
|
+
expect(read_rows).to eq check_rows
|
403
|
+
end
|
404
|
+
|
405
|
+
it "parse_line" do
|
406
|
+
read_rows = []
|
407
|
+
path = "spec/fixtures/postgresql.csv"
|
408
|
+
|
409
|
+
str = File.read(path)
|
410
|
+
read_rows = RdbCSV.parse_line(str, db: :postgresql, delimiter: ",")
|
411
|
+
|
412
|
+
expect(read_rows).to eq check_rows[0]
|
413
|
+
end
|
414
|
+
end
|
415
|
+
|
416
|
+
describe "Read tsv" do
|
417
|
+
it "open" do
|
418
|
+
read_rows = []
|
419
|
+
path = "spec/fixtures/postgresql.tsv"
|
420
|
+
|
421
|
+
RdbCSV.open(path, db: :postgresql, delimiter: "\t") do |tsv|
|
422
|
+
tsv.each do |row|
|
423
|
+
read_rows << row
|
424
|
+
end
|
425
|
+
end
|
426
|
+
|
427
|
+
expect(read_rows).to eq check_rows
|
428
|
+
end
|
429
|
+
|
430
|
+
it "foreach" do
|
431
|
+
read_rows = []
|
432
|
+
path = "spec/fixtures/postgresql.tsv"
|
433
|
+
|
434
|
+
RdbCSV.foreach(path, db: :postgresql, delimiter: "\t") do |row|
|
435
|
+
read_rows << row
|
436
|
+
end
|
437
|
+
|
438
|
+
expect(read_rows).to eq check_rows
|
439
|
+
end
|
440
|
+
|
441
|
+
it "parse without block" do
|
442
|
+
read_rows = []
|
443
|
+
path = "spec/fixtures/postgresql.tsv"
|
444
|
+
|
445
|
+
str = File.read(path)
|
446
|
+
read_rows = RdbCSV.parse(str, db: :postgresql, delimiter: "\t")
|
447
|
+
|
448
|
+
expect(read_rows).to eq check_rows
|
449
|
+
end
|
450
|
+
|
451
|
+
it "parse with block" do
|
452
|
+
read_rows = []
|
453
|
+
path = "spec/fixtures/postgresql.tsv"
|
454
|
+
|
455
|
+
str = File.read(path)
|
456
|
+
RdbCSV.parse(str, db: :postgresql, delimiter: "\t").each do |row|
|
457
|
+
read_rows << row
|
458
|
+
end
|
459
|
+
|
460
|
+
expect(read_rows).to eq check_rows
|
461
|
+
end
|
462
|
+
|
463
|
+
it "parse_line" do
|
464
|
+
read_rows = []
|
465
|
+
path = "spec/fixtures/postgresql.tsv"
|
466
|
+
|
467
|
+
str = File.read(path)
|
468
|
+
read_rows = RdbCSV.parse_line(str, db: :postgresql, delimiter: "\t")
|
469
|
+
|
470
|
+
expect(read_rows).to eq check_rows[0]
|
471
|
+
end
|
472
|
+
end
|
473
|
+
|
474
|
+
it "Write csv" do
|
475
|
+
read_rows = []
|
476
|
+
path = "tmp/postgresql.csv"
|
477
|
+
|
478
|
+
RdbCSV.open(path, 'w', db: :postgresql, delimiter: ",") do |csv|
|
479
|
+
check_rows.each do |row|
|
480
|
+
csv << row
|
481
|
+
end
|
482
|
+
end
|
483
|
+
|
484
|
+
RdbCSV.open(path, db: :postgresql, delimiter: ",") do |csv|
|
485
|
+
csv.each do |row|
|
486
|
+
read_rows << row
|
487
|
+
end
|
488
|
+
end
|
489
|
+
|
490
|
+
expect(read_rows).to eq check_rows
|
491
|
+
end
|
492
|
+
|
493
|
+
it "Write tsv" do
|
494
|
+
read_rows = []
|
495
|
+
path = "tmp/postgresql.tsv"
|
496
|
+
|
497
|
+
RdbCSV.open(path, 'w', db: :postgresql, delimiter: ",") do |tsv|
|
498
|
+
check_rows.each do |row|
|
499
|
+
tsv << row
|
500
|
+
end
|
501
|
+
end
|
502
|
+
|
503
|
+
RdbCSV.open(path, db: :postgresql, delimiter: ",") do |tsv|
|
504
|
+
tsv.each do |row|
|
505
|
+
read_rows << row
|
506
|
+
end
|
507
|
+
end
|
508
|
+
|
509
|
+
expect(read_rows).to eq check_rows
|
510
|
+
end
|
511
|
+
end
|
512
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require "bundler/setup"
|
2
|
+
require_relative "../lib/rdb_csv.rb"
|
3
|
+
|
4
|
+
RSpec.configure do |config|
|
5
|
+
# Enable flags like --only-failures and --next-failure
|
6
|
+
config.example_status_persistence_file_path = ".rspec_status"
|
7
|
+
|
8
|
+
# Disable RSpec exposing methods globally on `Module` and `main`
|
9
|
+
config.disable_monkey_patching!
|
10
|
+
|
11
|
+
config.expect_with :rspec do |c|
|
12
|
+
c.syntax = :expect
|
13
|
+
end
|
14
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rdb_csv
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- longicorn
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-08-
|
11
|
+
date: 2019-08-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -44,7 +44,39 @@ email:
|
|
44
44
|
executables: []
|
45
45
|
extensions: []
|
46
46
|
extra_rdoc_files: []
|
47
|
-
files:
|
47
|
+
files:
|
48
|
+
- ".gitignore"
|
49
|
+
- ".rspec"
|
50
|
+
- ".travis.yml"
|
51
|
+
- Gemfile
|
52
|
+
- Gemfile.lock
|
53
|
+
- LICENSE
|
54
|
+
- README.md
|
55
|
+
- Rakefile
|
56
|
+
- bin/console
|
57
|
+
- bin/setup
|
58
|
+
- lib/rdb_csv.rb
|
59
|
+
- lib/rdb_csv/reader.rb
|
60
|
+
- lib/rdb_csv/row.rb
|
61
|
+
- lib/rdb_csv/version.rb
|
62
|
+
- rdb_csv.gemspec
|
63
|
+
- spec/fixtures/mysql.csv
|
64
|
+
- spec/fixtures/mysql.tsv
|
65
|
+
- spec/fixtures/normal.csv
|
66
|
+
- spec/fixtures/normal.tsv
|
67
|
+
- spec/fixtures/postgresql.csv
|
68
|
+
- spec/fixtures/postgresql.tsv
|
69
|
+
- spec/load/README.md
|
70
|
+
- spec/load/create_table.mysql.sql
|
71
|
+
- spec/load/create_table.postgresql.sql
|
72
|
+
- spec/load/docker/docker-compose.mysql.yml
|
73
|
+
- spec/load/docker/docker-compose.postgresql.yml
|
74
|
+
- spec/load/load.mysql.csv.sql
|
75
|
+
- spec/load/load.mysql.tsv.sql
|
76
|
+
- spec/load/load.postgresql.csv.sql
|
77
|
+
- spec/load/load.postgresql.tsv.sql
|
78
|
+
- spec/rdb_csv_spec.rb
|
79
|
+
- spec/spec_helper.rb
|
48
80
|
homepage: https://github.com/longicorn/rdb_csv
|
49
81
|
licenses:
|
50
82
|
- MIT
|