flydata 0.3.20 → 0.3.21

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: e06e855feb4eedb44d34602d0e6d447f72eddc2f
4
- data.tar.gz: 960b559b4006bfcea9fecb6b96ef0457f2eed949
3
+ metadata.gz: 0c4aa0461989a989042cf8117321b6fb0a25290b
4
+ data.tar.gz: 489443d11c79f35f1736bf52c61b438b7dfe7e54
5
5
  SHA512:
6
- metadata.gz: 0cf8f7f398d49b1081be49e96d0111a5e9bb88102bdea6fb148a015629cd62d0140e11f22a0ad0e6bd490a3993d362a0d5c7af29fa58829434649487d0dcf7b2
7
- data.tar.gz: cf814b03327a2230bb90058c82c72b3c6e1b06225a2048dff20dd6744656614418cf609bd7c4a452570d229ff34c1ba4eca54e33b99f202f6a6c54850fab183c
6
+ metadata.gz: f1cf691ead10def34ef2f61fc1be6d879a1dc3761e4cda2610b47afd05e227f8b435eece8b75dfbc4b338eb774848f0bd70474ed3fa53e702da8d4fbddd7bad9
7
+ data.tar.gz: 73ba527eecb4925518fcf34f432cc397ee6059ff4c166c199666c5dd9e3601fd8a5fb245d32a0fcae4f4ea62bf9ba4b9c6738a88c8f8e99be302c5bfc60bd0b6
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.20
1
+ 0.3.21
@@ -4,6 +4,8 @@ require 'flydata-core/errors'
4
4
  module FlydataCore
5
5
  module TableDef
6
6
 
7
+ class NameTooLongError < RuntimeError; end
8
+
7
9
  class RedshiftTableDef
8
10
  TYPE_MAP_F2R = {
9
11
  'binary' => {type: 'varchar', use_params: true, default_value: ''},
@@ -146,7 +148,7 @@ EOS
146
148
  else
147
149
  type_info[:type]
148
150
  end
149
- line = %Q| "#{column[:column]}" #{rs_type}|
151
+ line = %Q| "#{convert_to_valid_column_name(column[:column])}" #{rs_type}|
150
152
  line += " NOT NULL" if column[:not_null]
151
153
  if (column.has_key?(:default))
152
154
  val = replace_default_value(type, type_info[:type], column[:default])
@@ -271,6 +273,37 @@ EOS
271
273
  sql
272
274
  end
273
275
 
276
+ # convert key to valid a column name
277
+ # http://docs.aws.amazon.com/redshift/latest/dg/r_names.html
278
+ # http://www.postgresql.org/docs/8.0/static/ddl-system-columns.html
279
+ def self.convert_to_valid_column_name(key)
280
+ convert_to_valid_name(key) {|n| redshift_reserved_column_name?(n) }
281
+ end
282
+
283
+ def self.convert_to_valid_table_name(key)
284
+ convert_to_valid_name(key)
285
+ end
286
+
287
+ MAX_COLUMNNAME_LENGTH = 127
288
+
289
+ def self.convert_to_valid_name(key)
290
+ name = key.downcase.gsub(/[^a-z0-9_$]/, '_')
291
+ do_convert = yield name if block_given?
292
+ name = "_#{name}" if do_convert || name =~ /^[0-9$]/
293
+ if name.length > MAX_COLUMNNAME_LENGTH
294
+ raise NameTooLongError, "Converted name is too long. size: #{name.size} name: #{name}"
295
+ end
296
+ name
297
+ end
298
+
299
+ REDSHIFT_RESERVED_COLUMNS = %w[oid tableoid xmin cmin xmax cmax ctid deletexid insertxid]
300
+ REDSHIFT_RESERVED_COLUMNS_HASH = REDSHIFT_RESERVED_COLUMNS.inject({}) {|h, word| h[word.to_sym] = true; h}
301
+
302
+ def self.redshift_reserved_column_name?(name)
303
+ return false unless name
304
+ REDSHIFT_RESERVED_COLUMNS_HASH[name.to_sym] == true
305
+ end
306
+
274
307
  def self.escape(text)
275
308
  text.gsub("'", "\\\\'")
276
309
  end
@@ -5,6 +5,7 @@ module FlydataCore
5
5
  module TableDef
6
6
 
7
7
  describe RedshiftTableDef do
8
+ let(:table_name) { 'test_table' }
8
9
 
9
10
  describe '.from_flydata_tabledef' do
10
11
  subject { described_class.from_flydata_tabledef(flydata_tabledef, option) }
@@ -127,6 +128,56 @@ EOT
127
128
  describe '.column_def_sql' do
128
129
  subject { described_class.column_def_sql(column, opt) }
129
130
  let(:column) { {} }
131
+ let(:opt) { {} }
132
+
133
+ shared_examples "test generated Redshift SQL for column" do
134
+ it do
135
+ expect(subject).to eq(expected_query)
136
+ end
137
+ end
138
+
139
+ context "test different column names" do
140
+ before do
141
+ column[:type] = "varchar(12)"
142
+ end
143
+ let(:expected_query) { %Q| "#{expected_column_name}" varchar(12)| }
144
+
145
+ context "normal column name" do
146
+ before do
147
+ column[:column] = "all_lower_case_not_reserved"
148
+ end
149
+ let(:expected_column_name) { "all_lower_case_not_reserved" }
150
+
151
+ it_behaves_like "test generated Redshift SQL for column"
152
+ end
153
+
154
+ context "capitalized column name" do
155
+ before do
156
+ column[:column] = "CapitalizedNotReserved"
157
+ end
158
+ let(:expected_column_name) { "capitalizednotreserved" }
159
+
160
+ it_behaves_like "test generated Redshift SQL for column"
161
+ end
162
+
163
+ context "reserved column name" do
164
+ before do
165
+ column[:column] = "oid"
166
+ end
167
+ let(:expected_column_name) { "_oid" }
168
+
169
+ it_behaves_like "test generated Redshift SQL for column"
170
+ end
171
+
172
+ context "captalized reserved column name" do
173
+ before do
174
+ column[:column] = "OID"
175
+ end
176
+ let(:expected_column_name) { "_oid" }
177
+
178
+ it_behaves_like "test generated Redshift SQL for column"
179
+ end
180
+ end
130
181
 
131
182
  let(:no_default_sql) { "" }
132
183
  shared_examples "default values" do |*examples|
@@ -171,12 +222,6 @@ EOT
171
222
  end
172
223
  end
173
224
 
174
- shared_examples "test generated Redshift SQL for column" do
175
- it do
176
- expect(subject).to eq(expected_query)
177
- end
178
- end
179
-
180
225
  shared_examples "test column types" do |*examples|
181
226
  context 'with varchar column def' do
182
227
  context 'when size is smaller than max size' do
@@ -478,6 +523,53 @@ EOT
478
523
  end
479
524
  end
480
525
 
526
+ describe '.flydata_ctl_columns_sql' do
527
+ subject { described_class.flydata_ctl_columns_sql(flydata_tabledef, schema_name) }
528
+ let(:flydata_tabledef) { {
529
+ table_name: table_name,
530
+ columns: [
531
+ { column: column_name, type: "varchar(12)" },
532
+ ],
533
+ default_charset: "UTF_8"} }
534
+ let(:schema_name) { nil }
535
+
536
+ let(:expected_sql) { <<EOS.strip }
537
+ DELETE FROM "flydata_ctl_columns" WHERE table_name = '#{table_name}';
538
+ INSERT INTO "flydata_ctl_columns" (table_name, column_name, src_data_type, ordinal_position) VALUES
539
+ ('#{table_name}', '#{expected_column_name}', 'varchar(12)', 1);
540
+ EOS
541
+
542
+ context "test different column names" do
543
+ context "normal column name" do
544
+ let(:column_name) { "all_lower_case_not_reserved" }
545
+ let(:expected_column_name) { column_name }
546
+
547
+ it { is_expected.to eq expected_sql }
548
+ end
549
+
550
+ context "capitalized column name" do
551
+ let(:column_name) { "CapitalizedNotReserved" }
552
+ let(:expected_column_name) { column_name }
553
+
554
+ it { is_expected.to eq expected_sql }
555
+ end
556
+
557
+ context "reserved column name" do
558
+ let(:column_name) { "oid" }
559
+ let(:expected_column_name) { column_name }
560
+
561
+ it { is_expected.to eq expected_sql }
562
+ end
563
+
564
+ context "captalized reserved column name" do
565
+ let(:column_name) { "OID" }
566
+ let(:expected_column_name) { column_name }
567
+
568
+ it { is_expected.to eq expected_sql }
569
+ end
570
+ end
571
+ end
572
+
481
573
  describe '.parse_timestamp' do
482
574
  let(:value) { nil }
483
575
  subject { described_class.parse_timestamp(value) }
data/flydata.gemspec CHANGED
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: flydata 0.3.20 ruby lib
5
+ # stub: flydata 0.3.21 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "flydata"
9
- s.version = "0.3.20"
9
+ s.version = "0.3.21"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib"]
13
13
  s.authors = ["Koichi Fujikawa", "Masashi Miyazaki", "Matthew Luu", "Mak Inada", "Sriram NS"]
14
- s.date = "2015-05-13"
14
+ s.date = "2015-05-14"
15
15
  s.description = "FlyData Agent"
16
16
  s.email = "sysadmin@flydata.com"
17
17
  s.executables = ["fdmysqldump", "flydata", "serverinfo"]
@@ -181,7 +181,7 @@ Gem::Specification.new do |s|
181
181
  ]
182
182
  s.homepage = "http://flydata.com/"
183
183
  s.licenses = ["All right reserved."]
184
- s.rubygems_version = "2.4.6"
184
+ s.rubygems_version = "2.4.3"
185
185
  s.summary = "FlyData Agent"
186
186
 
187
187
  if s.respond_to? :specification_version then
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flydata
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.20
4
+ version: 0.3.21
5
5
  platform: ruby
6
6
  authors:
7
7
  - Koichi Fujikawa
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2015-05-13 00:00:00.000000000 Z
15
+ date: 2015-05-14 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: rest-client
@@ -621,7 +621,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
621
621
  version: '0'
622
622
  requirements: []
623
623
  rubyforge_project:
624
- rubygems_version: 2.4.6
624
+ rubygems_version: 2.4.3
625
625
  signing_key:
626
626
  specification_version: 4
627
627
  summary: FlyData Agent