naginegi 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,93 @@
1
+ require 'pg'
2
+ require 'json'
3
+ require 'yaml'
4
+ require 'fileutils'
5
+ require 'naginegi/bigquery'
6
+
7
+ module Naginegi
8
+ module PostgreSQL
9
+ class PgClient
10
+ COLUMN_SQL = <<-SQL.freeze
11
+ SELECT column_name, data_type
12
+ FROM INFORMATION_SCHEMA.COLUMNS
13
+ WHERE table_name = $1
14
+ ORDER BY ordinal_position
15
+ SQL
16
+
17
+ def initialize(db_config)
18
+ @db_config = db_config
19
+ end
20
+
21
+ def client
22
+ @client ||= PG::Connection.new(
23
+ host: @db_config['host'],
24
+ user: @db_config['username'],
25
+ password: @db_config['password'],
26
+ dbname: @db_config['database']
27
+ )
28
+ end
29
+
30
+ def generate_bq_schema(table_name)
31
+ infos = columns(table_name)
32
+ BigQuery.generate_schema(infos)
33
+ end
34
+
35
+ def columns(table_name)
36
+ rows = client.exec_params(COLUMN_SQL, [table_name])
37
+ rows.map { |row| Column.new(row['column_name'], row['data_type']) }
38
+ end
39
+ end
40
+
41
+ class Column
42
+ attr_reader :column_name, :data_type
43
+
44
+ TYPE_MAPPINGS = {
45
+ 'smallint' => 'INT64',
46
+ 'integer' => 'INT64',
47
+ 'bigint' => 'INT64',
48
+ 'smallserial' => 'INT64',
49
+ 'serial' => 'INT64',
50
+ 'bigserial' => 'INT64',
51
+ 'decimal' => 'FLOAT64',
52
+ 'numeric' => 'FLOAT64',
53
+ 'real' => 'FLOAT64',
54
+ 'double precision' => 'FLOAT64',
55
+ 'character' => 'STRING',
56
+ 'character varying' => 'STRING',
57
+ 'text' => 'STRING',
58
+ 'date' => 'TIMESTAMP',
59
+ 'timestamp' => 'TIMESTAMP',
60
+ 'timestamp with time zone' => 'TIMESTAMP',
61
+ 'boolean' => 'BOOL'
62
+ }.freeze
63
+
64
+ def initialize(column_name, data_type)
65
+ @column_name = column_name
66
+ @data_type = data_type
67
+ end
68
+
69
+ def bigquery_data_type
70
+ TYPE_MAPPINGS[@data_type] || 'STRING'
71
+ end
72
+
73
+ def converted_value
74
+ if bigquery_data_type == 'TIMESTAMP'
75
+ # time zone translate to UTC
76
+ "EXTRACT(EPOCH FROM #{escaped_column_name}) AS #{escaped_column_name}"
77
+ else
78
+ escaped_column_name
79
+ end
80
+ end
81
+
82
+ def to_json(*a)
83
+ { 'name' => @column_name, 'type' => bigquery_data_type }.to_json(*a)
84
+ end
85
+
86
+ private
87
+
88
+ def escaped_column_name
89
+ "\"#{@column_name}\""
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,3 @@
1
+ module Naginegi
2
+ VERSION = '0.4.1'.freeze
3
+ end
data/lint.sh ADDED
@@ -0,0 +1,54 @@
1
+ #!/bin/bash
2
+
3
+ echo 'CIRCLE_BRANCH: ' ${CIRCLE_BRANCH}
4
+ TARGET_BRANCH=${CIRCLE_BRANCH}
5
+
6
+ # ローカルでの実行用にカレントブランチをセットする
7
+ if [ "$TARGET_BRANCH" = '' ]; then
8
+ TARGET_BRANCH=$(git rev-parse --abbrev-ref HEAD)
9
+ fi
10
+ echo 'TARGET_BRANCH: ' $TARGET_BRANCH
11
+
12
+ echo 'CIRCLE_BASE_BRANCH: ' ${CIRCLE_BASE_BRANCH}
13
+ BASE_BRANCH=${CIRCLE_BASE_BRANCH}
14
+
15
+ # ローカルでの実行時に環境変数をセットしていない時はmasterブランチと比較する
16
+ if [ "$BASE_BRANCH" = '' ]; then
17
+ BASE_BRANCH=origin/master
18
+ fi
19
+ echo 'BASE_BRANCH: ' $BASE_BRANCH
20
+
21
+ files=$(git diff --name-only $TARGET_BRANCH $BASE_BRANCH | grep -E '.rb' | egrep -v 'db/migrate|db/schema.rb|spec/factories')
22
+
23
+ error=false
24
+ for file in ${files}; do
25
+ # u-motion-api から同期されるファイルは確認不要
26
+ if [[ $file == *"app/models"* ]]; then
27
+ if [[ $file != *"app/models/admin"* ]]; then
28
+ continue
29
+ fi
30
+ fi
31
+
32
+ if [[ $file == *"app/serializers"* ]]; then
33
+ if [[ $file != *"app/serializers/admin"* ]]; then
34
+ continue
35
+ fi
36
+ fi
37
+
38
+ if [ -e $file ]; then
39
+ result=$(bundle exec rubocop ${file})
40
+ rubocop_error=$(echo "$result" | grep 'Offenses:')
41
+ if [ "$rubocop_error" != '' ]; then
42
+ error=true
43
+ echo ''
44
+ echo 'ERROR:' $file
45
+ echo "$result"
46
+ fi
47
+ fi
48
+ done
49
+
50
+ if $error; then
51
+ exit 1
52
+ fi
53
+
54
+ exit 0
@@ -0,0 +1,34 @@
1
+ lib = File.expand_path('lib', __dir__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'naginegi/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'naginegi'
7
+ spec.version = Naginegi::VERSION
8
+ spec.authors = ['cobot00']
9
+ spec.email = ['kobori75@gmail.com']
10
+
11
+ spec.summary = %q{Embulk utility for MySQL and PostgreSQL to BigQuery}
12
+ spec.description = %q{Generate Embulk config and BigQuery schema from RDBMS schema}
13
+ spec.homepage = 'https://github.com/cobot00/naginegi'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
17
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ end
19
+ spec.bindir = 'exe'
20
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
+ spec.require_paths = ['lib']
22
+
23
+ spec.add_development_dependency 'bundler', '2.1.4'
24
+ spec.add_development_dependency 'rake', '12.3.3'
25
+ spec.add_development_dependency 'rspec', '3.8.0'
26
+ spec.add_development_dependency 'rubocop', '0.49.1'
27
+ spec.add_development_dependency 'timecop', '0.9.1'
28
+
29
+ spec.add_dependency 'google-cloud-bigquery', '1.18.1'
30
+ spec.add_dependency 'mysql2', '0.5.3'
31
+ spec.add_dependency 'mysql2-cs-bind', '0.0.7'
32
+ spec.add_dependency 'pg', '1.2.2'
33
+ spec.add_dependency 'unindent', '1.0'
34
+ end
metadata ADDED
@@ -0,0 +1,203 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: naginegi
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.4.1
5
+ platform: ruby
6
+ authors:
7
+ - cobot00
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2020-02-01 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: 2.1.4
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 2.1.4
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '='
32
+ - !ruby/object:Gem::Version
33
+ version: 12.3.3
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '='
39
+ - !ruby/object:Gem::Version
40
+ version: 12.3.3
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '='
46
+ - !ruby/object:Gem::Version
47
+ version: 3.8.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '='
53
+ - !ruby/object:Gem::Version
54
+ version: 3.8.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: rubocop
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '='
60
+ - !ruby/object:Gem::Version
61
+ version: 0.49.1
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '='
67
+ - !ruby/object:Gem::Version
68
+ version: 0.49.1
69
+ - !ruby/object:Gem::Dependency
70
+ name: timecop
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '='
74
+ - !ruby/object:Gem::Version
75
+ version: 0.9.1
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '='
81
+ - !ruby/object:Gem::Version
82
+ version: 0.9.1
83
+ - !ruby/object:Gem::Dependency
84
+ name: google-cloud-bigquery
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '='
88
+ - !ruby/object:Gem::Version
89
+ version: 1.18.1
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '='
95
+ - !ruby/object:Gem::Version
96
+ version: 1.18.1
97
+ - !ruby/object:Gem::Dependency
98
+ name: mysql2
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '='
102
+ - !ruby/object:Gem::Version
103
+ version: 0.5.3
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '='
109
+ - !ruby/object:Gem::Version
110
+ version: 0.5.3
111
+ - !ruby/object:Gem::Dependency
112
+ name: mysql2-cs-bind
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - '='
116
+ - !ruby/object:Gem::Version
117
+ version: 0.0.7
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - '='
123
+ - !ruby/object:Gem::Version
124
+ version: 0.0.7
125
+ - !ruby/object:Gem::Dependency
126
+ name: pg
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - '='
130
+ - !ruby/object:Gem::Version
131
+ version: 1.2.2
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - '='
137
+ - !ruby/object:Gem::Version
138
+ version: 1.2.2
139
+ - !ruby/object:Gem::Dependency
140
+ name: unindent
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - '='
144
+ - !ruby/object:Gem::Version
145
+ version: '1.0'
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - '='
151
+ - !ruby/object:Gem::Version
152
+ version: '1.0'
153
+ description: Generate Embulk config and BigQuery schema from RDBMS schema
154
+ email:
155
+ - kobori75@gmail.com
156
+ executables: []
157
+ extensions: []
158
+ extra_rdoc_files: []
159
+ files:
160
+ - ".circleci/config.yml"
161
+ - ".gitignore"
162
+ - ".rubocop.yml"
163
+ - ".travis.yml"
164
+ - Gemfile
165
+ - Gemfile.lock
166
+ - LICENSE
167
+ - README.md
168
+ - Rakefile
169
+ - bin/console
170
+ - bin/setup
171
+ - lib/naginegi.rb
172
+ - lib/naginegi/bigquery.rb
173
+ - lib/naginegi/embulk.rb
174
+ - lib/naginegi/embulk_config.rb
175
+ - lib/naginegi/mysql.rb
176
+ - lib/naginegi/postgresql.rb
177
+ - lib/naginegi/version.rb
178
+ - lint.sh
179
+ - naginegi.gemspec
180
+ homepage: https://github.com/cobot00/naginegi
181
+ licenses:
182
+ - MIT
183
+ metadata: {}
184
+ post_install_message:
185
+ rdoc_options: []
186
+ require_paths:
187
+ - lib
188
+ required_ruby_version: !ruby/object:Gem::Requirement
189
+ requirements:
190
+ - - ">="
191
+ - !ruby/object:Gem::Version
192
+ version: '0'
193
+ required_rubygems_version: !ruby/object:Gem::Requirement
194
+ requirements:
195
+ - - ">="
196
+ - !ruby/object:Gem::Version
197
+ version: '0'
198
+ requirements: []
199
+ rubygems_version: 3.0.6
200
+ signing_key:
201
+ specification_version: 4
202
+ summary: Embulk utility for MySQL and PostgreSQL to BigQuery
203
+ test_files: []