db_schema-reader-postgres 0.1.1 → 0.2.rc1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9f12b3dcea5dc1a301418825e2b8da015e078c520195e42517da991830d3bc22
4
- data.tar.gz: 52778450688b800dccf4934525fc567f0d99a9b426095298f198728cb827a9e6
3
+ metadata.gz: 8b2b3ebe11fc219d52a9576207a384fa6dd8f9b6178a5a65efaadbb215c3dcd9
4
+ data.tar.gz: 0fbc9926bcf4429875278c1d9b9157cf91618f6dad67c245c109fd85dbfc04e8
5
5
  SHA512:
6
- metadata.gz: 7c222884746207d2c46ab112ed40b7d78b4de10feef39dbeee650fa0b40c58bd00307c121ce1fa550391379aa61e80a4d78275e7c2782394f4e91153be986997
7
- data.tar.gz: 7ec7a253c3ca0c576b6935df764a24456994b8a26a045d5614445164399dff84568c424d11955ab4560542eef9ec8d340c215ee82145c7b585b27c38b5cf003a
6
+ metadata.gz: 3f55b980f9ceb11448e1699da20f071dcc75cbd79c3dfee4869081f2fb1450b04d0027be2df92310082a5c54144c5ce8df27efa21cc1d9d19365a0127280512e
7
+ data.tar.gz: 809c304408c6f03014db7ad5169f36f6616d3765d6e31a96f6ee6e566d3e3c963788a6df796eac373e59851cc42c0b69ae21a335ceb2f2a7399adde32d1ac1db
data/.travis.yml CHANGED
@@ -1,10 +1,10 @@
1
1
  sudo: false
2
2
  language: ruby
3
3
  rvm:
4
- - 2.2.8
5
- - 2.3.5
6
- - 2.4.2
7
- before_install: gem install bundler -v 1.16.0
4
+ - 2.3.8
5
+ - 2.4.5
6
+ - 2.5.3
7
+ - 2.6.0
8
8
  services:
9
9
  - postgresql
10
10
  addons:
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
+ gem 'db_schema-definitions', github: 'db-schema/definitions', branch: 'primary_keys'
4
+
3
5
  gemspec
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  spec.add_runtime_dependency 'sequel'
22
22
  spec.add_runtime_dependency 'pg'
23
- spec.add_runtime_dependency 'db_schema-definitions', '~> 0.1.0'
23
+ spec.add_runtime_dependency 'db_schema-definitions', '= 0.2.rc1'
24
24
 
25
25
  spec.add_development_dependency 'bundler', '~> 1.16'
26
26
  spec.add_development_dependency 'rake', '~> 10.0'
@@ -5,6 +5,84 @@ require_relative 'postgres/version'
5
5
  module DbSchema
6
6
  module Reader
7
7
  class Postgres
8
+ COLUMNS_QUERY = <<-SQL.freeze
9
+ SELECT c.table_name,
10
+ c.column_name AS name,
11
+ c.ordinal_position AS pos,
12
+ c.column_default AS default,
13
+ c.is_nullable AS null,
14
+ c.data_type AS type,
15
+ c.is_identity,
16
+ c.udt_name AS custom_type_name,
17
+ c.character_maximum_length AS char_length,
18
+ c.numeric_precision AS num_precision,
19
+ c.numeric_scale AS num_scale,
20
+ c.datetime_precision AS dt_precision,
21
+ c.interval_type,
22
+ e.data_type AS element_type,
23
+ e.udt_name AS element_custom_type_name
24
+ FROM information_schema.columns AS c
25
+ LEFT JOIN information_schema.element_types AS e
26
+ ON e.object_catalog = c.table_catalog
27
+ AND e.object_schema = c.table_schema
28
+ AND e.object_name = c.table_name
29
+ AND e.object_type = 'TABLE'
30
+ AND e.collection_type_identifier = c.dtd_identifier
31
+ WHERE c.table_schema = 'public'
32
+ SQL
33
+
34
+ INDEXES_QUERY = <<-SQL.freeze
35
+ SELECT table_rel.relname AS table_name,
36
+ pg_class.relname AS name,
37
+ indkey AS column_positions,
38
+ indisprimary AS primary,
39
+ indisunique AS unique,
40
+ indoption AS index_options,
41
+ pg_get_expr(indpred, indrelid, true) AS condition,
42
+ amname AS index_type,
43
+ indexrelid AS index_oid
44
+ FROM pg_class, pg_index
45
+ LEFT JOIN pg_opclass
46
+ ON pg_opclass.oid = ANY(pg_index.indclass::int[])
47
+ LEFT JOIN pg_am
48
+ ON pg_am.oid = pg_opclass.opcmethod
49
+ JOIN pg_class AS table_rel
50
+ ON table_rel.oid = pg_index.indrelid
51
+ JOIN pg_namespace
52
+ ON pg_namespace.oid = table_rel.relnamespace
53
+ WHERE pg_class.oid = pg_index.indexrelid
54
+ AND pg_namespace.nspname = 'public'
55
+ GROUP BY table_name, name, column_positions, indisprimary, indisunique, index_options, condition, index_type, index_oid
56
+ SQL
57
+
58
+ EXPRESSION_INDEXES_QUERY = <<-SQL.freeze
59
+ WITH index_ids AS (SELECT unnest(?) AS index_id),
60
+ elements AS (SELECT unnest(?) AS element)
61
+ SELECT index_id,
62
+ array_agg(pg_get_indexdef(index_id, element, 't')) AS definitions
63
+ FROM index_ids, elements
64
+ GROUP BY index_id;
65
+ SQL
66
+
67
+ CONSTRAINTS_QUERY = <<-SQL.freeze
68
+ SELECT owner_table.relname AS table_name,
69
+ constr.conname AS name,
70
+ pg_get_expr(conbin, conrelid, true) AS condition,
71
+ referenced_table.relname AS referenced,
72
+ conkey,
73
+ confkey,
74
+ confupdtype AS on_update,
75
+ confdeltype AS on_delete,
76
+ condeferrable AS deferrable,
77
+ constr.contype AS type
78
+ FROM pg_constraint AS constr
79
+ JOIN pg_class AS owner_table
80
+ ON owner_table.oid = constr.conrelid
81
+ LEFT JOIN pg_class AS referenced_table
82
+ ON referenced_table.oid = constr.confrelid
83
+ WHERE contype IN ('c', 'f');
84
+ SQL
85
+
8
86
  ENUMS_QUERY = <<-SQL.freeze
9
87
  SELECT t.typname AS name,
10
88
  array_agg(e.enumlabel ORDER BY e.enumsortorder) AS values
@@ -35,13 +113,17 @@ SELECT extname
35
113
  end
36
114
 
37
115
  def read_tables
38
- connection.tables.map do |table_name|
39
- read_table(table_name)
40
- end
41
- end
116
+ checks_data, foreign_keys_data = constraints_data
42
117
 
43
- def read_table(table_name)
44
- Table.new(connection, table_name).read
118
+ columns_data.keys.map do |table_name|
119
+ Table.new(
120
+ table_name.to_sym,
121
+ columns_data[table_name],
122
+ indexes_data[table_name],
123
+ checks_data[table_name],
124
+ foreign_keys_data[table_name]
125
+ ).definition
126
+ end
45
127
  end
46
128
 
47
129
  def read_enums
@@ -55,6 +137,120 @@ SELECT extname
55
137
  Definitions::Extension.new(extension_data[:extname].to_sym)
56
138
  end
57
139
  end
140
+
141
+ private
142
+ def columns_data
143
+ @columns_data ||= connection[COLUMNS_QUERY].to_a.group_by do |column|
144
+ column[:table_name]
145
+ end
146
+ end
147
+
148
+ def indexes_data
149
+ @indexes_data ||= begin
150
+ raw_data = connection[INDEXES_QUERY].map do |index_data|
151
+ index_data.merge(
152
+ column_positions: index_data[:column_positions].split(' ').map(&:to_i),
153
+ index_options: index_data[:index_options].split(' ').map(&:to_i)
154
+ )
155
+ end
156
+
157
+ expressions_data = index_expressions_data(raw_data)
158
+
159
+ raw_data.map do |index_data|
160
+ columns = index_data[:column_positions].map do |position|
161
+ if position.zero?
162
+ expressions_data.fetch(index_data[:index_oid]).shift
163
+ else
164
+ get_field_name(index_data[:table_name], position)
165
+ end
166
+ end
167
+
168
+ index_data.delete(:index_oid)
169
+ index_data.delete(:column_positions)
170
+ index_data.merge(columns: columns)
171
+ end.group_by { |index| index[:table_name] }.tap { |h| h.default = [] }
172
+ end
173
+ end
174
+
175
+ def index_expressions_data(indexes_data)
176
+ all_positions, max_position = {}, 0
177
+
178
+ indexes_data.each do |index_data|
179
+ positions = index_data[:column_positions]
180
+ expression_positions = positions.each_index.select do |i|
181
+ positions[i].zero?
182
+ end
183
+
184
+ if expression_positions.any?
185
+ all_positions[index_data[:index_oid]] = expression_positions
186
+ max_position = [max_position, expression_positions.max].max
187
+ end
188
+ end
189
+
190
+ if all_positions.any?
191
+ connection[
192
+ EXPRESSION_INDEXES_QUERY,
193
+ Sequel.pg_array(all_positions.keys),
194
+ Sequel.pg_array((1..max_position.succ).to_a)
195
+ ].each_with_object({}) do |index_data, indexes_data|
196
+ index_id = index_data[:index_id]
197
+ expressions = all_positions[index_id].map { |pos| index_data[:definitions][pos] }
198
+
199
+ indexes_data[index_id] = expressions
200
+ end
201
+ else
202
+ {}
203
+ end
204
+ end
205
+
206
+ def constraints_data
207
+ checks = Hash.new { |h, k| h[k] = [] }
208
+ foreign_keys = Hash.new { |h, k| h[k] = [] }
209
+
210
+ connection[CONSTRAINTS_QUERY].each do |constraint|
211
+ case constraint[:type]
212
+ when 'c'
213
+ checks[constraint[:table_name]] << {
214
+ name: constraint[:name],
215
+ condition: constraint[:condition]
216
+ }
217
+ when 'f'
218
+ fields = constraint[:conkey].map do |position|
219
+ get_field_name(constraint[:table_name], position)
220
+ end
221
+
222
+ keys = constraint[:confkey].map do |position|
223
+ get_field_name(constraint[:referenced], position)
224
+ end
225
+
226
+ pkey_columns = indexes_data.fetch(constraint[:referenced]).find do |index|
227
+ index[:primary]
228
+ end.fetch(:columns)
229
+
230
+ keys = [] if keys == pkey_columns # this foreign key references a primary key
231
+
232
+ foreign_keys[constraint[:table_name]] << {
233
+ name: constraint[:name],
234
+ referenced: constraint[:referenced],
235
+ fields: fields,
236
+ keys: keys,
237
+ on_update: constraint[:on_update],
238
+ on_delete: constraint[:on_delete],
239
+ deferrable: constraint[:deferrable]
240
+ }
241
+ else
242
+ raise "Unknown constraint type #{constraint[:type].inspect}"
243
+ end
244
+ end
245
+
246
+ [checks, foreign_keys]
247
+ end
248
+
249
+ def get_field_name(table, position)
250
+ columns_data.fetch(table).find do |column|
251
+ column[:pos] == position
252
+ end.fetch(:name).to_sym
253
+ end
58
254
  end
59
255
  end
60
256
  end
@@ -2,6 +2,12 @@ module DbSchema
2
2
  module Reader
3
3
  class Postgres
4
4
  class Table
5
+ SERIAL_TYPES = {
6
+ smallint: :smallserial,
7
+ integer: :serial,
8
+ bigint: :bigserial
9
+ }.freeze
10
+
5
11
  DEFAULT_VALUE = /\A(
6
12
  ('(?<date>\d{4}-\d{2}-\d{2})'::date)
7
13
  |
@@ -16,102 +22,25 @@ module DbSchema
16
22
  (?<boolean>true|false)
17
23
  )/x
18
24
 
19
- COLUMN_NAMES_QUERY = <<-SQL.freeze
20
- SELECT c.column_name AS name,
21
- c.ordinal_position AS pos,
22
- c.column_default AS default,
23
- c.is_nullable AS null,
24
- c.data_type AS type,
25
- c.udt_name AS custom_type_name,
26
- c.character_maximum_length AS char_length,
27
- c.numeric_precision AS num_precision,
28
- c.numeric_scale AS num_scale,
29
- c.datetime_precision AS dt_precision,
30
- c.interval_type,
31
- e.data_type AS element_type,
32
- e.udt_name AS element_custom_type_name
33
- FROM information_schema.columns AS c
34
- LEFT JOIN information_schema.element_types AS e
35
- ON e.object_catalog = c.table_catalog
36
- AND e.object_schema = c.table_schema
37
- AND e.object_name = c.table_name
38
- AND e.object_type = 'TABLE'
39
- AND e.collection_type_identifier = c.dtd_identifier
40
- WHERE c.table_schema = 'public'
41
- AND c.table_name = ?
42
- SQL
43
-
44
- CONSTRAINTS_QUERY = <<-SQL.freeze
45
- SELECT conname AS name,
46
- pg_get_expr(conbin, conrelid, true) AS condition
47
- FROM pg_constraint, pg_class
48
- WHERE conrelid = pg_class.oid
49
- AND relname = ?
50
- AND contype = 'c'
51
- SQL
52
-
53
- INDEXES_QUERY = <<-SQL.freeze
54
- SELECT relname AS name,
55
- indkey AS column_positions,
56
- indisunique AS unique,
57
- indoption AS index_options,
58
- pg_get_expr(indpred, indrelid, true) AS condition,
59
- amname AS index_type,
60
- indexrelid AS index_oid
61
- FROM pg_class, pg_index
62
- LEFT JOIN pg_opclass
63
- ON pg_opclass.oid = ANY(pg_index.indclass::int[])
64
- LEFT JOIN pg_am
65
- ON pg_am.oid = pg_opclass.opcmethod
66
- WHERE pg_class.oid = pg_index.indexrelid
67
- AND pg_class.oid IN (
68
- SELECT indexrelid
69
- FROM pg_index, pg_class
70
- WHERE pg_class.relname = ?
71
- AND pg_class.oid = pg_index.indrelid
72
- AND indisprimary != 't'
73
- )
74
- GROUP BY name, column_positions, indisunique, index_options, condition, index_type, index_oid
75
- SQL
76
-
77
- EXPRESSION_INDEXES_QUERY = <<-SQL.freeze
78
- WITH index_ids AS (SELECT unnest(?) AS index_id),
79
- elements AS (SELECT unnest(?) AS element)
80
- SELECT index_id,
81
- array_agg(pg_get_indexdef(index_id, element, 't')) AS definitions
82
- FROM index_ids, elements
83
- GROUP BY index_id;
84
- SQL
85
-
86
- attr_reader :connection, :table_name
87
-
88
- def initialize(connection, table_name)
89
- @connection = connection
90
- @table_name = table_name
25
+ FKEY_ACTIONS = {
26
+ a: :no_action,
27
+ r: :restrict,
28
+ c: :cascade,
29
+ n: :set_null,
30
+ d: :set_default
31
+ }.freeze
32
+
33
+ attr_reader :table_name, :fields_data, :indexes_data, :checks_data, :fkeys_data
34
+
35
+ def initialize(table_name, fields_data, indexes_data, checks_data, fkeys_data)
36
+ @table_name = table_name
37
+ @fields_data = fields_data
38
+ @indexes_data = indexes_data
39
+ @checks_data = checks_data
40
+ @fkeys_data = fkeys_data
91
41
  end
92
42
 
93
- def read
94
- primary_key_name = connection.primary_key(table_name)
95
-
96
- fields = columns_data.map do |column_data|
97
- build_field(column_data, primary_key: column_data[:name] == primary_key_name)
98
- end
99
-
100
- indexes = indexes_data.map do |index_data|
101
- Definitions::Index.new(index_data)
102
- end.sort_by(&:name)
103
-
104
- foreign_keys = connection.foreign_key_list(table_name).map do |foreign_key_data|
105
- build_foreign_key(foreign_key_data)
106
- end
107
-
108
- checks = connection[CONSTRAINTS_QUERY, table_name.to_s].map do |check_data|
109
- Definitions::CheckConstraint.new(
110
- name: check_data[:name].to_sym,
111
- condition: check_data[:condition]
112
- )
113
- end
114
-
43
+ def definition
115
44
  Definitions::Table.new(
116
45
  table_name,
117
46
  fields: fields,
@@ -121,107 +50,71 @@ GROUP BY index_id;
121
50
  )
122
51
  end
123
52
 
124
- private
125
- def columns_data
126
- @columns_data ||= connection[COLUMN_NAMES_QUERY, table_name.to_s]
127
- end
128
-
129
- def indexes_data
130
- column_names = columns_data.reduce({}) do |names, column|
131
- names.merge(column[:pos] => column[:name].to_sym)
132
- end
133
-
134
- indexes_data = connection[INDEXES_QUERY, table_name.to_s].to_a
135
- expressions_data = index_expressions_data(indexes_data)
136
-
137
- indexes_data.map do |index|
138
- positions = index[:column_positions].split(' ').map(&:to_i)
139
- options = index[:index_options].split(' ').map(&:to_i)
140
-
141
- columns = positions.zip(options).map do |column_position, column_order_options|
142
- options = case column_order_options
143
- when 0
144
- {}
145
- when 3
146
- { order: :desc }
147
- when 2
148
- { nulls: :first }
149
- when 1
150
- { order: :desc, nulls: :last }
151
- end
152
-
153
- if column_position.zero?
154
- expression = expressions_data.fetch(index[:index_oid]).shift
155
- DbSchema::Definitions::Index::Expression.new(expression, **options)
156
- else
157
- DbSchema::Definitions::Index::TableField.new(column_names.fetch(column_position), **options)
158
- end
159
- end
160
-
161
- {
162
- name: index[:name].to_sym,
163
- columns: columns,
164
- unique: index[:unique],
165
- type: index[:index_type].to_sym,
166
- condition: index[:condition]
167
- }
53
+ def fields
54
+ fields_data.map do |field_data|
55
+ build_field(field_data)
168
56
  end
169
57
  end
170
58
 
171
- def index_expressions_data(indexes_data)
172
- all_positions, max_position = {}, 0
173
-
174
- indexes_data.each do |index_data|
175
- positions = index_data[:column_positions].split(' ').map(&:to_i)
176
- expression_positions = positions.each_index.select { |i| positions[i].zero? }
59
+ def indexes
60
+ indexes_data.map do |index_data|
61
+ build_index(index_data)
62
+ end.sort_by(&:name)
63
+ end
177
64
 
178
- if expression_positions.any?
179
- all_positions[index_data[:index_oid]] = expression_positions
180
- max_position = [max_position, expression_positions.max].max
181
- end
65
+ def checks
66
+ checks_data.map do |check_data|
67
+ Definitions::CheckConstraint.new(
68
+ name: check_data[:name].to_sym,
69
+ condition: check_data[:condition]
70
+ )
182
71
  end
72
+ end
183
73
 
184
- if all_positions.any?
185
- connection[
186
- EXPRESSION_INDEXES_QUERY,
187
- Sequel.pg_array(all_positions.keys),
188
- Sequel.pg_array((1..max_position.succ).to_a)
189
- ].each_with_object({}) do |index_data, indexes_data|
190
- index_id = index_data[:index_id]
191
- expressions = all_positions[index_id].map { |pos| index_data[:definitions][pos] }
192
-
193
- indexes_data[index_id] = expressions
194
- end
195
- else
196
- {}
74
+ def foreign_keys
75
+ fkeys_data.map do |foreign_key_data|
76
+ build_foreign_key(foreign_key_data)
197
77
  end
198
78
  end
199
79
 
200
- def build_field(data, primary_key: false)
80
+ private
81
+ def build_field(data)
201
82
  type = data[:type].to_sym.downcase
202
83
  if type == :'user-defined'
203
84
  type = data[:custom_type_name].to_sym
204
85
  end
205
86
 
87
+ serial_type = SERIAL_TYPES[type]
88
+
206
89
  nullable = (data[:null] != 'NO')
207
90
 
208
- unless primary_key || data[:default].nil?
209
- default = if match = DEFAULT_VALUE.match(data[:default])
210
- if match[:date]
211
- Date.parse(match[:date])
212
- elsif match[:time]
213
- Time.parse(match[:time])
214
- elsif match[:string]
215
- match[:string]
216
- elsif match[:integer]
217
- match[:integer].to_i
218
- elsif match[:float]
219
- match[:float].to_f
220
- elsif match[:boolean]
221
- match[:boolean] == 'true'
222
- end
91
+ if data[:is_identity] == 'YES'
92
+ type = serial_type
93
+ default = nil
94
+ elsif !data[:default].nil?
95
+ serial_field_default = "nextval('#{table_name}_#{data[:name]}_seq'::regclass)"
96
+
97
+ if !serial_type.nil? && !nullable && data[:default] == serial_field_default
98
+ type = serial_type
99
+ default = nil
223
100
  else
224
- data[:default].to_sym
101
+ default = if match = DEFAULT_VALUE.match(data[:default])
102
+ if match[:date]
103
+ Date.parse(match[:date])
104
+ elsif match[:time]
105
+ Time.parse(match[:time])
106
+ elsif match[:string]
107
+ match[:string]
108
+ elsif match[:integer]
109
+ match[:integer].to_i
110
+ elsif match[:float]
111
+ match[:float].to_f
112
+ elsif match[:boolean]
113
+ match[:boolean] == 'true'
114
+ end
115
+ else
116
+ data[:default].to_sym
117
+ end
225
118
  end
226
119
  end
227
120
 
@@ -263,35 +156,52 @@ GROUP BY index_id;
263
156
  Definitions::Field.build(
264
157
  data[:name].to_sym,
265
158
  type,
266
- primary_key: primary_key,
267
- null: nullable,
268
- default: default,
159
+ null: nullable,
160
+ default: default,
269
161
  **options
270
162
  )
271
163
  end
272
164
 
273
- def build_foreign_key(data)
274
- keys = if data[:key] == [primary_key_for(data[:table])]
275
- [] # this foreign key references a primary key
276
- else
277
- data[:key]
165
+ def build_index(data)
166
+ columns = data[:columns].zip(data[:index_options]).map do |column, order_options|
167
+ options = case order_options
168
+ when 0
169
+ {}
170
+ when 3
171
+ { order: :desc }
172
+ when 2
173
+ { nulls: :first }
174
+ when 1
175
+ { order: :desc, nulls: :last }
176
+ end
177
+
178
+ if column.is_a?(String)
179
+ DbSchema::Definitions::Index::Expression.new(column, **options)
180
+ else
181
+ DbSchema::Definitions::Index::TableField.new(column, **options)
182
+ end
278
183
  end
279
184
 
280
- Definitions::ForeignKey.new(
281
- name: data[:name],
282
- fields: data[:columns],
283
- table: data[:table],
284
- keys: keys,
285
- on_delete: data[:on_delete],
286
- on_update: data[:on_update],
287
- deferrable: data[:deferrable]
185
+ Definitions::Index.new(
186
+ name: data[:name].to_sym,
187
+ columns: columns,
188
+ unique: data[:unique],
189
+ primary: data[:primary],
190
+ type: data[:index_type].to_sym,
191
+ condition: data[:condition]
288
192
  )
289
193
  end
290
194
 
291
- def primary_key_for(table_name)
292
- if pkey = connection.primary_key(table_name)
293
- pkey.to_sym
294
- end
195
+ def build_foreign_key(data)
196
+ Definitions::ForeignKey.new(
197
+ name: data[:name].to_sym,
198
+ fields: data[:fields],
199
+ table: data[:referenced].to_sym,
200
+ keys: data[:keys],
201
+ on_update: FKEY_ACTIONS.fetch(data[:on_update].to_sym),
202
+ on_delete: FKEY_ACTIONS.fetch(data[:on_delete].to_sym),
203
+ deferrable: data[:deferrable]
204
+ )
295
205
  end
296
206
 
297
207
  # TODO: replace following methods with Transproc
@@ -1,7 +1,7 @@
1
1
  module DbSchema
2
2
  module Reader
3
3
  class Postgres
4
- VERSION = '0.1.1'
4
+ VERSION = '0.2.rc1'
5
5
  end
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: db_schema-reader-postgres
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vsevolod Romashov
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-10-31 00:00:00.000000000 Z
11
+ date: 2019-02-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sequel
@@ -42,16 +42,16 @@ dependencies:
42
42
  name: db_schema-definitions
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - '='
46
46
  - !ruby/object:Gem::Version
47
- version: 0.1.0
47
+ version: 0.2.rc1
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - '='
53
53
  - !ruby/object:Gem::Version
54
- version: 0.1.0
54
+ version: 0.2.rc1
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: bundler
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -202,12 +202,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
202
202
  version: '0'
203
203
  required_rubygems_version: !ruby/object:Gem::Requirement
204
204
  requirements:
205
- - - ">="
205
+ - - ">"
206
206
  - !ruby/object:Gem::Version
207
- version: '0'
207
+ version: 1.3.1
208
208
  requirements: []
209
- rubyforge_project:
210
- rubygems_version: 2.7.6
209
+ rubygems_version: 3.0.1
211
210
  signing_key:
212
211
  specification_version: 4
213
212
  summary: Database schema reader for PostgreSQL