myreplicator 1.0.6 → 1.1.0

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 (49) hide show
  1. data/app/assets/javascripts/myreplicator/select2.js +2685 -0
  2. data/app/assets/stylesheets/myreplicator/select2-spinner.gif +0 -0
  3. data/app/assets/stylesheets/myreplicator/select2.css +612 -0
  4. data/app/assets/stylesheets/myreplicator/select2.png +0 -0
  5. data/app/models/myreplicator/export.rb +25 -7
  6. data/app/models/myreplicator/vertica_export.rb +5 -0
  7. data/app/views/myreplicator/exports/_form.html.erb +48 -27
  8. data/app/views/myreplicator/exports/index.html.erb +4 -4
  9. data/db/migrate/20130213211927_create_myreplicator_vertica_exports.rb +22 -0
  10. data/db/migrate/20130213211927_create_myreplicator_vertica_exports.rb~ +8 -0
  11. data/lib/exporter/export_metadata.rb +7 -1
  12. data/lib/exporter/mysql_exporter.rb +103 -29
  13. data/lib/exporter/sql_commands.rb +8 -9
  14. data/lib/exporter.rb +1 -0
  15. data/lib/loader/loader.rb +32 -12
  16. data/lib/loader/vertica/source_db.rb +30 -0
  17. data/lib/loader/vertica/source_db.rb~ +30 -0
  18. data/lib/loader/vertica/types.rb +44 -0
  19. data/lib/loader/vertica/vertica_loader.rb +235 -0
  20. data/lib/loader/vertica/vertica_loader.rb~ +175 -0
  21. data/lib/loader/vertica/vertica_sql.rb +59 -0
  22. data/lib/loader/vertica/vertica_sql.rb~ +60 -0
  23. data/lib/loader/vertica.rb +1 -0
  24. data/lib/myreplicator/version.rb +1 -1
  25. data/lib/transporter/transporter.rb +11 -1
  26. data/test/dummy/app/models/vertica_db.rb +7 -0
  27. data/test/dummy/config/database.yml +7 -0
  28. data/test/dummy/config/database.yml~ +2 -2
  29. data/test/dummy/config/myreplicator.yml +5 -0
  30. data/test/dummy/config/myreplicator.yml~ +0 -2
  31. data/test/dummy/log/development.log +1664 -9510
  32. data/test/dummy/tmp/cache/assets/CD5/B90/sprockets%2Fc999d13a6a21113981c0d820e8043bdf +0 -0
  33. data/test/dummy/tmp/cache/assets/CD7/030/sprockets%2F9ba4859590582b8b72a650b2b00b6cd2 +0 -0
  34. data/test/dummy/tmp/cache/assets/CE5/670/sprockets%2Fe9e4122f1706626a21da6f8457f088ce +0 -0
  35. data/test/dummy/tmp/cache/assets/D06/5D0/sprockets%2F91850a20c0ddfa3d8814ca91870fb715 +0 -0
  36. data/test/dummy/tmp/cache/assets/D14/3A0/sprockets%2Fe59a60053fada52e8185281b4ee887a5 +0 -0
  37. data/test/dummy/tmp/cache/assets/D7C/E30/sprockets%2F0ba91e21bddfc7e1de102b22183e1e11 +0 -0
  38. data/test/dummy/tmp/cache/assets/D8B/B60/sprockets%2Faa32227c440a378ccd21218eefeb80bf +0 -0
  39. data/test/dummy/tmp/cache/assets/DA7/E50/sprockets%2F47bf4f2b4afeac775e6d572a83343fb8 +0 -0
  40. data/test/dummy/tmp/cache/assets/DA8/910/sprockets%2Fab5775c4a837bd4d97ac394d473cda9b +0 -0
  41. data/test/dummy/tmp/cache/assets/DAA/060/sprockets%2Facc0d22b9d28123cc1c84d0db630d0ba +0 -0
  42. data/test/dummy/tmp/cache/assets/DF8/5D0/sprockets%2Fb815ed34d61cfed96222daa3bfd1d84d +0 -0
  43. data/test/dummy/tmp/cache/assets/E1C/AC0/sprockets%2Faff544a3a34eb7dab7d46b0cb2cd7b70 +0 -0
  44. data/test/dummy/tmp/cache/assets/E2E/1F0/sprockets%2Fa24e3d7bc5ae4d40adf6f1b8fe94e7c3 +0 -0
  45. data/test/fixtures/myreplicator/vertica_exports.yml +11 -0
  46. data/test/unit/myreplicator/vertica_export_test.rb +9 -0
  47. metadata +43 -13
  48. data/test/dummy/tmp/myreplicator/okl_test_batchy_batches_1358547945.tsv.gz +0 -0
  49. data/test/dummy/tmp/myreplicator/okl_test_batchy_batches_1358547945.tsv.json +0 -1
@@ -1,6 +1,6 @@
1
1
  <%
2
2
  #rather than yaml arrays of the drop downs
3
- export_to = ["destination_db","s3","both"]
3
+ export_to = ["destination_db","backup","vertica"]
4
4
  export_type = ["incremental","fulldump"]
5
5
  %>
6
6
  <%= form_for(@export) do |f| %>
@@ -16,6 +16,18 @@ export_type = ["incremental","fulldump"]
16
16
  </div>
17
17
  <% end %>
18
18
  <div class="form-section">
19
+ <label>Export to</label>
20
+ <select name="export[export_to]" id="export_to" class="chosen" data-placeholder="Select export destination">
21
+ <% export_to.each do |val| %>
22
+ <option value="<%= val %>" <% if @export.export_to == val %>SELECTED<% end %>><%= val %></option>
23
+ <% end %>
24
+ </select>
25
+ <label>Export type</label>
26
+ <select name="export[export_type]" id="export_type" class="chosen" data-placeholder="Select your export type">
27
+ <% export_type.each do |val| %>
28
+ <option value="<%= val %>" <% if @export.export_type == val %>SELECTED<% end %>><%= val %></option>
29
+ <% end %>
30
+ </select>
19
31
  <label>Source Schema</label>
20
32
  <%= f.select :source_schema, @dbs %>
21
33
  <label>Destination Schema</label>
@@ -28,20 +40,8 @@ export_type = ["incremental","fulldump"]
28
40
  <%= f.text_field :incremental_column_type %>
29
41
  <label>Maximum Incremental Value</label>
30
42
  <%= f.text_field :max_incremental_value %>
31
- <label>S3 Path</label>
43
+ <label>Store a copy in</label>
32
44
  <%= f.text_field :s3_path %>
33
- <label>Export to</label>
34
- <select name="export[export_to]" id="export_to" class="chosen" data-placeholder="Select export destination">
35
- <% export_to.each do |val| %>
36
- <option value="<%= val %>" <% if @export.export_to == val %>SELECTED<% end %>><%= val %></option>
37
- <% end %>
38
- </select>
39
- <label>Export type</label>
40
- <select name="export[export_type]" id="export_type" class="chosen" data-placeholder="Select your export type">
41
- <% export_type.each do |val| %>
42
- <option value="<%= val %>" <% if @export.export_type == val %>SELECTED<% end %>><%= val %></option>
43
- <% end %>
44
- </select>
45
45
  <label>Active</label>
46
46
  <select name="export[active]" id="active" class="chosen">
47
47
  <option value="true" <% if @export.active == true %>SELECTED<% end %>>true</option>
@@ -124,8 +124,7 @@ export_type = ["incremental","fulldump"]
124
124
  <%= link_to content_tag(:span, 'cancel'), exports_path, :class => "btn left action cancel" %>
125
125
  </div>
126
126
  <% end %>
127
- <%= javascript_include_tag "myreplicator/chosen.jquery.min" %>
128
- <%= javascript_include_tag "myreplicator/cronwtf.min" %>
127
+
129
128
  <script>
130
129
  var dbs = {
131
130
  <% @tables.each do |key,values| %>
@@ -138,13 +137,28 @@ var dbs = {
138
137
  }
139
138
  $(function(){
140
139
  CronUI.translate();
141
- $(".chosen").chosen();
142
- $("#export_destination_schema,#export_table_name").chosen();
140
+ $(".chosen").select2();
141
+ var $destination = $("#export_destination_schema").clone();
142
+ var $table_name = $("#export_table_name").clone()
143
+ $("#export_destination_schema").select2();
144
+ $("#export_table_name").select2();
143
145
  $(".cron").chosen().change(function(){CronUI.translate()});
144
- $("#export_source_schema").chosen().change(function(){
146
+ $("#export_source_schema").select2().change(function(){
145
147
  exportSchemaSelect($(this).val())
146
148
  });
147
149
  exportSchemaSelect($("#export_source_schema").val());
150
+
151
+ $("#export_to").change(function(){
152
+ var exp = $(this).val();
153
+ if(exp == 'vertica'){
154
+ $("#export_destination_schema").select2("destroy").before('<input type="text" id="export_destination_schema" name="export[destination_schema]"/>').remove();
155
+ }else{
156
+ if($("#s2id_export_destination_schema").length < 1){
157
+ $("#export_destination_schema").before($destination).remove();
158
+ $("#export_destination_schema").select2();
159
+ }
160
+ }
161
+ })
148
162
  $("#cron-min").slider({
149
163
  min: 1,
150
164
  max: 59,
@@ -218,18 +232,25 @@ function editInit(){
218
232
  }
219
233
  }
220
234
  CronUI.translate();
221
- $("#export_table_name").val("<%= @export.table_name %>").trigger("liszt:updated");
235
+ <% if @export.export_to != 'vertica' %>
236
+ $("#export_table_name").select2("val","<%= @export.table_name %>")
237
+ <% else %>
238
+ $("#export_destination_schema").select2("destroy").before('<input type="text" id="export_destination_schema" name="export[destination_schema]" value="<%= @export.destination_schema %>"/>').remove();
239
+ <% end %>
222
240
  }
223
241
 
224
242
  function exportSchemaSelect(val){
225
243
  var target = $("#export_table_name");
226
- var tables = dbs[val];
227
- var l = tables.length;
228
- var options = "";
229
- for(i=0;i<l;i++){
230
- options += "<option value='"+tables[i]+"'>"+tables[i]+"</option>";
244
+ if(target.hasClass("select2-offscreen")){
245
+ target.select2("destroy")
246
+ var tables = dbs[val];
247
+ var l = tables.length;
248
+ var options = "";
249
+ for(i=0;i<l;i++){
250
+ options += "<option value='"+tables[i]+"'>"+tables[i]+"</option>";
251
+ }
252
+ target.val('').find("option").remove()
253
+ target.append(options).select2();
231
254
  }
232
- target.val('').find("option").remove().trigger("liszt:updated");
233
- target.append(options).trigger("liszt:updated");
234
255
  }
235
256
  </script>
@@ -8,14 +8,14 @@
8
8
  <table class="data-grid">
9
9
  <thead>
10
10
  <tr>
11
+ <th><%= sortable "export_type" %></th>
12
+ <th><%= sortable "export_to", "Export Desitination" %></th>
11
13
  <th colspan="2"><%= sortable "source_schema" %></th>
12
14
  <th><%= sortable "destination_schema" %></th>
13
15
  <th><%= sortable "table_name" %></th>
14
16
  <th><%= sortable "incremental_column" %></th>
15
17
  <th><%= sortable "incremental_column_type" %></th>
16
18
  <th><%= sortable "max_incremental_value" %></th>
17
- <th><%= sortable "export_to", "Export Desitination" %></th>
18
- <th><%= sortable "export_type" %></th>
19
19
  <th><%= sortable "s3_path" %></th>
20
20
  <th><%= sortable "cron" %></th>
21
21
  <th class="center">Actions</th>
@@ -24,6 +24,8 @@
24
24
  <tbody>
25
25
  <% @exports.each do |export| %>
26
26
  <tr>
27
+ <td><%= export.export_type %></td>
28
+ <td><%= export.export_to %></td>
27
29
  <td class="state"><span class="status <% if export.active %>active<% else %>inactive<% end %>" title="<% if export.active %>Active<% else %>Inactive<% end %>"></span></td>
28
30
  <td class="source"><%= export.source_schema %></td>
29
31
  <td><%= export.destination_schema %></td>
@@ -31,8 +33,6 @@
31
33
  <td><%= export.incremental_column %></td>
32
34
  <td><%= export.incremental_column_type %></td>
33
35
  <td><%= export.max_incremental_value %></td>
34
- <td><%= export.export_to %></td>
35
- <td><%= export.export_type %></td>
36
36
  <td><%= export.s3_path %></td>
37
37
  <td><span class="cron" data-cron="<%= export.cron %>" title=""><%= export.cron %></span></td>
38
38
  <td>
@@ -0,0 +1,22 @@
1
+ class CreateMyreplicatorVerticaExports < ActiveRecord::Migration
2
+ def change
3
+ create_table :myreplicator_vertica_exports do |t|
4
+ t.string :database
5
+ t.string :schema
6
+ t.string :table_name
7
+ t.string :file_path
8
+ t.string :file_format
9
+ t.string :delimiter
10
+ t.string :field_enclosed_by
11
+ t.string :line_terminated_by
12
+ t.string :cron
13
+ t.string :state, :default => "new"
14
+ t.text :error
15
+ t.boolean :active, :default => true
16
+ t.integer :exporter_pid
17
+ t.datetime :export_started_at, :default => nil
18
+ t.datetime :export_finished_at, :default => nil
19
+ t.timestamps
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,8 @@
1
+ class CreateMyreplicatorVerticaExports < ActiveRecord::Migration
2
+ def change
3
+ create_table :myreplicator_vertica_exports do |t|
4
+
5
+ t.timestamps
6
+ end
7
+ end
8
+ end
@@ -5,6 +5,7 @@ module Myreplicator
5
5
 
6
6
  attr_accessor(:export_time,
7
7
  :export_finished_at,
8
+ :export_to,
8
9
  :table,
9
10
  :database,
10
11
  :state,
@@ -13,6 +14,7 @@ module Myreplicator
13
14
  :incremental_val,
14
15
  :ssh,
15
16
  :export_type,
17
+ :store_in,
16
18
  :on_duplicate,
17
19
  :filepath,
18
20
  :zipped,
@@ -158,7 +160,9 @@ module Myreplicator
158
160
  :export_id => @export_id,
159
161
  :filepath => @filepath,
160
162
  :zipped => @zipped,
161
- :export_type => @export_type
163
+ :export_type => @export_type,
164
+ :export_to => @export_to,
165
+ :store_in => @store_in
162
166
  }
163
167
  return obj.to_json
164
168
  end
@@ -203,6 +207,8 @@ module Myreplicator
203
207
  @on_duplicate = options[:on_duplicate] if options[:on_duplicate]
204
208
  @export_type = options[:export_type] if options[:export_type]
205
209
  @zipped = options[:zipped].nil? ? false : options[:zipped]
210
+ @store_in = options[:store_in] if options[:store_in]
211
+ @export_to = options[:export_to] if options[:export_to]
206
212
  @ssh = nil
207
213
 
208
214
  @success_callbacks = []
@@ -15,19 +15,19 @@ module Myreplicator
15
15
 
16
16
  ExportMetadata.record(:table => @export_obj.table_name,
17
17
  :database => @export_obj.source_schema,
18
+ :export_to => load_to,
18
19
  :export_id => @export_obj.id,
19
20
  :filepath => filepath,
21
+ :store_in => @export_obj.s3_path,
20
22
  :incremental_col => @export_obj.incremental_column) do |metadata|
21
23
 
22
24
  prepare metadata
23
25
 
24
- case @export_obj.export_type?
25
- when :new
26
+ if @export_obj.export_type? == :new && load_to == "mysql"
26
27
  on_failure_state_trans(metadata, "new") # If failed, go back to new
27
28
  on_export_success(metadata)
28
29
  initial_export metadata
29
-
30
- when :incremental
30
+ elsif @export_obj.export_type? == :incremental or load_to == "vertica"
31
31
  on_failure_state_trans(metadata, "failed") # Set state trans on failure
32
32
  on_export_success(metadata)
33
33
  incremental_export metadata
@@ -35,7 +35,15 @@ module Myreplicator
35
35
 
36
36
  end # metadata
37
37
  end
38
-
38
+
39
+ def load_to
40
+ if @export_obj.export_to == "vertica"
41
+ return "vertica"
42
+ else
43
+ return "mysql"
44
+ end
45
+ end
46
+
39
47
  ##
40
48
  # Setups SSH connection to remote host
41
49
  ##
@@ -65,12 +73,10 @@ module Myreplicator
65
73
  metadata.export_type = "initial"
66
74
  max_value = @export_obj.max_value if @export_obj.incremental_export?
67
75
  cmd = initial_mysqldump_cmd
68
-
69
76
  exporting_state_trans # mark exporting
70
77
 
71
78
  puts "Exporting..."
72
79
  result = execute_export(cmd, metadata)
73
-
74
80
  check_result(result, 0)
75
81
 
76
82
  @export_obj.update_max_val(max_value) if @export_obj.incremental_export?
@@ -78,10 +84,19 @@ module Myreplicator
78
84
 
79
85
  def initial_mysqldump_cmd
80
86
  flags = ["create-options", "single-transaction"]
81
- cmd = SqlCommands.mysqldump(:db => @export_obj.source_schema,
82
- :flags => flags,
83
- :filepath => filepath,
84
- :table_name => @export_obj.table_name)
87
+ cmd = ""
88
+ # Mysql - Mysql Export
89
+ if @export_obj.export_to == "destination_db"
90
+ cmd = SqlCommands.mysqldump(:db => @export_obj.source_schema,
91
+ :flags => flags,
92
+ :filepath => filepath,
93
+ :table_name => @export_obj.table_name)
94
+ else # Other destinations
95
+ cmd = SqlCommands.mysql_export_outfile(:db => @export_obj.source_schema,
96
+ :filepath => filepath,
97
+ :table => @export_obj.table_name)
98
+ end
99
+
85
100
  return cmd
86
101
  end
87
102
 
@@ -118,6 +133,7 @@ module Myreplicator
118
133
  cmd = SqlCommands.mysql_export(:db => @export_obj.source_schema,
119
134
  :filepath => filepath,
120
135
  :sql => sql)
136
+
121
137
  return cmd
122
138
  end
123
139
 
@@ -125,27 +141,85 @@ module Myreplicator
125
141
  # Exports table incrementally, similar to incremental_export method
126
142
  # Dumps file in tmp directory specified in myreplicator.yml
127
143
  # Note that directory needs 777 permissions for mysql to be able to export the file
128
- # Uses ;~; as the delimiter and new line for lines
144
+ # Uses \\0 as the delimiter and new line for lines
129
145
  ##
130
146
 
131
147
  def incremental_export_into_outfile metadata
132
- max_value = @export_obj.max_value
133
- metadata.export_type = "incremental_outfile"
134
-
135
- @export_obj.update_max_val if @export_obj.max_incremental_value.blank?
136
-
137
- cmd = SqlCommands.mysql_export_outfile(:db => @export_obj.source_schema,
138
- :table => @export_obj.table_name,
139
- :filepath => filepath,
140
- :incremental_col => @export_obj.incremental_column,
141
- :incremental_col_type => @export_obj.incremental_column_type,
142
- :incremental_val => @export_obj.max_incremental_value)
143
- exporting_state_trans
144
- puts "Exporting..."
145
- result = execute_export(cmd, metadata)
146
- check_result(result, 0)
147
- max_value = incremental_export_into_outfile(metadata)
148
- return max_value
148
+ unless @export_obj.is_running?
149
+ max_value = @export_obj.max_value
150
+ metadata.export_type = "incremental_outfile"
151
+ @export_obj.update_max_val if @export_obj.max_incremental_value.blank?
152
+
153
+ options = {
154
+ :db => @export_obj.source_schema,
155
+ :table => @export_obj.table_name,
156
+ :filepath => filepath,
157
+ :destination_schema => @export_obj.destination_schema}
158
+
159
+ unless schema_changed?(options)[:changed]
160
+ options[:incremental_col] = @export_obj.incremental_column
161
+ options[:incremental_col_type] = @export_obj.incremental_column_type
162
+ options[:incremental_val] = @export_obj.max_incremental_value
163
+ end
164
+
165
+ cmd = SqlCommands.mysql_export_outfile(options)
166
+ exporting_state_trans
167
+ puts "Exporting..."
168
+ result = execute_export(cmd, metadata)
169
+ check_result(result, 0)
170
+ metadata.incremental_val = max_value # store max val in metadata
171
+ @export_obj.update_max_val(max_value) # update max value if export was successful
172
+ end
173
+ return false
174
+ end
175
+
176
+ def self.compare_schemas vertica_schema, mysql_schema
177
+ if vertica_schema.size != mysql_schema.size
178
+ return {:changed => true, :mysql_schema => mysql_schema, :vertica_schema => vertica_schema,:new => false}
179
+ else
180
+ index = 0
181
+ while index < vertica_schema.size
182
+ # puts vertica_schema.rows[index][:column_name] + " " + mysql_schema[index]["column_name"]
183
+ # check for column name
184
+ if vertica_schema.rows[index][:column_name] != mysql_schema[index]["column_name"]
185
+ return true
186
+ end
187
+
188
+ # puts vertica_schema.rows[index][:data_type] + " " + VerticaTypes.convert(mysql_schema[index]["data_type"],mysql_schema[index]["column_type"])
189
+ # check for column's data type
190
+ if (vertica_schema.rows[index][:data_type] != VerticaTypes.convert(mysql_schema[index]["data_type"],mysql_schema[index]["column_type"]) and vertica_schema.rows[index][:data_type] != "timestamp")
191
+ return true
192
+ end
193
+ # and others ?? (PRIMARY, DEFAULT NULL, etc.)
194
+ index += 1
195
+ end
196
+ end
197
+ return false
198
+ end
199
+
200
+ def self.schema_changed? options
201
+ puts options
202
+ mysql_schema = Loader.mysql_table_definition(options)
203
+ vertica_schema = VerticaLoader.destination_table_vertica(options)
204
+
205
+ # empty result set from vertica means table does not exist
206
+ unless vertica_schema.size > 0
207
+ return {:changed => true, :mysql_schema => mysql_schema, :new => true}
208
+ end
209
+
210
+ # compare two schemas
211
+ mysql_schema_simple_form = []
212
+ mysql_schema.each(:as => :hash) do |row|
213
+ mysql_schema_simple_form << row
214
+ end
215
+
216
+ mysql_schema_2 = mysql_schema_simple_form
217
+ if compare_schemas(vertica_schema, mysql_schema_2)
218
+ result = {:changed => true, :mysql_schema => mysql_schema, :vertica_schema => vertica_schema,:new => false}
219
+ else
220
+ result = {:changed => false}
221
+ end
222
+ return result
149
223
  end
150
224
 
151
225
  ##
@@ -36,7 +36,7 @@ module Myreplicator
36
36
  # cmd += "--tab=#{options[:filepath]} "
37
37
  # cmd += "--fields-enclosed-by=\'\"\' "
38
38
  # cmd += "--fields-escaped-by=\'\\\\\' "
39
-
39
+
40
40
  return cmd
41
41
  end
42
42
 
@@ -80,16 +80,17 @@ module Myreplicator
80
80
  options = args.extract_options!
81
81
  options.reverse_merge! :flags => []
82
82
  db = options[:db]
83
+
83
84
  # Database host when ssh'ed into the db server
84
85
 
85
86
  db_host = "127.0.0.1"
86
-
87
+
87
88
  if !ssh_configs(db)["ssh_db_host"].blank?
88
89
  db_host = ssh_configs(db)["ssh_db_host"]
89
90
  elsif !db_configs(db)["host"].blank?
90
- db_host += db_configs(db)["host"]
91
+ db_host = db_configs(db)["host"]
91
92
  end
92
-
93
+
93
94
  flags = ""
94
95
 
95
96
  self.mysql_flags.each_pair do |flag, value|
@@ -120,11 +121,11 @@ module Myreplicator
120
121
  def self.get_outfile_sql options
121
122
  sql = "SELECT * INTO OUTFILE '#{options[:filepath]}' "
122
123
 
123
- sql += " FIELDS TERMINATED BY ';~;' OPTIONALLY ENCLOSED BY '\\\"' LINES TERMINATED BY '\\n'"
124
+ sql += " FIELDS TERMINATED BY '\\0' OPTIONALLY ENCLOSED BY '\\\"' LINES TERMINATED BY '\\n'"
124
125
 
125
126
  sql += "FROM #{options[:db]}.#{options[:table]} "
126
127
 
127
- if options[:incremental_col] && options[:incremental_val]
128
+ if options[:incremental_col] && !options[:incremental_val].blank?
128
129
  if options[:incremental_col_type] == "datetime"
129
130
  sql += "WHERE #{options[:incremental_col]} >= '#{options[:incremental_val]}'"
130
131
  else
@@ -159,8 +160,6 @@ module Myreplicator
159
160
  end
160
161
  end
161
162
 
162
- # BOB : You always build the host,password,username part of the command
163
- # Seems like this should be in a function somewhere
164
163
  cmd = Myreplicator.mysql
165
164
  cmd += "#{flags} -u#{db_configs(db)["username"]} -p#{db_configs(db)["password"]} "
166
165
  cmd += "-h#{db_host} " if db_configs(db)["host"].blank?
@@ -189,7 +188,7 @@ module Myreplicator
189
188
  options = args.extract_options!
190
189
  sql = "SELECT * FROM #{options[:db]}.#{options[:table]} "
191
190
 
192
- if options[:incremental_col] && options[:incremental_val]
191
+ if options[:incremental_col] && !options[:incremental_val].blank?
193
192
  if options[:incremental_col_type] == "datetime"
194
193
  sql += "WHERE #{options[:incremental_col]} >= '#{options[:incremental_val]}'"
195
194
  else
data/lib/exporter.rb CHANGED
@@ -1,3 +1,4 @@
1
1
  Dir["#{File.expand_path(File.dirname(__FILE__))}/exporter/*.rb"].each { | f | require File.expand_path(f) }
2
2
  Dir["#{File.expand_path(File.dirname(__FILE__))}/transporter/*.rb"].each { | f | require File.expand_path(f) }
3
3
  Dir["#{File.expand_path(File.dirname(__FILE__))}/loader/*.rb"].each { | f | require File.expand_path(f) }
4
+ Dir["#{File.expand_path(File.dirname(__FILE__))}/loader/vertica/*.rb"].each { | f | require File.expand_path(f) }
data/lib/loader/loader.rb CHANGED
@@ -177,24 +177,31 @@ module Myreplicator
177
177
  metadata.zipped = false
178
178
 
179
179
  options = {:table_name => exp.table_name, :db => exp.destination_schema,
180
- :filepath => metadata.destination_filepath(tmp_dir)}
180
+ :filepath => metadata.destination_filepath(tmp_dir), :source_schema => exp.source_schema}
181
181
 
182
182
  if metadata.export_type == "incremental_outfile"
183
- options[:fields_terminated_by] = ";~;"
183
+ options[:fields_terminated_by] = "\\0"
184
184
  options[:lines_terminated_by] = "\\n"
185
185
  end
186
186
 
187
- cmd = ImportSql.load_data_infile(options)
188
-
189
- puts cmd
190
-
191
- result = `#{cmd}` # execute
192
-
193
- unless result.nil?
194
- if result.size > 0
195
- raise Exceptions::LoaderError.new("Incremental Load #{metadata.filename} Failed!\n#{result}")
187
+ case metadata.export_to
188
+ when "vertica"
189
+ options = {:table_name => exp.table_name, :db => ActiveRecord::Base.configurations["vertica"]["database"],
190
+ :filepath => metadata.destination_filepath(tmp_dir), :source_schema => exp.source_schema, :export_id => metadata.export_id}
191
+ options[:destination_schema] = exp.destination_schema
192
+ Kernel.p "===== LOAD TO VERTICA ====="
193
+ Kernel.p options
194
+ Myreplicator::VerticaLoader.load options
195
+ when "mysql"
196
+ cmd = ImportSql.load_data_infile(options)
197
+ puts cmd
198
+ result = `#{cmd}` # execute
199
+ unless result.nil?
200
+ if result.size > 0
201
+ raise Exceptions::LoaderError.new("Incremental Load #{metadata.filename} Failed!\n#{result}")
202
+ end
196
203
  end
197
- end
204
+ end #case
198
205
  end
199
206
 
200
207
  ##
@@ -252,5 +259,18 @@ module Myreplicator
252
259
  return files
253
260
  end
254
261
 
262
+ def self.mysql_table_definition options
263
+ Kernel.p options
264
+ sql = "SELECT table_schema, table_name, column_name, is_nullable, data_type, column_type, column_key "
265
+ sql += "FROM INFORMATION_SCHEMA.COLUMNS where table_name = '#{options[:table]}' "
266
+ sql += "and table_schema = '#{options[:source_schema]}';"
267
+
268
+ puts sql
269
+
270
+ desc = DB.exec_sql(options[:source_schema], sql)
271
+ puts desc
272
+ return desc
273
+ end
274
+
255
275
  end
256
276
  end
@@ -0,0 +1,30 @@
1
+ module Myreplicator
2
+ class DB < ActiveRecord::Base
3
+
4
+ def self.connect db
5
+ establish_connection(ActiveRecord::Base.configurations[db])
6
+ end
7
+
8
+ ##
9
+ # Returns tables as an Array
10
+ # releases the connection
11
+ ##
12
+ def self.get_tables(db)
13
+ tables = []
14
+ begin
15
+ self.connect(db)
16
+ tables = self.connection.tables
17
+ self.connection_pool.release_connection
18
+ rescue Mysql2::Error => e
19
+ puts "Connection to #{db} Failed!"
20
+ puts e.message
21
+ end
22
+ return tables
23
+ end
24
+
25
+ def self.exec_sql source_db,sql
26
+ DB.connect(source_db)
27
+ return DB.connection.execute(sql)
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,30 @@
1
+ module VerticaUtils
2
+ class SourceDb < ActiveRecord::Base
3
+
4
+ def self.connect db
5
+ establish_connection(ActiveRecord::Base.configurations[db])
6
+ end
7
+
8
+ ##
9
+ # Returns tables as an Array
10
+ # releases the connection
11
+ ##
12
+ def self.get_tables(db)
13
+ tables = []
14
+ begin
15
+ self.connect(db)
16
+ tables = self.connection.tables
17
+ self.connection_pool.release_connection
18
+ rescue Mysql2::Error => e
19
+ puts "Connection to #{db} Failed!"
20
+ puts e.message
21
+ end
22
+ return tables
23
+ end
24
+
25
+ def self.exec_sql source_db,sql
26
+ SourceDb.connect(source_db)
27
+ return SourceDb.connection.execute(sql)
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,44 @@
1
+ module Myreplicator
2
+ class VerticaTypes
3
+
4
+ def self.convert type, col_type
5
+ if mysql_vertica_conversion[type].blank?
6
+ return col_type
7
+ else
8
+ return mysql_vertica_conversion[type]
9
+ end
10
+ end
11
+
12
+ def self.mysql_vertica_conversion
13
+ map = {
14
+ "int" => "int",
15
+ "integer" => "int",
16
+ "int8" => "int",
17
+ "smallint" => "int",
18
+ "bigint" => "int",
19
+ "tinyint" => "int",
20
+ "numeric" => "int",
21
+ "text" => "VARCHAR(65000)",
22
+ "mediumtext" => "VARCHAR(65000)",
23
+ "bit" => "binary",
24
+ "longtext" => "VARCHAR(65000)",
25
+ "float" => "decimal"
26
+ }
27
+ end
28
+
29
+ def self.convert_key key
30
+ map = {
31
+ "UNI" => "UNIQUE",
32
+ " MUL" => "",
33
+ "PRI" => "PRIMARY KEY"
34
+ }
35
+
36
+ if map[key].blank?
37
+ return ""
38
+ else
39
+ return map[key]
40
+ end
41
+ end
42
+
43
+ end
44
+ end