kandata 0.2.0 → 0.3.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/README.md +18 -2
- data/lib/kandata.rb +2 -2
- data/lib/kandata/database.rb +20 -11
- data/lib/kandata/database/connection_info.rb +3 -1
- data/lib/kandata/tsv_file.rb +38 -12
- data/lib/kandata/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9841a7b354143f7fbdd512e7e1c84ee3cfe97622
|
4
|
+
data.tar.gz: 8f4a1bab20ab17cde5580e27ca0376edd6e53d42
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bb5391ce2ee2ac7112ce5320ebf7df616bee2d6baad69636c43342b50840148a465670796816713c7f1304bfc1e53170e6300d344852e75554e3ef5c0d086c2f
|
7
|
+
data.tar.gz: 5b29c796225cc9d6cf73b0fc70c77b5efc305c4c6a93ae2787dfe00d6be119b481b4440abf25148f76751e8496e5cef0a24ca210e55fdb276ce3ad4c991094ed
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Kandata
|
2
2
|
|
3
|
-
[](https://circleci.com/gh/eLicenseSystems/kandata)
|
4
4
|
[](https://badge.fury.io/rb/kandata)
|
5
5
|
|
6
6
|
Kandataは、TSVファイルを自分のローカルのMySQLデータベース内に簡単にロードするためのツールです。
|
@@ -16,6 +16,22 @@ MySQLサーバーがローカルで動作している必要があります。
|
|
16
16
|
|
17
17
|
## 利用方法
|
18
18
|
|
19
|
+
### Rubyスクリプト内から利用する場合
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
require 'kandata'
|
23
|
+
|
24
|
+
# TSVからデータ生成
|
25
|
+
# ローカルのMySQLサーバーのKandataデータベース内にuserテーブルを作成して、TSVでデータを流し込む
|
26
|
+
my_user = Kandata.build_from_tsv('./user.tsv')
|
27
|
+
|
28
|
+
# my_user はActiveRecordをextendしたクラスそのものなので、
|
29
|
+
# Railsのモデルクラスのように使って色々出来る。
|
30
|
+
# ex) my_user.where(last_login: nil).each do |v| v.disactivate end
|
31
|
+
```
|
32
|
+
|
33
|
+
### コマンドラインから実行する場合
|
34
|
+
|
19
35
|
以下のように実行します。
|
20
36
|
|
21
37
|
$ kandata load_tsv TSVファイル名 [--force]
|
@@ -37,7 +53,7 @@ MySQLサーバーがローカルで動作している必要があります。
|
|
37
53
|
- 各カラムへのINDEXの追加には対応していません。必要な場合は自分でSQLで`CREATE INDEX`してください。
|
38
54
|
|
39
55
|
## 今後の予定
|
40
|
-
-
|
56
|
+
- ~作成したテーブルに応じたActiveRecordモデルを自動生成できるようにする。~ **done**
|
41
57
|
- `require`で非RailsなRubyスクリプトで読み込んで使えるように。
|
42
58
|
- 作成したテーブルのバックアップなどの機能を追加する。
|
43
59
|
|
data/lib/kandata.rb
CHANGED
@@ -16,8 +16,8 @@ class Kandata
|
|
16
16
|
end
|
17
17
|
|
18
18
|
# テーブルを作成し、テーブルにデータを読み込み、テーブル名を戻す
|
19
|
-
def self.load_tsv(filename, force_load)
|
19
|
+
def self.load_tsv(filename, force_load, headers = nil)
|
20
20
|
client = Kandata::Database.new
|
21
|
-
client.load_tsv(filename, force_load)
|
21
|
+
client.load_tsv(filename, force_load, headers)
|
22
22
|
end
|
23
23
|
end
|
data/lib/kandata/database.rb
CHANGED
@@ -3,6 +3,7 @@ require 'mysql2'
|
|
3
3
|
|
4
4
|
class Kandata
|
5
5
|
# ActiveRecordを使わないでKandataデータベースにアクセスするためのクラス
|
6
|
+
# ignore :reek:InstanceVariableAssumption:
|
6
7
|
class Database < Mysql2::Client
|
7
8
|
def initialize
|
8
9
|
create_database_if_not_exists
|
@@ -15,8 +16,8 @@ class Kandata
|
|
15
16
|
end
|
16
17
|
|
17
18
|
# ignore :reek:ControlParameter:
|
18
|
-
def load_tsv(filename, force_update)
|
19
|
-
@tsv = Kandata::TsvFile.new(filename)
|
19
|
+
def load_tsv(filename, force_update, headers = nil)
|
20
|
+
@tsv = Kandata::TsvFile.new(filename, headers)
|
20
21
|
|
21
22
|
drop_table if force_update
|
22
23
|
create_table
|
@@ -30,18 +31,17 @@ class Kandata
|
|
30
31
|
# ignore :reek:FeatureEnvy:
|
31
32
|
def create_database_if_not_exists
|
32
33
|
client = Mysql2::Client.new(Kandata::Database::ConnectionInfo.host_and_user)
|
33
|
-
database_name = Kandata::Database::ConnectionInfo.database_name
|
34
34
|
|
35
35
|
begin
|
36
|
-
client.query("SHOW CREATE DATABASE
|
36
|
+
client.query("SHOW CREATE DATABASE `#{database_name}`")
|
37
37
|
rescue Mysql2::Error => error
|
38
38
|
raise error unless error.message == "Unknown database '#{database_name}'"
|
39
|
-
client.query("CREATE DATABASE
|
39
|
+
client.query("CREATE DATABASE `#{database_name}`")
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
43
|
def drop_table
|
44
|
-
query("DROP TABLE IF EXISTS
|
44
|
+
query("DROP TABLE IF EXISTS `#{database_name}`.`#{table_name}`")
|
45
45
|
end
|
46
46
|
|
47
47
|
def create_table
|
@@ -50,21 +50,30 @@ class Kandata
|
|
50
50
|
# 後で追加するため一旦削除
|
51
51
|
columns.delete('id')
|
52
52
|
|
53
|
-
columns_text = columns.map { |column| "#{column}
|
53
|
+
columns_text = columns.map { |column| "#{column} TEXT" }.join(',')
|
54
54
|
columns_text = 'id INTEGER AUTO_INCREMENT NOT NULL PRIMARY KEY,' + columns_text
|
55
55
|
|
56
|
-
query("CREATE TABLE
|
56
|
+
query("CREATE TABLE `#{database_name}`.`#{table_name}` (#{columns_text})")
|
57
57
|
end
|
58
58
|
|
59
59
|
def load_data
|
60
|
-
sql = "LOAD DATA LOCAL INFILE '#{@tsv.filename}' INTO TABLE
|
61
|
-
sql += "(#{@tsv.headers.join(',')})"
|
60
|
+
sql = "LOAD DATA LOCAL INFILE '#{@tsv.filename}' INTO TABLE `#{database_name}`.`#{table_name}` IGNORE 1 LINES "
|
61
|
+
sql += "(#{@tsv.headers.map { |column| "`#{column}`" }.join(',')})"
|
62
62
|
|
63
63
|
query(sql)
|
64
64
|
end
|
65
65
|
|
66
66
|
def full_table_name
|
67
|
-
"#{
|
67
|
+
"#{database_name}.#{table_name}"
|
68
|
+
end
|
69
|
+
|
70
|
+
# ignore :reek:UtilityFunction:
|
71
|
+
def database_name
|
72
|
+
Kandata::Database::ConnectionInfo.database_name
|
73
|
+
end
|
74
|
+
|
75
|
+
def table_name
|
76
|
+
@tsv.table_name if @tsv.present?
|
68
77
|
end
|
69
78
|
end
|
70
79
|
end
|
data/lib/kandata/tsv_file.rb
CHANGED
@@ -1,28 +1,37 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
require 'tempfile'
|
3
|
+
require 'nkf'
|
4
|
+
|
2
5
|
class Kandata
|
3
6
|
# 読み込み用TSVファイル
|
4
7
|
class TsvFile
|
5
|
-
attr_reader :filename, :headers
|
8
|
+
attr_reader :filename, :table_name, :headers
|
9
|
+
|
10
|
+
RESERVED_COLUMNS = ['type'].freeze
|
11
|
+
|
12
|
+
def initialize(filename, custom_headers = nil)
|
13
|
+
@table_name = File.basename(filename).sub('.tsv', '')
|
14
|
+
validate_table_name
|
6
15
|
|
7
|
-
|
8
|
-
@filename = filename
|
9
|
-
|
16
|
+
# TempFileにファイル内容をコピーしてパスを返す
|
17
|
+
@filename = copy_to_tempfile(filename)
|
18
|
+
|
19
|
+
@headers = custom_headers
|
20
|
+
@headers ||= File.open(@filename, 'r').first(&:readline).chomp.split("\t")
|
10
21
|
|
11
|
-
@headers = File.open(@filename, 'r').first(&:readline).chomp.split("\t")
|
12
22
|
validate_headers
|
13
23
|
end
|
14
24
|
|
15
|
-
def
|
16
|
-
raise 'テーブル名に使用できないファイル名です' unless table_name.match?(/^[0-9a-zA-Z$_]+$/)
|
25
|
+
def validate_table_name
|
26
|
+
raise 'テーブル名に使用できないファイル名です' unless @table_name.match?(/^[0-9a-zA-Z$_]+$/)
|
17
27
|
true
|
18
28
|
end
|
19
29
|
|
20
30
|
def validate_headers
|
21
|
-
duplicated_columns = @headers.group_by { |value| value }.reject { |_key, value| value.one? }.keys
|
22
31
|
raise "以下のカラムが複数存在しています #{duplicated_columns}" unless duplicated_columns.empty?
|
23
32
|
|
24
|
-
|
25
|
-
raise "以下のカラム名は使用できません #{
|
33
|
+
raise "以下のカラム名は使用できません #{invalid_columns}" unless invalid_columns.empty?
|
34
|
+
raise "以下のカラム名は使用できません #{RESERVED_COLUMNS}" if include_reserved_name?
|
26
35
|
|
27
36
|
# 現時点では、ミス防止のため、先頭以外にidカラムがあるとエラーとして処理する
|
28
37
|
raise '先頭以外にidカラムがあります' if include_id_column? && @headers[0] != 'id'
|
@@ -30,12 +39,29 @@ class Kandata
|
|
30
39
|
true
|
31
40
|
end
|
32
41
|
|
33
|
-
def
|
34
|
-
|
42
|
+
def duplicated_columns
|
43
|
+
@headers.group_by { |value| value }.reject { |_key, value| value.one? }.keys
|
44
|
+
end
|
45
|
+
|
46
|
+
def invalid_columns
|
47
|
+
@headers.reject { |value| value.match?(/^[0-9a-zA-Z$_]+$/) }
|
48
|
+
end
|
49
|
+
|
50
|
+
def include_reserved_name?
|
51
|
+
RESERVED_COLUMNS.any? { |name| @headers.include?(name) }
|
35
52
|
end
|
36
53
|
|
37
54
|
def include_id_column?
|
38
55
|
@headers.include?('id')
|
39
56
|
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def copy_to_tempfile(filename)
|
61
|
+
Tempfile.open(basename: self.class.name) do |file|
|
62
|
+
file.write(NKF.nkf('-w', File.open(filename, 'r').read))
|
63
|
+
file.path
|
64
|
+
end
|
65
|
+
end
|
40
66
|
end
|
41
67
|
end
|
data/lib/kandata/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kandata
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yuya TAMANO
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-04-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|