sq-dbsync 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -12,7 +12,9 @@ module Sq::Dbsync::Database
12
12
  def self.create(opts)
13
13
  case opts[:brand]
14
14
  when 'mysql'
15
- Sq::Dbsync::Database::Mysql.new(Sequel.connect(opts))
15
+ db = Sq::Dbsync::Database::Mysql.new(Sequel.connect(opts))
16
+ db.charset = opts[:charset] if opts[:charset]
17
+ db
16
18
  when 'postgresql'
17
19
  Sq::Dbsync::Database::Postgres.new(Sequel.connect(opts))
18
20
  else
@@ -16,6 +16,8 @@ module Sq::Dbsync::Database
16
16
 
17
17
  include Common
18
18
 
19
+ attr_accessor :charset
20
+
19
21
  def initialize(db)
20
22
  super
21
23
  @db = db
@@ -25,9 +27,11 @@ module Sq::Dbsync::Database
25
27
 
26
28
  def load_from_file(table_name, columns, file_name)
27
29
  ensure_connection
28
- sql = "LOAD DATA INFILE '%s' IGNORE INTO TABLE %s (%s)" % [
30
+ character_set = self.charset ? " character set #{self.charset}" : ""
31
+ sql = "LOAD DATA INFILE '%s' IGNORE INTO TABLE %s %s (%s)" % [
29
32
  file_name,
30
33
  table_name,
34
+ character_set,
31
35
  escape_columns(columns)
32
36
  ]
33
37
  db.run sql
@@ -42,9 +46,11 @@ module Sq::Dbsync::Database
42
46
  # Very low lock wait timeout, since we don't want loads to be blocked
43
47
  # waiting for long queries.
44
48
  set_lock_timeout(10)
45
- db.run "LOAD DATA INFILE '%s' REPLACE INTO TABLE %s (%s)" % [
49
+ character_set = self.charset ? " character set #{self.charset}" : ""
50
+ db.run "LOAD DATA INFILE '%s' REPLACE INTO TABLE %s %s (%s)" % [
46
51
  file_name,
47
52
  table_name,
53
+ character_set,
48
54
  escape_columns(columns)
49
55
  ]
50
56
  rescue Sequel::DatabaseError => e
@@ -134,6 +140,9 @@ module Sq::Dbsync::Database
134
140
  cmd += " -p%s" % opts[:password] if opts[:password]
135
141
  cmd += " -h %s" % opts[:host] if opts[:host]
136
142
  cmd += " -P %i" % opts[:port] if opts[:port]
143
+
144
+ cmd += " --default-character-set %s" % opts[:charset] if opts[:charset]
145
+
137
146
  cmd += " %s" % opts.fetch(:database)
138
147
 
139
148
  # This option prevents mysql from buffering results in memory before
@@ -1,5 +1,5 @@
1
1
  module Sq
2
2
  module Dbsync
3
- VERSION = '1.0.1'
3
+ VERSION = '1.0.2'
4
4
  end
5
5
  end
@@ -14,13 +14,14 @@ describe 'Syncing source databases to a target' do
14
14
  SQD::Manager.new(config, [[SQD::StaticTablePlan.new(plan), :source]])
15
15
  }
16
16
  let(:source) { manager.sources.fetch(:source) }
17
+ let(:mb4_source) { manager.sources.fetch(:mb4_source) }
17
18
  let(:alt_source) { manager.sources.fetch(:alt_source) }
18
19
  let(:target) { manager.target }
19
20
  let(:plan) {[{
20
21
  table_name: :test_table,
21
22
  source_table_name: :test_table,
22
23
  refresh_recent: true,
23
- columns: [:id, :updated_at]
24
+ columns: [:id, :updated_at, :value]
24
25
  }] }
25
26
 
26
27
  MINUTE = 60
@@ -74,6 +75,34 @@ describe 'Syncing source databases to a target' do
74
75
  target[:test_table ].map {|x| x[:id] }.should include(row)
75
76
  target[:alt_test_table ].map {|x| x[:id] }.should include(alt_row)
76
77
  end
78
+
79
+ it 'handles utf8mb4 inputs' do
80
+ plan = [{
81
+ table_name: :mb4_test_table,
82
+ source_table_name: :mb4_test_table,
83
+ refresh_recent: true,
84
+ columns: [:id, :updated_at, :value],
85
+ charset: "utf8mb4"
86
+ }]
87
+
88
+ config = {
89
+ sources: TEST_SOURCES,
90
+ target: MB4_TEST_TARGET,
91
+ logger: SQD::Loggers::Composite.new([logger]),
92
+ clock: ->{ @now }
93
+ }
94
+
95
+ manager = SQD::Manager.new(config, [[SQD::StaticTablePlan.new(plan), :mb4_source]])
96
+
97
+ row = mb4_source[:mb4_test_table].insert(updated_at: @now, value: "\u{1f4a9}")
98
+
99
+ manager.batch_nonactive
100
+
101
+ manager.target[:mb4_test_table].map {|x| x[:id] }.should include(row)
102
+ manager.target[:mb4_test_table].map {|x| x[:value] }.should include("\u{1f4a9}")
103
+ manager.target[:meta_last_sync_times].count.should == 1
104
+ end
105
+
77
106
  end
78
107
 
79
108
  context 'refresh recent load' do
@@ -211,6 +240,13 @@ describe 'Syncing source databases to a target' do
211
240
  primary_key :id
212
241
  DateTime :reporting_date
213
242
  DateTime :updated_at
243
+ String :value
244
+ end
245
+ mb4_source.create_table! :mb4_test_table, charset:"utf8mb4" do
246
+ primary_key :id
247
+ DateTime :reporting_date
248
+ DateTime :updated_at
249
+ String :value
214
250
  end
215
251
  source.create_table! :test_table_2 do
216
252
  primary_key :id
@@ -34,6 +34,7 @@ end
34
34
 
35
35
  TEST_SOURCES = {
36
36
  source: db_options(database: 'sq_dbsync_test_source'),
37
+ mb4_source: db_options(database: 'sq_dbsync_mb4_test_source', charset: "utf8mb4"),
37
38
  alt_source: db_options(database: 'sq_dbsync_test_source_alt'),
38
39
  postgres: db_options(
39
40
  user: `whoami`.chomp,
@@ -43,6 +44,7 @@ TEST_SOURCES = {
43
44
  )
44
45
  }
45
46
  TEST_TARGET = db_options(database: 'sq_dbsync_test_target')
47
+ MB4_TEST_TARGET = db_options(database: 'sq_dbsync_test_target', charset:"utf8mb4")
46
48
 
47
49
  $target = nil
48
50
  def test_target
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sq-dbsync
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-03-27 00:00:00.000000000 Z
13
+ date: 2013-04-15 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rspec
@@ -163,7 +163,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
163
163
  version: '0'
164
164
  requirements: []
165
165
  rubyforge_project:
166
- rubygems_version: 1.8.24
166
+ rubygems_version: 1.8.25
167
167
  signing_key:
168
168
  specification_version: 3
169
169
  summary: Column based, timestamp replication of MySQL and Postgres databases. Uses