flydata 0.6.4 → 0.6.5
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/Gemfile +1 -0
- data/Gemfile.lock +2 -0
- data/VERSION +1 -1
- data/flydata-core/lib/flydata-core/table_def/base.rb +31 -0
- data/flydata-core/lib/flydata-core/table_def/mysql_table_def.rb +9 -30
- data/flydata-core/lib/flydata-core/table_def/postgresql_table_def.rb +111 -0
- data/flydata-core/lib/flydata-core/table_def/redshift_table_def.rb +4 -1
- data/flydata-core/spec/table_def/postgresql_table_def_spec.rb +348 -0
- data/flydata-core/spec/table_def/redshift_table_def_spec.rb +25 -0
- data/flydata.gemspec +0 -0
- data/lib/flydata.rb +0 -7
- data/lib/flydata/command/base.rb +3 -2
- data/lib/flydata/fluent-plugins/flydata_plugin_ext/base.rb +5 -0
- data/lib/flydata/fluent-plugins/flydata_plugin_ext/flush_support.rb +52 -0
- data/lib/flydata/fluent-plugins/flydata_plugin_ext/flydata_sync.rb +55 -0
- data/lib/flydata/fluent-plugins/{idle_event_detector.rb → flydata_plugin_ext/idle_event_detector.rb} +0 -0
- data/lib/flydata/fluent-plugins/{preference.rb → flydata_plugin_ext/preference.rb} +2 -14
- data/lib/flydata/fluent-plugins/flydata_plugin_ext/transaction_support.rb +58 -0
- data/lib/flydata/fluent-plugins/in_mysql_binlog_flydata.rb +55 -135
- data/lib/flydata/fluent-plugins/mysql/dml_record_handler.rb +9 -4
- data/lib/flydata/helper/server.rb +7 -0
- data/lib/flydata/preference/data_entry_preference.rb +5 -13
- data/lib/flydata/source.rb +1 -1
- data/lib/flydata/source/data_entry.rb +29 -0
- data/lib/flydata/source/sync.rb +19 -0
- data/lib/flydata/source/sync_generate_table_ddl.rb +47 -7
- data/lib/flydata/source_mysql/data_entry.rb +22 -0
- data/lib/flydata/source_mysql/parser/dump_parser.rb +1 -1
- data/lib/flydata/source_mysql/parser/mysql_alter_table.treetop +8 -3
- data/lib/flydata/source_mysql/sync.rb +1 -8
- data/lib/flydata/source_mysql/sync_generate_table_ddl.rb +11 -16
- data/lib/flydata/source_postgresql/data_entry.rb +21 -0
- data/lib/flydata/source_postgresql/sync.rb +29 -0
- data/lib/flydata/source_postgresql/sync_generate_table_ddl.rb +126 -0
- data/spec/flydata/fluent-plugins/{idle_event_detector_spec.rb → flydata_plugin_ext/idle_event_detector_spec.rb} +1 -1
- data/spec/flydata/fluent-plugins/in_mysql_binlog_flydata_spec.rb +10 -0
- data/spec/flydata/source_mysql/parser/alter_table_parser_spec.rb +119 -0
- data/spec/flydata/source_mysql/parser/dump_parser_spec.rb +32 -1
- data/spec/flydata/source_mysql/sync_generate_table_ddl_spec.rb +4 -4
- metadata +31 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 614092c4a27b51744d8f8fdbd521e95205455eac
|
4
|
+
data.tar.gz: 3e6d10c8acd5331700c312c1982a6a9acdba3c66
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0370a93f87eedacf8b56210c15363be7f040980b73eb938cf077953a16d0da942d522881601e21ded8a89a1376c480263483a61d4b0932cd41b70739c457f964
|
7
|
+
data.tar.gz: d870e1abfe9491ad135b1b8ee4e45a293b8a312db2823b7a1cc73fd7d337d19a47e68935c2b6fa606a1f0b2a95af87e7c0ee350170192638b109e75acf567647
|
data/Gemfile
CHANGED
@@ -9,6 +9,7 @@ gem "highline", '~> 1.6', '>= 1.6.19'
|
|
9
9
|
gem "fluentd", "0.10.46"
|
10
10
|
gem "fluent-plugin-mysql-binlog", '~> 0.0', '>= 0.0.2'
|
11
11
|
gem "mysql2", '~> 0.3', '>= 0.3.17'
|
12
|
+
gem "pg", '~> 0.18.4'
|
12
13
|
gem "slop", '~> 3.4', '>= 3.4.6'
|
13
14
|
gem "treetop", '~> 1.5', '>= 1.5.3'
|
14
15
|
gem "sys-filesystem", '~> 1.1', '>= 1.1.3'
|
data/Gemfile.lock
CHANGED
@@ -79,6 +79,7 @@ GEM
|
|
79
79
|
multi_json (~> 1.3)
|
80
80
|
multi_xml (~> 0.5)
|
81
81
|
rack (~> 1.2)
|
82
|
+
pg (0.18.4)
|
82
83
|
polyglot (0.3.5)
|
83
84
|
protected_attributes (1.0.8)
|
84
85
|
activemodel (>= 4.0.1, < 5.0)
|
@@ -139,6 +140,7 @@ DEPENDENCIES
|
|
139
140
|
json (~> 1.8, >= 1.8.0)
|
140
141
|
kodama (~> 0.1, >= 0.1.8)
|
141
142
|
mysql2 (~> 0.3, >= 0.3.17)
|
143
|
+
pg (~> 0.18.4)
|
142
144
|
protected_attributes (~> 1.0, >= 1.0.8)
|
143
145
|
pry
|
144
146
|
rake-compiler (~> 0.9, >= 0.9.5)
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.6.
|
1
|
+
0.6.5
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module FlydataCore
|
2
|
+
module TableDef
|
3
|
+
|
4
|
+
class Base
|
5
|
+
def initialize(table_def, table_name, columns, column_def, default_charset,
|
6
|
+
default_source_charset, comment)
|
7
|
+
@table_def = table_def
|
8
|
+
@table_name = table_name
|
9
|
+
@columns = columns
|
10
|
+
@column_def = column_def
|
11
|
+
@default_charset = default_charset
|
12
|
+
@default_source_charset = default_source_charset
|
13
|
+
@comment = comment
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_reader :columns, :column_def, :table_name, :default_source_charset
|
17
|
+
|
18
|
+
def to_flydata_tabledef
|
19
|
+
tabledef = { table_name: @table_name,
|
20
|
+
columns: @columns,
|
21
|
+
}
|
22
|
+
tabledef[:default_charset] = @default_charset if @default_charset
|
23
|
+
tabledef[:comment] = @comment if @comment
|
24
|
+
tabledef[:src_ddl] = @table_def
|
25
|
+
|
26
|
+
tabledef
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
@@ -1,14 +1,16 @@
|
|
1
|
+
require 'flydata-core/table_def/base'
|
2
|
+
|
1
3
|
module FlydataCore
|
2
4
|
module TableDef
|
3
5
|
|
4
|
-
class MysqlTableDef
|
6
|
+
class MysqlTableDef < Base
|
5
7
|
# Check and set the varchar(char) size which is converted from
|
6
8
|
# length to byte size.
|
7
9
|
# On Mysql the record size of varchar(char) is a length of characters.
|
8
10
|
# ex) varchar(6) on mysql -> varchar(18) on flydata
|
9
11
|
PROC_override_varchar = ->(type, mysql_type, flydata_type) do
|
10
12
|
return type unless %w(char varchar).include?(mysql_type)
|
11
|
-
if type =~ /\((\d
|
13
|
+
if type =~ /\((\s*\d+\s*)\)/
|
12
14
|
# expect 3 byte UTF-8 character
|
13
15
|
"#{flydata_type}(#{$1.to_i * 3})"
|
14
16
|
else
|
@@ -18,7 +20,7 @@ class MysqlTableDef
|
|
18
20
|
|
19
21
|
PROC_override_varbinary = ->(type, mysql_type, flydata_type) do
|
20
22
|
return type unless %w(binary varbinary).include?(mysql_type)
|
21
|
-
if type =~ /\((\d+)\)/
|
23
|
+
if type =~ /\((\s*\d+\s*)\)/ ###DEBUG/\((\d+)\)/
|
22
24
|
# expect 2 bytes for each original byte + 2 bytes for the prefix
|
23
25
|
# ex) 4E5DFF => "0x4e5dff"
|
24
26
|
"#{flydata_type}(#{$1.to_i * 2 + 2})"
|
@@ -87,24 +89,13 @@ class MysqlTableDef
|
|
87
89
|
params ? self.new(*params) : nil
|
88
90
|
end
|
89
91
|
|
90
|
-
def initialize(table_def, table_name, columns, column_def, default_charset,
|
91
|
-
default_charset_mysql, comment)
|
92
|
-
@table_def = table_def
|
93
|
-
@table_name = table_name
|
94
|
-
@columns = columns
|
95
|
-
@column_def = column_def
|
96
|
-
@default_charset = default_charset
|
97
|
-
@default_charset_mysql = default_charset_mysql
|
98
|
-
@comment = comment
|
99
|
-
end
|
100
|
-
|
101
92
|
def self._create(io, options)
|
102
93
|
table_def = ''
|
103
94
|
table_name = nil
|
104
95
|
columns = []
|
105
96
|
column_def = {}
|
106
97
|
default_charset = nil
|
107
|
-
|
98
|
+
default_source_charset = nil
|
108
99
|
comment = nil
|
109
100
|
|
110
101
|
position = :before_create_table
|
@@ -135,8 +126,8 @@ class MysqlTableDef
|
|
135
126
|
#) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='test table';
|
136
127
|
elsif stripped_line.start_with?(')')
|
137
128
|
if line =~ /DEFAULT CHARSET\s*=\s*([a-z0-9]+)/
|
138
|
-
|
139
|
-
default_charset = flydata_charset(
|
129
|
+
default_source_charset = $1
|
130
|
+
default_charset = flydata_charset(default_source_charset)
|
140
131
|
end
|
141
132
|
comment = $1 if /COMMENT='((?:\\'|[^'])*)'/.match(line)
|
142
133
|
position = :after_create_table
|
@@ -157,21 +148,9 @@ class MysqlTableDef
|
|
157
148
|
break
|
158
149
|
end
|
159
150
|
end
|
160
|
-
position == :after_create_table ? [table_def, table_name, columns, column_def, default_charset,
|
151
|
+
position == :after_create_table ? [table_def, table_name, columns, column_def, default_charset, default_source_charset, comment] : nil
|
161
152
|
end
|
162
|
-
attr_reader :columns, :column_def, :table_name, :default_charset_mysql
|
163
153
|
|
164
|
-
def to_flydata_tabledef
|
165
|
-
tabledef = { table_name: @table_name,
|
166
|
-
columns: @columns,
|
167
|
-
}
|
168
|
-
tabledef[:default_charset] = @default_charset if @default_charset
|
169
|
-
tabledef[:comment] = @comment if @comment
|
170
|
-
tabledef[:src_ddl] = @table_def
|
171
|
-
|
172
|
-
tabledef
|
173
|
-
end
|
174
|
-
|
175
154
|
# Replaces a MySQL string with an empty string ('')
|
176
155
|
def self.strip_string(line)
|
177
156
|
line.gsub(/'(\\'|''|[^'])*'/, "''")
|
@@ -0,0 +1,111 @@
|
|
1
|
+
require 'flydata-core/table_def/base'
|
2
|
+
|
3
|
+
module FlydataCore
|
4
|
+
module TableDef
|
5
|
+
|
6
|
+
class PostgresqlTableDef < Base
|
7
|
+
|
8
|
+
VALUE_CONVERTERS = {}
|
9
|
+
|
10
|
+
TYPE_MAP_P2F = {
|
11
|
+
'bigint' => {type: 'int8'},
|
12
|
+
'character varying' => {type: 'varchar',
|
13
|
+
width_attrs:["character_octet_length"]}, # TODO check def_width
|
14
|
+
'integer' => {type: 'int4'},
|
15
|
+
'timestamp with time zone' => {type: 'datetime'}, # TODO may need override?
|
16
|
+
'timestamp without time zone' => {type: 'datetime'}, # TODO may need override?
|
17
|
+
'bytea' => {type: 'varbinary'}, # TODO need value conversion
|
18
|
+
'numeric' => {type: 'numeric',
|
19
|
+
width_attrs:["numeric_precision", "numeric_scale"],
|
20
|
+
def_width:[nil, 0],
|
21
|
+
},
|
22
|
+
# TODO add more types
|
23
|
+
}
|
24
|
+
|
25
|
+
def self.convert_to_flydata_type(information_schema_columns)
|
26
|
+
pg_type = information_schema_columns["data_type"]
|
27
|
+
unless TYPE_MAP_P2F.has_key?(pg_type)
|
28
|
+
raise "Unknown PostgreSQL type or internal error. type:#{pg_type}"
|
29
|
+
end
|
30
|
+
type_hash = TYPE_MAP_P2F[pg_type]
|
31
|
+
flydata_type = type_hash[:type]
|
32
|
+
ret_type = flydata_type
|
33
|
+
|
34
|
+
width_values = get_width_values(information_schema_columns, type_hash)
|
35
|
+
if width_values
|
36
|
+
ret_type += "(#{width_values.join(",")})"
|
37
|
+
end
|
38
|
+
|
39
|
+
if type_hash[:override]
|
40
|
+
ret_type = type_hash[:override].call(ret_type, pg_type, flydata_type)
|
41
|
+
end
|
42
|
+
ret_type
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.create(information_schema_columns, options)
|
46
|
+
params = _create(information_schema_columns, options)
|
47
|
+
params ? self.new(*params) : nil
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def self.get_width_values(information_schema_columns, type_hash)
|
53
|
+
values = []
|
54
|
+
if type_hash.has_key?(:width_attrs)
|
55
|
+
values = type_hash[:width_attrs].collect{|attr| information_schema_columns[attr] }
|
56
|
+
end
|
57
|
+
|
58
|
+
if type_hash.has_key?(:def_width)
|
59
|
+
if values.nil? || values.size != type_hash[:def_width].size
|
60
|
+
raise "The number of the default values must match the number of width attributes def_width:#{type_hash[:def_width].inspect} width_attrs:#{type_hash[:width_attrs].inspect}"
|
61
|
+
end
|
62
|
+
values = values.each_with_index.collect {|v, i| v ? v : type_hash[:def_width][i]}
|
63
|
+
end
|
64
|
+
values.pop until values.empty? || values.last # remove trailing nil
|
65
|
+
if values.any?{|v| v.nil?}
|
66
|
+
raise "nil value is not allowed"
|
67
|
+
end
|
68
|
+
values.empty? ? nil : values
|
69
|
+
end
|
70
|
+
|
71
|
+
def self._create(information_schema_columns, options)
|
72
|
+
table_def = information_schema_columns.inspect
|
73
|
+
table_name = nil
|
74
|
+
columns = []
|
75
|
+
column_def = {}
|
76
|
+
# SourcePostgresql uses UTF8 client encoding no matter what the server
|
77
|
+
# encoding is.
|
78
|
+
default_charset = 'UTF_8'
|
79
|
+
default_charset_postgresql = 'UTF8'
|
80
|
+
comment = nil
|
81
|
+
|
82
|
+
information_schema_columns.each do |iscol|
|
83
|
+
column = parse_one_column_def(iscol)
|
84
|
+
if table_name
|
85
|
+
unless table_name == column[:table]
|
86
|
+
raise "Table name must match through all columns. Got `#{table_name}` and `#{column[:table]}`"
|
87
|
+
end
|
88
|
+
else
|
89
|
+
table_name = column[:table]
|
90
|
+
end
|
91
|
+
columns << column
|
92
|
+
coldef = iscol.inspect
|
93
|
+
column_def[column[:column]] = coldef
|
94
|
+
end
|
95
|
+
[table_def, table_name, columns, column_def, default_charset, default_charset_postgresql, comment]
|
96
|
+
end
|
97
|
+
|
98
|
+
def self.parse_one_column_def(information_schema_column)
|
99
|
+
column = {}
|
100
|
+
column[:table] = information_schema_column["table_name"]
|
101
|
+
column[:column] = information_schema_column["column_name"]
|
102
|
+
column[:type] = convert_to_flydata_type(information_schema_column)
|
103
|
+
column[:not_null] = true if information_schema_column["is_nullable"] == "NO"
|
104
|
+
column[:primary_key] = true if information_schema_column["is_primary"]
|
105
|
+
column[:default] = information_schema_column["column_default"] # TODO nill handling
|
106
|
+
column
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
end
|
@@ -229,7 +229,7 @@ EOS
|
|
229
229
|
|
230
230
|
if (column.has_key?(:default))
|
231
231
|
val = replace_default_value(type, type_info[:type], column[:default])
|
232
|
-
line += " DEFAULT #{val}"
|
232
|
+
line += " DEFAULT #{val}" if val
|
233
233
|
elsif not_null && opt[:for] == :alter_table
|
234
234
|
# Redshift doesn't allow adding a not null column without default value
|
235
235
|
# Add a defalt value
|
@@ -275,6 +275,9 @@ EOS
|
|
275
275
|
default_value.oct
|
276
276
|
elsif /^'.*'$/.match(default_value)
|
277
277
|
default_value
|
278
|
+
elsif /\s*nextval\(/.match(default_value)
|
279
|
+
# Redshift does not support nextval() function. Set no default.
|
280
|
+
nil
|
278
281
|
else
|
279
282
|
"'#{default_value}'"
|
280
283
|
end
|
@@ -0,0 +1,348 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'flydata-core/table_def/postgresql_table_def'
|
3
|
+
|
4
|
+
module FlydataCore
|
5
|
+
module TableDef
|
6
|
+
|
7
|
+
describe PostgresqlTableDef do
|
8
|
+
let(:subject_object) {
|
9
|
+
described_class.new(table_def, table_name, columns, column_def,
|
10
|
+
default_charset, default_charset_postgresql, comment)
|
11
|
+
}
|
12
|
+
|
13
|
+
let(:table_def) { double('table_def') }
|
14
|
+
let(:table_name) { double('table_name') }
|
15
|
+
let(:columns) { double('columns') }
|
16
|
+
let(:column_def) { double('column_def') }
|
17
|
+
let(:default_charset) { double('default_charset') }
|
18
|
+
let(:default_charset_postgresql) { double('default_charset_postgresql') }
|
19
|
+
let(:comment) { double('comment') }
|
20
|
+
|
21
|
+
let(:information_schema_columns) { {} }
|
22
|
+
|
23
|
+
describe '.convert_to_flydata_type' do
|
24
|
+
subject { described_class.convert_to_flydata_type(information_schema_columns) }
|
25
|
+
|
26
|
+
before do
|
27
|
+
information_schema_columns["data_type"] = data_type
|
28
|
+
end
|
29
|
+
|
30
|
+
let(:type_hash) { double('type_hash') }
|
31
|
+
let(:numeric_precision) { nil }
|
32
|
+
let(:numeric_scale) { nil }
|
33
|
+
let(:width_values) do
|
34
|
+
a = [ numeric_precision, numeric_scale ]
|
35
|
+
a.pop until a.empty? || a.last
|
36
|
+
a.empty? ? nil : a
|
37
|
+
end
|
38
|
+
before do
|
39
|
+
allow(described_class).to receive(:get_width_values).
|
40
|
+
with(information_schema_columns, type_hash).
|
41
|
+
and_return(width_values)
|
42
|
+
end
|
43
|
+
|
44
|
+
context "with data type numeric" do
|
45
|
+
let(:data_type) { "numeric" }
|
46
|
+
|
47
|
+
before do
|
48
|
+
information_schema_columns["numeric_precision"] = numeric_precision
|
49
|
+
information_schema_columns["numeric_scale"] = numeric_scale
|
50
|
+
end
|
51
|
+
|
52
|
+
let(:type_hash) { PostgresqlTableDef::TYPE_MAP_P2F[data_type] }
|
53
|
+
|
54
|
+
context "with precision nil" do
|
55
|
+
let(:numeric_precision) { nil }
|
56
|
+
context "with scale nil" do
|
57
|
+
let(:numeric_scale) { nil }
|
58
|
+
it { is_expected.to eq "numeric" }
|
59
|
+
end
|
60
|
+
context "with scale 2" do
|
61
|
+
let(:numeric_scale) { 2 }
|
62
|
+
it do
|
63
|
+
expect(described_class).to receive(:get_width_values).
|
64
|
+
with(information_schema_columns, type_hash).and_raise("test")
|
65
|
+
|
66
|
+
expect{subject}.to raise_error("test")
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
context "with precision 23" do
|
71
|
+
let(:numeric_precision) { 23 }
|
72
|
+
context "with scale nil" do
|
73
|
+
let(:numeric_scale) { nil }
|
74
|
+
it { is_expected.to eq "numeric(23)" }
|
75
|
+
end
|
76
|
+
context "with scale 2" do
|
77
|
+
let(:numeric_scale) { 2 }
|
78
|
+
it { is_expected.to eq "numeric(23,2)" }
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
# TODO Add data type specific specs here
|
83
|
+
context "with unknown data type" do
|
84
|
+
let(:data_type) { "duck" }
|
85
|
+
it { expect{subject}.to raise_error /Unknown PostgreSQL type/ }
|
86
|
+
end
|
87
|
+
context "with no data type" do
|
88
|
+
let(:data_type) { nil }
|
89
|
+
it { expect{subject}.to raise_error /Unknown PostgreSQL type/ }
|
90
|
+
end
|
91
|
+
context "with test data type" do
|
92
|
+
let(:data_type) { test_data_type }
|
93
|
+
|
94
|
+
before do
|
95
|
+
allow(PostgresqlTableDef::TYPE_MAP_P2F).to receive(:has_key?).
|
96
|
+
with(test_data_type).and_return true
|
97
|
+
allow(PostgresqlTableDef::TYPE_MAP_P2F).to receive(:[]).
|
98
|
+
with(test_data_type).and_return test_type_hash
|
99
|
+
end
|
100
|
+
let(:test_data_type) { double('test_data_type') }
|
101
|
+
|
102
|
+
let(:type_hash) { test_type_hash }
|
103
|
+
let(:test_type_hash) { {type: test_fd_type} }
|
104
|
+
let(:test_fd_type) { "testfdtype" }
|
105
|
+
|
106
|
+
let(:override_proc) { double('override_proc') }
|
107
|
+
let(:overriden_type) { double('overriden_type') }
|
108
|
+
|
109
|
+
context "no width values" do
|
110
|
+
let(:width_values) { nil }
|
111
|
+
|
112
|
+
it { is_expected.to eq test_fd_type }
|
113
|
+
end
|
114
|
+
context "single width value" do
|
115
|
+
let(:width_values) { [10] }
|
116
|
+
|
117
|
+
it { is_expected.to eq "#{test_fd_type}(10)" }
|
118
|
+
end
|
119
|
+
context "two width values" do
|
120
|
+
let(:width_values) { [10,2] }
|
121
|
+
|
122
|
+
it { is_expected.to eq "#{test_fd_type}(10,2)"}
|
123
|
+
end
|
124
|
+
context "with override proc" do
|
125
|
+
before do
|
126
|
+
test_type_hash[:override] = override_proc
|
127
|
+
end
|
128
|
+
it 'calls the override proc of the type and return its result' do
|
129
|
+
expect(override_proc).to receive(:call).
|
130
|
+
with(test_fd_type, test_data_type, test_fd_type).
|
131
|
+
and_return(overriden_type)
|
132
|
+
|
133
|
+
is_expected.to eq overriden_type
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
describe '.get_width_values(information_schema_columns, type_hash)' do
|
140
|
+
subject { described_class.send(:get_width_values,
|
141
|
+
information_schema_columns, type_hash) }
|
142
|
+
|
143
|
+
let(:type_hash) { {} }
|
144
|
+
|
145
|
+
context 'with no width attr' do
|
146
|
+
before do
|
147
|
+
type_hash.delete(:width_attrs)
|
148
|
+
end
|
149
|
+
context 'without default' do
|
150
|
+
before do
|
151
|
+
type_hash.delete(:def_width)
|
152
|
+
end
|
153
|
+
|
154
|
+
it { is_expected.to be_nil }
|
155
|
+
end
|
156
|
+
context 'with default' do
|
157
|
+
before do
|
158
|
+
type_hash[:def_width] = [10]
|
159
|
+
end
|
160
|
+
|
161
|
+
it { expect{ subject }.to raise_error }
|
162
|
+
end
|
163
|
+
end
|
164
|
+
context 'with a single width attr' do
|
165
|
+
before do
|
166
|
+
type_hash[:width_attrs] = ["char_octet_length"]
|
167
|
+
end
|
168
|
+
context 'without default' do
|
169
|
+
before do
|
170
|
+
type_hash.delete(:def_width)
|
171
|
+
end
|
172
|
+
context 'when attr value exists' do
|
173
|
+
before do
|
174
|
+
information_schema_columns["char_octet_length"] = 1024
|
175
|
+
end
|
176
|
+
|
177
|
+
it { is_expected.to eq [ 1024 ] }
|
178
|
+
end
|
179
|
+
context 'when attr value does not exist' do
|
180
|
+
before do
|
181
|
+
information_schema_columns.delete("char_octet_length")
|
182
|
+
end
|
183
|
+
|
184
|
+
it { is_expected.to be_nil }
|
185
|
+
end
|
186
|
+
end
|
187
|
+
context 'with default' do
|
188
|
+
before do
|
189
|
+
type_hash[:def_width] = [10]
|
190
|
+
end
|
191
|
+
context 'when attr value exists' do
|
192
|
+
before do
|
193
|
+
information_schema_columns["char_octet_length"] = 1024
|
194
|
+
end
|
195
|
+
|
196
|
+
it { is_expected.to eq [1024] }
|
197
|
+
end
|
198
|
+
context 'when attr value does not exist' do
|
199
|
+
before do
|
200
|
+
information_schema_columns.delete("char_octet_length")
|
201
|
+
end
|
202
|
+
|
203
|
+
it { is_expected.to eq [10] }
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
context 'with two width attrs' do
|
208
|
+
before do
|
209
|
+
type_hash[:width_attrs] = ["precision", "scale"]
|
210
|
+
end
|
211
|
+
context 'without default' do
|
212
|
+
before do
|
213
|
+
type_hash.delete(:def_width)
|
214
|
+
end
|
215
|
+
context 'when the 1st attr value exists' do
|
216
|
+
before do
|
217
|
+
information_schema_columns["precision"] = 23
|
218
|
+
end
|
219
|
+
context 'when the 2nd attr value exists' do
|
220
|
+
before do
|
221
|
+
information_schema_columns["scale"] = 2
|
222
|
+
end
|
223
|
+
|
224
|
+
it { is_expected.to eq [23, 2] }
|
225
|
+
end
|
226
|
+
context 'when the 2nd attr value does not exist' do
|
227
|
+
before do
|
228
|
+
information_schema_columns.delete("scale")
|
229
|
+
end
|
230
|
+
|
231
|
+
it 'omits trailing nils' do
|
232
|
+
is_expected.to eq [23]
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
236
|
+
context 'when the 1st attr value does not exist' do
|
237
|
+
before do
|
238
|
+
information_schema_columns.delete("precision")
|
239
|
+
end
|
240
|
+
context 'when the 2nd attr value exists' do
|
241
|
+
before do
|
242
|
+
information_schema_columns["scale"] = 2
|
243
|
+
end
|
244
|
+
|
245
|
+
it { expect{subject}.to raise_error }
|
246
|
+
end
|
247
|
+
context 'when the 2nd attr value does not exist' do
|
248
|
+
before do
|
249
|
+
information_schema_columns.delete("scale")
|
250
|
+
end
|
251
|
+
|
252
|
+
it { is_expected.to be_nil }
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
256
|
+
context 'with default' do
|
257
|
+
before do
|
258
|
+
type_hash[:def_width] = [10, 0]
|
259
|
+
end
|
260
|
+
context 'when the 1st attr value exists' do
|
261
|
+
before do
|
262
|
+
information_schema_columns["precision"] = 23
|
263
|
+
end
|
264
|
+
context 'when the 2nd attr value exists' do
|
265
|
+
before do
|
266
|
+
information_schema_columns["scale"] = 2
|
267
|
+
end
|
268
|
+
|
269
|
+
it { is_expected.to eq [23, 2] }
|
270
|
+
end
|
271
|
+
context 'when the 2nd attr value does not exist' do
|
272
|
+
before do
|
273
|
+
information_schema_columns.delete("scale")
|
274
|
+
end
|
275
|
+
|
276
|
+
it { is_expected.to eq [23, 0] }
|
277
|
+
end
|
278
|
+
end
|
279
|
+
context 'when the 1st attr value does not exist' do
|
280
|
+
before do
|
281
|
+
information_schema_columns.delete("precision")
|
282
|
+
end
|
283
|
+
context 'when the 2nd attr value exists' do
|
284
|
+
before do
|
285
|
+
information_schema_columns["scale"] = 2
|
286
|
+
end
|
287
|
+
|
288
|
+
it { is_expected.to eq [10, 2] }
|
289
|
+
end
|
290
|
+
context 'when the 2nd attr value does not exist' do
|
291
|
+
before do
|
292
|
+
information_schema_columns.delete("scale")
|
293
|
+
end
|
294
|
+
|
295
|
+
it { is_expected.to eq [10, 0] }
|
296
|
+
end
|
297
|
+
end
|
298
|
+
end
|
299
|
+
context 'when the number of default values does not match
|
300
|
+
the attr number' do
|
301
|
+
before do
|
302
|
+
type_hash[:def_width] = [10]
|
303
|
+
end
|
304
|
+
context 'when the 1st attr value exists' do
|
305
|
+
before do
|
306
|
+
information_schema_columns["precision"] = 23
|
307
|
+
end
|
308
|
+
context 'when the 2nd attr value exists' do
|
309
|
+
before do
|
310
|
+
information_schema_columns["scale"] = 2
|
311
|
+
end
|
312
|
+
|
313
|
+
it { expect{subject}.to raise_error }
|
314
|
+
end
|
315
|
+
context 'when the 2nd attr value does not exist' do
|
316
|
+
before do
|
317
|
+
information_schema_columns.delete("scale")
|
318
|
+
end
|
319
|
+
|
320
|
+
it { expect{subject}.to raise_error }
|
321
|
+
end
|
322
|
+
end
|
323
|
+
context 'when the 1st attr value does not exist' do
|
324
|
+
before do
|
325
|
+
information_schema_columns.delete("precision")
|
326
|
+
end
|
327
|
+
context 'when the 2nd attr value exists' do
|
328
|
+
before do
|
329
|
+
information_schema_columns["scale"] = 2
|
330
|
+
end
|
331
|
+
|
332
|
+
it { expect{subject}.to raise_error }
|
333
|
+
end
|
334
|
+
context 'when the 2nd attr value does not exist' do
|
335
|
+
before do
|
336
|
+
information_schema_columns.delete("scale")
|
337
|
+
end
|
338
|
+
|
339
|
+
it { expect{subject}.to raise_error }
|
340
|
+
end
|
341
|
+
end
|
342
|
+
end
|
343
|
+
end
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
347
|
+
end
|
348
|
+
end
|