myreplicator 0.0.16 → 0.0.17
Sign up to get free protection for your applications and to get access to all the features.
- data/app/assets/stylesheets/myreplicator/application.css +53 -10
- data/app/controllers/myreplicator/exports_controller.rb +17 -1
- data/app/controllers/myreplicator/home_controller.rb +4 -1
- data/app/helpers/myreplicator/application_helper.rb +20 -0
- data/app/models/myreplicator/export.rb +108 -23
- data/app/models/myreplicator/log.rb +90 -0
- data/app/views/myreplicator/exports/_form.html.erb +33 -9
- data/app/views/myreplicator/home/_home_menu.erb +6 -2
- data/app/views/myreplicator/home/errors.html.erb +15 -5
- data/app/views/myreplicator/home/index.html.erb +20 -43
- data/db/migrate/20121025191622_create_myreplicator_exports.rb +0 -6
- data/db/migrate/20121212003652_create_myreplicator_logs.rb +21 -0
- data/lib/exporter/export_metadata.rb +8 -1
- data/lib/exporter/mysql_exporter.rb +32 -0
- data/lib/exporter/sql_commands.rb +85 -4
- data/lib/loader/loader.rb +48 -7
- data/lib/myreplicator.rb +16 -4
- data/lib/myreplicator/version.rb +1 -1
- data/lib/transporter/parallelizer.rb +8 -0
- data/lib/transporter/transporter.rb +75 -11
- data/test/dummy/config/myreplicator.yml +0 -2
- data/test/dummy/config/myreplicator.yml~ +2 -0
- data/test/dummy/db/migrate/{20121108204327_create_myreplicator_exports.myreplicator.rb~ → 20121213003552_create_myreplicator_exports.myreplicator.rb} +3 -1
- data/test/dummy/db/migrate/20121213003553_create_myreplicator_logs.myreplicator.rb +22 -0
- data/test/dummy/db/schema.rb +24 -7
- data/test/dummy/log/development.log +1083 -0
- data/test/dummy/tmp/cache/assets/CD5/B90/sprockets%2Fc999d13a6a21113981c0d820e8043bdf +0 -0
- data/test/dummy/tmp/cache/assets/D8B/B60/sprockets%2Faa32227c440a378ccd21218eefeb80bf +0 -0
- data/test/dummy/tmp/cache/assets/DF8/5D0/sprockets%2Fb815ed34d61cfed96222daa3bfd1d84d +0 -0
- data/test/dummy/tmp/myreplicator/okl_test_batchy_batches_1355432256.tsv.gz +0 -0
- data/test/unit/myreplicator/log_test.rb +9 -0
- metadata +14 -8
- data/test/dummy/db/migrate/20121115194022_create_myreplicator_exports.myreplicator.rb +0 -36
@@ -3,7 +3,6 @@
|
|
3
3
|
export_to = ["destination_db","s3","both"]
|
4
4
|
export_type = ["incremental","fulldump"]
|
5
5
|
%>
|
6
|
-
|
7
6
|
<%= form_for(@export) do |f| %>
|
8
7
|
<% if @export.errors.any? %>
|
9
8
|
<div id="error_explanation">
|
@@ -18,11 +17,11 @@ export_type = ["incremental","fulldump"]
|
|
18
17
|
<% end %>
|
19
18
|
<div class="form-section">
|
20
19
|
<label>Source Schema</label>
|
21
|
-
<%= f.
|
20
|
+
<%= f.select :source_schema, @dbs %>
|
22
21
|
<label>Destination Schema</label>
|
23
|
-
<%= f.
|
22
|
+
<%= f.select :destination_schema, @dbs %>
|
24
23
|
<label>Table Name</label>
|
25
|
-
<%= f.
|
24
|
+
<%= f.select :table_name, [] %>
|
26
25
|
<label>Incremental Column</label>
|
27
26
|
<%= f.text_field :incremental_column %>
|
28
27
|
<label>Maximum Incremental Value</label>
|
@@ -93,12 +92,29 @@ export_type = ["incremental","fulldump"]
|
|
93
92
|
<%= javascript_include_tag "myreplicator/chosen.jquery.min" %>
|
94
93
|
<%= javascript_include_tag "myreplicator/cronwtf.min" %>
|
95
94
|
<script>
|
95
|
+
var dbs = {
|
96
|
+
<% @tables.each do |key,values| %>
|
97
|
+
"<%= key %>":[
|
98
|
+
<% values.each do |table| %>
|
99
|
+
"<%= table %>",
|
100
|
+
<% end %>
|
101
|
+
],
|
102
|
+
<% end %>
|
103
|
+
}
|
96
104
|
$(function(){
|
97
105
|
CronUI.translate();
|
98
106
|
$(".chosen").chosen();
|
107
|
+
$("#export_destination_schema,#export_table_name").chosen();
|
99
108
|
$(".cron").chosen().change(function(){CronUI.translate()});
|
109
|
+
$("#export_source_schema").chosen().change(function(){
|
110
|
+
exportSchemaSelect($(this).val())
|
111
|
+
});
|
112
|
+
exportSchemaSelect($("#export_source_schema").val());
|
113
|
+
<%- if @edit -%>
|
114
|
+
editInit();
|
115
|
+
<%- end -%>
|
116
|
+
})
|
100
117
|
|
101
|
-
<%- if @edit -%>
|
102
118
|
function editInit(){
|
103
119
|
var cron = "<%= @export.cron %>";
|
104
120
|
var displays = ["#min","#hour","#day","#month","#dow"];
|
@@ -108,10 +124,18 @@ function editInit(){
|
|
108
124
|
$(displays[i]).val(cron_vals[i]).trigger("liszt:updated");
|
109
125
|
}
|
110
126
|
CronUI.translate();
|
127
|
+
$("#export_table_name").val("<%= @export.table_name %>").trigger("liszt:updated");
|
111
128
|
}
|
112
|
-
editInit();
|
113
|
-
<%- end -%>
|
114
129
|
|
115
|
-
|
116
|
-
|
130
|
+
function exportSchemaSelect(val){
|
131
|
+
var target = $("#export_table_name");
|
132
|
+
var tables = dbs[val];
|
133
|
+
var l = tables.length;
|
134
|
+
var options = "";
|
135
|
+
for(i=0;i<l;i++){
|
136
|
+
options += "<option value='"+tables[i]+"'>"+tables[i]+"</option>";
|
137
|
+
}
|
138
|
+
target.val('').find("option").remove().trigger("liszt:updated");
|
139
|
+
target.append(options).trigger("liszt:updated");
|
140
|
+
}
|
117
141
|
</script>
|
@@ -1,5 +1,9 @@
|
|
1
|
+
<%
|
2
|
+
err = err_count
|
3
|
+
run = run_count
|
4
|
+
%>
|
1
5
|
<div class="home-menu">
|
2
6
|
<span>lists:</span>
|
3
|
-
<a href="<%= root_url %>" class="<% if @option == 'overview' %>on<% end %>">overview
|
4
|
-
<a href="<%= errors_path %>" class="<% if @option == 'errors' %>on<% end %>">errors
|
7
|
+
<a href="<%= root_url %>" class="<% if @option == 'overview' %>on<% end %> overview">overview <% if run > 0 %><span><%= run %></span><% end %></a>
|
8
|
+
<a href="<%= errors_path %>" class="<% if @option == 'errors' %>on<% end %>">errors <% if err > 0 %><span><%= err %></span><% end %></a>
|
5
9
|
</div>
|
@@ -1,10 +1,20 @@
|
|
1
1
|
<%= render :partial => 'home_menu' %>
|
2
2
|
<% @exports.each do |ex| %>
|
3
3
|
<div class="error-display">
|
4
|
-
<span><em>table name:</em> <%= ex.table_name %></span>
|
5
|
-
<span><em>source schema:</em><%= ex.source_schema %></span>
|
6
|
-
<span><em>updated at:</em><%= ex.updated_at.strftime("%Y-%m-%d %H:%M") %></span>
|
7
|
-
<span><em>error:</em></span>
|
8
|
-
<pre><%= ex.error %></pre>
|
4
|
+
<span><em>table name:</em> <%= ex.table_name %></span>
|
5
|
+
<span><em>source schema:</em><%= ex.source_schema %></span>
|
6
|
+
<span><em>updated at:</em><%= ex.updated_at.strftime("%Y-%m-%d %H:%M") %></span>
|
7
|
+
<span><em>error:</em></span>
|
8
|
+
<pre><%= ex.error %></pre>
|
9
|
+
</div>
|
10
|
+
<% end %>
|
11
|
+
<% @logs.each do |log| %>
|
12
|
+
<div class="error-display">
|
13
|
+
<span><em>name:</em> <%= log.name %></span>
|
14
|
+
<span><em>file:</em> <%= log.file %></span>
|
15
|
+
<span><em>type:</em> <%= log.job_type %></span>
|
16
|
+
<span><em>started:</em> <%= log.started_at.strftime("%Y-%m-%d %H:%M:%S") %></span>
|
17
|
+
<span><em>error:</em></span>
|
18
|
+
<pre><%= log.error %></pre>
|
9
19
|
</div>
|
10
20
|
<% end %>
|
@@ -1,48 +1,25 @@
|
|
1
1
|
<%= render :partial => 'home_menu' %>
|
2
|
-
<% states = @exports.group_by(&:state) %>
|
3
2
|
<div id="overview-wrapper">
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
<% states.each do |state, exports| %>
|
25
|
-
<li id="<%= state.downcase %>_state">
|
26
|
-
<h4><%= state %> Exports</h4>
|
27
|
-
<table class="data-grid">
|
28
|
-
<thead>
|
29
|
-
<tr>
|
30
|
-
<th>Table</th>
|
31
|
-
<th>Schema</th>
|
32
|
-
<th>Updated</th>
|
33
|
-
</tr>
|
34
|
-
</thead>
|
35
|
-
<tbody>
|
36
|
-
<% exports.sort{|a,b| b.updated_at<=>a.updated_at}.each do |ex| %>
|
37
|
-
<td><%= ex.table_name %></td>
|
38
|
-
<td><%= ex.source_schema %></td>
|
39
|
-
<td><%= ex.updated_at.strftime("%Y-%m-%d %H:%M") %></td>
|
40
|
-
<% end %>
|
41
|
-
</tbody>
|
42
|
-
</table>
|
43
|
-
</li>
|
44
|
-
<% end %>
|
45
|
-
</ul>
|
3
|
+
<h6>Running tasks</h6>
|
4
|
+
<table class="overview">
|
5
|
+
<% @logs.each do |log| %>
|
6
|
+
<tr>
|
7
|
+
<td>
|
8
|
+
<span class="name"><%= log.name %></span>
|
9
|
+
<span class="file"><%= log.file %></span>
|
10
|
+
</td>
|
11
|
+
<td><%= log.state %></td>
|
12
|
+
<td><%= log.job_type %></td>
|
13
|
+
<td><%= log.started_at.strftime("%Y-%m-%d %H:%M:%S") %></td>
|
14
|
+
<td><%= chronos(@now.to_i - log.started_at.to_i) %></td>
|
15
|
+
</tr>
|
16
|
+
<% end %>
|
17
|
+
</table>
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
|
22
|
+
|
46
23
|
</div>
|
47
24
|
<script>
|
48
25
|
jQuery(function(){
|
@@ -15,14 +15,8 @@ class CreateMyreplicatorExports < ActiveRecord::Migration
|
|
15
15
|
t.text :error
|
16
16
|
t.boolean :active, :default => true
|
17
17
|
t.integer :exporter_pid
|
18
|
-
t.integer :transporter_pid
|
19
|
-
t.integer :loader_pid
|
20
18
|
t.datetime :export_started_at, :default => nil
|
21
19
|
t.datetime :export_finished_at, :default => nil
|
22
|
-
t.datetime :load_started_at, :default => nil
|
23
|
-
t.datetime :load_finished_at, :default => nil
|
24
|
-
t.datetime :transfer_started_at, :default => nil
|
25
|
-
t.datetime :transfer_finished_at, :default => nil
|
26
20
|
t.timestamps
|
27
21
|
end
|
28
22
|
add_index :myreplicator_exports, [:source_schema, :destination_schema, :table_name], :unique => true, :name => "unique_index"
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class CreateMyreplicatorLogs < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :myreplicator_logs do |t|
|
4
|
+
t.integer :pid
|
5
|
+
t.string :job_type
|
6
|
+
t.string :name
|
7
|
+
t.string :file
|
8
|
+
t.string :state
|
9
|
+
t.string :thread_state
|
10
|
+
t.string :hostname
|
11
|
+
t.string :export_id
|
12
|
+
t.text :error
|
13
|
+
t.text :backtrace
|
14
|
+
t.string :guid
|
15
|
+
t.datetime :started_at, :default => nil
|
16
|
+
t.datetime :finished_at, :default => nil
|
17
|
+
|
18
|
+
t.timestamps
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -32,6 +32,7 @@ module Myreplicator
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
+
# BOB : This only handles gzipped files, is that what you want?
|
35
36
|
def filename
|
36
37
|
name = filepath.split("/").last
|
37
38
|
name = zipped ? "#{name}.gz" : name
|
@@ -44,7 +45,7 @@ module Myreplicator
|
|
44
45
|
|
45
46
|
##
|
46
47
|
# Keeps track of the state of the export
|
47
|
-
#
|
48
|
+
# Stores itself in a JSON file on exit
|
48
49
|
##
|
49
50
|
def self.record *args
|
50
51
|
options = args.extract_options!
|
@@ -160,6 +161,11 @@ module Myreplicator
|
|
160
161
|
return path
|
161
162
|
end
|
162
163
|
|
164
|
+
##
|
165
|
+
# Writes Json to file using echo
|
166
|
+
# file is written to remote server via SSH
|
167
|
+
# Echo is used for writing the file
|
168
|
+
##
|
163
169
|
def store!
|
164
170
|
cmd = "echo \"#{self.to_json.gsub("\"","\\\\\"")}\" > #{@filepath}.json"
|
165
171
|
puts cmd
|
@@ -175,6 +181,7 @@ module Myreplicator
|
|
175
181
|
|
176
182
|
def set_attributes options
|
177
183
|
options.symbolize_keys!
|
184
|
+
|
178
185
|
@export_time = options[:export_time] if options[:export_time]
|
179
186
|
@table = options[:table] if options[:table]
|
180
187
|
@database = options[:database] if options[:database]
|
@@ -31,9 +31,12 @@ module Myreplicator
|
|
31
31
|
metadata.state = "export_completed"
|
32
32
|
wrapup metadata
|
33
33
|
end
|
34
|
+
|
34
35
|
elsif !is_running?
|
35
36
|
# local max value for incremental export
|
37
|
+
|
36
38
|
max_value = incremental_export(metadata)
|
39
|
+
#max_value = incremental_export_into_outfile(metadata)
|
37
40
|
|
38
41
|
metadata.incremental_val = max_value # store max val in metadata
|
39
42
|
|
@@ -128,9 +131,38 @@ module Myreplicator
|
|
128
131
|
puts "Exporting..."
|
129
132
|
result = execute_export(cmd, metadata)
|
130
133
|
check_result(result, 0)
|
134
|
+
|
135
|
+
return max_value
|
131
136
|
end
|
132
137
|
|
133
138
|
|
139
|
+
##
|
140
|
+
# Exports table incrementally, similar to incremental_export method
|
141
|
+
# Dumps file in tmp directory specified in myreplicator.yml
|
142
|
+
# Note that directory needs 777 permissions for mysql to be able to export the file
|
143
|
+
# Uses ;~; as the delimiter and new line for lines
|
144
|
+
##
|
145
|
+
|
146
|
+
def incremental_export_into_outfile metadata
|
147
|
+
max_value = @export_obj.max_value
|
148
|
+
@export_obj.update_max_val if @export_obj.max_incremental_value.blank?
|
149
|
+
|
150
|
+
cmd = SqlCommands.mysql_export_outfile(:db => @export_obj.source_schema,
|
151
|
+
:table => @export_obj.table_name,
|
152
|
+
:filepath => filepath,
|
153
|
+
:incremental_col => @export_obj.incremental_column,
|
154
|
+
:incremental_col_type => @export_obj.incremental_column_type,
|
155
|
+
:incremental_val => @export_obj.max_incremental_value)
|
156
|
+
|
157
|
+
metadata.export_type = "incremental_outfile"
|
158
|
+
update_export(:state => "exporting", :export_started_at => Time.now, :exporter_pid => Process.pid)
|
159
|
+
puts "Exporting..."
|
160
|
+
result = execute_export(cmd, metadata)
|
161
|
+
check_result(result, 0)
|
162
|
+
|
163
|
+
return max_value
|
164
|
+
end
|
165
|
+
|
134
166
|
##
|
135
167
|
# Completes an export process
|
136
168
|
# Zips files, updates states etc
|
@@ -34,14 +34,25 @@ module Myreplicator
|
|
34
34
|
return cmd
|
35
35
|
end
|
36
36
|
|
37
|
+
##
|
38
|
+
# Db configs for active record connection
|
39
|
+
##
|
40
|
+
|
37
41
|
def self.db_configs db
|
38
42
|
ActiveRecord::Base.configurations[db]
|
39
43
|
end
|
40
44
|
|
45
|
+
##
|
46
|
+
# Configs needed for SSH connection to source server
|
47
|
+
##
|
48
|
+
|
41
49
|
def self.ssh_configs db
|
42
50
|
Myreplicator.configs[db]
|
43
51
|
end
|
44
52
|
|
53
|
+
##
|
54
|
+
# Default dump flags
|
55
|
+
##
|
45
56
|
def self.dump_flags
|
46
57
|
{"add-locks" => true,
|
47
58
|
"compact" => false,
|
@@ -55,6 +66,10 @@ module Myreplicator
|
|
55
66
|
}
|
56
67
|
end
|
57
68
|
|
69
|
+
##
|
70
|
+
# Mysql exports using -e flag
|
71
|
+
##
|
72
|
+
|
58
73
|
def self.mysql_export *args
|
59
74
|
options = args.extract_options!
|
60
75
|
options.reverse_merge! :flags => []
|
@@ -83,6 +98,69 @@ module Myreplicator
|
|
83
98
|
return cmd
|
84
99
|
end
|
85
100
|
|
101
|
+
##
|
102
|
+
# Mysql export data into outfile option
|
103
|
+
# Provided for tables that need special delimiters
|
104
|
+
##
|
105
|
+
|
106
|
+
def self.get_outfile_sql options
|
107
|
+
sql = "SELECT * INTO OUTFILE '#{options[:filepath]}' "
|
108
|
+
|
109
|
+
sql += " FIELDS TERMINATED BY ';~;' OPTIONALLY ENCLOSED BY '\\\"' LINES TERMINATED BY '\\n'"
|
110
|
+
|
111
|
+
sql += "FROM #{options[:db]}.#{options[:table]} "
|
112
|
+
|
113
|
+
if options[:incremental_col] && options[:incremental_val]
|
114
|
+
if options[:incremental_col_type] == "datetime"
|
115
|
+
sql += "WHERE #{options[:incremental_col]} >= '#{options[:incremental_val]}'"
|
116
|
+
else
|
117
|
+
sql += "WHERE #{options[:incremental_col]} >= #{options[:incremental_val]}"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
return sql
|
122
|
+
end
|
123
|
+
|
124
|
+
##
|
125
|
+
# Export using outfile
|
126
|
+
# ;~; delimited
|
127
|
+
# terminated by newline
|
128
|
+
# Location of the output file needs to have 777 perms
|
129
|
+
##
|
130
|
+
def self.mysql_export_outfile *args
|
131
|
+
options = args.extract_options!
|
132
|
+
options.reverse_merge! :flags => []
|
133
|
+
db = options[:db]
|
134
|
+
|
135
|
+
# Database host when ssh'ed into the db server
|
136
|
+
db_host = ssh_configs(db)["ssh_db_host"].nil? ? "127.0.0.1" : ssh_configs(db)["ssh_db_host"]
|
137
|
+
|
138
|
+
flags = ""
|
139
|
+
|
140
|
+
self.mysql_flags.each_pair do |flag, value|
|
141
|
+
if options[:flags].include? flag
|
142
|
+
flags += " --#{flag} "
|
143
|
+
elsif value
|
144
|
+
flags += " --#{flag} "
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
# BOB : You always build the host,password,username part of the command
|
149
|
+
# Seems like this should be in a function somewhere
|
150
|
+
cmd = Myreplicator.mysql
|
151
|
+
cmd += "#{flags} -u#{db_configs(db)["username"]} -p#{db_configs(db)["password"]} "
|
152
|
+
cmd += "-h#{db_host} " if db_configs(db)["host"].blank?
|
153
|
+
cmd += db_configs(db)["port"].blank? ? "-P3306 " : "-P#{db_configs(db)["port"]} "
|
154
|
+
cmd += "--execute=\"#{get_outfile_sql(options)}\" "
|
155
|
+
|
156
|
+
puts cmd
|
157
|
+
|
158
|
+
return cmd
|
159
|
+
end
|
160
|
+
|
161
|
+
##
|
162
|
+
# Default flags for mysql export
|
163
|
+
##
|
86
164
|
def self.mysql_flags
|
87
165
|
{"column-names" => false,
|
88
166
|
"quick" => true,
|
@@ -90,6 +168,9 @@ module Myreplicator
|
|
90
168
|
}
|
91
169
|
end
|
92
170
|
|
171
|
+
##
|
172
|
+
# Builds SQL needed for incremental exports
|
173
|
+
##
|
93
174
|
def self.export_sql *args
|
94
175
|
options = args.extract_options!
|
95
176
|
sql = "SELECT * FROM #{options[:db]}.#{options[:table]} "
|
@@ -105,6 +186,10 @@ module Myreplicator
|
|
105
186
|
return sql
|
106
187
|
end
|
107
188
|
|
189
|
+
##
|
190
|
+
# Gets the Maximum value for the incremental
|
191
|
+
# column of the export job
|
192
|
+
##
|
108
193
|
def self.max_value_sql *args
|
109
194
|
options = args.extract_options!
|
110
195
|
sql = ""
|
@@ -118,9 +203,5 @@ module Myreplicator
|
|
118
203
|
return sql
|
119
204
|
end
|
120
205
|
|
121
|
-
def self.mysql_export_outfile
|
122
|
-
|
123
|
-
end
|
124
|
-
|
125
206
|
end
|
126
207
|
end
|
data/lib/loader/loader.rb
CHANGED
@@ -3,6 +3,8 @@ require "exporter"
|
|
3
3
|
module Myreplicator
|
4
4
|
class Loader
|
5
5
|
|
6
|
+
@queue = :myreplicator_load # Provided for Resque
|
7
|
+
|
6
8
|
def initialize *args
|
7
9
|
options = args.extract_options!
|
8
10
|
end
|
@@ -11,10 +13,22 @@ module Myreplicator
|
|
11
13
|
@tmp_dir ||= File.join(Myreplicator.app_root,"tmp", "myreplicator")
|
12
14
|
end
|
13
15
|
|
14
|
-
|
16
|
+
##
|
17
|
+
# Main method provided for resque
|
18
|
+
##
|
19
|
+
def self.perform
|
20
|
+
load # Kick off the load process
|
21
|
+
end
|
22
|
+
|
23
|
+
##
|
24
|
+
# Kicks off all initial loads first and then all incrementals
|
25
|
+
# Looks at metadata files stored locally
|
26
|
+
##
|
27
|
+
def self.load
|
15
28
|
initials = []
|
16
29
|
incrementals = []
|
17
30
|
|
31
|
+
# Read all metadata files
|
18
32
|
metadata_files.each do |metadata|
|
19
33
|
if metadata.export_type == "initial"
|
20
34
|
initials << metadata
|
@@ -22,16 +36,32 @@ module Myreplicator
|
|
22
36
|
incrementals << metadata
|
23
37
|
end
|
24
38
|
end
|
25
|
-
|
39
|
+
|
40
|
+
# Load all new tables
|
26
41
|
initials.each do |metadata|
|
27
42
|
puts metadata.table
|
28
|
-
|
43
|
+
|
44
|
+
Log.run(:job_type => "loader",
|
45
|
+
:name => "initial_import",
|
46
|
+
:file => metadata.filename,
|
47
|
+
:export_id => metadata.export_id) do |log|
|
48
|
+
|
49
|
+
initial_load metadata
|
50
|
+
end
|
51
|
+
|
29
52
|
cleanup metadata
|
30
53
|
end
|
31
54
|
|
55
|
+
# Load all incremental files
|
32
56
|
incrementals.each do |metadata|
|
33
57
|
puts metadata.table
|
34
|
-
|
58
|
+
Log.run(:job_type => "loader",
|
59
|
+
:name => "incremental_import",
|
60
|
+
:file => metadata.filename,
|
61
|
+
:export_id => metadata.export_id) do |log|
|
62
|
+
|
63
|
+
incremental_load metadata
|
64
|
+
end
|
35
65
|
cleanup metadata
|
36
66
|
end
|
37
67
|
end
|
@@ -47,12 +77,14 @@ module Myreplicator
|
|
47
77
|
cmd = ImportSql.initial_load(:db => exp.destination_schema,
|
48
78
|
:filepath => metadata.destination_filepath(tmp_dir))
|
49
79
|
puts cmd
|
80
|
+
|
50
81
|
result = `#{cmd}` # execute
|
51
82
|
unless result.nil?
|
52
83
|
if result.size > 0
|
53
84
|
raise Exceptions::LoaderError.new("Initial Load #{metadata.filename} Failed!\n#{result}")
|
54
85
|
end
|
55
86
|
end
|
87
|
+
|
56
88
|
end
|
57
89
|
|
58
90
|
##
|
@@ -63,12 +95,21 @@ module Myreplicator
|
|
63
95
|
exp = Export.find(metadata.export_id)
|
64
96
|
unzip(metadata.filename)
|
65
97
|
metadata.zipped = false
|
98
|
+
|
99
|
+
options = {:table_name => exp.table_name, :db => exp.destination_schema,
|
100
|
+
:filepath => metadata.destination_filepath(tmp_dir)}
|
101
|
+
|
102
|
+
if metadata.export_type == "incremental_outfile"
|
103
|
+
options[:fields_terminated_by] = ";~;"
|
104
|
+
options[:lines_terminated_by] = "\\n"
|
105
|
+
end
|
106
|
+
|
107
|
+
cmd = ImportSql.load_data_infile(options)
|
66
108
|
|
67
|
-
cmd = ImportSql.load_data_infile(:table_name => exp.table_name,
|
68
|
-
:db => exp.destination_schema,
|
69
|
-
:filepath => metadata.destination_filepath(tmp_dir))
|
70
109
|
puts cmd
|
110
|
+
|
71
111
|
result = `#{cmd}` # execute
|
112
|
+
|
72
113
|
unless result.nil?
|
73
114
|
if result.size > 0
|
74
115
|
raise Exceptions::LoaderError.new("Incremental Load #{metadata.filename} Failed!\n#{result}")
|