flydata 0.1.12 → 0.1.13

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.
@@ -31,17 +31,19 @@ class RedshiftTableDef
31
31
  }
32
32
  def self.from_flydata_tabledef(flydata_tabledef, options = {})
33
33
  options[:flydata_ctl_table] = true unless options.has_key?(:flydata_ctl_table)
34
+ schema_name = options[:schema_name]
34
35
 
35
36
  tabledef = ""
36
- tabledef += create_flydata_ctl_table_sql if options[:flydata_ctl_table]
37
- tabledef += create_table_sql(flydata_tabledef)
38
- tabledef += comment_sql(flydata_tabledef)
39
- tabledef += flydata_ctl_sql(flydata_tabledef)
37
+ tabledef += create_flydata_ctl_table_sql(schema_name) if options[:flydata_ctl_table]
38
+ tabledef += create_table_sql(flydata_tabledef, schema_name)
39
+ tabledef += comment_sql(flydata_tabledef, schema_name)
40
+ tabledef += flydata_ctl_sql(flydata_tabledef, schema_name)
40
41
  end
41
42
 
43
+ FLYDATA_CTL_COLUMNS_TABLE = "flydata_ctl_columns"
42
44
  CREATE_FLYDATA_CTL_TABLE_SQL = <<EOS
43
- DROP TABLE flydata_ctl_columns;
44
- CREATE TABLE flydata_ctl_columns (
45
+ DROP TABLE %s;
46
+ CREATE TABLE %s(
45
47
  id integer NOT NULL IDENTITY(1,1),
46
48
  table_name varchar(128) NOT NULL,
47
49
  column_name varchar(128) NOT NULL,
@@ -51,9 +53,19 @@ CREATE TABLE flydata_ctl_columns (
51
53
  PRIMARY KEY(id)
52
54
  ) DISTKEY(table_name) SORTKEY(table_name);
53
55
  EOS
54
- def self.create_flydata_ctl_table_sql
56
+
57
+ def self.table_name_for_ddl(table_name, schema_name)
58
+ schema_name.to_s.empty? ? "\"#{table_name}\"" : "\"#{schema_name}\".\"#{table_name}\""
59
+ end
60
+
61
+ def self.flydata_ctl_table_for_ddl(schema_name)
62
+ table_name_for_ddl(FLYDATA_CTL_COLUMNS_TABLE, schema_name)
63
+ end
64
+
65
+ def self.create_flydata_ctl_table_sql(schema_name)
55
66
  # No drop table here intentionally because losing the data is fatal.
56
- CREATE_FLYDATA_CTL_TABLE_SQL
67
+ tbl = flydata_ctl_table_for_ddl(schema_name)
68
+ CREATE_FLYDATA_CTL_TABLE_SQL % [tbl, tbl]
57
69
  end
58
70
 
59
71
  CREATE_TABLE_SQL = <<EOS
@@ -63,7 +75,7 @@ CREATE TABLE %s (
63
75
  );
64
76
  EOS
65
77
 
66
- def self.create_table_sql(flydata_tabledef)
78
+ def self.create_table_sql(flydata_tabledef, schema_name)
67
79
  lines = flydata_tabledef[:columns].collect{|column| column_def_sql(column) }
68
80
  pk_def = primary_key_sql(flydata_tabledef)
69
81
  lines << pk_def if pk_def
@@ -71,7 +83,8 @@ EOS
71
83
  contents = lines.join(",\n")
72
84
 
73
85
  table_name = flydata_tabledef[:table_name]
74
- CREATE_TABLE_SQL % [table_name, table_name, contents]
86
+ redshift_tbl = table_name_for_ddl(table_name, schema_name)
87
+ CREATE_TABLE_SQL % [redshift_tbl, redshift_tbl, contents]
75
88
  end
76
89
 
77
90
  def self.column_def_sql(column)
@@ -118,13 +131,13 @@ EOS
118
131
  pks.empty? ? nil : " PRIMARY KEY (#{pks.join(',')})"
119
132
  end
120
133
 
121
- def self.comment_sql(flydata_tabledef)
134
+ def self.comment_sql(flydata_tabledef, schema_name)
122
135
  sql = ""
123
136
  flydata_tabledef[:columns].each do |col|
124
137
  next unless col[:comment]
125
138
 
126
139
  sql += <<EOS
127
- COMMENT ON COLUMN #{flydata_tabledef[:table_name]}."#{col[:name]}"
140
+ COMMENT ON COLUMN #{table_name_for_ddl(flydata_tabledef[:table_name], schema_name)}."#{col[:name]}"
128
141
  IS '#{col[:comment]}';
129
142
  EOS
130
143
  end
@@ -132,11 +145,12 @@ EOS
132
145
  end
133
146
 
134
147
  FLYDATA_CTL_COLUMNS_SQL = <<EOS
135
- DELETE FROM flydata_ctl_columns WHERE table_name = '%s';
136
- INSERT INTO flydata_ctl_columns (table_name, column_name, src_data_type, ordinal_position) VALUES
148
+ DELETE FROM %s WHERE table_name = '%s';
149
+ INSERT INTO %s (table_name, column_name, src_data_type, ordinal_position) VALUES
137
150
  EOS
138
- def self.flydata_ctl_sql(flydata_tabledef)
139
- sql = FLYDATA_CTL_COLUMNS_SQL % [ flydata_tabledef[:table_name] ]
151
+ def self.flydata_ctl_sql(flydata_tabledef, schema_name)
152
+ flydata_ctl_tbl = flydata_ctl_table_for_ddl(schema_name)
153
+ sql = FLYDATA_CTL_COLUMNS_SQL % [ flydata_ctl_tbl, flydata_tabledef[:table_name], flydata_ctl_tbl ]
140
154
  values = []
141
155
  flydata_tabledef[:columns].each.with_index(1) do |col, i|
142
156
  values << "('#{flydata_tabledef[:table_name]}', '#{col[:name]}', '#{escape(col[:type])}', #{i})"
@@ -280,16 +280,11 @@ EOT
280
280
  end
281
281
  end
282
282
 
283
- context 'when received alter table event' do
284
- it do
285
- expect_no_emitted_record(alter_table_add_column_event)
286
- end
287
- end
288
-
289
- #TODO: Uncomment the following test and delete the above one after supporting alter table
290
283
  context 'when received alter table add column event' do
291
284
  it do
292
- skip "Now alter table add column is not supported"
285
+ # TODO Replace the expectation when enabling alter table
286
+ expect_no_emitted_record(alter_table_add_column_event)
287
+ =begin
293
288
  expect_emitted_records(alter_table_add_column_event, {
294
289
  type: :alter_table,
295
290
  table_name: "test_table",
@@ -300,12 +295,15 @@ EOT
300
295
  actions: [{
301
296
  action: :add_column, column: "sum", :type=>'int4'}],
302
297
  })
298
+ =end
303
299
  end
304
300
  end
305
301
 
306
302
  context 'when received alter table drop column event' do
307
303
  it do
308
- skip "Now alter table drop column is not supported"
304
+ # TODO Replace the expectation when enabling alter table
305
+ expect_no_emitted_record(alter_table_drop_column_event)
306
+ =begin
309
307
  expect_emitted_records(alter_table_drop_column_event, {
310
308
  type: :alter_table,
311
309
  table_name: "test_table",
@@ -316,6 +314,7 @@ EOT
316
314
  actions: [{
317
315
  action: :drop_column, column: "sum"}],
318
316
  })
317
+ =end
319
318
  end
320
319
  end
321
320
 
@@ -234,6 +234,60 @@ describe 'MysqlAlterTableParser' do
234
234
  end
235
235
  end
236
236
 
237
+ context 'when table_name is wrapped with backquote' do
238
+ let(:query) { "alter table `test_table` drop value" }
239
+ it do
240
+ expect(subject).to eq(
241
+ type: :alter_table,
242
+ table_name: "test_table",
243
+ actions: [{
244
+ action: :drop_column,
245
+ column: "value"
246
+ }])
247
+ end
248
+ end
249
+
250
+ context 'when keywords are capitalized' do
251
+ let(:query) { "ALTER TABLE `test_table` DROP value" }
252
+ it do
253
+ expect(subject).to eq(
254
+ type: :alter_table,
255
+ table_name: "test_table",
256
+ actions: [{
257
+ action: :drop_column,
258
+ column: "value"
259
+ }])
260
+ end
261
+ end
262
+
263
+ context 'when table_name includes schema' do
264
+ let(:query) { "alter table test_schema.test_table drop value" }
265
+ it do
266
+ expect(subject).to eq(
267
+ type: :alter_table,
268
+ schema_name: "test_schema",
269
+ table_name: "test_table",
270
+ actions: [{
271
+ action: :drop_column,
272
+ column: "value"
273
+ }])
274
+ end
275
+ end
276
+
277
+ context 'when table_name includes schema with quotes' do
278
+ let(:query) { "alter table `test_schema`.`test_table` drop `value`" }
279
+ it do
280
+ expect(subject).to eq(
281
+ type: :alter_table,
282
+ schema_name: "test_schema",
283
+ table_name: "test_table",
284
+ actions: [{
285
+ action: :drop_column,
286
+ column: "value"
287
+ }])
288
+ end
289
+ end
290
+
237
291
  context 'when query has unsupported drop dextension' do
238
292
  subject { parser.parse(query) }
239
293
 
@@ -6,6 +6,136 @@ module TableDef
6
6
 
7
7
  describe RedshiftTableDef do
8
8
 
9
+ describe '.from_flydata_tabledef' do
10
+ let(:flydata_tabledef) { {
11
+ table_name: "test_table",
12
+ columns: [
13
+ { name: "id", type: "int4(11)", not_null: true, primary_key: true },
14
+ { name: "value", type: "text" },
15
+ ],
16
+ default_charset: "utf8;"} }
17
+ let(:option) { { flydata_ctl_table: false } }
18
+
19
+ subject { described_class.from_flydata_tabledef(flydata_tabledef, option) }
20
+
21
+ context 'with simple flydatadef' do
22
+ it 'should return ddl' do
23
+ expect(subject).to eq( <<EOT.strip )
24
+ DROP TABLE "test_table";
25
+ CREATE TABLE "test_table" (
26
+ "id" int4 NOT NULL,
27
+ "value" varchar(max),
28
+ PRIMARY KEY (id)
29
+ );
30
+ DELETE FROM "flydata_ctl_columns" WHERE table_name = 'test_table';
31
+ INSERT INTO "flydata_ctl_columns" (table_name, column_name, src_data_type, ordinal_position) VALUES
32
+ ('test_table', 'id', 'int4(11)', 1),
33
+ ('test_table', 'value', 'text', 2);
34
+ EOT
35
+ end
36
+ end
37
+
38
+ context 'with flydata_ctl_columns option true' do
39
+ let(:option) { { flydata_ctl_columns: true } }
40
+
41
+ it 'should return ddl including flydata_ctl_columns creation' do
42
+ expect(subject).to eq( <<EOT.strip )
43
+ DROP TABLE "flydata_ctl_columns";
44
+ CREATE TABLE "flydata_ctl_columns"(
45
+ id integer NOT NULL IDENTITY(1,1),
46
+ table_name varchar(128) NOT NULL,
47
+ column_name varchar(128) NOT NULL,
48
+ src_data_type varchar(1024) NOT NULL,
49
+ revision int NOT NULL DEFAULT 1,
50
+ ordinal_position int NOT NULL,
51
+ PRIMARY KEY(id)
52
+ ) DISTKEY(table_name) SORTKEY(table_name);
53
+ DROP TABLE "test_table";
54
+ CREATE TABLE "test_table" (
55
+ "id" int4 NOT NULL,
56
+ "value" varchar(max),
57
+ PRIMARY KEY (id)
58
+ );
59
+ DELETE FROM "flydata_ctl_columns" WHERE table_name = 'test_table';
60
+ INSERT INTO "flydata_ctl_columns" (table_name, column_name, src_data_type, ordinal_position) VALUES
61
+ ('test_table', 'id', 'int4(11)', 1),
62
+ ('test_table', 'value', 'text', 2);
63
+ EOT
64
+ end
65
+ end
66
+
67
+ context 'with flydatadef with comment' do
68
+ let(:flydata_tabledef) { {
69
+ table_name: "test_table",
70
+ columns: [
71
+ { name: "id", type: "int4(11)", not_null: true, primary_key: true },
72
+ { name: "value", type: "text" },
73
+ { name: "cmnt", type: "text", comment: "helloworld" },
74
+ ],
75
+ default_charset: "utf8;"} }
76
+
77
+ it 'should add comment creation ddl' do
78
+ expect(subject).to eq( <<EOT.strip )
79
+ DROP TABLE "test_table";
80
+ CREATE TABLE "test_table" (
81
+ "id" int4 NOT NULL,
82
+ "value" varchar(max),
83
+ "cmnt" varchar(max),
84
+ PRIMARY KEY (id)
85
+ );
86
+ COMMENT ON COLUMN "test_table"."cmnt"
87
+ IS 'helloworld';
88
+ DELETE FROM "flydata_ctl_columns" WHERE table_name = 'test_table';
89
+ INSERT INTO "flydata_ctl_columns" (table_name, column_name, src_data_type, ordinal_position) VALUES
90
+ ('test_table', 'id', 'int4(11)', 1),
91
+ ('test_table', 'value', 'text', 2),
92
+ ('test_table', 'cmnt', 'text', 3);
93
+ EOT
94
+ end
95
+ end
96
+
97
+ context 'with schema_name' do
98
+ let(:flydata_tabledef) { {
99
+ table_name: "test_table",
100
+ columns: [
101
+ { name: "id", type: "int4(11)", not_null: true, primary_key: true },
102
+ { name: "value", type: "text" },
103
+ { name: "cmnt", type: "text", comment: "helloworld" },
104
+ ],
105
+ default_charset: "utf8;"} }
106
+ let(:option) { { flydata_ctl_table: true, schema_name: 'test_schema' } }
107
+
108
+ it 'should preappend schema name to table name' do
109
+ expect(subject).to eq( <<EOT.strip )
110
+ DROP TABLE "test_schema"."flydata_ctl_columns";
111
+ CREATE TABLE "test_schema"."flydata_ctl_columns"(
112
+ id integer NOT NULL IDENTITY(1,1),
113
+ table_name varchar(128) NOT NULL,
114
+ column_name varchar(128) NOT NULL,
115
+ src_data_type varchar(1024) NOT NULL,
116
+ revision int NOT NULL DEFAULT 1,
117
+ ordinal_position int NOT NULL,
118
+ PRIMARY KEY(id)
119
+ ) DISTKEY(table_name) SORTKEY(table_name);
120
+ DROP TABLE "test_schema"."test_table";
121
+ CREATE TABLE "test_schema"."test_table" (
122
+ "id" int4 NOT NULL,
123
+ "value" varchar(max),
124
+ "cmnt" varchar(max),
125
+ PRIMARY KEY (id)
126
+ );
127
+ COMMENT ON COLUMN "test_schema"."test_table"."cmnt"
128
+ IS 'helloworld';
129
+ DELETE FROM "test_schema"."flydata_ctl_columns" WHERE table_name = 'test_table';
130
+ INSERT INTO "test_schema"."flydata_ctl_columns" (table_name, column_name, src_data_type, ordinal_position) VALUES
131
+ ('test_table', 'id', 'int4(11)', 1),
132
+ ('test_table', 'value', 'text', 2),
133
+ ('test_table', 'cmnt', 'text', 3);
134
+ EOT
135
+ end
136
+ end
137
+ end
138
+
9
139
  describe '.column_def_sql' do
10
140
  let(:column) { {} }
11
141
  subject { described_class.column_def_sql(column) }