pgsync 0.5.5 → 0.6.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.

Potentially problematic release.


This version of pgsync might be problematic. Click here for more details.

@@ -18,29 +18,69 @@ module PgSync
18
18
  end
19
19
  end
20
20
 
21
+ def warning(message)
22
+ log colorize(message, :yellow)
23
+ end
24
+
25
+ def deprecated(message)
26
+ warning "[DEPRECATED] #{message}"
27
+ end
28
+
21
29
  def output
22
30
  $stderr
23
31
  end
24
32
 
25
- def config_file
26
- search_tree(db_config_file(@options[:db]) || @options[:config] || ".pgsync.yml")
33
+ def db_config_file(db)
34
+ ".pgsync-#{db}.yml"
27
35
  end
28
36
 
29
- def db_config_file(db)
30
- ".pgsync-#{db}.yml" if db
37
+ def confirm_tables_exist(data_source, tasks, description)
38
+ tasks.map(&:table).each do |table|
39
+ unless data_source.table_exists?(table)
40
+ raise Error, "Table not found in #{description}: #{table}"
41
+ end
42
+ end
43
+ end
44
+
45
+ def first_schema
46
+ @first_schema ||= source.search_path.find { |sp| sp != "pg_catalog" }
47
+ end
48
+
49
+ def task_name(task)
50
+ friendly_name(task.table)
31
51
  end
32
52
 
33
- def search_tree(file)
34
- return file if File.exist?(file)
53
+ def friendly_name(table)
54
+ if table.schema == first_schema
55
+ table.name
56
+ else
57
+ table.full_name
58
+ end
59
+ end
35
60
 
36
- path = Dir.pwd
37
- # prevent infinite loop
38
- 20.times do
39
- absolute_file = File.join(path, file)
40
- break absolute_file if File.exist?(absolute_file)
41
- path = File.dirname(path)
42
- break if path == "/"
61
+ def quote_ident_full(ident)
62
+ if ident.is_a?(Table)
63
+ [quote_ident(ident.schema), quote_ident(ident.name)].join(".")
64
+ else # temp table names are strings
65
+ quote_ident(ident)
43
66
  end
44
67
  end
68
+
69
+ def quote_ident(value)
70
+ PG::Connection.quote_ident(value)
71
+ end
72
+
73
+ def escape(value)
74
+ if value.is_a?(String)
75
+ "'#{quote_string(value)}'"
76
+ else
77
+ value
78
+ end
79
+ end
80
+
81
+ # activerecord
82
+ def quote_string(s)
83
+ s.gsub(/\\/, '\&\&').gsub(/'/, "''")
84
+ end
45
85
  end
46
86
  end
@@ -1,3 +1,3 @@
1
1
  module PgSync
2
- VERSION = "0.5.5"
2
+ VERSION = "0.6.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pgsync
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.5
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-05-14 00:00:00.000000000 Z
11
+ date: 2020-06-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parallel
@@ -124,9 +124,12 @@ files:
124
124
  - lib/pgsync/client.rb
125
125
  - lib/pgsync/data_source.rb
126
126
  - lib/pgsync/init.rb
127
+ - lib/pgsync/schema_sync.rb
127
128
  - lib/pgsync/sync.rb
128
- - lib/pgsync/table_list.rb
129
+ - lib/pgsync/table.rb
129
130
  - lib/pgsync/table_sync.rb
131
+ - lib/pgsync/task.rb
132
+ - lib/pgsync/task_resolver.rb
130
133
  - lib/pgsync/utils.rb
131
134
  - lib/pgsync/version.rb
132
135
  homepage: https://github.com/ankane/pgsync
@@ -1,141 +0,0 @@
1
- module PgSync
2
- class TableList
3
- include Utils
4
-
5
- attr_reader :args, :opts, :source, :config
6
-
7
- def initialize(args, options, source, config)
8
- @args = args
9
- @opts = options
10
- @source = source
11
- @config = config
12
- @groups = config["groups"] || {}
13
- end
14
-
15
- def group?(group)
16
- @groups.key?(group)
17
- end
18
-
19
- def tables
20
- tables = {}
21
- sql = args[1]
22
-
23
- groups = to_arr(opts[:groups])
24
- tables2 = to_arr(opts[:tables])
25
-
26
- if args[0]
27
- # could be a group, table, or mix
28
- to_arr(args[0]).each do |tag|
29
- group, id = tag.split(":", 2)
30
- if group?(group)
31
- groups << tag
32
- else
33
- tables2 << tag
34
- end
35
- end
36
- end
37
-
38
- groups.each do |tag|
39
- group, id = tag.split(":", 2)
40
- raise Error, "Group not found: #{group}" unless group?(group)
41
-
42
- # if id
43
- # # TODO show group name and value
44
- # log colorize("`pgsync group:value` is deprecated and will have a different function in 0.6.0.", :yellow)
45
- # log colorize("Use `pgsync group --var 1=value` instead.", :yellow)
46
- # end
47
-
48
- @groups[group].each do |table|
49
- table_sql = nil
50
- if table.is_a?(Array)
51
- table, table_sql = table
52
- end
53
- add_table(tables, table, id, sql || table_sql)
54
- end
55
- end
56
-
57
- tables2.each do |tag|
58
- table, id = tag.split(":", 2)
59
- raise Error, "Cannot use parameters with tables" if id
60
- add_table(tables, table, id, sql)
61
- end
62
-
63
- if !opts[:groups] && !opts[:tables] && !args[0]
64
- exclude = to_arr(opts[:exclude])
65
- exclude = source.fully_resolve_tables(exclude).keys if exclude.any?
66
-
67
- tabs = source.tables
68
- unless opts[:all_schemas]
69
- schemas = Set.new(opts[:schemas] ? to_arr(opts[:schemas]) : source.search_path)
70
- tabs.select! { |t| schemas.include?(t.split(".", 2)[0]) }
71
- end
72
-
73
- (tabs - exclude).each do |k|
74
- tables[k] = {}
75
- end
76
- end
77
-
78
- source.fully_resolve_tables(tables)
79
- end
80
-
81
- private
82
-
83
- def to_arr(value)
84
- if value.is_a?(Array)
85
- value
86
- else
87
- # Split by commas, but don't use commas inside double quotes
88
- # https://stackoverflow.com/questions/21105360/regex-find-comma-not-inside-quotes
89
- value.to_s.split(/(?!\B"[^"]*),(?![^"]*"\B)/)
90
- end
91
- end
92
-
93
- def add_table(tables, table, id, sql)
94
- tables2 =
95
- if table.include?("*")
96
- regex = Regexp.new('\A' + Regexp.escape(table).gsub('\*','[^\.]*') + '\z')
97
- source.tables.select { |t| regex.match(t) || regex.match(t.split(".", 2).last) }
98
- else
99
- [table]
100
- end
101
-
102
- tables2.each do |tab|
103
- tables[tab] = {}
104
- tables[tab][:sql] = table_sql(sql, id) if sql
105
- end
106
- end
107
-
108
- def table_sql(sql, id)
109
- # vars must match \w
110
- missing_vars = sql.scan(/{\w+}/).map { |v| v[1..-2] }
111
-
112
- vars = {}
113
-
114
- # legacy
115
- if id
116
- vars["id"] = cast(id)
117
- vars["1"] = cast(id)
118
- end
119
-
120
- # opts[:var].each do |value|
121
- # k, v = value.split("=", 2)
122
- # vars[k] = v
123
- # end
124
-
125
- sql = sql.dup
126
- vars.each do |k, v|
127
- # only sub if in var list
128
- sql.gsub!("{#{k}}", cast(v)) if missing_vars.delete(k)
129
- end
130
-
131
- raise Error, "Missing variables: #{missing_vars.uniq.join(", ")}" if missing_vars.any?
132
-
133
- sql
134
- end
135
-
136
- # TODO quote vars in next major version
137
- def cast(value)
138
- value.to_s.gsub(/\A\"|\"\z/, '')
139
- end
140
- end
141
- end