flydata 0.6.3 → 0.6.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +2 -2
  3. data/VERSION +1 -1
  4. data/bin/fdredshift +78 -0
  5. data/circle.yml +1 -1
  6. data/ext/flydata/{parser/mysql → source_mysql/parser}/.gitignore +0 -0
  7. data/ext/flydata/{parser/mysql → source_mysql/parser}/dump_parser_ext.cpp +3 -3
  8. data/ext/flydata/source_mysql/parser/extconf.rb +3 -0
  9. data/ext/flydata/{parser/mysql → source_mysql/parser}/parser.txt +0 -0
  10. data/ext/flydata/{parser/mysql → source_mysql/parser}/sql_parser.cpp +0 -0
  11. data/ext/flydata/{parser/mysql → source_mysql/parser}/sql_parser.h +0 -0
  12. data/flydata-core/lib/flydata-core/mysql/binlog_pos.rb +34 -32
  13. data/flydata-core/lib/flydata-core/mysql/compatibility_checker.rb +20 -0
  14. data/flydata-core/lib/flydata-core/table_def/mysql_table_def.rb +12 -4
  15. data/flydata-core/lib/flydata-core/table_def/redshift_table_def.rb +60 -6
  16. data/flydata-core/spec/mysql/binlog_pos_spec.rb +474 -0
  17. data/flydata-core/spec/table_def/mysql_table_def_spec.rb +57 -0
  18. data/flydata-core/spec/table_def/mysql_to_redshift_table_def_spec.rb +174 -20
  19. data/flydata-core/spec/table_def/mysqldump_test_col_comment_with_AUTO_INCREMENT_keyword.dump +43 -0
  20. data/flydata-core/spec/table_def/mysqldump_test_col_comment_with_not_null_keyword.dump +43 -0
  21. data/flydata-core/spec/table_def/mysqldump_test_col_comment_with_unique_keyword.dump +43 -0
  22. data/flydata-core/spec/table_def/mysqldump_test_col_comment_with_unsigned_keyword.dump +43 -0
  23. data/flydata-core/spec/table_def/redshift_table_def_spec.rb +41 -8
  24. data/flydata.gemspec +0 -0
  25. data/lib/flydata/cli.rb +11 -5
  26. data/lib/flydata/command/base.rb +14 -1
  27. data/lib/flydata/command/exclusive_runnable.rb +42 -12
  28. data/lib/flydata/command/helper.rb +6 -6
  29. data/lib/flydata/command/sender.rb +4 -3
  30. data/lib/flydata/command/setup.rb +30 -381
  31. data/lib/flydata/command/stop.rb +1 -0
  32. data/lib/flydata/command/sync.rb +273 -301
  33. data/lib/flydata/compatibility_check.rb +24 -117
  34. data/lib/flydata/fluent-plugins/in_mysql_binlog_flydata.rb +3 -3
  35. data/lib/flydata/fluent-plugins/mysql/alter_table_query_handler.rb +2 -2
  36. data/lib/flydata/fluent-plugins/mysql/binlog_record_handler.rb +6 -6
  37. data/lib/flydata/fluent-plugins/mysql/truncate_table_query_handler.rb +0 -1
  38. data/lib/flydata/parser.rb +14 -0
  39. data/lib/flydata/{parser_provider.rb → parser/parser_provider.rb} +6 -4
  40. data/lib/flydata/parser/source_table.rb +33 -0
  41. data/lib/flydata/source.rb +105 -0
  42. data/lib/flydata/source/component.rb +21 -0
  43. data/lib/flydata/source/errors.rb +7 -0
  44. data/lib/flydata/source/generate_source_dump.rb +72 -0
  45. data/lib/flydata/source/parse_dump_and_send.rb +52 -0
  46. data/lib/flydata/source/setup.rb +31 -0
  47. data/lib/flydata/source/source_pos.rb +45 -0
  48. data/lib/flydata/source/sync.rb +56 -0
  49. data/lib/flydata/source/sync_generate_table_ddl.rb +43 -0
  50. data/lib/flydata/source_file/setup.rb +17 -0
  51. data/lib/flydata/source_file/sync.rb +14 -0
  52. data/lib/flydata/{command → source_mysql/command}/mysql.rb +2 -1
  53. data/lib/flydata/{command → source_mysql/command}/mysql_command_base.rb +2 -4
  54. data/lib/flydata/{command → source_mysql/command}/mysqlbinlog.rb +2 -1
  55. data/lib/flydata/{command → source_mysql/command}/mysqldump.rb +2 -1
  56. data/lib/flydata/source_mysql/generate_source_dump.rb +53 -0
  57. data/lib/flydata/source_mysql/mysql_compatibility_check.rb +114 -0
  58. data/lib/flydata/source_mysql/parse_dump_and_send.rb +28 -0
  59. data/lib/flydata/{parser/mysql → source_mysql/parser}/.gitignore +0 -0
  60. data/lib/flydata/{parser/mysql → source_mysql/parser}/dump_parser.rb +32 -67
  61. data/lib/flydata/{parser/mysql → source_mysql/parser}/mysql_alter_table.treetop +0 -0
  62. data/lib/flydata/source_mysql/setup.rb +24 -0
  63. data/lib/flydata/source_mysql/source_pos.rb +21 -0
  64. data/lib/flydata/source_mysql/sync.rb +45 -0
  65. data/lib/flydata/source_mysql/sync_generate_table_ddl.rb +40 -0
  66. data/lib/flydata/{mysql → source_mysql}/table_ddl.rb +6 -17
  67. data/lib/flydata/source_zendesk/sync_generate_table_ddl.rb +30 -0
  68. data/lib/flydata/source_zendesk/zendesk_flydata_tabledefs.rb +133 -0
  69. data/lib/flydata/sync_file_manager.rb +132 -73
  70. data/lib/flydata/table_ddl.rb +18 -0
  71. data/spec/flydata/cli_spec.rb +1 -0
  72. data/spec/flydata/command/exclusive_runnable_spec.rb +19 -8
  73. data/spec/flydata/command/sender_spec.rb +1 -1
  74. data/spec/flydata/command/setup_spec.rb +4 -4
  75. data/spec/flydata/command/sync_spec.rb +97 -134
  76. data/spec/flydata/compatibility_check_spec.rb +16 -289
  77. data/spec/flydata/fluent-plugins/mysql/alter_table_query_handler_spec.rb +3 -3
  78. data/spec/flydata/fluent-plugins/mysql/dml_record_handler_spec.rb +1 -1
  79. data/spec/flydata/fluent-plugins/mysql/shared_query_handler_context.rb +4 -2
  80. data/spec/flydata/fluent-plugins/mysql/truncate_query_handler_spec.rb +1 -1
  81. data/spec/flydata/source_mysql/generate_source_dump_spec.rb +69 -0
  82. data/spec/flydata/source_mysql/mysql_compatibility_check_spec.rb +280 -0
  83. data/spec/flydata/{parser/mysql → source_mysql/parser}/alter_table_parser_spec.rb +2 -2
  84. data/spec/flydata/{parser/mysql → source_mysql/parser}/dump_parser_spec.rb +75 -70
  85. data/spec/flydata/source_mysql/sync_generate_table_ddl_spec.rb +137 -0
  86. data/spec/flydata/{mysql → source_mysql}/table_ddl_spec.rb +2 -2
  87. data/spec/flydata/source_spec.rb +140 -0
  88. data/spec/flydata/source_zendesk/sync_generate_table_ddl_spec.rb +33 -0
  89. data/spec/flydata/sync_file_manager_spec.rb +157 -77
  90. data/tmpl/redshift_mysql_data_entry.conf.tmpl +1 -1
  91. metadata +56 -23
  92. data/ext/flydata/parser/mysql/extconf.rb +0 -3
  93. data/lib/flydata/mysql/binlog_position.rb +0 -22
  94. data/spec/flydata/mysql/binlog_position_spec.rb +0 -35
@@ -0,0 +1,43 @@
1
+ -- MySQL dump 10.13 Distrib 5.5.37, for debian-linux-gnu (x86_64)
2
+ --
3
+ -- Host: localhost Database: flydata_sync
4
+ -- ------------------------------------------------------
5
+ -- Server version 5.5.37-0ubuntu0.12.04.1-log
6
+
7
+ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
8
+ /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
9
+ /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
10
+ /*!40101 SET NAMES utf8 */;
11
+ /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
12
+ /*!40103 SET TIME_ZONE='+00:00' */;
13
+ /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
14
+ /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
15
+ /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
16
+ /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
17
+
18
+ --
19
+ -- Table structure for table `sample1`
20
+ --
21
+
22
+ DROP TABLE IF EXISTS `sample1`;
23
+ /*!40101 SET @saved_cs_client = @@character_set_client */;
24
+ /*!40101 SET character_set_client = utf8 */;
25
+ CREATE TABLE `sample1` (
26
+ `id` int(11) NOT NULL AUTO_INCREMENT,
27
+ `title` varchar(256) DEFAULT NULL COMMENT 'This column is not AUTO_INCREMENT column.',
28
+ `name` text,
29
+ `num` int(11) DEFAULT NULL,
30
+ PRIMARY KEY (`id`)
31
+ ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
32
+ /*!40101 SET character_set_client = @saved_cs_client */;
33
+ /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
34
+
35
+ /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
36
+ /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
37
+ /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
38
+ /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
39
+ /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
40
+ /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
41
+ /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
42
+
43
+ -- Dump completed on 2014-07-15 10:07:45
@@ -0,0 +1,43 @@
1
+ -- MySQL dump 10.13 Distrib 5.5.37, for debian-linux-gnu (x86_64)
2
+ --
3
+ -- Host: localhost Database: flydata_sync
4
+ -- ------------------------------------------------------
5
+ -- Server version 5.5.37-0ubuntu0.12.04.1-log
6
+
7
+ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
8
+ /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
9
+ /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
10
+ /*!40101 SET NAMES utf8 */;
11
+ /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
12
+ /*!40103 SET TIME_ZONE='+00:00' */;
13
+ /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
14
+ /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
15
+ /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
16
+ /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
17
+
18
+ --
19
+ -- Table structure for table `sample1`
20
+ --
21
+
22
+ DROP TABLE IF EXISTS `sample1`;
23
+ /*!40101 SET @saved_cs_client = @@character_set_client */;
24
+ /*!40101 SET character_set_client = utf8 */;
25
+ CREATE TABLE `sample1` (
26
+ `id` int(11) NOT NULL AUTO_INCREMENT,
27
+ `title` varchar(256) DEFAULT NULL COMMENT 'This column is not null column.',
28
+ `name` text,
29
+ `num` int(11) DEFAULT NULL,
30
+ PRIMARY KEY (`id`)
31
+ ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
32
+ /*!40101 SET character_set_client = @saved_cs_client */;
33
+ /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
34
+
35
+ /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
36
+ /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
37
+ /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
38
+ /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
39
+ /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
40
+ /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
41
+ /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
42
+
43
+ -- Dump completed on 2014-07-15 10:07:45
@@ -0,0 +1,43 @@
1
+ -- MySQL dump 10.13 Distrib 5.5.37, for debian-linux-gnu (x86_64)
2
+ --
3
+ -- Host: localhost Database: flydata_sync
4
+ -- ------------------------------------------------------
5
+ -- Server version 5.5.37-0ubuntu0.12.04.1-log
6
+
7
+ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
8
+ /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
9
+ /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
10
+ /*!40101 SET NAMES utf8 */;
11
+ /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
12
+ /*!40103 SET TIME_ZONE='+00:00' */;
13
+ /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
14
+ /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
15
+ /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
16
+ /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
17
+
18
+ --
19
+ -- Table structure for table `sample1`
20
+ --
21
+
22
+ DROP TABLE IF EXISTS `sample1`;
23
+ /*!40101 SET @saved_cs_client = @@character_set_client */;
24
+ /*!40101 SET character_set_client = utf8 */;
25
+ CREATE TABLE `sample1` (
26
+ `id` int(11) NOT NULL AUTO_INCREMENT,
27
+ `title` varchar(256) DEFAULT NULL COMMENT 'This column is not unique column.',
28
+ `name` text,
29
+ `num` int(11) DEFAULT NULL,
30
+ PRIMARY KEY (`id`)
31
+ ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
32
+ /*!40101 SET character_set_client = @saved_cs_client */;
33
+ /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
34
+
35
+ /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
36
+ /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
37
+ /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
38
+ /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
39
+ /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
40
+ /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
41
+ /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
42
+
43
+ -- Dump completed on 2014-07-15 10:07:45
@@ -0,0 +1,43 @@
1
+ -- MySQL dump 10.13 Distrib 5.5.37, for debian-linux-gnu (x86_64)
2
+ --
3
+ -- Host: localhost Database: flydata_sync
4
+ -- ------------------------------------------------------
5
+ -- Server version 5.5.37-0ubuntu0.12.04.1-log
6
+
7
+ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
8
+ /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
9
+ /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
10
+ /*!40101 SET NAMES utf8 */;
11
+ /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
12
+ /*!40103 SET TIME_ZONE='+00:00' */;
13
+ /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
14
+ /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
15
+ /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
16
+ /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
17
+
18
+ --
19
+ -- Table structure for table `sample1`
20
+ --
21
+
22
+ DROP TABLE IF EXISTS `sample1`;
23
+ /*!40101 SET @saved_cs_client = @@character_set_client */;
24
+ /*!40101 SET character_set_client = utf8 */;
25
+ CREATE TABLE `sample1` (
26
+ `id` int(11) NOT NULL AUTO_INCREMENT,
27
+ `title` varchar(256) DEFAULT NULL COMMENT 'This column is not unsigned column.',
28
+ `name` text,
29
+ `num` int(11) DEFAULT NULL,
30
+ PRIMARY KEY (`id`)
31
+ ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
32
+ /*!40101 SET character_set_client = @saved_cs_client */;
33
+ /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
34
+
35
+ /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
36
+ /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
37
+ /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
38
+ /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
39
+ /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
40
+ /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
41
+ /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
42
+
43
+ -- Dump completed on 2014-07-15 10:07:45
@@ -1,5 +1,6 @@
1
1
  require 'spec_helper'
2
2
  require 'flydata-core/table_def'
3
+ require 'timecop'
3
4
 
4
5
  module FlydataCore
5
6
  module TableDef
@@ -28,9 +29,23 @@ describe RedshiftTableDef do
28
29
 
29
30
  let(:schema_prefix) { "" }
30
31
 
32
+ let(:drop_table_subquery) { <<EOT }
33
+ DROP TABLE IF EXISTS #{schema_prefix}"test_table_flydata20160125232857";
34
+ CREATE TABLE IF NOT EXISTS #{schema_prefix}"test_table" (
35
+ "id" int4,
36
+ "age" int8,
37
+ "value" varchar(max),
38
+ PRIMARY KEY ("id")
39
+ ) DISTKEY("id") SORTKEY("id");
40
+ ALTER TABLE #{schema_prefix}"test_table" RENAME TO "test_table_flydata20160125232857";
41
+ EOT
42
+
43
+ let(:drop_backup_table_subquery) { <<EOT.strip }
44
+ DROP TABLE IF EXISTS #{schema_prefix}"test_table_flydata20160125232857";
45
+ EOT
46
+
31
47
  let(:create_table_queries) { <<EOT.strip }
32
- DROP TABLE IF EXISTS #{schema_prefix}"test_table";
33
- CREATE TABLE #{schema_prefix}"test_table" (
48
+ #{drop_table_subquery}CREATE TABLE #{schema_prefix}"test_table" (
34
49
  "id" int4,
35
50
  "age" int8,
36
51
  "value" varchar(max),
@@ -79,9 +94,13 @@ EOT
79
94
  CREATE SCHEMA IF NOT EXISTS "test_schema";
80
95
  EOT
81
96
 
97
+ before do
98
+ Timecop.freeze(Time.local(2016, 1, 25, 23, 28, 57))
99
+ end
100
+
82
101
  context 'with simple flydatadef' do
83
102
  it 'should return ddl' do
84
- expect(subject).to eq "#{create_table_queries}\n#{flydata_ctl_update}"
103
+ expect(subject).to eq "BEGIN;\n#{create_table_queries}\n#{flydata_ctl_update}\nCOMMIT;\n#{drop_backup_table_subquery}\n"
85
104
  end
86
105
  end
87
106
 
@@ -89,7 +108,18 @@ EOT
89
108
  let(:option) { { flydata_ctl_columns: true } }
90
109
 
91
110
  it 'should return ddl including flydata_ctl_columns creation' do
92
- expect(subject).to eq "#{flydata_ctl_create}\n#{create_table_queries}\n#{flydata_ctl_update}"
111
+ expect(subject).to eq "#{flydata_ctl_create}\nBEGIN;\n#{create_table_queries}\n#{flydata_ctl_update}\nCOMMIT;\n#{drop_backup_table_subquery}\n"
112
+ end
113
+ end
114
+
115
+ context 'when skip_drop_table option is true' do
116
+ before do
117
+ option.merge!(skip_drop_table: true)
118
+ end
119
+
120
+ let(:drop_table_subquery) { ""}
121
+ it 'should return ddl' do
122
+ expect(subject).to eq "BEGIN;\n#{create_table_queries}\n#{flydata_ctl_update}\nCOMMIT;\n"
93
123
  end
94
124
  end
95
125
 
@@ -97,7 +127,7 @@ EOT
97
127
  let(:value_column) { value_column_hash.merge(comment: "helloworld") }
98
128
 
99
129
  it 'should add comment creation ddl' do
100
- expect(subject).to eq "#{create_table_queries}\n#{comment_subquery}\n#{flydata_ctl_update}"
130
+ expect(subject).to eq "BEGIN;\n#{create_table_queries}\n#{comment_subquery}\n#{flydata_ctl_update}\nCOMMIT;\n#{drop_backup_table_subquery}\n"
101
131
  end
102
132
  end
103
133
 
@@ -107,12 +137,15 @@ EOT
107
137
  let(:schema_prefix) { '"test_schema".' }
108
138
 
109
139
  it 'should preappend schema name to table name' do
110
- expect(subject).to eq <<EOT.strip
140
+ expect(subject).to eq <<EOT
111
141
  #{create_schema_query}
112
142
  #{flydata_ctl_create}
143
+ BEGIN;
113
144
  #{create_table_queries}
114
145
  #{comment_subquery}
115
146
  #{flydata_ctl_update}
147
+ COMMIT;
148
+ #{drop_backup_table_subquery}
116
149
  EOT
117
150
  end
118
151
  end
@@ -121,7 +154,7 @@ EOT
121
154
  let(:value_column) { value_column_hash.merge(charset: "ISO_8859_1") }
122
155
  let(:value_type) { "#{value_type_body} cs:ISO_8859_1" }
123
156
  it 'should return ddl' do
124
- expect(subject).to eq "#{create_table_queries}\n#{flydata_ctl_update}"
157
+ expect(subject).to eq "BEGIN;\n#{create_table_queries}\n#{flydata_ctl_update}\nCOMMIT;\n#{drop_backup_table_subquery}\n"
125
158
  end
126
159
  end
127
160
  end
@@ -540,7 +573,7 @@ EOT
540
573
  default_charset: "UTF_8"} }
541
574
  let(:schema_name) { nil }
542
575
 
543
- let(:expected_sql) { <<EOS.strip }
576
+ let(:expected_sql) { <<EOS }
544
577
  DELETE FROM "flydata_ctl_columns" WHERE table_name = '#{table_name}';
545
578
  INSERT INTO "flydata_ctl_columns" (table_name, column_name, src_data_type, ordinal_position) VALUES
546
579
  ('#{table_name}', '#{expected_column_name}', 'varchar(12)', 1);
data/flydata.gemspec CHANGED
Binary file
data/lib/flydata/cli.rb CHANGED
@@ -2,6 +2,7 @@ require 'slop'
2
2
  require 'flydata/command_loggable'
3
3
  require 'flydata/errors'
4
4
  require 'flydata/helpers'
5
+ require 'flydata/source'
5
6
 
6
7
  module Flydata
7
8
  class Cli
@@ -70,11 +71,16 @@ module Flydata
70
71
  end
71
72
  COMMAND_DIR = 'flydata/command'
72
73
  def require_command_source(cmd)
73
- source_path = File.join(COMMAND_DIR, cmd)
74
- begin
75
- require source_path
76
- rescue LoadError
77
- # ignore
74
+ command_dirs = [COMMAND_DIR] + Source.command_dir_paths
75
+ command_dirs.each do |command_dir|
76
+ source_path = File.join(command_dir, cmd)
77
+ result = begin
78
+ require source_path
79
+ :success
80
+ rescue LoadError
81
+ :fail
82
+ end
83
+ break if result == :success
78
84
  end
79
85
  end
80
86
  end
@@ -1,6 +1,7 @@
1
1
  require 'slop'
2
2
  require 'flydata/api_client'
3
3
  require 'flydata/command_loggable'
4
+ require 'flydata/source'
4
5
  require 'flydata/command/exclusive_runnable'
5
6
  require 'flydata/preference/data_entry_preference'
6
7
 
@@ -42,10 +43,14 @@ module Flydata
42
43
 
43
44
  def data_entry
44
45
  @de ||= retrieve_data_entries.first
45
- raise "There are no data entries." unless @de
46
+ raise "No data entry exists. Please set one up on the FlyData Console (#{dashboard_url})" unless @de
46
47
  @de
47
48
  end
48
49
 
50
+ def source
51
+ @source ||= Source.create(data_entry)
52
+ end
53
+
49
54
  def register_crontab
50
55
  data_entries = retrieve_data_entries
51
56
  if data_entries.any?{|e| e['log_deletion']}
@@ -55,6 +60,14 @@ module Flydata
55
60
  end
56
61
  end
57
62
 
63
+ def dashboard_url
64
+ "#{flydata.flydata_api_host}/dashboard"
65
+ end
66
+
67
+ def redshift_console_url
68
+ "#{flydata.flydata_api_host}/redshift_clusters/query/new"
69
+ end
70
+
58
71
  # print console
59
72
  def newline; puts end
60
73
  def separator(str="=")
@@ -11,6 +11,21 @@ module ExclusiveRunnable
11
11
  end
12
12
 
13
13
  module ClassMethods
14
+ # messages
15
+ COMMAND_IS_ALREADY_RUNNING = <<EOT
16
+ Command `%s` is already running or terminated abnormally. (pid:%s)
17
+ Wait until the command completes or stop the command.
18
+ EOT
19
+ DATA_INCONSISTENCY_MAY_OCCUR = <<EOT
20
+
21
+ !! Command `%s` is still running. (pid:%s)
22
+ We highly recommend to *stop the process* before run a new command.
23
+ If two commands run concurrently, DATA INCONSISTENCY MAY OCCUR.
24
+
25
+ EOT
26
+ CONCURRENT_RUN = <<EOT
27
+ Run command:"%s" while a process for the previous command:"%s" still exists (pid:%s)
28
+ EOT
14
29
  def run_exclusive(method, options = {})
15
30
  saved_method = :"__#{method}"
16
31
  alias_method saved_method, method
@@ -19,18 +34,27 @@ module ExclusiveRunnable
19
34
  result = nil
20
35
  exclusive_run_info = nil
21
36
  begin
22
- info = self.class.load_exclusive_run_info
23
- if info
24
- #TODO If the previous command terminates abnormally,
25
- # 'exclusive_run.info' file won't be deleted even the pid
26
- # doesn't exist anymore.
27
- # This prevents execution of any commands afterwards, and
28
- # the user will see this misleading error message.
29
- # Introducing "--force-run" option can be a solution.
30
-
31
- raise "Command `#{info['command']}` is already running. Wait until the command completes or stop the command. (pid:#{info['pid']})"
37
+ new_command = self.class.command(method, options)
38
+ new_pid = Process.pid
39
+ old_exclusive_run_info = self.class.load_exclusive_run_info
40
+ if old_exclusive_run_info
41
+ old_command = old_exclusive_run_info['command']
42
+ old_pid = old_exclusive_run_info['pid']
43
+
44
+ raise COMMAND_IS_ALREADY_RUNNING % [ old_command, old_pid ] if !opts.force_run?
45
+
46
+ #`force-run` option is specified.
47
+ #Override old `exclusive_run.info` file and run a command.
48
+ if self.class.process_exist?(old_pid)
49
+ log_warn_stderr DATA_INCONSISTENCY_MAY_OCCUR % [ old_command, old_pid ]
50
+ exit unless ask_yes_no("Do you proceed?", false)
51
+ end
52
+ $log.info CONCURRENT_RUN % [ new_command, old_command, old_pid ]
53
+ self.class.delete_exclusive_run_info
32
54
  end
33
- exclusive_run_info = { command: self.class.command(method, options), pid: Process.pid }
55
+
56
+ #Run a command
57
+ exclusive_run_info = { command: new_command, pid: new_pid }
34
58
  self.class.save_exclusive_run_info(exclusive_run_info)
35
59
  result = send(saved_method, *args)
36
60
  ensure
@@ -65,7 +89,13 @@ module ExclusiveRunnable
65
89
  path = exclusive_run_info_path
66
90
  File.delete(path) if File.exists?(path)
67
91
  end
68
-
92
+ def process_exist?(pid)
93
+ # Returns true if the process is running.
94
+ Process.getpgid(pid.to_i)
95
+ true
96
+ rescue Errno::ESRCH
97
+ false
98
+ end
69
99
  def command(subcommand, options = {})
70
100
  return options[:command] if options[:command]
71
101
 
@@ -49,7 +49,7 @@ module Flydata
49
49
 
50
50
  def stop(options = {})
51
51
  if running?
52
- run_command(stop_cmd)
52
+ run_command(stop_cmd, options)
53
53
  else
54
54
  log_info_stdout("Helper is not running.", {}, options)
55
55
  end
@@ -66,7 +66,7 @@ module Flydata
66
66
  def restart(options = {})
67
67
  if running?
68
68
  log_info_stdout("Restarting Helper.", {}, options)
69
- run_command(stop_cmd)
69
+ run_command(stop_cmd, options)
70
70
  end
71
71
  raw_start
72
72
  end
@@ -74,7 +74,7 @@ module Flydata
74
74
  def reload(options = {})
75
75
  if running?
76
76
  log_info_stdout("Reloading Helper.", {}, options)
77
- run_command(kill_hup_cmd)
77
+ run_command(kill_hup_cmd, options)
78
78
  end
79
79
  end
80
80
 
@@ -95,14 +95,14 @@ module Flydata
95
95
  end
96
96
  end
97
97
 
98
- def run_command(cmd)
98
+ def run_command(cmd, options)
99
99
  o, e, s = Util::Shell.run_cmd(cmd)
100
100
  log_error_stderr(e) if not e.to_s.empty?
101
101
  success = (s.to_i == 0)
102
102
  if success
103
- log_info_stdout("Done")
103
+ log_info_stdout("Done", {}, options)
104
104
  else
105
- log_error_stderr("Failed")
105
+ log_error_stderr("Failed", {}, options)
106
106
  end
107
107
  success
108
108
  end