load_data_infile2 0.1.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/.gitignore +10 -0
- data/.travis.yml +23 -0
- data/Gemfile +16 -0
- data/LICENSE.txt +21 -0
- data/README.md +152 -0
- data/Rakefile +11 -0
- data/bin/console +14 -0
- data/bin/db_setup +9 -0
- data/bin/setup +8 -0
- data/lib/load_data_infile2/active_record.rb +31 -0
- data/lib/load_data_infile2/active_record_extension.rb +13 -0
- data/lib/load_data_infile2/client.rb +33 -0
- data/lib/load_data_infile2/railtie.rb +9 -0
- data/lib/load_data_infile2/sql.rb +135 -0
- data/lib/load_data_infile2/version.rb +3 -0
- data/lib/load_data_infile2.rb +22 -0
- data/load_data_infile2.gemspec +27 -0
- metadata +132 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ee78daaa7a49adfaf7bac627fb97de928af9350a
|
4
|
+
data.tar.gz: 2c99cc602db05c974caabda934219819d11a0ae8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b3e9d44aa682e0b4a2756f1d84d4735a81593b6ea410d6ef68c9c039f394e5a939cabacd38d3eb5609bf904c1fbc34f6f34950bb88adeda750e39f19244841f8
|
7
|
+
data.tar.gz: e6fd92e7045803cea17d2083347782915864d0168acdedf7a321faf0e1f57732c702a10d6cbf0e1141f409c2cb9f0eda5e474be9ece26b77241a198b77e2d520
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
dist: trusty
|
2
|
+
sudo: required
|
3
|
+
language: ruby
|
4
|
+
rvm:
|
5
|
+
- 2.2.5
|
6
|
+
- 2.3.1
|
7
|
+
before_install: gem install bundler
|
8
|
+
cache:
|
9
|
+
- bundler
|
10
|
+
- apt
|
11
|
+
before_script:
|
12
|
+
- bin/db_setup
|
13
|
+
addons:
|
14
|
+
apt:
|
15
|
+
packages:
|
16
|
+
- mysql-server-5.6
|
17
|
+
- mysql-client-core-5.6
|
18
|
+
- mysql-client-5.6
|
19
|
+
code_climate:
|
20
|
+
repo_token: a8b76c6c9740d0f664cf714144dc93d3a2c415d205a9a9f33b41d6a146ac7a26
|
21
|
+
notifications:
|
22
|
+
slack:
|
23
|
+
secure: IR+RpuGQZDcMYUODakC7fTlT78KkLUe3sxc7c3GY/SUxiHruG0AreIH6KvlVsfR5QH9gGERpAropUjt6Y38GtMKnmRItedbHlaMVNY35cRHt3LsNGh36AmzV/cEqWlFbWLWdZm6iLyAC1KfDomLijsC3cV04oIq3N2ljaxp0iIzK3UEd8EG/XR99s/F4mzUhCF1fm+pAcaW8EyXZaNJQmHykJsBGUPcpGOPDZ76shKHNXupWFxG0vgDApsTe9uBAUshpUoXLGDsPrkOsXZiLvL0px5ckbC8tJasqgBdGpKWq0J5hx+BjuY/ECAnpdG8Sru/pRx+oDgb81lz8UCSUyRXq7zm8RoJqK9u4hhGRuaMR9sgoE6Lfi6IWzzfIUheHs+rC8XalDmllv+l6+jbHTz43ccllE2lnl7oF/VZ4YiSJkCPkUp37mSfIktB+7YMo1wu9QuyhLdcdAy2y73pkMamNPQms5sOYTm97iV0WmdTGUrRsoUnC+b49i6mJhJgsmdAquSjVMlu7fmfiahDAh5jEU+Te2i8SNkDNu+KNmRuRIJacx/tGd8CR9E659FaDCTlHIbO26jvIBlChtaXQh3U/QCFm6lU3JkuM6zLvklEIL3PzPZJzKegDHtiiVB4NyyVqSc0aU2FW6X5GNldc0wFWLe9SMO4CPIoMyG3jpL8=
|
data/Gemfile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
# Specify your gem's dependencies in load_data_infile2.gemspec
|
4
|
+
gemspec
|
5
|
+
|
6
|
+
group :development, :test do
|
7
|
+
gem 'pry'
|
8
|
+
gem 'pry-power_assert'
|
9
|
+
gem 'pry-doc'
|
10
|
+
gem 'pry-byebug'
|
11
|
+
end
|
12
|
+
|
13
|
+
group :test do
|
14
|
+
gem 'rails', require: false
|
15
|
+
gem "codeclimate-test-reporter", require: false
|
16
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2016 nalabjp
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,152 @@
|
|
1
|
+
# LoadDataInfile2
|
2
|
+
|
3
|
+
[](https://travis-ci.org/nalabjp/load_data_infile2)
|
4
|
+
[](https://codeclimate.com/github/nalabjp/load_data_infile2)
|
5
|
+
[](https://codeclimate.com/github/nalabjp/load_data_infile2/coverage)
|
6
|
+
[](https://gemnasium.com/nalabjp/load_data_infile2)
|
7
|
+
|
8
|
+
Import the data at a high speed to the table from a text file, using the [MySQL `LOAD DATA INFILE` statement](http://dev.mysql.com/doc/refman/5.7/en/load-data.html).
|
9
|
+
|
10
|
+
This gem is dependent on [mysql2](https://github.com/brianmario/mysql2).
|
11
|
+
|
12
|
+
By using mysql2, as well as plugin of ActiveRecord, it is possible to use in pure Ruby script.
|
13
|
+
|
14
|
+
## Installation
|
15
|
+
|
16
|
+
Add to your Gemfile:
|
17
|
+
|
18
|
+
```ruby
|
19
|
+
gem 'load_data_infile2'
|
20
|
+
```
|
21
|
+
|
22
|
+
And bundle.
|
23
|
+
|
24
|
+
## Examples
|
25
|
+
### Basic Usage
|
26
|
+
|
27
|
+
Database configuration:
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
db_config = {
|
31
|
+
host: 'localhost'
|
32
|
+
database: 'ldi_test'
|
33
|
+
username: 'root'
|
34
|
+
}
|
35
|
+
```
|
36
|
+
|
37
|
+
Create client:
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
ldi_client = LoadDataInfile2::Client.new(db_config)
|
41
|
+
```
|
42
|
+
|
43
|
+
Import from CSV file:
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
ldi_client.import('/path/to/data.csv')
|
47
|
+
```
|
48
|
+
|
49
|
+
[Default options](https://github.com/nalabjp/load_data_infile2/blob/master/lib/load_data_infile2.rb#L10-L22) are CSV format:
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
module LoadDataInfile2
|
53
|
+
class << self
|
54
|
+
def default_import_options
|
55
|
+
@default_import_options ||= {
|
56
|
+
fields_terminated_by: ',', # CSV
|
57
|
+
fields_optionally_enclosed_by: '"', # standard format of CSV
|
58
|
+
fields_escaped_by: '"', # standard format of CSV
|
59
|
+
lines_terminated_by: "\\n",
|
60
|
+
ignore_lines: 0
|
61
|
+
}
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
```
|
66
|
+
|
67
|
+
### TSV format
|
68
|
+
|
69
|
+
If you are using TSV format:
|
70
|
+
|
71
|
+
```ruby
|
72
|
+
opts = {
|
73
|
+
fileds_terminated_by: "\\t",
|
74
|
+
fields_optionally_enclosed_by: "",
|
75
|
+
fields_escaped_by: "\\"
|
76
|
+
}
|
77
|
+
ldi_client = LoadDataInfile2::Client.new(db_config, opts)
|
78
|
+
ldi_client.import('/path/to/data.tsv')
|
79
|
+
```
|
80
|
+
|
81
|
+
### LOAD DATA LOCAL INFILE
|
82
|
+
|
83
|
+
If you use `LOCAL` option:
|
84
|
+
|
85
|
+
```ruby
|
86
|
+
opts = { local_infile: true }
|
87
|
+
ldi_client = LoadDataInfile2::Client.new(db_config, opts)
|
88
|
+
ldi_client.import('/path/to/data.csv')
|
89
|
+
# => Execute "LOAD DATA LOCAL INFILE '/path/to/data.csv' INTO TABLE `ldi_test`.`data`;"
|
90
|
+
```
|
91
|
+
|
92
|
+
### SQL Options
|
93
|
+
Support all options of LOAD DATA INFILE statement on MySQL 5.7 .
|
94
|
+
|
95
|
+
see: http://dev.mysql.com/doc/refman/5.7/en/load-data.html
|
96
|
+
|
97
|
+
For examples:
|
98
|
+
|
99
|
+
```ruby
|
100
|
+
opts = { local_infile: true }
|
101
|
+
sql_opts = { table: 'special_users', ignore_lines: 1 }
|
102
|
+
ldi_client = LoadDataInfile2::Client.new(db_config, opts)
|
103
|
+
ldi_client.import('/path/to/users.csv', sql_opts)
|
104
|
+
```
|
105
|
+
|
106
|
+
#### Mappings
|
107
|
+
|MySQL|LoadDataInfile2|
|
108
|
+
| --- | --- |
|
109
|
+
| LOW_PRIORITY | low_priority_or_concurrent: :low_priority |
|
110
|
+
| CONCURRENT | low_priority_or_concurrent: :concurrent |
|
111
|
+
| LOCAL | local_infile: true |
|
112
|
+
| REPLACE | replace_or_ignore: :replace |
|
113
|
+
| IGNORE | replace_or_ignore: :ignore |
|
114
|
+
| *tbl_name* | table: 'special_table_name' |
|
115
|
+
| PARTITION | partition: 'p0' / ['p0', 'p1', ...] |
|
116
|
+
| CHARCTER SET | charset: 'utf8' |
|
117
|
+
| FIELDS TERMINATED BY | fields_terminated_by: ',' |
|
118
|
+
| FIELDS ENCLOSED BY | fields_enclosed_by: '"' |
|
119
|
+
| FIELDS OPTIONALLY ENCLOSED BY | fields_optionally_enclosed_by: '"' |
|
120
|
+
| FIELDS ESCAPED BY | fields_escaped_by: '"' |
|
121
|
+
| LINES STARTING BY | lines_starting_by: '***' |
|
122
|
+
| LINES TERMINATED BY | lines_terminated_by: '\\n' |
|
123
|
+
| IGNORE LINES | ignore_lines: 1 |
|
124
|
+
| *col_name_or_user_var* | columns: ['col1', 'col2', '@var3', ...] |
|
125
|
+
| SET *col_name* = *expr* | set: { col1: "'specific value'", col2: '@var', col3: 'NOW()' } |
|
126
|
+
|
127
|
+
### In Rails
|
128
|
+
|
129
|
+
Subclass of ActiveRecord is added `.load_data_infile`.
|
130
|
+
|
131
|
+
For example, in the case of User model, you can call the class method named `load_data_infile` from the User model.
|
132
|
+
|
133
|
+
```ruby
|
134
|
+
User.load_data_infile('/path/to/data.csv')
|
135
|
+
```
|
136
|
+
|
137
|
+
If you want to pass options to the initialization of `LoadDataInfile2::ActiveRecord`, you can use the accessor of class variable named `.default_load_data_infile_options`.
|
138
|
+
|
139
|
+
```ruby
|
140
|
+
User.default_load_data_infile_options = { ignore_lines: 1 }
|
141
|
+
User.load_data_infile('/path/to/data.csv')
|
142
|
+
```
|
143
|
+
|
144
|
+
## Contributing
|
145
|
+
|
146
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/nalabjp/load_data_infile2.
|
147
|
+
|
148
|
+
## License
|
149
|
+
|
150
|
+
MIT License
|
151
|
+
|
152
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "load_data_infile2"
|
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 "pry"
|
14
|
+
Pry.start
|
data/bin/db_setup
ADDED
data/bin/setup
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'load_data_infile2/sql'
|
2
|
+
|
3
|
+
module LoadDataInfile2
|
4
|
+
class ActiveRecord
|
5
|
+
def initialize(ar_subclass, options = {})
|
6
|
+
@ar_class = ar_subclass
|
7
|
+
if options[:local_infile]
|
8
|
+
raise "Require option as `local_infile: true` in config/database.yml" unless ar_class.connection.instance_variable_get(:@connection).query_options[:local_infile]
|
9
|
+
end
|
10
|
+
|
11
|
+
@load_data_infile_options = LoadDataInfile2.default_import_options.merge(options)
|
12
|
+
@load_data_infile_options[:charset] = ar_class.connection_config[:charset] unless options.has_key?(:charset)
|
13
|
+
end
|
14
|
+
|
15
|
+
def import(file, options = {})
|
16
|
+
query(build_sql(file, options))
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
attr_reader :ar_class, :load_data_infile_options
|
22
|
+
|
23
|
+
def build_sql(file, options = {})
|
24
|
+
LoadDataInfile2::Sql.new(file, ar_class.quoted_table_name, load_data_infile_options.merge(options)).build
|
25
|
+
end
|
26
|
+
|
27
|
+
def query(sql)
|
28
|
+
ar_class.connection.execute(sql)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'load_data_infile2/active_record'
|
2
|
+
|
3
|
+
module LoadDataInfile2
|
4
|
+
module ActiveRecordExtension
|
5
|
+
def load_data_infile(file, options = {})
|
6
|
+
LoadDataInfile2::ActiveRecord.new(self, default_load_data_infile_options).import(file, options)
|
7
|
+
end
|
8
|
+
|
9
|
+
cattr_accessor :default_load_data_infile_options do
|
10
|
+
{}
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'mysql2'
|
2
|
+
require 'load_data_infile2/sql'
|
3
|
+
|
4
|
+
module LoadDataInfile2
|
5
|
+
class Client < ::Mysql2::Client
|
6
|
+
attr_reader :load_data_infile_options
|
7
|
+
|
8
|
+
def initialize(config, options = {})
|
9
|
+
if options[:local_infile]
|
10
|
+
config = config.merge(local_infile: true)
|
11
|
+
end
|
12
|
+
super(config)
|
13
|
+
|
14
|
+
@load_data_infile_options = LoadDataInfile2.default_import_options.merge(options)
|
15
|
+
@load_data_infile_options[:charset] = query_options[:charset] unless options.has_key?(:charset)
|
16
|
+
end
|
17
|
+
|
18
|
+
def import(file, options = {})
|
19
|
+
query(build_sql(file, options))
|
20
|
+
end
|
21
|
+
|
22
|
+
def quoted_table_name_for(table)
|
23
|
+
[query_options[:database], table].compact.map!{|w| "`#{w}`"}.join('.')
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def build_sql(file, options = {})
|
29
|
+
table = options.delete(:table) || File.basename(file, '.*')
|
30
|
+
LoadDataInfile2::Sql.new(file, quoted_table_name_for(table), load_data_infile_options.merge(options)).build
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
module LoadDataInfile2
|
2
|
+
class Sql
|
3
|
+
# @param [String] file File name
|
4
|
+
# @param [String] table Table name
|
5
|
+
# @param [Hash] options Options for `LOAD DATA INFILE` query
|
6
|
+
# @option options [Symbol] :low_priority_or_concurrent :low_priority or :concurrent option
|
7
|
+
# @option options [Symbol] :replace_or_ignore :replace or :ignore for duplicated record
|
8
|
+
# @option options [Boolean] :local_infile Use local file
|
9
|
+
# @option options [Array] :partition Partition names
|
10
|
+
# @option options [String] :charset Character set
|
11
|
+
# @option options [String] :fields_terminated_by Column delimiter
|
12
|
+
# @option options [String] :fields_enclosed_by Enclosure character, for example double quote
|
13
|
+
# @option options [String] :fields_optionally_enclosed_by If the input value is not necessarily enclosed, use OPTIONALLY
|
14
|
+
# @option options [String] :fields_escaped_by Escape character
|
15
|
+
# @option options [String] :lines_starting_by Common prefix for all lines to skip over the prefix, and anything before it
|
16
|
+
# @option options [String] :lines_terminated_by Line delimiter
|
17
|
+
# @option options [String] :ignore_lines Number of ignore lines from the start of the file
|
18
|
+
# @option options [Array] :columns Specify a column list, if the order of the fields in the input file differs from the order of the columns in the table
|
19
|
+
# The column list can contain either column names or user variables
|
20
|
+
# @option options [Hash] :set Key of Hash should have only column name, value of Hash can use a scalar subquery
|
21
|
+
#
|
22
|
+
# @see https://dev.mysql.com/doc/refman/5.6/en/load-data.html
|
23
|
+
def initialize(file, table, options = {})
|
24
|
+
@file = file
|
25
|
+
@table = table
|
26
|
+
@options = options
|
27
|
+
end
|
28
|
+
|
29
|
+
def build
|
30
|
+
[
|
31
|
+
load_data_infile,
|
32
|
+
replace_or_ignore,
|
33
|
+
into_table,
|
34
|
+
partition,
|
35
|
+
character_set,
|
36
|
+
fields,
|
37
|
+
lines,
|
38
|
+
ignore_lines,
|
39
|
+
columns,
|
40
|
+
set
|
41
|
+
].compact.join(' ').concat(';')
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
attr_reader :file, :table, :options
|
47
|
+
|
48
|
+
def load_data_infile
|
49
|
+
stmt = 'LOAD DATA '
|
50
|
+
stmt.concat("#{options[:low_priority_or_concurrent].upcase} ") if %i(low_priority concurrent).include?(options[:low_priority_or_concurrent])
|
51
|
+
stmt.concat('LOCAL ') if options[:local_infile]
|
52
|
+
stmt.concat("INFILE '#{file}'")
|
53
|
+
stmt
|
54
|
+
end
|
55
|
+
|
56
|
+
def replace_or_ignore
|
57
|
+
options[:replace_or_ignore].to_s.upcase if %i(replace ignore).include?(options[:replace_or_ignore])
|
58
|
+
end
|
59
|
+
|
60
|
+
def into_table
|
61
|
+
"INTO TABLE #{table}"
|
62
|
+
end
|
63
|
+
|
64
|
+
def partition
|
65
|
+
"PARTITION (#{Array(options[:partition]).join(', ')})" if options[:partition] && options[:partition].size > 0
|
66
|
+
end
|
67
|
+
|
68
|
+
def character_set
|
69
|
+
"CHARACTER SET #{options[:charset]}" if options[:charset]
|
70
|
+
end
|
71
|
+
|
72
|
+
def fields
|
73
|
+
fields = [
|
74
|
+
fields_terminated_by,
|
75
|
+
fields_enclosed_by,
|
76
|
+
fields_optionally_enclosed_by,
|
77
|
+
fields_escaped_by
|
78
|
+
].compact
|
79
|
+
|
80
|
+
return if fields.size == 0
|
81
|
+
|
82
|
+
"FIELDS #{fields.join(' ')}"
|
83
|
+
end
|
84
|
+
|
85
|
+
def fields_terminated_by
|
86
|
+
"TERMINATED BY '#{options[:fields_terminated_by]}'" if options[:fields_terminated_by]
|
87
|
+
end
|
88
|
+
|
89
|
+
def fields_enclosed_by
|
90
|
+
"ENCLOSED BY '#{options[:fields_enclosed_by]}'" if options[:fields_enclosed_by]
|
91
|
+
end
|
92
|
+
|
93
|
+
def fields_optionally_enclosed_by
|
94
|
+
"OPTIONALLY ENCLOSED BY '#{options[:fields_optionally_enclosed_by]}'" if options[:fields_optionally_enclosed_by]
|
95
|
+
end
|
96
|
+
|
97
|
+
def fields_escaped_by
|
98
|
+
"ESCAPED BY '#{options[:fields_escaped_by]}'" if options[:fields_escaped_by]
|
99
|
+
end
|
100
|
+
|
101
|
+
def lines
|
102
|
+
lines = [
|
103
|
+
lines_starting_by,
|
104
|
+
lines_terminated_by
|
105
|
+
].compact
|
106
|
+
|
107
|
+
return if lines.size == 0
|
108
|
+
|
109
|
+
"LINES #{lines.join(' ')}"
|
110
|
+
end
|
111
|
+
|
112
|
+
def lines_starting_by
|
113
|
+
"STARTING BY '#{options[:lines_starting_by]}'" if options[:lines_starting_by]
|
114
|
+
end
|
115
|
+
|
116
|
+
def lines_terminated_by
|
117
|
+
"TERMINATED BY '#{options[:lines_terminated_by]}'" if options[:lines_terminated_by]
|
118
|
+
end
|
119
|
+
|
120
|
+
def ignore_lines
|
121
|
+
"IGNORE #{options[:ignore_lines].to_i} LINES" if options[:ignore_lines].to_i > 0
|
122
|
+
end
|
123
|
+
|
124
|
+
def columns
|
125
|
+
"(#{options[:columns].join(', ')})" if options[:columns] && options[:columns].size > 0
|
126
|
+
end
|
127
|
+
|
128
|
+
def set
|
129
|
+
if options[:set] && options[:set].size > 0
|
130
|
+
s = options[:set].map {|col, val| "#{col} = #{val}" }.join(', ')
|
131
|
+
"SET #{s}"
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'load_data_infile2/version'
|
2
|
+
require 'load_data_infile2/client'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'rails'
|
6
|
+
require 'load_data_infile2/railtie'
|
7
|
+
rescue LoadError
|
8
|
+
end
|
9
|
+
|
10
|
+
module LoadDataInfile2
|
11
|
+
class << self
|
12
|
+
def default_import_options
|
13
|
+
@default_import_options ||= {
|
14
|
+
fields_terminated_by: ',', # CSV
|
15
|
+
fields_optionally_enclosed_by: '"', # standard format of CSV
|
16
|
+
fields_escaped_by: '"', # standard format of CSV
|
17
|
+
lines_terminated_by: "\\n",
|
18
|
+
ignore_lines: 0
|
19
|
+
}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
lib = File.expand_path('../lib', __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require 'load_data_infile2/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = 'load_data_infile2'
|
7
|
+
spec.version = LoadDataInfile2::VERSION
|
8
|
+
spec.authors = ['nalabjp']
|
9
|
+
spec.email = ['nalabjp@gmail.com']
|
10
|
+
|
11
|
+
spec.summary = "This gem provides MySQL's LOAD DATA INFILE for Mysql2 and ActiveRecord"
|
12
|
+
spec.description = "This gem provides MySQL's LOAD DATA INFILE for Mysql2 and ActiveRecord"
|
13
|
+
spec.homepage = 'https://github.com/nalabjp/load_data_infile2'
|
14
|
+
spec.license = 'MIT'
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
17
|
+
spec.bindir = 'exe'
|
18
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
|
21
|
+
spec.add_dependency 'mysql2', '~> 0.4'
|
22
|
+
|
23
|
+
spec.add_development_dependency 'bundler', '~> 1.12'
|
24
|
+
spec.add_development_dependency 'rake'
|
25
|
+
spec.add_development_dependency 'rails'
|
26
|
+
spec.add_development_dependency 'test-unit-rails'
|
27
|
+
end
|
metadata
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: load_data_infile2
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- nalabjp
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-07-10 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: mysql2
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.4'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.4'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.12'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.12'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rails
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: test-unit-rails
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description: This gem provides MySQL's LOAD DATA INFILE for Mysql2 and ActiveRecord
|
84
|
+
email:
|
85
|
+
- nalabjp@gmail.com
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- ".gitignore"
|
91
|
+
- ".travis.yml"
|
92
|
+
- Gemfile
|
93
|
+
- LICENSE.txt
|
94
|
+
- README.md
|
95
|
+
- Rakefile
|
96
|
+
- bin/console
|
97
|
+
- bin/db_setup
|
98
|
+
- bin/setup
|
99
|
+
- lib/load_data_infile2.rb
|
100
|
+
- lib/load_data_infile2/active_record.rb
|
101
|
+
- lib/load_data_infile2/active_record_extension.rb
|
102
|
+
- lib/load_data_infile2/client.rb
|
103
|
+
- lib/load_data_infile2/railtie.rb
|
104
|
+
- lib/load_data_infile2/sql.rb
|
105
|
+
- lib/load_data_infile2/version.rb
|
106
|
+
- load_data_infile2.gemspec
|
107
|
+
homepage: https://github.com/nalabjp/load_data_infile2
|
108
|
+
licenses:
|
109
|
+
- MIT
|
110
|
+
metadata: {}
|
111
|
+
post_install_message:
|
112
|
+
rdoc_options: []
|
113
|
+
require_paths:
|
114
|
+
- lib
|
115
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
116
|
+
requirements:
|
117
|
+
- - ">="
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
version: '0'
|
120
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
requirements: []
|
126
|
+
rubyforge_project:
|
127
|
+
rubygems_version: 2.5.1
|
128
|
+
signing_key:
|
129
|
+
specification_version: 4
|
130
|
+
summary: This gem provides MySQL's LOAD DATA INFILE for Mysql2 and ActiveRecord
|
131
|
+
test_files: []
|
132
|
+
has_rdoc:
|