sq-dbsync 1.0.3 → 1.0.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.
- data/README.md +6 -0
- data/lib/sq/dbsync/database/common.rb +9 -1
- data/lib/sq/dbsync/database/postgres.rb +16 -0
- data/lib/sq/dbsync/version.rb +1 -1
- data/spec/integration/batch_load_action_spec.rb +0 -15
- metadata +86 -95
data/README.md
CHANGED
@@ -15,6 +15,12 @@ existing solutions were able to do this adequately.
|
|
15
15
|
At some point you will need to bite the bullet and implement a real ETL system,
|
16
16
|
but `sq-dbsync` can tide you over until you get there.
|
17
17
|
|
18
|
+
dbsync is MySQL `utf8mb4` clean: it will correctly handle four-byte
|
19
|
+
UTF8 characters like emojis. Under JRuby, you'll need to have the
|
20
|
+
server character set configured to `utf8mb4`. The specs include tests
|
21
|
+
for this; they'll fail if you run them under JRuby against MySQL with
|
22
|
+
different server character set.
|
23
|
+
|
18
24
|
Usage
|
19
25
|
-----
|
20
26
|
|
@@ -21,7 +21,15 @@ module Sq::Dbsync::Database
|
|
21
21
|
query = query.filter("#{plan.timestamp} > ?", last_row_at - overlap)
|
22
22
|
end
|
23
23
|
|
24
|
-
|
24
|
+
sql = query.sql
|
25
|
+
|
26
|
+
sql = customize_sql(sql, db.schema(table_name))
|
27
|
+
|
28
|
+
extract_sql_to_file(sql, file_name)
|
29
|
+
end
|
30
|
+
|
31
|
+
def customize_sql(sql, schema)
|
32
|
+
sql
|
25
33
|
end
|
26
34
|
|
27
35
|
def hash_schema(table_name)
|
@@ -26,6 +26,7 @@ module Sq::Dbsync::Database
|
|
26
26
|
ensure_connection
|
27
27
|
|
28
28
|
result = schema(table_name).each do |col, metadata|
|
29
|
+
metadata[:source_db_type] ||= metadata[:db_type]
|
29
30
|
metadata[:db_type] = psql_to_mysql_conversion(metadata[:db_type])
|
30
31
|
end
|
31
32
|
|
@@ -59,6 +60,21 @@ module Sq::Dbsync::Database
|
|
59
60
|
}.fetch(db_type, db_type)
|
60
61
|
end
|
61
62
|
|
63
|
+
|
64
|
+
# 'with time zone' pg fields have to be selected as
|
65
|
+
# "column-name"::timestamp or they end up with a +XX tz offset on
|
66
|
+
# them, which isn't the correct format for timestamp fields (which
|
67
|
+
# is what they get turned into for portability.)
|
68
|
+
|
69
|
+
def customize_sql(sql, schema)
|
70
|
+
schema.each do |name, metadata|
|
71
|
+
if metadata[:source_db_type].end_with? "with time zone"
|
72
|
+
sql.sub! %r{"#{name}"}, '\0::timestamp'
|
73
|
+
end
|
74
|
+
end
|
75
|
+
sql
|
76
|
+
end
|
77
|
+
|
62
78
|
def extract_sql_to_file(sql, file_name)
|
63
79
|
sql = "COPY (#{sql}) TO STDOUT"
|
64
80
|
file = sql_to_file(sql)
|
data/lib/sq/dbsync/version.rb
CHANGED
@@ -203,21 +203,6 @@ describe SQD::BatchLoadAction do
|
|
203
203
|
let(:source) { test_source(:source) }
|
204
204
|
|
205
205
|
it_should_behave_like 'a batch load'
|
206
|
-
|
207
|
-
it 'loads records with bodgy timestamps' do
|
208
|
-
create_source_table_with(
|
209
|
-
id: 1,
|
210
|
-
col1: 'hello',
|
211
|
-
pii: 'don alias',
|
212
|
-
created_at: '0000-00-00 00:00:00',
|
213
|
-
updated_at: '0000-00-00 00:00:00'
|
214
|
-
)
|
215
|
-
registry.ensure_storage_exists
|
216
|
-
|
217
|
-
action.call
|
218
|
-
|
219
|
-
target[:test_table].count.should == 1
|
220
|
-
end
|
221
206
|
end
|
222
207
|
|
223
208
|
describe 'with PG source' do
|
metadata
CHANGED
@@ -1,105 +1,105 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: sq-dbsync
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.4
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 1
|
8
|
-
- 0
|
9
|
-
- 3
|
10
|
-
version: 1.0.3
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Xavier Shay
|
14
9
|
- Damon McCormick
|
15
10
|
autorequire:
|
16
11
|
bindir: bin
|
17
12
|
cert_chain: []
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
- !ruby/object:Gem::Dependency
|
13
|
+
date: 2013-04-17 00:00:00.000000000 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
22
16
|
name: rspec
|
23
|
-
|
24
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
25
18
|
none: false
|
26
|
-
requirements:
|
19
|
+
requirements:
|
27
20
|
- - ~>
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
|
30
|
-
segments:
|
31
|
-
- 2
|
32
|
-
- 0
|
33
|
-
version: "2.0"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '2.0'
|
34
23
|
type: :development
|
35
|
-
version_requirements: *id001
|
36
|
-
- !ruby/object:Gem::Dependency
|
37
|
-
name: rake
|
38
24
|
prerelease: false
|
39
|
-
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ~>
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
version: '2.0'
|
31
|
+
- !ruby/object:Gem::Dependency
|
32
|
+
name: rake
|
33
|
+
requirement: !ruby/object:Gem::Requirement
|
40
34
|
none: false
|
41
|
-
requirements:
|
42
|
-
- -
|
43
|
-
- !ruby/object:Gem::Version
|
44
|
-
|
45
|
-
segments:
|
46
|
-
- 0
|
47
|
-
version: "0"
|
35
|
+
requirements:
|
36
|
+
- - ! '>='
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '0'
|
48
39
|
type: :development
|
49
|
-
version_requirements: *id002
|
50
|
-
- !ruby/object:Gem::Dependency
|
51
|
-
name: simplecov
|
52
40
|
prerelease: false
|
53
|
-
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ! '>='
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: simplecov
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
54
50
|
none: false
|
55
|
-
requirements:
|
56
|
-
- -
|
57
|
-
- !ruby/object:Gem::Version
|
58
|
-
|
59
|
-
segments:
|
60
|
-
- 0
|
61
|
-
version: "0"
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
62
55
|
type: :development
|
63
|
-
version_requirements: *id003
|
64
|
-
- !ruby/object:Gem::Dependency
|
65
|
-
name: cane
|
66
56
|
prerelease: false
|
67
|
-
|
57
|
+
version_requirements: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
59
|
+
requirements:
|
60
|
+
- - ! '>='
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
- !ruby/object:Gem::Dependency
|
64
|
+
name: cane
|
65
|
+
requirement: !ruby/object:Gem::Requirement
|
68
66
|
none: false
|
69
|
-
requirements:
|
70
|
-
- -
|
71
|
-
- !ruby/object:Gem::Version
|
72
|
-
|
73
|
-
segments:
|
74
|
-
- 0
|
75
|
-
version: "0"
|
67
|
+
requirements:
|
68
|
+
- - ! '>='
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '0'
|
76
71
|
type: :development
|
77
|
-
version_requirements: *id004
|
78
|
-
- !ruby/object:Gem::Dependency
|
79
|
-
name: sequel
|
80
72
|
prerelease: false
|
81
|
-
|
73
|
+
version_requirements: !ruby/object:Gem::Requirement
|
82
74
|
none: false
|
83
|
-
requirements:
|
84
|
-
- -
|
85
|
-
- !ruby/object:Gem::Version
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
75
|
+
requirements:
|
76
|
+
- - ! '>='
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
79
|
+
- !ruby/object:Gem::Dependency
|
80
|
+
name: sequel
|
81
|
+
requirement: !ruby/object:Gem::Requirement
|
82
|
+
none: false
|
83
|
+
requirements:
|
84
|
+
- - ! '>='
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '0'
|
90
87
|
type: :runtime
|
91
|
-
|
88
|
+
prerelease: false
|
89
|
+
version_requirements: !ruby/object:Gem::Requirement
|
90
|
+
none: false
|
91
|
+
requirements:
|
92
|
+
- - ! '>='
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '0'
|
92
95
|
description: Column based, timestamp replication of MySQL and Postgres databases.
|
93
|
-
email:
|
96
|
+
email:
|
94
97
|
- xavier@squareup.com
|
95
98
|
- damon@squaerup.com
|
96
99
|
executables: []
|
97
|
-
|
98
100
|
extensions: []
|
99
|
-
|
100
101
|
extra_rdoc_files: []
|
101
|
-
|
102
|
-
files:
|
102
|
+
files:
|
103
103
|
- spec/acceptance/loading_spec.rb
|
104
104
|
- spec/acceptance_helper.rb
|
105
105
|
- spec/database_helper.rb
|
@@ -145,38 +145,30 @@ files:
|
|
145
145
|
- sq-dbsync.gemspec
|
146
146
|
homepage: http://github.com/square/sq-dbsync
|
147
147
|
licenses: []
|
148
|
-
|
149
148
|
post_install_message:
|
150
149
|
rdoc_options: []
|
151
|
-
|
152
|
-
require_paths:
|
150
|
+
require_paths:
|
153
151
|
- lib
|
154
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
152
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
155
153
|
none: false
|
156
|
-
requirements:
|
157
|
-
- -
|
158
|
-
- !ruby/object:Gem::Version
|
159
|
-
|
160
|
-
|
161
|
-
- 0
|
162
|
-
version: "0"
|
163
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
154
|
+
requirements:
|
155
|
+
- - ! '>='
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: '0'
|
158
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
164
159
|
none: false
|
165
|
-
requirements:
|
166
|
-
- -
|
167
|
-
- !ruby/object:Gem::Version
|
168
|
-
|
169
|
-
segments:
|
170
|
-
- 0
|
171
|
-
version: "0"
|
160
|
+
requirements:
|
161
|
+
- - ! '>='
|
162
|
+
- !ruby/object:Gem::Version
|
163
|
+
version: '0'
|
172
164
|
requirements: []
|
173
|
-
|
174
165
|
rubyforge_project:
|
175
166
|
rubygems_version: 1.8.25
|
176
167
|
signing_key:
|
177
168
|
specification_version: 3
|
178
|
-
summary: Column based, timestamp replication of MySQL and Postgres databases. Uses
|
179
|
-
|
169
|
+
summary: Column based, timestamp replication of MySQL and Postgres databases. Uses
|
170
|
+
Ruby for the glue code but pushes the heavy lifting on to the database.
|
171
|
+
test_files:
|
180
172
|
- spec/acceptance/loading_spec.rb
|
181
173
|
- spec/acceptance_helper.rb
|
182
174
|
- spec/database_helper.rb
|
@@ -193,4 +185,3 @@ test_files:
|
|
193
185
|
- spec/unit/pipeline_spec.rb
|
194
186
|
- spec/unit/stream_logger_spec.rb
|
195
187
|
- spec/unit_helper.rb
|
196
|
-
has_rdoc: false
|