flydata 0.6.14 → 0.7.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.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/flydata-core/Gemfile +1 -0
- data/flydata-core/Gemfile.lock +5 -0
- data/flydata-core/lib/flydata-core/errors.rb +4 -2
- data/flydata-core/lib/flydata-core/mysql/binlog_pos.rb +4 -0
- data/flydata-core/lib/flydata-core/postgresql/compatibility_checker.rb +119 -0
- data/flydata-core/lib/flydata-core/postgresql/config.rb +58 -0
- data/flydata-core/lib/flydata-core/postgresql/pg_client.rb +170 -0
- data/flydata-core/lib/flydata-core/postgresql/snapshot.rb +49 -0
- data/flydata-core/lib/flydata-core/postgresql/source_pos.rb +71 -10
- data/flydata-core/lib/flydata-core/table_def/mysql_table_def.rb +1 -1
- data/flydata-core/lib/flydata-core/table_def/postgresql_table_def.rb +76 -17
- data/flydata-core/lib/flydata-core/table_def/redshift_table_def.rb +59 -10
- data/flydata-core/spec/mysql/binlog_pos_spec.rb +10 -2
- data/flydata-core/spec/postgresql/compatibility_checker_spec.rb +148 -0
- data/flydata-core/spec/postgresql/config_spec.rb +85 -0
- data/flydata-core/spec/postgresql/pg_client_spec.rb +195 -0
- data/flydata-core/spec/postgresql/snapshot_spec.rb +55 -0
- data/flydata-core/spec/postgresql/source_pos_spec.rb +70 -8
- data/flydata-core/spec/table_def/postgresql_table_def_spec.rb +80 -19
- data/flydata-core/spec/table_def/redshift_table_def_spec.rb +211 -14
- data/flydata.gemspec +0 -0
- data/lib/flydata.rb +1 -0
- data/lib/flydata/command/sender.rb +10 -7
- data/lib/flydata/command/sync.rb +4 -1
- data/lib/flydata/fluent-plugins/flydata_plugin_ext/base.rb +1 -0
- data/lib/flydata/fluent-plugins/flydata_plugin_ext/fluent_log_ext.rb +73 -0
- data/lib/flydata/fluent-plugins/flydata_plugin_ext/flydata_sync.rb +35 -10
- data/lib/flydata/fluent-plugins/flydata_plugin_ext/flydata_sync_diff_based.rb +29 -0
- data/lib/flydata/fluent-plugins/flydata_plugin_ext/flydata_sync_query_based.rb +26 -0
- data/lib/flydata/fluent-plugins/flydata_plugin_ext/preference.rb +29 -13
- data/lib/flydata/fluent-plugins/in_mysql_binlog_flydata.rb +10 -18
- data/lib/flydata/fluent-plugins/in_postgresql_query_based_flydata.rb +64 -0
- data/lib/flydata/helpers.rb +1 -3
- data/lib/flydata/plugin_support/context.rb +14 -2
- data/lib/flydata/plugin_support/source_position_file.rb +35 -0
- data/lib/flydata/plugin_support/sync_record_emittable.rb +2 -1
- data/lib/flydata/query_based_sync/client.rb +101 -0
- data/lib/flydata/query_based_sync/record_size_estimator.rb +39 -0
- data/lib/flydata/query_based_sync/resource_requester.rb +70 -0
- data/lib/flydata/query_based_sync/response.rb +122 -0
- data/lib/flydata/query_based_sync/response_handler.rb +30 -0
- data/lib/flydata/source/sync_generate_table_ddl.rb +1 -1
- data/lib/flydata/source_mysql/plugin_support/binlog_record_dispatcher.rb +2 -2
- data/lib/flydata/source_mysql/plugin_support/binlog_record_handler.rb +3 -9
- data/lib/flydata/source_mysql/plugin_support/context.rb +26 -2
- data/lib/flydata/source_mysql/plugin_support/source_position_file.rb +14 -0
- data/lib/flydata/source_mysql/table_ddl.rb +3 -3
- data/lib/flydata/source_mysql/{plugin_support/table_meta.rb → table_meta.rb} +3 -10
- data/lib/flydata/source_postgresql/generate_source_dump.rb +44 -63
- data/lib/flydata/source_postgresql/parse_dump_and_send.rb +2 -0
- data/lib/flydata/source_postgresql/plugin_support/context.rb +13 -0
- data/lib/flydata/source_postgresql/plugin_support/source_position_file.rb +14 -0
- data/lib/flydata/source_postgresql/query_based_sync/client.rb +16 -0
- data/lib/flydata/source_postgresql/query_based_sync/diff_query_generator.rb +135 -0
- data/lib/flydata/source_postgresql/query_based_sync/resource_requester.rb +86 -0
- data/lib/flydata/source_postgresql/query_based_sync/response.rb +12 -0
- data/lib/flydata/source_postgresql/query_based_sync/response_handler.rb +12 -0
- data/lib/flydata/source_postgresql/sync_generate_table_ddl.rb +25 -79
- data/lib/flydata/source_postgresql/table_meta.rb +168 -0
- data/lib/flydata/sync_file_manager.rb +5 -5
- data/lib/flydata/table_meta.rb +19 -0
- data/spec/flydata/fluent-plugins/flydata_plugin_ext/flydata_sync_context.rb +85 -0
- data/spec/flydata/fluent-plugins/flydata_plugin_ext/flydata_sync_diff_based_shared_examples.rb +36 -0
- data/spec/flydata/fluent-plugins/flydata_plugin_ext/flydata_sync_query_based_shared_examples.rb +37 -0
- data/spec/flydata/fluent-plugins/flydata_plugin_ext/flydata_sync_shared_examples.rb +67 -0
- data/spec/flydata/fluent-plugins/in_mysql_binlog_flydata_spec.rb +119 -96
- data/spec/flydata/fluent-plugins/in_postgresql_query_based_flydata_spec.rb +82 -0
- data/spec/flydata/fluent-plugins/sync_source_plugin_context.rb +29 -0
- data/spec/flydata/plugin_support/context_spec.rb +37 -3
- data/spec/flydata/query_based_sync/client_spec.rb +79 -0
- data/spec/flydata/query_based_sync/query_based_sync_context.rb +116 -0
- data/spec/flydata/query_based_sync/record_size_estimator_spec.rb +54 -0
- data/spec/flydata/query_based_sync/resource_requester_spec.rb +58 -0
- data/spec/flydata/query_based_sync/response_handler_spec.rb +36 -0
- data/spec/flydata/query_based_sync/response_spec.rb +157 -0
- data/spec/flydata/source_mysql/plugin_support/context_spec.rb +7 -1
- data/spec/flydata/source_mysql/plugin_support/dml_record_handler_spec.rb +2 -15
- data/spec/flydata/source_mysql/plugin_support/drop_database_query_handler_spec.rb +1 -1
- data/spec/flydata/source_mysql/plugin_support/shared_query_handler_context.rb +12 -11
- data/spec/flydata/source_mysql/plugin_support/source_position_file_spec.rb +53 -0
- data/spec/flydata/source_mysql/plugin_support/truncate_query_handler_spec.rb +1 -1
- data/spec/flydata/source_mysql/table_ddl_spec.rb +5 -5
- data/spec/flydata/source_mysql/{plugin_support/table_meta_spec.rb → table_meta_spec.rb} +6 -7
- data/spec/flydata/source_postgresql/generate_source_dump_spec.rb +165 -77
- data/spec/flydata/source_postgresql/query_based_sync/diff_query_generator_spec.rb +213 -0
- data/spec/flydata/source_postgresql/query_based_sync/query_based_sync_postgresql_context.rb +76 -0
- data/spec/flydata/source_postgresql/query_based_sync/resource_requester_spec.rb +70 -0
- data/spec/flydata/source_postgresql/table_meta_spec.rb +77 -0
- metadata +49 -6
- data/lib/flydata/source_mysql/plugin_support/binlog_position_file.rb +0 -23
- data/lib/flydata/source_postgresql/pg_client.rb +0 -43
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
require 'flydata/query_based_sync/resource_requester.rb'
|
|
2
|
+
require 'flydata/source_postgresql/query_based_sync/response.rb'
|
|
3
|
+
require 'flydata/source_postgresql/query_based_sync/diff_query_generator'
|
|
4
|
+
require 'flydata-core/postgresql/pg_client'
|
|
5
|
+
|
|
6
|
+
module Flydata
|
|
7
|
+
module SourcePostgresql
|
|
8
|
+
module QueryBasedSync
|
|
9
|
+
|
|
10
|
+
class ResourceRequester < Flydata::QueryBasedSync::ResourceRequester
|
|
11
|
+
RESPONSE_CLASS = Flydata::SourcePostgresql::QueryBasedSync::Response
|
|
12
|
+
|
|
13
|
+
# Override
|
|
14
|
+
def create_resource_client(context)
|
|
15
|
+
FlydataCore::Postgresql::PGClient.new(context.dbconf)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Override
|
|
19
|
+
def fetch_responses_once(table_name, latest_src_pos)
|
|
20
|
+
table_sym = table_name.to_sym
|
|
21
|
+
t_meta = context.table_meta[table_sym]
|
|
22
|
+
|
|
23
|
+
table_src_pos = context.table_src_pos_files[table_sym].pos
|
|
24
|
+
master_src_pos = context.cur_src_pos_file.pos
|
|
25
|
+
|
|
26
|
+
# Set from_sid, to_sid and pk_values
|
|
27
|
+
|
|
28
|
+
to_sid = latest_src_pos.snapshot
|
|
29
|
+
pk_values = nil
|
|
30
|
+
|
|
31
|
+
# - table.binlog.pos does not exist
|
|
32
|
+
if table_src_pos.nil?
|
|
33
|
+
from_sid = master_src_pos.snapshot
|
|
34
|
+
# - pk_values exists -> continue from the last transaction
|
|
35
|
+
elsif table_src_pos.pk_values
|
|
36
|
+
from_sid = table_src_pos.snapshot
|
|
37
|
+
to_sid = table_src_pos.to_snapshot
|
|
38
|
+
pk_values = table_src_pos.pk_values
|
|
39
|
+
else
|
|
40
|
+
from_sid = table_src_pos.snapshot
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
if from_sid == to_sid
|
|
44
|
+
log_debug("Skip fetching records (No changes)")
|
|
45
|
+
return
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
log_debug("Start query", from_sid: from_sid, to_sid: to_sid, pk_values: pk_values)
|
|
49
|
+
|
|
50
|
+
# Create and execute query
|
|
51
|
+
query = generate_query(t_meta, from_sid, to_sid, pk_values)
|
|
52
|
+
|
|
53
|
+
result = @resource_client.query(query)
|
|
54
|
+
|
|
55
|
+
# Create response object based on result
|
|
56
|
+
responses = build_responses(table_name, result, from_sid: from_sid, to_sid: to_sid, pk_values: pk_values)
|
|
57
|
+
|
|
58
|
+
Array(responses)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
private
|
|
62
|
+
|
|
63
|
+
def generate_query(t_meta, from_sid, to_sid, pk_values)
|
|
64
|
+
last_pks = if pk_values
|
|
65
|
+
pk_values.collect{|h| h.values.first}
|
|
66
|
+
else
|
|
67
|
+
nil
|
|
68
|
+
end
|
|
69
|
+
DiffQueryGenerator.new(t_meta[:table_name], t_meta[:table_schema],
|
|
70
|
+
to_sid: to_sid,
|
|
71
|
+
from_sid: from_sid,
|
|
72
|
+
columns: t_meta[:columns],
|
|
73
|
+
pk_columns: t_meta[:primary_keys],
|
|
74
|
+
last_pks: last_pks,
|
|
75
|
+
limit: t_meta[:max_num_rows_per_query],
|
|
76
|
+
).build_query
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def build_responses(table_name, raw_result, query_cond = {})
|
|
80
|
+
RESPONSE_CLASS.create_responses(context, table_name, raw_result, query_cond)
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
require 'flydata/source/sync_generate_table_ddl'
|
|
2
|
-
require 'flydata
|
|
3
|
-
require 'flydata/source_postgresql/pg_client'
|
|
2
|
+
require 'flydata/source_postgresql/table_meta'
|
|
4
3
|
|
|
5
4
|
module Flydata
|
|
6
5
|
module SourcePostgresql
|
|
@@ -21,96 +20,43 @@ class SyncGenerateTableDdl < Source::SyncGenerateTableDdl
|
|
|
21
20
|
def each_source_tabledef(tables, options, &block)
|
|
22
21
|
# PostgreSQL options.
|
|
23
22
|
tables = tables.clone
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
if tables.to_s == '' || tables.to_s == '[]'
|
|
27
|
-
raise ArgumentError, "tables is nil or empty"
|
|
28
|
-
end
|
|
29
|
-
_each_tabledef(tables, options, &block)
|
|
30
|
-
rescue TableMissingError => e
|
|
31
|
-
tables.delete e.table
|
|
32
|
-
missing_tables << e.table
|
|
33
|
-
return missing_tables if tables.empty?
|
|
34
|
-
retry
|
|
23
|
+
if tables.to_s == '' || tables.to_s == '[]'
|
|
24
|
+
raise ArgumentError, "tables is nil or empty"
|
|
35
25
|
end
|
|
36
|
-
|
|
26
|
+
_each_tabledef(tables, options, &block)
|
|
37
27
|
end
|
|
38
28
|
|
|
39
29
|
private
|
|
40
30
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
FROM pg_index i
|
|
45
|
-
JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey)
|
|
46
|
-
RIGHT JOIN
|
|
47
|
-
(SELECT (table_catalog ||'.'|| table_schema ||'.'|| table_name)::regclass AS regid, *
|
|
48
|
-
FROM information_schema.columns) c
|
|
49
|
-
ON i.indrelid = c.regid AND a.attname = c.column_name
|
|
50
|
-
WHERE c.table_schema = $1 AND c.table_name IN (%s)
|
|
51
|
-
ORDER BY c.table_name, c.ordinal_position;
|
|
52
|
-
EOS
|
|
53
|
-
TABLE_PLACEHOLDER_START_NUM = 2 # because $1 is used by table_schema
|
|
31
|
+
def table_meta(tables, options)
|
|
32
|
+
Flydata::SourcePostgresql::TableMeta.new(options, tables)
|
|
33
|
+
end
|
|
54
34
|
|
|
55
35
|
def _each_tabledef(tables, options, &block)
|
|
56
|
-
|
|
36
|
+
all_table_meta = options[:table_meta]
|
|
37
|
+
unless all_table_meta
|
|
38
|
+
all_table_meta = table_meta(tables, options)
|
|
39
|
+
all_table_meta.reload
|
|
40
|
+
end
|
|
57
41
|
|
|
58
|
-
|
|
59
|
-
res = cli.query(COLUMNS_QUERY, [options['schema']] + tables,
|
|
60
|
-
placeholder_start_num: TABLE_PLACEHOLDER_START_NUM,
|
|
61
|
-
placeholder_size: tables.size)
|
|
42
|
+
missing_tables = []
|
|
62
43
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
columns = []
|
|
69
|
-
completed_tables = []
|
|
70
|
-
res.each do |row|
|
|
71
|
-
table_name = row["table_name"]
|
|
72
|
-
unless table_name == current_table
|
|
73
|
-
unless columns.empty?
|
|
74
|
-
tabledef = create_tabledef_and_yield(columns, create_opt, &block)
|
|
75
|
-
completed_tables << current_table
|
|
76
|
-
columns = []
|
|
77
|
-
break unless tabledef
|
|
78
|
-
end
|
|
79
|
-
current_table = table_name
|
|
44
|
+
tables.each do |table|
|
|
45
|
+
t_meta = all_table_meta[table]
|
|
46
|
+
unless t_meta && !t_meta.empty?
|
|
47
|
+
missing_tables << table
|
|
48
|
+
next
|
|
80
49
|
end
|
|
81
|
-
columns << row
|
|
82
|
-
end
|
|
83
|
-
unless columns.empty?
|
|
84
|
-
create_tabledef_and_yield(columns, create_opt, &block)
|
|
85
|
-
completed_tables << current_table
|
|
86
|
-
end
|
|
87
|
-
missing_tables = tables - completed_tables
|
|
88
|
-
unless missing_tables.empty?
|
|
89
|
-
raise TableMissingError.new("Table is missing", missing_tables.first)
|
|
90
|
-
end
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
def placeholder_string(num_items, start_num)
|
|
94
|
-
num_items.times.collect{|i| "$#{i + start_num}"}.join(",")
|
|
95
|
-
end
|
|
96
50
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
yield(nil, e)
|
|
51
|
+
table_def = t_meta[:table_def]
|
|
52
|
+
if table_def
|
|
53
|
+
yield(table_def, nil)
|
|
54
|
+
else
|
|
55
|
+
yield(nil, t_meta[:table_def_err])
|
|
56
|
+
end
|
|
104
57
|
end
|
|
105
|
-
pg_tabledef
|
|
106
|
-
end
|
|
107
58
|
|
|
108
|
-
|
|
109
|
-
def initialize(message, table)
|
|
110
|
-
super(message)
|
|
111
|
-
@table = table
|
|
112
|
-
end
|
|
113
|
-
attr_reader :table
|
|
59
|
+
missing_tables
|
|
114
60
|
end
|
|
115
61
|
end
|
|
116
62
|
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
require 'flydata/table_meta'
|
|
2
|
+
require 'flydata-core/postgresql/pg_client'
|
|
3
|
+
require 'flydata-core/postgresql/snapshot'
|
|
4
|
+
require 'flydata-core/table_def/postgresql_table_def'
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
module Flydata
|
|
8
|
+
module SourcePostgresql
|
|
9
|
+
|
|
10
|
+
# Fetch and keep table meta information
|
|
11
|
+
#
|
|
12
|
+
# <table-name(Symbol)>:
|
|
13
|
+
# primary_keys: <Array of String> # Set primary key names. ex: ['group_id', 'category_id']
|
|
14
|
+
# pk_positions: <Array of Integer> # Set the ordinal position of primary keys. ex: [1, 3]
|
|
15
|
+
# max_row_size: <Integer> # byte, calculated based on column size
|
|
16
|
+
# max_num_rows_per_query>: <Integer> # max number of rows per query
|
|
17
|
+
# raw_columns: <Hash> # raw information schema data
|
|
18
|
+
# columns: table_def.columns
|
|
19
|
+
# table_def:
|
|
20
|
+
# columns:
|
|
21
|
+
# table:
|
|
22
|
+
# column:
|
|
23
|
+
# type:
|
|
24
|
+
# not_null:
|
|
25
|
+
# primary_key:
|
|
26
|
+
# default:
|
|
27
|
+
# column_size: (new) # Set in `PostgresqlTableDef.parse_one_column_def`
|
|
28
|
+
#
|
|
29
|
+
class TableMeta < Flydata::TableMeta
|
|
30
|
+
|
|
31
|
+
GET_TABLE_META_SQL = <<EOT
|
|
32
|
+
SELECT
|
|
33
|
+
c.table_catalog,
|
|
34
|
+
c.table_schema,
|
|
35
|
+
c.table_name,
|
|
36
|
+
c.column_name,
|
|
37
|
+
c.ordinal_position,
|
|
38
|
+
c.column_default,
|
|
39
|
+
c.is_nullable,
|
|
40
|
+
c.data_type,
|
|
41
|
+
c.character_maximum_length,
|
|
42
|
+
c.character_octet_length,
|
|
43
|
+
CASE WHEN c.data_type='money' THEN 19
|
|
44
|
+
ELSE c.numeric_precision END AS numeric_precision,
|
|
45
|
+
c.numeric_precision_radix,
|
|
46
|
+
CASE WHEN c.data_type='money' THEN (
|
|
47
|
+
SELECT CASE WHEN scale IS NULL THEN 0 ELSE scale END
|
|
48
|
+
FROM (SELECT length(substring(999999::money::char varying, '\.([0-9]+)$')) AS scale) s)
|
|
49
|
+
ELSE c.numeric_scale END AS numeric_scale,
|
|
50
|
+
c.datetime_precision,
|
|
51
|
+
i.indisprimary AS is_primary
|
|
52
|
+
FROM
|
|
53
|
+
pg_index i
|
|
54
|
+
JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey)
|
|
55
|
+
RIGHT JOIN
|
|
56
|
+
(SELECT
|
|
57
|
+
(table_catalog ||'.'|| table_schema ||'.'|| table_name)::regclass AS regid,
|
|
58
|
+
*
|
|
59
|
+
FROM information_schema.columns
|
|
60
|
+
) c
|
|
61
|
+
ON i.indrelid = c.regid AND a.attname = c.column_name
|
|
62
|
+
WHERE
|
|
63
|
+
c.table_catalog = '%{database}'
|
|
64
|
+
AND c.table_schema IN (%{schema})
|
|
65
|
+
AND c.table_name IN (%{tables})
|
|
66
|
+
ORDER BY
|
|
67
|
+
c.table_name, c.ordinal_position;
|
|
68
|
+
EOT
|
|
69
|
+
|
|
70
|
+
GET_CURRENT_SNAPSHOT_SQL = "SELECT txid_current_snapshot();"
|
|
71
|
+
|
|
72
|
+
DEFAULT_MAX_FETCH_RECORD_SIZE = 50000
|
|
73
|
+
#DEFAULT_MAX_FETCH_RECORD_SIZE = 8
|
|
74
|
+
|
|
75
|
+
def initialize(dbconf, tables, schema = nil) # 64mb
|
|
76
|
+
@dbconf = dbconf
|
|
77
|
+
@database = dbconf[:dbname] || dbconf[:database] || dbconf['database']
|
|
78
|
+
@tables = tables
|
|
79
|
+
@schema = schema || dbconf[:schema] || dbconf['schema']
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
attr_reader :current_snapshot
|
|
83
|
+
|
|
84
|
+
def reload(pg_client = nil)
|
|
85
|
+
schema = @schema ? "'#{@schema}'" : "select current_schema"
|
|
86
|
+
sql = GET_TABLE_META_SQL % {
|
|
87
|
+
database: @database,
|
|
88
|
+
schema: schema,
|
|
89
|
+
tables: @tables.collect{|t| "'#{t}'"}.join(','),
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
conn = pg_client
|
|
93
|
+
if conn.nil?
|
|
94
|
+
local_conn = conn = FlydataCore::Postgresql::PGClient.new(@dbconf)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Set table_meta
|
|
98
|
+
columns = conn.query(sql)
|
|
99
|
+
@table_meta = build_table_meta(columns)
|
|
100
|
+
|
|
101
|
+
# Set current snapshot
|
|
102
|
+
current_snapshot_str = conn.
|
|
103
|
+
query(GET_CURRENT_SNAPSHOT_SQL).first['txid_current_snapshot']
|
|
104
|
+
@current_snapshot = FlydataCore::Postgresql::Snapshot.new(current_snapshot_str)
|
|
105
|
+
|
|
106
|
+
self
|
|
107
|
+
ensure
|
|
108
|
+
local_conn.close rescue nil if local_conn
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def build_table_meta(columns)
|
|
112
|
+
ret = Hash.new{|h,k| h[k]={} }
|
|
113
|
+
|
|
114
|
+
# Put ret[<table-name-sym>][:raw_columns]
|
|
115
|
+
columns.each do |col|
|
|
116
|
+
column_name = col['column_name'].to_sym
|
|
117
|
+
table_name = col['table_name'].to_sym
|
|
118
|
+
t_meta = ret[table_name]
|
|
119
|
+
t_meta[:raw_columns] ||= {}
|
|
120
|
+
t_meta[:raw_columns][column_name] = col
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
ret.each do |table_name, t_meta|
|
|
124
|
+
begin
|
|
125
|
+
table_def = FlydataCore::TableDef::PostgresqlTableDef.create(
|
|
126
|
+
t_meta[:raw_columns].values, :skip_primary_key_check)
|
|
127
|
+
rescue FlydataCore::TableDefError => e
|
|
128
|
+
t_meta.merge!(
|
|
129
|
+
table_name: table_name,
|
|
130
|
+
table_def_err: e,
|
|
131
|
+
)
|
|
132
|
+
# Skip when getting an error when parsing the columns
|
|
133
|
+
next
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
primary_keys = []
|
|
137
|
+
pk_positions = []
|
|
138
|
+
table_def.columns.each.with_index(1) do |col, index|
|
|
139
|
+
col_name = col[:column]
|
|
140
|
+
if col[:primary_key]
|
|
141
|
+
primary_keys << col_name
|
|
142
|
+
pk_positions << index.to_s
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
t_meta.merge!(
|
|
147
|
+
table_name: table_name.to_s,
|
|
148
|
+
primary_keys: primary_keys,
|
|
149
|
+
pk_positions: pk_positions,
|
|
150
|
+
#max_row_size: max_row_size, #TODO: calculation
|
|
151
|
+
#max_num_rows_per_query: max_row_size + 128, #TODO: calculation
|
|
152
|
+
max_num_rows_per_query: DEFAULT_MAX_FETCH_RECORD_SIZE,
|
|
153
|
+
columns: table_def.columns,
|
|
154
|
+
table_def: table_def,
|
|
155
|
+
)
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
ret
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def calc_column_size(column)
|
|
162
|
+
#TODO: Implement the check logic based on column type
|
|
163
|
+
124
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
end
|
|
168
|
+
end
|
|
@@ -9,7 +9,7 @@ module Flydata
|
|
|
9
9
|
class SyncFileManager
|
|
10
10
|
DUMP_DIR = ENV['FLYDATA_DUMP'] || File.join(FLYDATA_HOME, 'dump')
|
|
11
11
|
BACKUP_DIR = ENV['FLYDATA_BACKUP'] || File.join(FLYDATA_HOME, 'backup')
|
|
12
|
-
TABLE_POSITIONS_DIR =
|
|
12
|
+
TABLE_POSITIONS_DIR = FLYDATA_TABLE_POSITIONS_DIR
|
|
13
13
|
|
|
14
14
|
def initialize(data_entry, source = nil)
|
|
15
15
|
@data_entry = data_entry
|
|
@@ -65,7 +65,6 @@ module Flydata
|
|
|
65
65
|
|
|
66
66
|
def save_generated_ddl(tables, contents = "1")
|
|
67
67
|
tables = [ tables ] unless tables.kind_of?(Array)
|
|
68
|
-
table_positions_dir_path = ENV['FLYDATA_TABLE_POSITIONS'] || File.join(FLYDATA_HOME, 'positions')
|
|
69
68
|
#Create positions if dir does not exist
|
|
70
69
|
unless File.directory?(table_positions_dir_path)
|
|
71
70
|
FileUtils.mkdir_p(table_positions_dir_path)
|
|
@@ -76,7 +75,6 @@ module Flydata
|
|
|
76
75
|
end
|
|
77
76
|
|
|
78
77
|
def get_new_table_list(tables, file_type)
|
|
79
|
-
table_positions_dir_path = ENV['FLYDATA_TABLE_POSITIONS'] || File.join(FLYDATA_HOME, 'positions')
|
|
80
78
|
new_tables = []
|
|
81
79
|
tables.each do |table|
|
|
82
80
|
new_tables << table unless File.exists?(File.join(table_positions_dir_path, "#{table}.#{file_type}"))
|
|
@@ -408,13 +406,15 @@ module Flydata
|
|
|
408
406
|
end
|
|
409
407
|
|
|
410
408
|
def get_table_source_raw_pos(table_name) #returns String. interface for fluentd
|
|
411
|
-
file =
|
|
409
|
+
file = table_source_pos_file_path(table_name)
|
|
412
410
|
return nil unless File.exists?(file)
|
|
413
411
|
|
|
414
412
|
File.open(file, 'r').readline
|
|
415
413
|
end
|
|
416
414
|
|
|
417
|
-
|
|
415
|
+
def table_source_pos_file_path(table_name)
|
|
416
|
+
File.join(table_positions_dir_path, table_name + ".binlog.pos")
|
|
417
|
+
end
|
|
418
418
|
|
|
419
419
|
def install_table_source_pos_files(tables)
|
|
420
420
|
FileUtils.mkdir_p(table_positions_dir_path) unless Dir.exists?(table_positions_dir_path)
|