samidare 0.0.11 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: eaced8c4bed3cea616f56ffe1bd1bf72776f103c
4
- data.tar.gz: d3ef165a96055bc1dd51fbafef03268a76550ba1
3
+ metadata.gz: e2e4fe3e66626b0fd4eaf311505f35fd0b6c72e5
4
+ data.tar.gz: bf4ffdd752f991a74f55541a40068c2f560cc774
5
5
  SHA512:
6
- metadata.gz: bb7a324305a0c9221fbcc505e91ff12f7171a9584d549502b9c1a55c755cb92a6fce0da381e11b044c35c24c29bd1a9ae97466a2caadb81e61261916e4f873de
7
- data.tar.gz: 2db8446c60c1be68741871681c686c5a4fb3e08a9c087fa3f96ca9cdce8d1527e5abacd2d052c3b31e784ecee45c250d98b6c70f2baf4389367735f07115dae3
6
+ metadata.gz: cec779faaaefadbd2731fd3010ea735fadae9823231bf4307d3c7d1ff7d1eb29804563812d15129611937da6eb5adce08af9bcef0eef709d758d2bd5f9fd126e
7
+ data.tar.gz: 5959e5303709334e485676f55c522f435b0d03ea461f2e4cba7cf085c9b034118ca1ee0522af418290164d94c5f6759a6aa5e5130755d44e6ac7eceacb189263
@@ -1,58 +1,27 @@
1
1
  require 'samidare/version'
2
2
  require 'samidare/embulk_utility'
3
+ require 'samidare/embulk'
4
+ require 'samidare/mysql'
3
5
 
4
6
  module Samidare
5
7
  class EmbulkClient
6
- def generate_config(config)
7
- Samidare::EmbulkUtility::ConfigGenerator.new(config).generate_config
8
+ def generate_config(bq_config)
9
+ Samidare::EmbulkUtility::ConfigGenerator.new.generate_config(database_configs, bq_config)
8
10
  end
9
11
 
10
- def run(config, target_tables = [])
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, target_tables)
15
- end
12
+ def run(bq_config, target_table_names = [])
13
+ error_tables = Samidare::Embulk.new.run(
14
+ database_configs,
15
+ Samidare::MySQL::TableConfig.generate_table_configs,
16
+ bq_config,
17
+ target_table_names)
18
+ # return batch status(true: all tables success)
19
+ error_tables.size == 0
16
20
  end
17
21
 
18
22
  private
19
- def embulk_run(db_name, bq_dataset, tables, config, target_tables)
20
- process_times = []
21
- big_query = Samidare::BigQueryUtility.new(config)
22
- tables.each do |table|
23
- next unless target_table?(table.name, target_tables)
24
-
25
- start_time = Time.now
26
- log "table: #{table.name} - start"
27
-
28
- begin
29
- big_query.delete_table(bq_dataset, table.name)
30
- log "table: #{table.name} - deleted"
31
- rescue
32
- log "table: #{table.name} - does not exist"
33
- end
34
-
35
- cmd = "embulk run #{config['config_dir']}/#{db_name}/#{table.name}.yml"
36
- log "cmd: #{cmd}"
37
- result = system(cmd) ? 'success' : 'error'
38
-
39
- process_time = Time.now - start_time
40
- message = "table: #{table.name} - result: #{result} #{sprintf('%10.1f', process_time)}sec"
41
- log message
42
- process_times << message
43
- end
44
- log '------------------------------------'
45
- log "db_name: #{db_name}"
46
- process_times.each { |process_time| log process_time }
47
- end
48
-
49
- def target_table?(table, target_tables)
50
- return true if target_tables.empty?
51
- target_tables.include?(table)
52
- end
53
-
54
- def log(message)
55
- puts "[#{Time.now.strftime("%Y-%m-%d %H:%M:%S")}] #{message}"
23
+ def database_configs
24
+ YAML.load_file('database.yml')
56
25
  end
57
26
  end
58
27
  end
@@ -39,33 +39,33 @@ module Samidare
39
39
  @current_date = Date.today
40
40
  end
41
41
 
42
- def self.generate_schema(column_infos)
43
- json_body = column_infos.map { |column_info| column_info.to_json }.join(",\n")
42
+ def self.generate_schema(columns)
43
+ json_body = columns.map { |column| column.to_json }.join(",\n")
44
44
  "[\n" + json_body + "\n]\n"
45
45
  end
46
46
 
47
- def self.generate_sql(table_info, column_infos)
48
- columns = column_infos.map { |column_info| column_info.converted_value }
47
+ def self.generate_sql(table_config, columns)
48
+ columns = columns.map { |column| column.converted_value }
49
49
  sql = "SELECT " + columns.join(",")
50
- sql << " FROM #{table_info.name}"
51
- sql << " WHERE #{table_info.condition}" if table_info.condition
50
+ sql << " FROM #{table_config.name}"
51
+ sql << " WHERE #{table_config.condition}" if table_config.condition
52
52
  sql << "\n"
53
53
  sql
54
54
  end
55
55
 
56
- def generate_embulk_config(db_name, db_info, table_info, column_infos)
57
- host = db_info['host']
58
- user = db_info['username']
59
- password = db_info['password']
60
- database = db_info['database']
61
- query = Samidare::BigQueryUtility.generate_sql(table_info, column_infos)
56
+ def generate_embulk_config(db_name, database_config, table_config, columns)
57
+ host = database_config['host']
58
+ user = database_config['username']
59
+ password = database_config['password']
60
+ database = database_config['database']
61
+ query = Samidare::BigQueryUtility.generate_sql(table_config, columns)
62
62
  project = @config['project_id']
63
63
  p12_keyfile_path = @config['key']
64
64
  service_account_email = @config['service_email']
65
- dataset = db_info['bq_dataset']
66
- table_name = actual_table_name(table_info.name, db_info['daily_snapshot'] || table_info.daily_snapshot)
67
- schema_path = "#{@config['schema_dir']}/#{db_name}/#{table_info.name}.json"
68
- path_prefix = "/var/tmp/embulk_#{db_name}_#{table_info.name}"
65
+ dataset = database_config['bq_dataset']
66
+ table_name = actual_table_name(table_config.name, database_config['daily_snapshot'] || table_config.daily_snapshot)
67
+ schema_path = "#{@config['schema_dir']}/#{db_name}/#{table_config.name}.json"
68
+ path_prefix = "/var/tmp/embulk_#{db_name}_#{table_config.name}"
69
69
 
70
70
  ERB.new(CONTENTS).result(binding)
71
71
  end
@@ -0,0 +1,57 @@
1
+ module Samidare
2
+ class Embulk
3
+ def run(database_configs, all_table_configs, bq_config, target_table_names = [])
4
+ error_tables = []
5
+ database_configs.keys.each do |db_name|
6
+ table_configs = target_table_configs(all_table_configs[db_name], target_table_names)
7
+ error_tables << run_by_database(db_name, table_configs, database_configs[db_name]['bq_dataset'], bq_config)
8
+ end
9
+ error_tables
10
+ end
11
+
12
+ def target_table_configs(table_configs, target_table_names)
13
+ return table_configs if target_table_names.empty?
14
+ table_configs.select { |table_config| target_table_names.include?(table_config.name) }
15
+ end
16
+
17
+ private
18
+ def run_by_database(db_name, table_configs, bq_dataset, bq_config)
19
+ process_times = []
20
+ error_tables = []
21
+ big_query = Samidare::BigQueryUtility.new(bq_config)
22
+ table_configs.each do |table_config|
23
+ start_time = Time.now
24
+ log "table: #{table_config.name} - start"
25
+
26
+ begin
27
+ big_query.delete_table(bq_dataset, table_config.name)
28
+ log "table: #{table_config.name} - deleted"
29
+ rescue
30
+ log "table: #{table_config.name} - does not exist"
31
+ end
32
+
33
+ cmd = "embulk run #{bq_config['config_dir']}/#{db_name}/#{table_config.name}.yml"
34
+ log "cmd: #{cmd}"
35
+ if system(cmd)
36
+ result = 'success'
37
+ else
38
+ result = 'error'
39
+ error_tables << table_config.name
40
+ end
41
+
42
+ process_time = "table: #{table_config.name} - result: #{result} #{sprintf('%10.1f', Time.now - start_time)}sec"
43
+ log process_time
44
+ process_times << process_time
45
+ end
46
+ log '------------------------------------'
47
+ log "db_name: #{db_name}"
48
+ process_times.each { |process_time| log process_time }
49
+
50
+ error_tables
51
+ end
52
+
53
+ def log(message)
54
+ puts "[#{Time.now.strftime("%Y-%m-%d %H:%M:%S")}] #{message}"
55
+ end
56
+ end
57
+ end
@@ -1,36 +1,28 @@
1
- require 'mysql2-cs-bind'
2
- require 'json'
3
- require 'yaml'
4
- require 'fileutils'
5
- require 'samidare/bigquery_utility'
6
-
7
1
  module Samidare
8
2
  module EmbulkUtility
9
3
  class ConfigGenerator
10
- def initialize(bq_config)
11
- @bq_config = bq_config.dup
12
- end
13
-
14
- def generate_config
15
- db_infos = EmbulkUtility::DBInfo.generate_db_infos
16
- table_infos = EmbulkUtility::TableInfo.generate_table_infos
17
- bq_utility = BigQueryUtility.new(@bq_config)
4
+ def generate_config(database_configs, bq_config)
5
+ bq_utility = BigQueryUtility.new(bq_config)
18
6
 
19
- db_infos.keys.each do |db_name|
20
- db_info = db_infos[db_name]
21
- table_info = table_infos[db_name]
22
- mysql_client = EmbulkUtility::MySQLClient.new(db_info)
7
+ database_configs.keys.each do |db_name|
8
+ database_config = database_configs[db_name]
9
+ table_configs = all_table_configs[db_name]
10
+ mysql_client = MySQL::MySQLClient.new(database_config)
23
11
 
24
- table_info.each do |table|
12
+ table_configs.each do |table_config|
25
13
  write(
26
- "#{@bq_config['schema_dir']}/#{db_name}",
27
- "#{table.name}.json",
28
- mysql_client.generate_bq_schema(table.name)
14
+ "#{bq_config['schema_dir']}/#{db_name}",
15
+ "#{table_config.name}.json",
16
+ mysql_client.generate_bq_schema(table_config.name)
29
17
  )
30
18
  write(
31
- "#{@bq_config['config_dir']}/#{db_name}",
32
- "#{table.name}.yml",
33
- bq_utility.generate_embulk_config(db_name, db_info, table, mysql_client.column_infos(table.name))
19
+ "#{bq_config['config_dir']}/#{db_name}",
20
+ "#{table_config.name}.yml",
21
+ bq_utility.generate_embulk_config(
22
+ db_name,
23
+ database_config,
24
+ table_config,
25
+ mysql_client.columns(table_config.name))
34
26
  )
35
27
  end
36
28
  end
@@ -41,122 +33,9 @@ module Samidare
41
33
  FileUtils.mkdir_p(directory) unless FileTest.exist?(directory)
42
34
  File.write("#{directory}/#{file_name}", content)
43
35
  end
44
- end
45
-
46
- class MySQLClient
47
- COLUMN_INFO_SQL = <<-SQL
48
- SELECT column_name, data_type
49
- FROM INFORMATION_SCHEMA.COLUMNS
50
- WHERE table_schema = ?
51
- AND table_name = ?
52
- ORDER BY ordinal_position
53
- SQL
54
-
55
- def initialize(db_info)
56
- @db_info = db_info
57
- end
58
-
59
- def client
60
- @client ||= Mysql2::Client.new(
61
- :host => @db_info['host'],
62
- :username => @db_info['username'],
63
- :password => @db_info['password'],
64
- :database => @db_info['database'])
65
- end
66
-
67
- def generate_bq_schema(table_name)
68
- infos = column_infos(table_name)
69
- BigQueryUtility.generate_schema(infos)
70
- end
71
36
 
72
- def column_infos(table_name)
73
- rows = client.xquery(COLUMN_INFO_SQL, @db_info['database'], table_name)
74
- rows.map { |row| ColumnInfo.new(row['column_name'], row['data_type']) }
75
- end
76
- end
77
-
78
- class DBInfo
79
- def self.generate_db_infos
80
- configs = YAML.load_file('database.yml')
81
- configs
82
- end
83
- end
84
-
85
- class TableInfo
86
- def initialize(config)
87
- @config = config.dup
88
- end
89
-
90
- def self.generate_table_infos
91
- configs = YAML.load_file('table.yml')
92
- configs.each_with_object({}) do |(db, db_info), table_infos|
93
- table_infos[db] = db_info['tables'].map { |config| TableInfo.new(config) }
94
- table_infos
95
- end
96
- end
97
-
98
- def name
99
- @config['name']
100
- end
101
-
102
- def daily_snapshot
103
- @config['daily_snapshot'] || false
104
- end
105
-
106
- def condition
107
- @config['condition']
108
- end
109
- end
110
-
111
- class ColumnInfo
112
- attr_reader :column_name, :data_type
113
-
114
- TYPE_MAPPINGS = {
115
- 'int' => 'integer',
116
- 'tinyint' => 'integer',
117
- 'smallint' => 'integer',
118
- 'mediumint' => 'integer',
119
- 'bigint' => 'integer',
120
- 'float' => 'float',
121
- 'double' => 'float',
122
- 'decimal' => 'float',
123
- 'char' => 'string',
124
- 'varchar' => 'string',
125
- 'tinytext' => 'string',
126
- 'text' => 'string',
127
- 'date' => 'timestamp',
128
- 'datetime' => 'timestamp',
129
- 'timestamp' => 'timestamp'
130
- }
131
-
132
- def initialize(column_name, data_type)
133
- @column_name = column_name
134
- @data_type = data_type
135
- end
136
-
137
- def bigquery_data_type
138
- TYPE_MAPPINGS[@data_type]
139
- end
140
-
141
- def converted_value
142
- if bigquery_data_type == 'timestamp'
143
- # time zone translate to UTC
144
- "UNIX_TIMESTAMP(#{escaped_column_name}) AS #{escaped_column_name}"
145
- elsif data_type == 'tinyint'
146
- # for MySQL tinyint(1) problem
147
- "CAST(#{escaped_column_name} AS signed) AS #{escaped_column_name}"
148
- else
149
- escaped_column_name
150
- end
151
- end
152
-
153
- def to_json(*a)
154
- { "name" => @column_name, "type" => bigquery_data_type }.to_json(*a)
155
- end
156
-
157
- private
158
- def escaped_column_name
159
- "`#{@column_name}`"
37
+ def all_table_configs
38
+ @all_table_configs ||= MySQL::TableConfig.generate_table_configs
160
39
  end
161
40
  end
162
41
  end
@@ -0,0 +1,117 @@
1
+ require 'mysql2-cs-bind'
2
+ require 'json'
3
+ require 'yaml'
4
+ require 'fileutils'
5
+ require 'samidare/bigquery_utility'
6
+
7
+ module Samidare
8
+ module MySQL
9
+ class MySQLClient
10
+ COLUMN_SQL = <<-SQL
11
+ SELECT column_name, data_type
12
+ FROM INFORMATION_SCHEMA.COLUMNS
13
+ WHERE table_schema = ?
14
+ AND table_name = ?
15
+ ORDER BY ordinal_position
16
+ SQL
17
+
18
+ def initialize(database_config)
19
+ @database_config = database_config
20
+ end
21
+
22
+ def client
23
+ @client ||= Mysql2::Client.new(
24
+ :host => @database_config['host'],
25
+ :username => @database_config['username'],
26
+ :password => @database_config['password'],
27
+ :database => @database_config['database'])
28
+ end
29
+
30
+ def generate_bq_schema(table_name)
31
+ infos = columns(table_name)
32
+ BigQueryUtility.generate_schema(infos)
33
+ end
34
+
35
+ def columns(table_name)
36
+ rows = client.xquery(COLUMN_SQL, @database_config['database'], table_name)
37
+ rows.map { |row| Column.new(row['column_name'], row['data_type']) }
38
+ end
39
+ end
40
+
41
+ class TableConfig
42
+ attr_reader :name, :daily_snapshot, :condition
43
+
44
+ def initialize(config)
45
+ @name = config['name']
46
+ @daily_snapshot = config['daily_snapshot'] || false
47
+ @condition = config['condition']
48
+ end
49
+
50
+ def self.generate_table_configs(file_path = 'table.yml')
51
+ configs = YAML.load_file(file_path)
52
+ configs.each_with_object({}) do |(db, database_config), table_configs|
53
+ table_configs[db] = database_config['tables'].map { |config| TableConfig.new(config) }
54
+ table_configs
55
+ end
56
+ end
57
+
58
+ def ==(another)
59
+ self.instance_variables.all? do |v|
60
+ self.instance_variable_get(v) == another.instance_variable_get(v)
61
+ end
62
+ end
63
+ end
64
+
65
+ class Column
66
+ attr_reader :column_name, :data_type
67
+
68
+ TYPE_MAPPINGS = {
69
+ 'int' => 'integer',
70
+ 'tinyint' => 'integer',
71
+ 'smallint' => 'integer',
72
+ 'mediumint' => 'integer',
73
+ 'bigint' => 'integer',
74
+ 'float' => 'float',
75
+ 'double' => 'float',
76
+ 'decimal' => 'float',
77
+ 'char' => 'string',
78
+ 'varchar' => 'string',
79
+ 'tinytext' => 'string',
80
+ 'text' => 'string',
81
+ 'date' => 'timestamp',
82
+ 'datetime' => 'timestamp',
83
+ 'timestamp' => 'timestamp'
84
+ }
85
+
86
+ def initialize(column_name, data_type)
87
+ @column_name = column_name
88
+ @data_type = data_type
89
+ end
90
+
91
+ def bigquery_data_type
92
+ TYPE_MAPPINGS[@data_type]
93
+ end
94
+
95
+ def converted_value
96
+ if bigquery_data_type == 'timestamp'
97
+ # time zone translate to UTC
98
+ "UNIX_TIMESTAMP(#{escaped_column_name}) AS #{escaped_column_name}"
99
+ elsif data_type == 'tinyint'
100
+ # for MySQL tinyint(1) problem
101
+ "CAST(#{escaped_column_name} AS signed) AS #{escaped_column_name}"
102
+ else
103
+ escaped_column_name
104
+ end
105
+ end
106
+
107
+ def to_json(*a)
108
+ { "name" => @column_name, "type" => bigquery_data_type }.to_json(*a)
109
+ end
110
+
111
+ private
112
+ def escaped_column_name
113
+ "`#{@column_name}`"
114
+ end
115
+ end
116
+ end
117
+ end
@@ -1,3 +1,3 @@
1
1
  module Samidare
2
- VERSION = "0.0.11"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -4,12 +4,12 @@ require 'timecop'
4
4
 
5
5
  describe Samidare::BigQueryUtility do
6
6
  describe '.generate_schema' do
7
- subject { Samidare::BigQueryUtility.generate_schema(column_infos) }
7
+ subject { Samidare::BigQueryUtility.generate_schema(columns) }
8
8
 
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')
9
+ let(:columns) { [
10
+ Samidare::MySQL::Column.new('id', 'int'),
11
+ Samidare::MySQL::Column.new('name', 'varchar'),
12
+ Samidare::MySQL::Column.new('created_at', 'datetime')
13
13
  ] }
14
14
  let(:schema_json) {
15
15
  <<-JSON.unindent
@@ -24,22 +24,22 @@ describe Samidare::BigQueryUtility do
24
24
  end
25
25
 
26
26
  describe '.generate_sql' do
27
- subject { Samidare::BigQueryUtility.generate_sql(table_info, column_infos) }
27
+ subject { Samidare::BigQueryUtility.generate_sql(table_config, columns) }
28
28
 
29
- let(:column_infos) { [
30
- Samidare::EmbulkUtility::ColumnInfo.new('id', 'int'),
31
- Samidare::EmbulkUtility::ColumnInfo.new('name', 'varchar'),
32
- Samidare::EmbulkUtility::ColumnInfo.new('created_at', 'datetime')
29
+ let(:columns) { [
30
+ Samidare::MySQL::Column.new('id', 'int'),
31
+ Samidare::MySQL::Column.new('name', 'varchar'),
32
+ Samidare::MySQL::Column.new('created_at', 'datetime')
33
33
  ] }
34
34
 
35
35
  context 'no condition' do
36
- let(:table_info) { Samidare::EmbulkUtility::TableInfo.new({ 'name' => 'simple' }) }
36
+ let(:table_config) { Samidare::MySQL::TableConfig.new({ 'name' => 'simple' }) }
37
37
  let(:sql) { "SELECT `id`,`name`,UNIX_TIMESTAMP(`created_at`) AS `created_at` FROM simple\n" }
38
38
  it { expect(subject).to eq sql }
39
39
  end
40
40
 
41
41
  context 'has condition' do
42
- let(:table_info) { Samidare::EmbulkUtility::TableInfo.new({ 'name' => 'simple', 'condition' => 'created_at >= CURRENT_DATE() - INTERVAL 3 MONTH' }) }
42
+ let(:table_config) { Samidare::MySQL::TableConfig.new({ 'name' => 'simple', 'condition' => 'created_at >= CURRENT_DATE() - INTERVAL 3 MONTH' }) }
43
43
  let(:sql) { "SELECT `id`,`name`,UNIX_TIMESTAMP(`created_at`) AS `created_at` FROM simple WHERE created_at >= CURRENT_DATE() - INTERVAL 3 MONTH\n" }
44
44
  it { expect(subject).to eq sql }
45
45
  end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ describe Samidare::Embulk do
4
+ describe '#target_table_configs' do
5
+ subject { Samidare::Embulk.new(nil, nil).target_table_configs(table_configs, target_table_names) }
6
+
7
+ context 'all tables' do
8
+ let(:table_hoge) { Samidare::MySQL::TableConfig.new({ 'name' => 'hoge' }) }
9
+ let(:table_fuga) { Samidare::MySQL::TableConfig.new({ 'name' => 'fuga' }) }
10
+ let(:table_configs) { [table_hoge, table_fuga] }
11
+ let(:target_table_names) { [] }
12
+ it { expect(subject).to match(table_configs) }
13
+ end
14
+
15
+ context 'target table selected' do
16
+ let(:table_hoge) { Samidare::MySQL::TableConfig.new({ 'name' => 'hoge' }) }
17
+ let(:table_fuga) { Samidare::MySQL::TableConfig.new({ 'name' => 'fuga' }) }
18
+ let(:table_configs) { [table_hoge, table_fuga] }
19
+ let(:target_table_names) { ['hoge'] }
20
+ it { expect(subject).to match([table_hoge]) }
21
+ end
22
+ end
23
+ end
@@ -1,15 +1,15 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Samidare::EmbulkUtility::ColumnInfo do
4
- let(:column_info) { Samidare::EmbulkUtility::ColumnInfo.new(column_name, data_type) }
3
+ describe Samidare::MySQL::Column do
4
+ let(:column) { Samidare::MySQL::Column.new(column_name, data_type) }
5
5
  let(:column_name) { 'id' }
6
6
  let(:data_type) { 'int' }
7
7
 
8
- it { expect(column_info.column_name).to eq 'id' }
9
- it { expect(column_info.data_type).to eq 'int' }
8
+ it { expect(column.column_name).to eq 'id' }
9
+ it { expect(column.data_type).to eq 'int' }
10
10
 
11
11
  describe '#bigquery_data_type' do
12
- subject { column_info.bigquery_data_type }
12
+ subject { column.bigquery_data_type }
13
13
 
14
14
  context 'int' do
15
15
  let(:data_type) { 'int' }
@@ -88,7 +88,7 @@ describe Samidare::EmbulkUtility::ColumnInfo do
88
88
  end
89
89
 
90
90
  describe '#converted_value' do
91
- subject { column_info.converted_value }
91
+ subject { column.converted_value }
92
92
 
93
93
  context 'datetime' do
94
94
  let(:column_name) { 'create_at' }
@@ -110,7 +110,7 @@ describe Samidare::EmbulkUtility::ColumnInfo do
110
110
  end
111
111
 
112
112
  describe '#to_json' do
113
- subject { column_info.to_json }
113
+ subject { column.to_json }
114
114
 
115
115
  let(:column_name) { 'id' }
116
116
  let(:data_type) { 'int' }
@@ -0,0 +1,135 @@
1
+ require 'spec_helper'
2
+
3
+ describe Samidare::MySQL::TableConfig do
4
+
5
+ describe '.generate_table_configs' do
6
+ subject { Samidare::MySQL::TableConfig.generate_table_configs('spec/support/table.yml') }
7
+ let(:db01_hoge) { Samidare::MySQL::TableConfig.new({ 'name' => 'hoge', 'daily_snapshot' => true }) }
8
+ let(:db01_simple) { Samidare::MySQL::TableConfig.new({ 'name' => 'simple' }) }
9
+ let(:db02_fuga) { Samidare::MySQL::TableConfig.new({ 'name' => 'fuga' }) }
10
+ let(:db02_with_condition) { Samidare::MySQL::TableConfig.new({ 'name' => 'with_condition', 'condition' => 'created_at < CURRENT_DATE()' }) }
11
+
12
+ it { expect(subject['db01'][0]).to eq db01_hoge }
13
+ it { expect(subject['db01'][1]).to eq db01_simple }
14
+ it { expect(subject['db02'][0]).to eq db02_fuga }
15
+ it { expect(subject['db02'][1]).to eq db02_with_condition }
16
+ end
17
+ end
18
+
19
+ describe Samidare::MySQL::Column do
20
+ let(:column) { Samidare::MySQL::Column.new(column_name, data_type) }
21
+ let(:column_name) { 'id' }
22
+ let(:data_type) { 'int' }
23
+
24
+ it { expect(column.column_name).to eq 'id' }
25
+ it { expect(column.data_type).to eq 'int' }
26
+
27
+ describe '#bigquery_data_type' do
28
+ subject { column.bigquery_data_type }
29
+
30
+ context 'int' do
31
+ let(:data_type) { 'int' }
32
+ it { expect(subject).to eq 'integer' }
33
+ end
34
+
35
+ context 'tinyint' do
36
+ let(:data_type) { 'tinyint' }
37
+ it { expect(subject).to eq 'integer' }
38
+ end
39
+
40
+ context 'smallint' do
41
+ let(:data_type) { 'smallint' }
42
+ it { expect(subject).to eq 'integer' }
43
+ end
44
+
45
+ context 'mediumint' do
46
+ let(:data_type) { 'mediumint' }
47
+ it { expect(subject).to eq 'integer' }
48
+ end
49
+
50
+ context 'bigint' do
51
+ let(:data_type) { 'bigint' }
52
+ it { expect(subject).to eq 'integer' }
53
+ end
54
+
55
+ context 'float' do
56
+ let(:data_type) { 'float' }
57
+ it { expect(subject).to eq 'float' }
58
+ end
59
+
60
+ context 'double' do
61
+ let(:data_type) { 'double' }
62
+ it { expect(subject).to eq 'float' }
63
+ end
64
+
65
+ context 'decimal' do
66
+ let(:data_type) { 'decimal' }
67
+ it { expect(subject).to eq 'float' }
68
+ end
69
+
70
+ context 'char' do
71
+ let(:data_type) { 'char' }
72
+ it { expect(subject).to eq 'string' }
73
+ end
74
+
75
+ context 'varchar' do
76
+ let(:data_type) { 'varchar' }
77
+ it { expect(subject).to eq 'string' }
78
+ end
79
+
80
+ context 'tinytext' do
81
+ let(:data_type) { 'tinytext' }
82
+ it { expect(subject).to eq 'string' }
83
+ end
84
+
85
+ context 'text' do
86
+ let(:data_type) { 'text' }
87
+ it { expect(subject).to eq 'string' }
88
+ end
89
+
90
+ context 'date' do
91
+ let(:data_type) { 'date' }
92
+ it { expect(subject).to eq 'timestamp' }
93
+ end
94
+
95
+ context 'datetime' do
96
+ let(:data_type) { 'datetime' }
97
+ it { expect(subject).to eq 'timestamp' }
98
+ end
99
+
100
+ context 'timestamp' do
101
+ let(:data_type) { 'timestamp' }
102
+ it { expect(subject).to eq 'timestamp' }
103
+ end
104
+ end
105
+
106
+ describe '#converted_value' do
107
+ subject { column.converted_value }
108
+
109
+ context 'datetime' do
110
+ let(:column_name) { 'create_at' }
111
+ let(:data_type) { 'datetime' }
112
+ it { expect(subject).to eq 'UNIX_TIMESTAMP(`create_at`) AS `create_at`' }
113
+ end
114
+
115
+ context 'int' do
116
+ let(:column_name) { 'id' }
117
+ let(:data_type) { 'int' }
118
+ it { expect(subject).to eq '`id`' }
119
+ end
120
+
121
+ context 'varchar' do
122
+ let(:column_name) { 'explanation' }
123
+ let(:data_type) { 'varchar' }
124
+ it { expect(subject).to eq '`explanation`' }
125
+ end
126
+ end
127
+
128
+ describe '#to_json' do
129
+ subject { column.to_json }
130
+
131
+ let(:column_name) { 'id' }
132
+ let(:data_type) { 'int' }
133
+ it { expect(subject).to eq '{"name":"id","type":"integer"}' }
134
+ end
135
+ end
@@ -1,30 +1,7 @@
1
- require 'spec_helper'
2
-
3
- describe Samidare do
4
- it 'has a version number' do
5
- expect(Samidare::VERSION).not_to be nil
6
- end
7
-
8
- describe Samidare::EmbulkClient do
9
- describe '#target_table?' do
10
- subject { Samidare::EmbulkClient.new.send(:target_table?, table, target_tables) }
11
- context 'target_tables is empty' do
12
- let(:table) { 'hoge' }
13
- let(:target_tables) { [] }
14
- it { expect(subject).to be_truthy }
15
- end
16
-
17
- context 'is included' do
18
- let(:table) { 'hoge' }
19
- let(:target_tables) { ['hoge'] }
20
- it { expect(subject).to be_truthy }
21
- end
22
-
23
- context 'is not included' do
24
- let(:table) { 'hoge' }
25
- let(:target_tables) { ['fuga'] }
26
- it { expect(subject).to be_falsy }
27
- end
28
- end
29
- end
30
- end
1
+ require 'spec_helper'
2
+
3
+ describe Samidare do
4
+ it 'has a version number' do
5
+ expect(Samidare::VERSION).not_to be nil
6
+ end
7
+ end
@@ -0,0 +1,13 @@
1
+ db01:
2
+ host: localhost
3
+ username: root
4
+ password:
5
+ database: embulk
6
+ bq_dataset: mysql
7
+
8
+ db02:
9
+ host: localhost
10
+ username: root
11
+ password:
12
+ database: embulk2
13
+ bq_dataset: mysql2
@@ -0,0 +1,11 @@
1
+ db01:
2
+ tables:
3
+ - name: hoge
4
+ daily_snapshot: true
5
+ - name: simple
6
+
7
+ db02:
8
+ tables:
9
+ - name: fuga
10
+ - name: with_condition
11
+ condition: created_at < CURRENT_DATE()
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: samidare
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.11
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryoji Kobori
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-16 00:00:00.000000000 Z
11
+ date: 2015-12-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -179,13 +179,19 @@ files:
179
179
  - Rakefile
180
180
  - lib/samidare.rb
181
181
  - lib/samidare/bigquery_utility.rb
182
+ - lib/samidare/embulk.rb
182
183
  - lib/samidare/embulk_utility.rb
184
+ - lib/samidare/mysql.rb
183
185
  - lib/samidare/version.rb
184
186
  - samidare.gemspec
185
187
  - spec/samidare/bigquery_utility_spec.rb
188
+ - spec/samidare/embulk_spec.rb
186
189
  - spec/samidare/embulk_utility_spec.rb
190
+ - spec/samidare/mysql_spec.rb
187
191
  - spec/samidare_spec.rb
188
192
  - spec/spec_helper.rb
193
+ - spec/support/databe.yml
194
+ - spec/support/table.yml
189
195
  homepage: https://github.com/cobot00/samidare
190
196
  licenses:
191
197
  - MIT
@@ -212,6 +218,10 @@ specification_version: 4
212
218
  summary: Embulk utility for MySQL to BigQuery
213
219
  test_files:
214
220
  - spec/samidare/bigquery_utility_spec.rb
221
+ - spec/samidare/embulk_spec.rb
215
222
  - spec/samidare/embulk_utility_spec.rb
223
+ - spec/samidare/mysql_spec.rb
216
224
  - spec/samidare_spec.rb
217
225
  - spec/spec_helper.rb
226
+ - spec/support/databe.yml
227
+ - spec/support/table.yml