samidare 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/.rspec +2 -0
- data/.travis.yml +3 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +22 -0
- data/README.md +44 -0
- data/Rakefile +7 -0
- data/lib/samidare.rb +51 -0
- data/lib/samidare/bigquery_utility.rb +46 -0
- data/lib/samidare/embulk_config.erb +25 -0
- data/lib/samidare/embulk_utility.rb +155 -0
- data/lib/samidare/version.rb +3 -0
- data/samidare.gemspec +33 -0
- data/spec/samidare/bigquery_utility_spec.rb +41 -0
- data/spec/samidare/embulk_utility_spec.rb +94 -0
- data/spec/samidare_spec.rb +7 -0
- data/spec/spec_helper.rb +2 -0
- metadata +220 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 63ca3ecfca7bdd2d9928119a4565520a6cb43e3a
|
4
|
+
data.tar.gz: 9f8ba50115e2d24ec87cf0bf18a049a8cdf2cc0e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6b215d706b0ba77f13587597e5c79268176e79410b171f17a8d6f49c755569432699ddedb406d57d75ff6d86d357cc0829e2f6f1c5b4a1e57f1bfbc084509c6c
|
7
|
+
data.tar.gz: 0b171bee1aa063719c4e4c87c7d311df09f611c9153ea11f4202ddc91777e1a035b91c3aa689ad12c6cd8c02001776daa3ef3bd866d8adb39c4bd54f7f46d44c
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Ryoji Kobori
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# Samidare
|
2
|
+
|
3
|
+
Generate Embulk config and BigQuery schema from MySQL schema and run Embulk.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'samidare'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install samidare
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
config = {
|
25
|
+
'project_id' => 'BIGQUERY_PROJECT_ID',
|
26
|
+
'project_name' => 'BIGQUERY_PROJECT_NAME',
|
27
|
+
'service_email' => 'SERVICE_ACCOUNT_EMAIL',
|
28
|
+
'key' => '/etc/embulk/bigquery.p12',
|
29
|
+
'schema_dir' => '/var/tmp/embulk/schema',
|
30
|
+
'config_dir' => '/var/tmp/embulk/config',
|
31
|
+
'auth_method' => 'private_key'
|
32
|
+
}
|
33
|
+
|
34
|
+
Samidare.generate_config(config)
|
35
|
+
Samidare.embulk_run(config)
|
36
|
+
```
|
37
|
+
|
38
|
+
## Contributing
|
39
|
+
|
40
|
+
1. Fork it ( https://github.com/[my-github-username]/samidare/fork )
|
41
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
42
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
43
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
44
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/lib/samidare.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'samidare/version'
|
2
|
+
require 'samidare/embulk_utility'
|
3
|
+
|
4
|
+
module Samidare
|
5
|
+
class << self
|
6
|
+
def generate_config(config)
|
7
|
+
Samidare::EmbulkUtility::ConfigGenerator.new(config).generate_config
|
8
|
+
end
|
9
|
+
|
10
|
+
def embulk_run(config)
|
11
|
+
db_infos = Samidare::EmbulkUtility::DBInfo.generate_db_infos
|
12
|
+
table_infos = Samidare::EmbulkUtility::TableInfo.generate_table_infos
|
13
|
+
db_infos.keys.each do |db_name|
|
14
|
+
embulk_run(db_name, db_infos[db_name]['bq_dataset'], table_infos[db_name], config)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
def embulk_run(db_name, bq_dataset, tables, config)
|
20
|
+
process_times = []
|
21
|
+
big_query = Samidare::BigQueryUtility.new(config)
|
22
|
+
tables.each do |table|
|
23
|
+
start_time = Time.now
|
24
|
+
log "table: #{table.name} - start"
|
25
|
+
|
26
|
+
begin
|
27
|
+
big_query.delete_table(bq_dataset, table.name)
|
28
|
+
log "table: #{table.name} - deleted"
|
29
|
+
rescue
|
30
|
+
log "table: #{table.name} - not exists"
|
31
|
+
end
|
32
|
+
|
33
|
+
cmd = "embulk run #{ENV['EMBULK_CONFIG_DIR']}/#{db_name}/#{table.name}.yml"
|
34
|
+
log "cmd: #{cmd}"
|
35
|
+
result = system(cmd) ? 'success' : 'error'
|
36
|
+
|
37
|
+
process_time = Time.now - start_time
|
38
|
+
message = "table: #{table.name} - result: #{result} #{sprintf('%10.1f', process_time)}sec"
|
39
|
+
log message
|
40
|
+
process_times << message
|
41
|
+
end
|
42
|
+
log '------------------------------------'
|
43
|
+
log "db_name: #{db_name}"
|
44
|
+
process_times.each { |process_time| log process_time }
|
45
|
+
end
|
46
|
+
|
47
|
+
def log(message)
|
48
|
+
puts "[#{Time.now.strftime("%Y-%m-%d %H:%M:%S")}] #{message}"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'erb'
|
3
|
+
require 'big_query'
|
4
|
+
|
5
|
+
module Samidare
|
6
|
+
class BigQueryUtility
|
7
|
+
def initialize(config)
|
8
|
+
@config = config.dup
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.generate_schema(column_infos)
|
12
|
+
json_body = column_infos.map { |column_info| column_info.to_json }.join(",\n")
|
13
|
+
"[\n" + json_body + "\n]\n"
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.generate_sql(table_name, column_infos)
|
17
|
+
columns = column_infos.map { |column_info| column_info.converted_value }
|
18
|
+
sql = "SELECT " + columns.join(",")
|
19
|
+
sql << " FROM #{table_name}\n"
|
20
|
+
end
|
21
|
+
|
22
|
+
def generate_embulk_config(db_name, db_info, table_info, column_infos)
|
23
|
+
host = db_info['host']
|
24
|
+
user = db_info['username']
|
25
|
+
password = db_info['password']
|
26
|
+
database = db_info['database']
|
27
|
+
query = Samidare::BigQueryUtility.generate_sql(table_info.name, column_infos)
|
28
|
+
project = @config['project_name']
|
29
|
+
p12_keyfile_path = @config['key']
|
30
|
+
service_account_email = @config['service_email']
|
31
|
+
dataset = db_info['bq_dataset']
|
32
|
+
table_name = table_info.name
|
33
|
+
schema_path = "#{@config['schema_dir']}/#{db_name}/#{table_info.name}.json"
|
34
|
+
path_prefix = "/var/tmp/embulk_#{db_name}_#{table_info.name}"
|
35
|
+
|
36
|
+
File.open('lib/samidare/embulk_config.erb') { |f| ERB.new(f.read).result(binding) }
|
37
|
+
end
|
38
|
+
|
39
|
+
def delete_table(dataset, table_name)
|
40
|
+
@config['dataset'] = dataset
|
41
|
+
|
42
|
+
bq = BigQuery::Client.new(@config)
|
43
|
+
bq.delete_table(table_name)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
in:
|
2
|
+
type: mysql
|
3
|
+
user: <%= user %>
|
4
|
+
password: <%= password %>
|
5
|
+
database: <%= database %>
|
6
|
+
host: <%= host %>
|
7
|
+
query: |
|
8
|
+
<%= query %>
|
9
|
+
out:
|
10
|
+
type: bigquery
|
11
|
+
project: <%= project %>
|
12
|
+
p12_keyfile_path: <%= p12_keyfile_path %>
|
13
|
+
service_account_email: <%= service_account_email %>
|
14
|
+
dataset: <%= dataset %>
|
15
|
+
table: <%= table_name %>
|
16
|
+
schema_path: <%= schema_path %>
|
17
|
+
auto_create_table: 1
|
18
|
+
path_prefix: <%= path_prefix %>
|
19
|
+
source_format: NEWLINE_DELIMITED_JSON
|
20
|
+
file_ext: .json.gz
|
21
|
+
delete_from_local_when_job_end: 1
|
22
|
+
formatter:
|
23
|
+
type: jsonl
|
24
|
+
encoders:
|
25
|
+
- {type: gzip}
|
@@ -0,0 +1,155 @@
|
|
1
|
+
require 'mysql2-cs-bind'
|
2
|
+
require 'json'
|
3
|
+
require 'yaml'
|
4
|
+
require 'samidare/bigquery_utility'
|
5
|
+
|
6
|
+
module Samidare
|
7
|
+
module EmbulkUtility
|
8
|
+
class ConfigGenerator
|
9
|
+
def initialize(bq_config)
|
10
|
+
@bq_config = bq_config.dup
|
11
|
+
end
|
12
|
+
|
13
|
+
def generate_config
|
14
|
+
db_infos = EmbulkUtility::DBInfo.generate_db_infos
|
15
|
+
table_infos = EmbulkUtility::TableInfo.generate_table_infos
|
16
|
+
bq_utility = BigQueryUtility.new(@bq_config)
|
17
|
+
|
18
|
+
db_infos.keys.each do |db_name|
|
19
|
+
db_info = db_infos[db_name]
|
20
|
+
table_info = table_infos[db_name]
|
21
|
+
mysql_client = EmbulkUtility::MySQLClient.new(db_info)
|
22
|
+
|
23
|
+
table_info.each do |table|
|
24
|
+
write(
|
25
|
+
"#{@bq_config['schema_dir']}/#{db_name}",
|
26
|
+
"#{table.name}.json",
|
27
|
+
mysql_client.generate_bq_schema(table.name)
|
28
|
+
)
|
29
|
+
write(
|
30
|
+
"#{@bq_config['config_dir']}/#{db_name}",
|
31
|
+
"#{table.name}.yml",
|
32
|
+
bq_utility.generate_embulk_config(db_name, db_info, table, mysql_client.column_infos(table.name))
|
33
|
+
)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
def write(directory, file_name, content)
|
40
|
+
FileUtils.mkdir_p(directory) unless FileTest.exist?(directory)
|
41
|
+
File.write("#{directory}/#{file_name}", content)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class MySQLClient
|
46
|
+
COLUMN_INFO_SQL = <<-SQL
|
47
|
+
SELECT column_name, data_type
|
48
|
+
FROM INFORMATION_SCHEMA.COLUMNS
|
49
|
+
WHERE table_schema = ?
|
50
|
+
AND table_name = ?
|
51
|
+
ORDER BY ordinal_position
|
52
|
+
SQL
|
53
|
+
|
54
|
+
def initialize(db_info)
|
55
|
+
@db_info = db_info
|
56
|
+
end
|
57
|
+
|
58
|
+
def client
|
59
|
+
@client ||= Mysql2::Client.new(
|
60
|
+
:host => @db_info['host'],
|
61
|
+
:username => @db_info['username'],
|
62
|
+
:password => @db_info['password'],
|
63
|
+
:database => @db_info['database'])
|
64
|
+
end
|
65
|
+
|
66
|
+
def generate_bq_schema(table_name)
|
67
|
+
infos = column_infos(table_name)
|
68
|
+
BigQueryUtility.generate_schema(infos)
|
69
|
+
end
|
70
|
+
|
71
|
+
def column_infos(table_name)
|
72
|
+
rows = client.xquery(COLUMN_INFO_SQL, @db_info['database'], table_name)
|
73
|
+
rows.map { |row| ColumnInfo.new(row['column_name'], row['data_type']) }
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
class DBInfo
|
78
|
+
attr_reader :name, :host, :username, :password, :database, :bq_dataset
|
79
|
+
|
80
|
+
def initialize(config)
|
81
|
+
@name = config['name']
|
82
|
+
@host = config['host']
|
83
|
+
@username = config['username']
|
84
|
+
@password = config['password']
|
85
|
+
@database = config['database']
|
86
|
+
@bq_dataset = config['bq_dataset']
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.generate_db_infos
|
90
|
+
configs = YAML.load_file('database.yml')
|
91
|
+
configs
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
class TableInfo
|
96
|
+
def initialize(config)
|
97
|
+
@config = config.dup
|
98
|
+
end
|
99
|
+
|
100
|
+
def self.generate_table_infos
|
101
|
+
configs = YAML.load_file('table.yml')
|
102
|
+
configs.each_with_object({}) do |(db, db_info), table_infos|
|
103
|
+
table_infos[db] = db_info['tables'].map { |config| TableInfo.new(config) }
|
104
|
+
table_infos
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def name
|
109
|
+
@config['name']
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
class ColumnInfo
|
114
|
+
attr_reader :column_name, :data_type
|
115
|
+
|
116
|
+
TYPE_MAPPINGS = {
|
117
|
+
'int' => 'integer',
|
118
|
+
'tinyint' => 'integer',
|
119
|
+
'bigint' => 'integer',
|
120
|
+
'double' => 'float',
|
121
|
+
'decimal' => 'float',
|
122
|
+
'varchar' => 'string',
|
123
|
+
'text' => 'string',
|
124
|
+
'date' => 'timestamp',
|
125
|
+
'datetime' => 'timestamp',
|
126
|
+
'timestamp' => 'timestamp'
|
127
|
+
}
|
128
|
+
|
129
|
+
def initialize(column_name, data_type)
|
130
|
+
@column_name = column_name
|
131
|
+
@data_type = data_type
|
132
|
+
end
|
133
|
+
|
134
|
+
def bigquery_data_type
|
135
|
+
TYPE_MAPPINGS[@data_type]
|
136
|
+
end
|
137
|
+
|
138
|
+
def converted_value
|
139
|
+
if bigquery_data_type == 'timestamp'
|
140
|
+
# time zone translate to UTC
|
141
|
+
"UNIX_TIMESTAMP(#{@column_name}) AS #{@column_name}"
|
142
|
+
elsif data_type == 'tinyint'
|
143
|
+
# for MySQL tinyint(1) problem
|
144
|
+
"CAST(#{@column_name} AS signed) AS #{@column_name}"
|
145
|
+
else
|
146
|
+
@column_name
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def to_json(*a)
|
151
|
+
{ "name" => @column_name, "type" => bigquery_data_type }.to_json(*a)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
data/samidare.gemspec
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'samidare/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'samidare'
|
8
|
+
spec.version = Samidare::VERSION
|
9
|
+
spec.authors = ['Ryoji Kobori']
|
10
|
+
spec.email = ['kobori75@gmail.com']
|
11
|
+
spec.summary = %q{Embulk utility for MySQL to BigQuery}
|
12
|
+
spec.description = %q{Generate Embulk config and BigQuery schema from MySQL schema}
|
13
|
+
spec.homepage = 'https://github.com/cobot00/samidare'
|
14
|
+
spec.license = 'MIT'
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
|
21
|
+
spec.add_development_dependency 'bundler', '~> 1.7'
|
22
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
23
|
+
spec.add_development_dependency 'rspec'
|
24
|
+
spec.add_development_dependency 'unindent'
|
25
|
+
|
26
|
+
spec.add_dependency 'mysql2-cs-bind'
|
27
|
+
spec.add_dependency 'embulk-output-bigquery'
|
28
|
+
spec.add_dependency 'embulk-input-mysql'
|
29
|
+
spec.add_dependency 'embulk-output-mysql'
|
30
|
+
spec.add_dependency 'embulk-parser-jsonl'
|
31
|
+
spec.add_dependency 'embulk-formatter-jsonl'
|
32
|
+
spec.add_dependency 'bigquery'
|
33
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'unindent'
|
3
|
+
|
4
|
+
describe Samidare::BigQueryUtility do
|
5
|
+
describe '.generate_schema' do
|
6
|
+
subject { Samidare::BigQueryUtility.generate_schema(column_infos) }
|
7
|
+
|
8
|
+
context '' do
|
9
|
+
let(:column_infos) { [
|
10
|
+
Samidare::EmbulkUtility::ColumnInfo.new('id', 'int'),
|
11
|
+
Samidare::EmbulkUtility::ColumnInfo.new('name', 'varchar'),
|
12
|
+
Samidare::EmbulkUtility::ColumnInfo.new('created_at', 'datetime')
|
13
|
+
] }
|
14
|
+
let(:schema_json) {
|
15
|
+
<<-JSON.unindent
|
16
|
+
[
|
17
|
+
{"name":"id","type":"integer"},
|
18
|
+
{"name":"name","type":"string"},
|
19
|
+
{"name":"created_at","type":"timestamp"}
|
20
|
+
]
|
21
|
+
JSON
|
22
|
+
}
|
23
|
+
it { expect(subject).to eq schema_json }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '.generate_sql' do
|
28
|
+
subject { Samidare::BigQueryUtility.generate_sql(table_name, column_infos) }
|
29
|
+
|
30
|
+
context '' do
|
31
|
+
let(:table_name) { 'simple' }
|
32
|
+
let(:column_infos) { [
|
33
|
+
Samidare::EmbulkUtility::ColumnInfo.new('id', 'int'),
|
34
|
+
Samidare::EmbulkUtility::ColumnInfo.new('name', 'varchar'),
|
35
|
+
Samidare::EmbulkUtility::ColumnInfo.new('created_at', 'datetime')
|
36
|
+
] }
|
37
|
+
let(:sql) { "SELECT id,name,UNIX_TIMESTAMP(created_at) AS created_at FROM simple\n" }
|
38
|
+
it { expect(subject).to eq sql }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Samidare::EmbulkUtility::ColumnInfo do
|
4
|
+
let(:column_info) { Samidare::EmbulkUtility::ColumnInfo.new(column_name, data_type) }
|
5
|
+
let(:column_name) { 'id' }
|
6
|
+
let(:data_type) { 'int' }
|
7
|
+
|
8
|
+
it { expect(column_info.column_name).to eq 'id' }
|
9
|
+
it { expect(column_info.data_type).to eq 'int' }
|
10
|
+
|
11
|
+
describe '#bigquery_data_type' do
|
12
|
+
subject { column_info.bigquery_data_type }
|
13
|
+
|
14
|
+
context 'int' do
|
15
|
+
let(:data_type) { 'int' }
|
16
|
+
it { expect(subject).to eq 'integer' }
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'tinyint' do
|
20
|
+
let(:data_type) { 'tinyint' }
|
21
|
+
it { expect(subject).to eq 'integer' }
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'bigint' do
|
25
|
+
let(:data_type) { 'bigint' }
|
26
|
+
it { expect(subject).to eq 'integer' }
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'double' do
|
30
|
+
let(:data_type) { 'double' }
|
31
|
+
it { expect(subject).to eq 'float' }
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'decimal' do
|
35
|
+
let(:data_type) { 'decimal' }
|
36
|
+
it { expect(subject).to eq 'float' }
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'varchar' do
|
40
|
+
let(:data_type) { 'varchar' }
|
41
|
+
it { expect(subject).to eq 'string' }
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'text' do
|
45
|
+
let(:data_type) { 'text' }
|
46
|
+
it { expect(subject).to eq 'string' }
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'date' do
|
50
|
+
let(:data_type) { 'date' }
|
51
|
+
it { expect(subject).to eq 'timestamp' }
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'datetime' do
|
55
|
+
let(:data_type) { 'datetime' }
|
56
|
+
it { expect(subject).to eq 'timestamp' }
|
57
|
+
end
|
58
|
+
|
59
|
+
context 'timestamp' do
|
60
|
+
let(:data_type) { 'timestamp' }
|
61
|
+
it { expect(subject).to eq 'timestamp' }
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe '#converted_value' do
|
66
|
+
subject { column_info.converted_value }
|
67
|
+
|
68
|
+
context 'datetime' do
|
69
|
+
let(:column_name) { 'create_at' }
|
70
|
+
let(:data_type) { 'datetime' }
|
71
|
+
it { expect(subject).to eq 'UNIX_TIMESTAMP(create_at) AS create_at' }
|
72
|
+
end
|
73
|
+
|
74
|
+
context 'int' do
|
75
|
+
let(:column_name) { 'id' }
|
76
|
+
let(:data_type) { 'int' }
|
77
|
+
it { expect(subject).to eq 'id' }
|
78
|
+
end
|
79
|
+
|
80
|
+
context 'varchar' do
|
81
|
+
let(:column_name) { 'explanation' }
|
82
|
+
let(:data_type) { 'varchar' }
|
83
|
+
it { expect(subject).to eq 'explanation' }
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe '#to_json' do
|
88
|
+
subject { column_info.to_json }
|
89
|
+
|
90
|
+
let(:column_name) { 'id' }
|
91
|
+
let(:data_type) { 'int' }
|
92
|
+
it { expect(subject).to eq '{"name":"id","type":"integer"}' }
|
93
|
+
end
|
94
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,220 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: samidare
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ryoji Kobori
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-07-14 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.7'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
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: unindent
|
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: mysql2-cs-bind
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: embulk-output-bigquery
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: embulk-input-mysql
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: embulk-output-mysql
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: embulk-parser-jsonl
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: embulk-formatter-jsonl
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :runtime
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: bigquery
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
type: :runtime
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
167
|
+
description: Generate Embulk config and BigQuery schema from MySQL schema
|
168
|
+
email:
|
169
|
+
- kobori75@gmail.com
|
170
|
+
executables: []
|
171
|
+
extensions: []
|
172
|
+
extra_rdoc_files: []
|
173
|
+
files:
|
174
|
+
- ".gitignore"
|
175
|
+
- ".rspec"
|
176
|
+
- ".travis.yml"
|
177
|
+
- Gemfile
|
178
|
+
- LICENSE.txt
|
179
|
+
- README.md
|
180
|
+
- Rakefile
|
181
|
+
- lib/samidare.rb
|
182
|
+
- lib/samidare/bigquery_utility.rb
|
183
|
+
- lib/samidare/embulk_config.erb
|
184
|
+
- lib/samidare/embulk_utility.rb
|
185
|
+
- lib/samidare/version.rb
|
186
|
+
- samidare.gemspec
|
187
|
+
- spec/samidare/bigquery_utility_spec.rb
|
188
|
+
- spec/samidare/embulk_utility_spec.rb
|
189
|
+
- spec/samidare_spec.rb
|
190
|
+
- spec/spec_helper.rb
|
191
|
+
homepage: https://github.com/cobot00/samidare
|
192
|
+
licenses:
|
193
|
+
- MIT
|
194
|
+
metadata: {}
|
195
|
+
post_install_message:
|
196
|
+
rdoc_options: []
|
197
|
+
require_paths:
|
198
|
+
- lib
|
199
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
200
|
+
requirements:
|
201
|
+
- - ">="
|
202
|
+
- !ruby/object:Gem::Version
|
203
|
+
version: '0'
|
204
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
205
|
+
requirements:
|
206
|
+
- - ">="
|
207
|
+
- !ruby/object:Gem::Version
|
208
|
+
version: '0'
|
209
|
+
requirements: []
|
210
|
+
rubyforge_project:
|
211
|
+
rubygems_version: 2.4.8
|
212
|
+
signing_key:
|
213
|
+
specification_version: 4
|
214
|
+
summary: Embulk utility for MySQL to BigQuery
|
215
|
+
test_files:
|
216
|
+
- spec/samidare/bigquery_utility_spec.rb
|
217
|
+
- spec/samidare/embulk_utility_spec.rb
|
218
|
+
- spec/samidare_spec.rb
|
219
|
+
- spec/spec_helper.rb
|
220
|
+
has_rdoc:
|