sq-dbsync 1.0.6 → 1.0.7
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 +14 -0
- data/lib/sq/dbsync/batch_load_action.rb +1 -2
- data/lib/sq/dbsync/database/common.rb +2 -3
- data/lib/sq/dbsync/database/postgres.rb +26 -26
- data/lib/sq/dbsync/incremental_load_action.rb +2 -3
- data/lib/sq/dbsync/load_action.rb +3 -3
- data/lib/sq/dbsync/refresh_recent_load_action.rb +2 -2
- data/lib/sq/dbsync/version.rb +1 -1
- data/spec/integration/batch_load_action_spec.rb +3 -3
- metadata +2 -2
data/README.md
CHANGED
@@ -171,6 +171,20 @@ Documentation
|
|
171
171
|
* `timestamp` The column to treat as a timestamp. Must be a member of the
|
172
172
|
`:columns` option. (default: select `updated_at` or `created_at`, in that
|
173
173
|
order)
|
174
|
+
* `type_casts` a hash for specifying column-level type casting from postgres
|
175
|
+
data types to mysql data types. Primarily intended for custom postgres type
|
176
|
+
defintions that have no mysql equivalent. The hash key is the column name,
|
177
|
+
and the value is the desired mysql column type. See the
|
178
|
+
`Sq::Dbsync::Database::Postgres::CASTS` constant for the format of the hash.
|
179
|
+
Example:
|
180
|
+
|
181
|
+
```ruby
|
182
|
+
{
|
183
|
+
:table_name => :some_table,
|
184
|
+
:columns => [ :custom_postgres_type ],
|
185
|
+
:type_casts => { :custom_postgres_type => "varchar(255)" }
|
186
|
+
}
|
187
|
+
```
|
174
188
|
|
175
189
|
### Handling Deletes
|
176
190
|
|
@@ -32,9 +32,9 @@ module Sq::Dbsync::Database
|
|
32
32
|
sql
|
33
33
|
end
|
34
34
|
|
35
|
-
def hash_schema(
|
35
|
+
def hash_schema(plan)
|
36
36
|
ensure_connection
|
37
|
-
Hash[schema(
|
37
|
+
Hash[schema(plan.source_table_name)]
|
38
38
|
end
|
39
39
|
|
40
40
|
def name
|
@@ -94,6 +94,5 @@ module Sq::Dbsync::Database
|
|
94
94
|
Process.waitpid2(pid)[1]
|
95
95
|
end
|
96
96
|
end
|
97
|
-
|
98
97
|
end
|
99
98
|
end
|
@@ -8,6 +8,24 @@ module Sq::Dbsync::Database
|
|
8
8
|
# Decorator around a Sequel database object, providing some non-standard
|
9
9
|
# extensions required for effective extraction from Postgres.
|
10
10
|
class Postgres < Delegator
|
11
|
+
CASTS = {
|
12
|
+
"text" => "varchar(255)",
|
13
|
+
"character varying(255)" => "varchar(255)",
|
14
|
+
|
15
|
+
# 255 is an arbitrary choice here. The one example we have
|
16
|
+
# only has data 32 characters long in it.
|
17
|
+
"character varying" => "varchar(255)",
|
18
|
+
|
19
|
+
# Arbitrarily chosen precision. The default numeric type in mysql is
|
20
|
+
# (10, 0), which is perhaps the most useless default I could imagine.
|
21
|
+
"numeric" => "numeric(12,6)",
|
22
|
+
"boolean" => "char(1)",
|
23
|
+
|
24
|
+
# mysql has no single-column representation for timestamp with time zone
|
25
|
+
"timestamp with time zone" => "datetime",
|
26
|
+
"time without time zone" => "time",
|
27
|
+
"timestamp without time zone" => "datetime",
|
28
|
+
}
|
11
29
|
|
12
30
|
include Sq::Dbsync::Database::Common
|
13
31
|
|
@@ -22,12 +40,15 @@ module Sq::Dbsync::Database
|
|
22
40
|
# Unimplemented
|
23
41
|
end
|
24
42
|
|
25
|
-
def hash_schema(
|
43
|
+
def hash_schema(plan)
|
44
|
+
type_casts = plan.type_casts || {}
|
26
45
|
ensure_connection
|
27
46
|
|
28
|
-
result = schema(
|
47
|
+
result = schema(plan.source_table_name).each do |col, metadata|
|
29
48
|
metadata[:source_db_type] ||= metadata[:db_type]
|
30
|
-
metadata[:db_type] =
|
49
|
+
metadata[:db_type] = cast_psql_to_mysql(
|
50
|
+
metadata[:db_type], type_casts[col.to_s]
|
51
|
+
)
|
31
52
|
end
|
32
53
|
|
33
54
|
Hash[result]
|
@@ -37,35 +58,14 @@ module Sq::Dbsync::Database
|
|
37
58
|
|
38
59
|
attr_reader :db
|
39
60
|
|
40
|
-
def
|
41
|
-
|
42
|
-
"text" => "varchar(255)",
|
43
|
-
"character varying(255)" => "varchar(255)",
|
44
|
-
|
45
|
-
# 255 is an arbitrary choice here. The one example we have
|
46
|
-
# only has data 32 characters long in it.
|
47
|
-
"character varying" => "varchar(255)",
|
48
|
-
|
49
|
-
# Arbitrarily chosen precision. The default numeric type in mysql is
|
50
|
-
# (10, 0), which is perhaps the most useless default I could imagine.
|
51
|
-
"numeric" => "numeric(12,6)",
|
52
|
-
|
53
|
-
"time without time zone" => "time",
|
54
|
-
"timestamp without time zone" => "datetime",
|
55
|
-
|
56
|
-
# mysql has no single-column representation for timestamp with time zone
|
57
|
-
"timestamp with time zone" => "datetime",
|
58
|
-
|
59
|
-
"boolean" => "char(1)"
|
60
|
-
}.fetch(db_type, db_type)
|
61
|
+
def cast_psql_to_mysql(db_type, cast=nil)
|
62
|
+
CASTS.fetch(db_type, cast || db_type)
|
61
63
|
end
|
62
64
|
|
63
|
-
|
64
65
|
# 'with time zone' pg fields have to be selected as
|
65
66
|
# "column-name"::timestamp or they end up with a +XX tz offset on
|
66
67
|
# them, which isn't the correct format for timestamp fields (which
|
67
68
|
# is what they get turned into for portability.)
|
68
|
-
|
69
69
|
def customize_sql(sql, schema)
|
70
70
|
schema.each do |name, metadata|
|
71
71
|
if metadata[:source_db_type].end_with? "with time zone"
|
@@ -72,7 +72,7 @@ module Sq::Dbsync
|
|
72
72
|
|
73
73
|
def filter_columns
|
74
74
|
source = plan.source_db
|
75
|
-
source_columns = source.hash_schema(plan
|
75
|
+
source_columns = source.hash_schema(plan).keys
|
76
76
|
plan.columns = resolve_columns(plan, source_columns) &
|
77
77
|
(target_columns || source_columns)
|
78
78
|
end
|
@@ -81,8 +81,7 @@ module Sq::Dbsync
|
|
81
81
|
# Because we may create the target table later if necessary,
|
82
82
|
# we need to check if it *really* exists
|
83
83
|
target_columns = if target.table_exists?(plan.table_name)
|
84
|
-
|
85
|
-
target.hash_schema(tname).keys
|
84
|
+
target.hash_schema(plan).keys
|
86
85
|
else
|
87
86
|
nil
|
88
87
|
end
|
@@ -83,9 +83,9 @@ module Sq::Dbsync
|
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
86
|
-
def add_schema_to_table_plan(
|
87
|
-
|
88
|
-
|
86
|
+
def add_schema_to_table_plan(plan)
|
87
|
+
plan.schema ||= plan.source_db.hash_schema(plan)
|
88
|
+
plan
|
89
89
|
end
|
90
90
|
|
91
91
|
def resolve_columns(plan, source_columns)
|
@@ -49,7 +49,7 @@ module Sq::Dbsync
|
|
49
49
|
|
50
50
|
def filter_columns
|
51
51
|
source = plan.source_db
|
52
|
-
source_columns = source.hash_schema(plan
|
52
|
+
source_columns = source.hash_schema(plan).keys
|
53
53
|
plan.columns = resolve_columns(plan, source_columns) &
|
54
54
|
(target_columns || source_columns)
|
55
55
|
end
|
@@ -58,7 +58,7 @@ module Sq::Dbsync
|
|
58
58
|
# Because we may create the target table later if necessary,
|
59
59
|
# we need to check if it *really* exists
|
60
60
|
target_columns = if target.table_exists?(plan.table_name)
|
61
|
-
target.hash_schema(plan
|
61
|
+
target.hash_schema(plan).keys
|
62
62
|
else
|
63
63
|
nil
|
64
64
|
end
|
data/lib/sq/dbsync/version.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'integration_helper'
|
2
|
-
|
3
2
|
require 'sq/dbsync/database/connection'
|
4
3
|
require 'sq/dbsync/loggers'
|
5
4
|
require 'sq/dbsync/batch_load_action'
|
@@ -54,8 +53,9 @@ describe SQD::BatchLoadAction do
|
|
54
53
|
it 'copies all columns to target' do
|
55
54
|
action.call
|
56
55
|
|
57
|
-
|
58
|
-
|
56
|
+
plan = OpenStruct.new(table_plan)
|
57
|
+
target.hash_schema(plan).keys.should ==
|
58
|
+
source.hash_schema(plan).keys
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
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.
|
4
|
+
version: 1.0.7
|
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-05-
|
13
|
+
date: 2013-05-29 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rspec
|