flydata 0.6.3 → 0.6.4

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.
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