pg_graph 0.5.0 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 123eb2c8963ee6c45420315db19a876e76e5322ca7069d74e3d50fa4792aab58
4
- data.tar.gz: 5be39db46db7775b25a40b02c76c65cedb8bf365128d5c3b602c1e3ca9003552
3
+ metadata.gz: 38b9eb4ca9867310cda60284befd00b8819dd91ab0f337c053a47e2045c41f35
4
+ data.tar.gz: f4fe9a924423df0b43b3e0609ba3075e864902ff7a6e92d1c7d2baf522065f31
5
5
  SHA512:
6
- metadata.gz: d1c6a0c25c6980031763409d6357df388db14002c6c8c49b6eb92b93ac9cf180d9cfe7eb0789b622e5f2fc078f08a603b33ccb433947d0bd5c308bf16c204a0a
7
- data.tar.gz: b43cfb4089d4fcffa32f62019c256065b9f3b00c1dddb47edb3c4ca490a68dfb1495dd68fd7204e3d42051aadeca7b737652a129ef6d3bdfd84ff47a2dafa44d
6
+ metadata.gz: f057d02742170bfb37e2fc93e6c1419c65ca8081e8543c33c497e29efa82598c9cb82ef10b3359143b7ad56482328de8c8b8e59b75749f89df940b355fe874f9
7
+ data.tar.gz: 37e9bc383ef07636a85740dd73350ba7dacd8b67036250b0959b41b31f4d91afef540f8ae4b841dbbbc513b50bd5b439e1b63230175a407d00cfd364302418a0
data/exe/pg_graph CHANGED
@@ -11,12 +11,14 @@ include ShellOpts
11
11
  SPEC = %(
12
12
  @ Load, dump, and clean databases
13
13
 
14
+ -- DATABASE
15
+
14
16
  pg_graph is a utility that uses the PgGraph module to load, dump, or clean a
15
17
  database. It uses a variety of formats that can be executed by psql(1)
16
18
  ('psql') or by the Postgres library exec() call ('exec', 'sql'). It can also
17
19
  read and write Yaml data ('yaml') that is useful for exchanging data with
18
20
  other programs
19
-
21
+
20
22
  Note that when you're loading or dumping data in one of the SQL formats,
21
23
  you're almost always better off using postgres' own tools
22
24
  (pg_dump/pg_restore/pg_sql), except in the special case when the data
@@ -44,8 +46,8 @@ SPEC = %(
44
46
  Read/write reflections in the given table. The table argument can be both a
45
47
  full UID (eg. "my_schema.my_reflections") or just a table name in the public
46
48
  schema. Default is "public.reflections". The table and schema is created
47
- if not present.
48
-
49
+ if not present.
50
+
49
51
  If this option is used together with the --reflections option, the
50
52
  reflections are read from th e given file and written back to the database.
51
53
  If both options are missing, pg_graph will look for the default table and
@@ -74,7 +76,7 @@ SPEC = %(
74
76
  extension but can also be set explicitly using the --format option. Reads
75
77
  from standard input if FILE is missing
76
78
 
77
- dump! -- DATABASE
79
+ dump! -- DATABASE
78
80
  Dumps data on standard output. Default is to dump the type system in yaml
79
81
  format but this can be explicitly set using the --kind and --format options
80
82
 
@@ -96,7 +98,7 @@ def load_type(timer, opts, database)
96
98
  PgMeta.new(conn)
97
99
  end
98
100
  }
99
- reflector = tg.time("reflector") {
101
+ reflector = tg.time("reflector") {
100
102
  table, schema = opts.reflections_table&.split(".")&.reverse
101
103
  schema ||= PgGraph::Reflector::REFLECTIONS_SCHEMA
102
104
  table ||= PgGraph::Reflector::REFLECTIONS_TABLE
@@ -115,7 +117,7 @@ def load_type(timer, opts, database)
115
117
  end
116
118
  end
117
119
  }
118
-
120
+
119
121
  type = timer.time("type") { PgGraph::Type.new(meta, reflector, ignore: opts.ignore) }
120
122
  [conn, type]
121
123
  end
@@ -133,7 +135,7 @@ case opts.subcommand || :dump!
133
135
  if opts.format?
134
136
  format = opts.format
135
137
  else
136
- format =
138
+ format =
137
139
  case File.extname(file)
138
140
  when ".sql"; "sql"
139
141
  when ".yaml", ".yml"; "yaml"
@@ -143,7 +145,7 @@ case opts.subcommand || :dump!
143
145
  end
144
146
 
145
147
  case format
146
- when "sql", "exec";
148
+ when "sql", "exec";
147
149
  connection = timer.time("connect") { PgConn.new(database) }
148
150
  timer.time("load file") {
149
151
  connection.exec(IO.read(file))
@@ -37,8 +37,8 @@ module PgGraph::Data
37
37
  # value of a field even if the field is an association
38
38
  def object() self end
39
39
 
40
- def inspect(payload = inspect_inner)
41
- "#<#{self.class}:#{uid}#{payload ? " #{payload}" : ""}>"
40
+ def inspect(payload = inspect_inner)
41
+ "#<#{self.class}:#{uid}#{payload ? " #{payload}" : ""}>"
42
42
  end
43
43
 
44
44
  def to_h() raise NotThis end
@@ -93,7 +93,7 @@ module PgGraph::Data
93
93
  end
94
94
 
95
95
  def dup() Database.new(type, to_h) end
96
-
96
+
97
97
  # Make Database pretend it is a PgGraph::Data object
98
98
  def is_a?(klass) klass == PgGraph::Type or super end
99
99
 
@@ -115,7 +115,7 @@ module PgGraph::Data
115
115
  id.nil? ? object : object[id]
116
116
  end
117
117
 
118
- def ==(other) to_h == other.to_h end
118
+ def ==(other) to_h == other.to_h end
119
119
 
120
120
  alias_method :to_h, :data
121
121
 
@@ -129,12 +129,12 @@ module PgGraph::Data
129
129
  render.to_s
130
130
  end
131
131
 
132
- def to_exec_sql(ids: {}, delete: :all)
133
- to_sql(format: :exec, ids: ids, delete: delete)
132
+ def to_exec_sql(ids: {}, delete: :all)
133
+ to_sql(format: :exec, ids: ids, delete: delete)
134
134
  end
135
135
 
136
- def to_psql_sql(files = [], ids: {}, delete: :all)
137
- to_sql(format: :psql, ids: ids, delete: delete, files: files)
136
+ def to_psql_sql(files = [], ids: {}, delete: :all)
137
+ to_sql(format: :psql, ids: ids, delete: delete, files: files)
138
138
  end
139
139
 
140
140
  # :call-seq:
@@ -208,8 +208,8 @@ module PgGraph::Data
208
208
  def data() @impl.map { |k,v| [k, v.data] }.to_h end
209
209
 
210
210
  alias_method :to_h, :data
211
- # def to_sql()
212
- # tables.select { |table| !table.empty? }.map(&:to_sql).join("\n")
211
+ # def to_sql()
212
+ # tables.select { |table| !table.empty? }.map(&:to_sql).join("\n")
213
213
  # end
214
214
  def to_yaml() @impl.map { |k,v| [k, v.to_yaml] }.to_h end
215
215
  end
@@ -245,29 +245,29 @@ module PgGraph::Data
245
245
  type.fields.each { |column|
246
246
  next if column.is_a?(PgGraph::Type::SimpleColumn)
247
247
  that_table = db[column.type.schema.name][column.type.table.name]
248
- association =
248
+ association =
249
249
  case column
250
250
  when PgGraph::Type::KindRecordColumn
251
251
  KindAssociation.new(1,
252
- self, that_table,
253
- column.this_link_column.to_sym,
252
+ self, that_table,
253
+ column.this_link_column.to_sym,
254
254
  column.that_link_column.to_sym)
255
255
  when PgGraph::Type::RecordColumn
256
- Association.new(1,
257
- self, that_table,
258
- column.this_link_column.to_sym,
256
+ Association.new(1,
257
+ self, that_table,
258
+ column.this_link_column.to_sym,
259
259
  column.that_link_column.to_sym)
260
260
  when PgGraph::Type::NmTableColumn, PgGraph::Type::MmTableColumn
261
261
  dimension = column.is_a?(PgGraph::Type::NmTableColumn) ? 2 : 3
262
262
  nm_table = db[column.mm_table.schema.name][column.mm_table.name]
263
- LinkAssociation.new(dimension,
263
+ LinkAssociation.new(dimension,
264
264
  self, that_table, nm_table,
265
- column.this_link_column.to_sym, column.this_mm_column.to_sym,
265
+ column.this_link_column.to_sym, column.this_mm_column.to_sym,
266
266
  column.that_mm_column.to_sym, column.that_link_column.to_sym)
267
267
  when PgGraph::Type::TableColumn
268
- Association.new(2,
269
- self, that_table,
270
- column.this_link_column.to_sym,
268
+ Association.new(2,
269
+ self, that_table,
270
+ column.this_link_column.to_sym,
271
271
  column.that_link_column.to_sym)
272
272
  else
273
273
  raise NotHere
@@ -284,7 +284,7 @@ module PgGraph::Data
284
284
 
285
285
  # Return record with the given ID
286
286
  def [](id) @impl[id] end
287
-
287
+
288
288
  # True if the table contains a record with the given ID
289
289
  def id?(id) @impl.key?(id) end
290
290
 
@@ -348,7 +348,7 @@ module PgGraph::Data
348
348
  uid =~ /^(.*?)\[(\d+)\]$/
349
349
  [$1, $2.to_i]
350
350
  end
351
-
351
+
352
352
  # Redefine GUID to include ID of record
353
353
  def guid() "#{table.guid}[#{id}]" end
354
354
 
@@ -371,7 +371,7 @@ module PgGraph::Data
371
371
  constrain columns, lambda { |h| h.key?(:id) }, "No :id field"
372
372
  @table = table # has to go before super
373
373
  super(table.type.record_type, dimension: 1)
374
- @impl = columns.map { |k,v| [k, Column.new(self, k, v)] }.to_h
374
+ @impl = columns.map { |k,v| [k, Column.new(self, k, v)] }.to_h
375
375
  for name, association in table.associations
376
376
  if association.is_a?(KindAssociation) #&& @impl.key?(name)
377
377
  next if !@impl.key?(name)
@@ -407,9 +407,9 @@ module PgGraph::Data
407
407
  def columns() @impl.values.select { |field| field.is_a?(Column) } end
408
408
 
409
409
  # List of columns excluding generated columns
410
- def value_columns()
410
+ def value_columns()
411
411
  columns.select { |column| !column.type.generated? }.uniq
412
- end
412
+ end
413
413
 
414
414
  # List of association objects in the record
415
415
  def associations() @impl.values.select { |field| field.is_a?(AssociationField) } end
@@ -422,7 +422,7 @@ module PgGraph::Data
422
422
  # def data() @impl.select { |k,v| v.is_a?(Column) }.map { |k,v| [k, v.data] }.to_h end
423
423
 
424
424
  def data()
425
- @impl.select { |k,v| v.is_a?(Column) || v.is_a?(KindRecordField) }.map { |k,v| [k, v.data] }.to_h
425
+ @impl.select { |k,v| v.is_a?(Column) || v.is_a?(KindRecordField) }.map { |k,v| [k, v.data] }.to_h
426
426
  end
427
427
 
428
428
  alias_method :to_h, :data
@@ -516,7 +516,7 @@ module PgGraph::Data
516
516
  # Return the value of the association. This is either a Record, TableValue,
517
517
  # or MmTableValue depending on the dimension of the association
518
518
  def object()
519
- @object ||= Dimension.value_class(dimension).new(table, association.get_records(record))
519
+ @object ||= Dimension.value_class(dimension).new(table, association.get_records(record))
520
520
  end
521
521
  end
522
522
 
@@ -530,7 +530,7 @@ module PgGraph::Data
530
530
  super(record, name, association)
531
531
  @column = column
532
532
  end
533
-
533
+
534
534
  def value_type() @column.value_type end
535
535
  def value() @column.value end
536
536
  def data() @column.data end
@@ -85,7 +85,7 @@ module PgGraph::Data
85
85
  case format
86
86
  when :sql; to_a.join("\n")
87
87
  when :exec; to_a.join("\n")
88
- when :psql; to_psql(files).map { |group| group.join("\n") }.join("\n\n")
88
+ when :psql; to_psql(files).map { |group| group.join("\n") }.join("\n\n")
89
89
  end
90
90
  end
91
91
 
@@ -134,7 +134,7 @@ module PgGraph::Data
134
134
  ]
135
135
  end
136
136
 
137
- def render_begin()
137
+ def render_begin()
138
138
  [ "begin;" ]
139
139
  end
140
140
 
@@ -154,7 +154,7 @@ module PgGraph::Data
154
154
  end
155
155
 
156
156
  def render_deletes(kind)
157
- table_uids =
157
+ table_uids =
158
158
  case kind
159
159
  when :none; []
160
160
  when :touched; @tables.reject(&:empty?).map(&:uid)
@@ -177,7 +177,7 @@ module PgGraph::Data
177
177
  end
178
178
 
179
179
  def render_truncates(kind)
180
- table_uids =
180
+ table_uids =
181
181
  case kind
182
182
  when :none; []
183
183
  when :touched; @tables.reject(&:empty?).map(&:uid)
@@ -190,12 +190,24 @@ module PgGraph::Data
190
190
 
191
191
  def render_updates
192
192
  @update_records.map { |record|
193
- "update #{record.table.uid} set " \
194
- + record.value_columns
195
- .select { |column| !column.type.primary_key? }
196
- .map { |column| "#{column.name} = #{render_value(column)}" }
197
- .join(", ") + " " \
198
- + "where id = #{record.id};"
193
+ # Temporary fix for the case where a kind field is updated. Kind fields
194
+ # are not considered value_columns (!) so kind fields are skipped in
195
+ # the original code below. FIXME FIXME FIXME
196
+ "update #{record.table.uid} set " +
197
+ record.to_h.keys
198
+ .map { |key| record[key] }
199
+ .reject { |column| column.type.primary_key? }
200
+ .map { |column|
201
+ "#{column.name} = #{render_value(column)}"
202
+ }.join(", ") + " " \
203
+ + "where id = #{record.id};"
204
+
205
+ # "update #{record.table.uid} set " \
206
+ # + record.value_columns
207
+ # .select { |column| !column.type.primary_key? }
208
+ # .map { |column| "#{column.name} = #{render_value(column)}" }
209
+ # .join(", ") + " " \
210
+ # + "where id = #{record.id};"
199
211
  }
200
212
  end
201
213
 
@@ -262,7 +274,7 @@ module PgGraph::Data
262
274
  end
263
275
  end
264
276
 
265
- def render_commit()
277
+ def render_commit()
266
278
  [ "commit;" ]
267
279
  end
268
280
  end
@@ -9,7 +9,7 @@ module PgGraph::Data
9
9
 
10
10
  # Fake class: RecordValue.new(table, records) simply returns the Record object
11
11
  class RecordValue < Value
12
- def self.new(table, records)
12
+ def self.new(table, records)
13
13
  constrain table, Table
14
14
  constrain records, [Record]
15
15
  records.first
@@ -50,7 +50,7 @@ module PgGraph::Data
50
50
  @impl = {}
51
51
  records.each { |record| (@impl[record.id] ||= []) << record }
52
52
  end
53
-
53
+
54
54
  # Number of records including duplicates
55
55
  def size() records.size end
56
56
 
@@ -2,6 +2,12 @@
2
2
  require 'constrain'
3
3
  require 'indented_io'
4
4
 
5
+ def putv(*variables)
6
+ for var in Array(variables)
7
+ puts "#{var}: #{self.send(var).inspect}"
8
+ end
9
+ end
10
+
5
11
  module PgGraph
6
12
  class Reflection
7
13
  # Textual representation of match RE (String)
@@ -30,7 +36,7 @@ module PgGraph
30
36
  attr_reader :pluralize
31
37
 
32
38
  # RE corresponding to #match. #re always match a full UID
33
- attr_reader :re
39
+ attr_reader :re
34
40
 
35
41
  # Number of name components (database, schema, table, column). It can be
36
42
  # between one and four. By ordering reflections from highest to lowest
@@ -41,6 +47,11 @@ module PgGraph
41
47
  # True if this is a default reflection
42
48
  attr_reader :default_reflection
43
49
 
50
+ def dump
51
+ puts "Reflection"
52
+ indent { putv :match, :re, :this, :that, :multi?, :pluralize, :components }
53
+ end
54
+
44
55
  # +this+ and +that+ are template strings, nil, or false
45
56
  def initialize(match, this, that, multi = nil, pluralize = nil, default_reflection = false)
46
57
  constrain match, Regexp, String
@@ -67,9 +78,9 @@ module PgGraph
67
78
  end
68
79
 
69
80
  def to_yaml
70
- {
71
- match: match, this: this, that: that, multi: multi, pluralize: pluralize,
72
- default_reflection: default_reflection
81
+ {
82
+ match: match, this: this, that: that, multi: multi, pluralize: pluralize,
83
+ default_reflection: default_reflection
73
84
  }
74
85
  end
75
86
 
@@ -82,8 +93,8 @@ module PgGraph
82
93
  # +hash+ has the keys :match, :this, :that, and :pluralize. The keys can
83
94
  # also be strings
84
95
  def self.load_yaml(hash)
85
- Reflection.new *METHODS.map { |key|
86
- value = hash[key].nil? ? hash[key.to_s] : hash[key]
96
+ Reflection.new *METHODS.map { |key|
97
+ value = hash[key].nil? ? hash[key.to_s] : hash[key]
87
98
  value == "nil" ? nil : value
88
99
  }
89
100
  end
@@ -117,7 +128,7 @@ module PgGraph
117
128
  def dup() Reflector.new(reflections.dup) end
118
129
 
119
130
  # Return true if the Reflector has no reflections
120
- def empty?()
131
+ def empty?()
121
132
  @reflection_list ? reflections.empty? : !@reflections.values.all?(:empty?)
122
133
  end
123
134
 
@@ -126,8 +137,8 @@ module PgGraph
126
137
  def add(*reflections)
127
138
  @reflection_list = nil
128
139
  # reverse makes it possible to use #insert but keep order:
129
- Array(reflections).flatten.reverse.each { |reflection|
130
- @reflections[reflection.components].insert(0, reflection)
140
+ Array(reflections).flatten.reverse.each { |reflection|
141
+ @reflections[reflection.components].insert(0, reflection)
131
142
  }
132
143
  end
133
144
 
@@ -141,10 +152,11 @@ module PgGraph
141
152
 
142
153
  # Find 'that' field name for the given UID by searching through reflections
143
154
  # for a match. The name is pluralized if the matcher returns true or if the
144
- # matcher returns nil and unique is false The :table option can be used to
155
+ # matcher returns nil and unique is false. The :table option can be used to
145
156
  # override the table name in '$$' rules. This is used in N:M and M:M
146
- # relations. Returns nil if no match was found or if a matching reflection
147
- # has #continue equal to false
157
+ # relations. Returns false if the :that property is set to false in the
158
+ # reflections file. Returns nil if no match was found or if a matching
159
+ # reflection has #continue equal to false
148
160
  def that(uid, unique, multi = false, table: nil)
149
161
  constrain uid, String
150
162
  if (name, pluralize = do_match(uid, :that, multi, table: table))
@@ -193,14 +205,14 @@ module PgGraph
193
205
  table ||= REFLECTIONS_TABLE
194
206
  self.class.ensure_table(conn, schema, table)
195
207
  values = reflections.select { |r| !r.default_reflection }.map.with_index { |reflection, i|
196
- values = "(" + Reflection::METHODS.map { |m|
208
+ values = "(" + Reflection::METHODS.map { |m|
197
209
  v = reflection.send(m)
198
210
  v.nil? ? "null" : "'#{v}'"
199
211
  }.join(", ") + ", #{i})"
200
212
  }.join(",\n")
201
213
 
202
214
  conn.exec %(
203
- insert into #{schema}.#{table}
215
+ insert into #{schema}.#{table}
204
216
  (match, this, that, multi, pluralize, default_reflection, ordinal)
205
217
  values
206
218
  #{values}
@@ -215,14 +227,14 @@ module PgGraph
215
227
  {"match"=>"/parent_(\\w+)_id/", "that"=>"child_$1"},
216
228
  {"match"=>"/child_(\\w+)_id/", "that"=>"parent_$1"},
217
229
  {"match"=>"kind", "this"=>"kind", "that"=>"$$"},
218
- {"match"=>"/(\\w+)_kind/", "this"=>"$1", "that"=>"$$"},
230
+ {"match"=>"/(\\w+)_kind/", "this"=>"$1", "that"=>"$$"},
219
231
  {"match"=>"/(\\w+)_by_id/", "this"=>"$1_by", "that"=>"$1_$$", pluralize: true},
220
232
  {"match"=>"/(\\w+)_id/", "this"=>"$1", "that"=>"$$", multi: false},
221
233
  {"match"=>"/(\\w+)_id/", "this"=>"$1", "that"=>"$1_of", multi: true, pluralize: false},
222
234
  {"match"=>"/(\\w+)/", "this"=>"$1", "that"=>"$$"}, # Kind fields w/o explicit 'kind'
223
235
  ]
224
- initializers.map { |initializer|
225
- Reflection.load_yaml initializer.merge(default_reflection: true)
236
+ initializers.map { |initializer|
237
+ Reflection.load_yaml initializer.merge(default_reflection: true)
226
238
  }
227
239
  end
228
240
  end
@@ -240,7 +252,7 @@ module PgGraph
240
252
  match_data = reflection.re.match(uid) or next
241
253
  template = reflection.send(kind).dup
242
254
  if template == false
243
- return nil
255
+ return [false, false]
244
256
  elsif template
245
257
  table ||= uid.split(".")[-2]
246
258
  template.gsub!(/\$\$/, table)
@@ -7,7 +7,7 @@ module PgGraph::Type
7
7
  # Array of [record, meta_column] tuples
8
8
  field_columns = []
9
9
  link_columns = []
10
- kind_columns = [] # The link side
10
+ kind_columns = [] # The link side
11
11
  id_link_columns = [] # sub tables
12
12
 
13
13
  # Temporary arrays of meta tables
@@ -21,7 +21,7 @@ module PgGraph::Type
21
21
  meta_schema.tables.values.select { |t| t.table? }.each { |meta_table| # FIXME Ignore views for now
22
22
  (meta_table.mm_table? ? mm_tables : tables) << meta_table
23
23
  table = Table.new(
24
- schema, meta_table.name,
24
+ schema, meta_table.name,
25
25
  mm_table: meta_table.mm_table?,
26
26
  depending_materialized_views: meta_table.depending_views.select(&:materialized?))
27
27
  record_type = RecordType.new(table)
@@ -32,7 +32,7 @@ module PgGraph::Type
32
32
  # Create basic types needed by columns
33
33
  type_name = meta_column.type
34
34
  if !schema.key?(type_name) && !catalog.key?(type_name)
35
- if meta_column.array?
35
+ if meta_column.array?
36
36
  element_name = meta_column.element_type
37
37
  dimensions = meta_column.dimensions
38
38
  if !schema.key?(element_name) && !catalog.key?(element_name)
@@ -51,7 +51,7 @@ module PgGraph::Type
51
51
  if meta_column.name == "id"
52
52
  id_link_columns
53
53
  elsif meta_column.name =~ /^(?:.*_)?kind$/
54
- kind_columns
54
+ kind_columns
55
55
  else
56
56
  link_columns
57
57
  end
@@ -76,7 +76,7 @@ module PgGraph::Type
76
76
  next if meta_column.kind?
77
77
  type = record_type.schema[meta_column.type] || catalog[meta_column.type]
78
78
  SimpleColumn.new(
79
- record_type, meta_column.name, meta_column.name, type,
79
+ record_type, meta_column.name, meta_column.name, type,
80
80
  ordinal: meta_column.ordinal,
81
81
  **column_options(meta_column))
82
82
  }
@@ -104,7 +104,7 @@ module PgGraph::Type
104
104
  (reference_count[record_type] ||= {})[type] ||= 0
105
105
  reference_count[record_type][type] += 1 if reflector.multi?(this_link_column)
106
106
 
107
- field =
107
+ field =
108
108
  if meta_column.kind?
109
109
  name = reflector.this(meta_column.uid) || meta_column.name
110
110
  name = meta_column.name if record_type[name] # Check for duplicates
@@ -144,10 +144,10 @@ module PgGraph::Type
144
144
  else
145
145
  multi = reference_count[this_record_type][that_record_type] > 1
146
146
  name = reflector.that(uid, this_column.unique?, multi, table: this_record_type.name)
147
- name ||= PgGraph.inflector.pluralize(this_column.table.name) if this_column.kind?
147
+ name ||= PgGraph.inflector.pluralize(this_column.table.name) if name.nil? && this_column.kind?
148
148
  end
149
149
 
150
- next if name.nil?
150
+ next if !name
151
151
 
152
152
  # Check for name collisions
153
153
  if that_record_type.key?(name)
@@ -171,7 +171,7 @@ module PgGraph::Type
171
171
  # Create back-references
172
172
  if this_column.unique?
173
173
  RecordColumn.new(
174
- that_record_type, name, nil, this_record_type,
174
+ that_record_type, name, nil, this_record_type,
175
175
  this_column.that_link_column, this_column.this_link_column)
176
176
  else
177
177
  TableColumn.new(that_record_type, name, this_table.type,
@@ -237,7 +237,7 @@ module PgGraph::Type
237
237
  if table1.type.record_type.key?(column1_name)
238
238
  raise Error, "Duplicate column name in #{table1.identifier}: #{column1_name}"
239
239
  end
240
-
240
+
241
241
  if table2.type.record_type.key?(column2_name)
242
242
  raise Error, "Duplicate column name in #{table2.identifier}: #{column2_name}"
243
243
  end
@@ -1,7 +1,7 @@
1
1
 
2
2
  module PgGraph::Type
3
3
  class Error < StandardError; end
4
-
4
+
5
5
  class Node < HashTree::Set
6
6
  include Constrain
7
7
 
@@ -16,7 +16,7 @@ module PgGraph::Type
16
16
  # The full Ruby model identifier of the object within a database. It
17
17
  # corresponds to #uid
18
18
  def schema_identifier() identifier end
19
-
19
+
20
20
  # :call-seq: initialize(database, name, attach: true)
21
21
  def initialize(parent, name, **opts)
22
22
  constrain parent, Node, NilClass
@@ -24,8 +24,8 @@ module PgGraph::Type
24
24
  super
25
25
  end
26
26
 
27
- def inspect(payload = inspect_inner)
28
- "#<#{self.class}:#{name.inspect}#{payload ? " #{payload}" : ""}>"
27
+ def inspect(payload = inspect_inner)
28
+ "#<#{self.class}:#{name.inspect}#{payload ? " #{payload}" : ""}>"
29
29
  end
30
30
 
31
31
  def inspect_inner() nil end
@@ -33,9 +33,9 @@ module PgGraph::Type
33
33
  protected
34
34
  # Nodes with nil keys are not attached. This is used in PgCatalogSchema to
35
35
  # avoid being included in the list of schemas
36
- def do_attach(key, child)
36
+ def do_attach(key, child)
37
37
  !key?(key) or raise PgGraph::Error, "Duplicate fields in #{self.uid}: '#{key}'"
38
- super if child
38
+ super if child
39
39
  end
40
40
 
41
41
  # Forward list of methods to object. The arguments should be strings or symbols
@@ -48,7 +48,7 @@ module PgGraph::Type
48
48
 
49
49
  # Included by tables, records, and fields
50
50
  module TableObject
51
- # Circular definitions. Classes that include TableObject should redefine at least
51
+ # Circular definitions. Classes that include TableObject should redefine at least
52
52
  # one of the methods to break the loop
53
53
  def table() record_type.table end
54
54
  def table_type() table.type end
@@ -95,7 +95,7 @@ module PgGraph::Type
95
95
  @reflector = reflector || @reflector
96
96
  case arg
97
97
  # #read_meta is a member of Database but defined in read.rb
98
- when PgMeta; read_meta(arg, ignore: ignore)
98
+ when PgMeta; read_meta(arg, ignore: ignore)
99
99
  when PgConn; read_meta(PgMeta.new(arg), ignore: ignore)
100
100
  end
101
101
  end
@@ -282,12 +282,12 @@ module PgGraph::Type
282
282
  end
283
283
 
284
284
  # List of postgres columns. The columns are sorted by ordinal
285
- def columns()
285
+ def columns()
286
286
  @columns ||= begin
287
287
  cols = fields.map { |field|
288
288
  case field
289
289
  when SimpleColumn; field
290
- when KindRecordColumn;
290
+ when KindRecordColumn;
291
291
  if field.kind_column&.parent
292
292
  nil
293
293
  else
@@ -308,7 +308,7 @@ module PgGraph::Type
308
308
  cols = fields.map { |field|
309
309
  case field
310
310
  when SimpleColumn; field
311
- when KindRecordColumn;
311
+ when KindRecordColumn;
312
312
  if field.kind_column&.parent
313
313
  nil
314
314
  else
@@ -324,7 +324,7 @@ module PgGraph::Type
324
324
  end
325
325
 
326
326
  # TODO: Rename #columns to #postgres_columns and #abstract_columns to #columns
327
- def abstract_columns
327
+ def abstract_columns
328
328
  @abstract_columns ||= fields.map { |field|
329
329
  case field
330
330
  when SimpleColumn; field
@@ -334,19 +334,19 @@ module PgGraph::Type
334
334
  nil
335
335
  end
336
336
  }.compact.sort_by(&:ordinal)
337
-
337
+
338
338
  end
339
339
 
340
340
  # List of columns excluding generated fields
341
- def value_columns()
341
+ def value_columns()
342
342
  columns.select { |column| !column.generated? }
343
343
  end
344
344
 
345
345
  # True iff name if the name of a postgres column
346
346
  # def column?(name) self[name].is_a?(SimpleColumn) end
347
- def column?(name)
347
+ def column?(name)
348
348
  raise "See the rename TODO above"
349
- @columns_hash.key?(name)
349
+ @columns_hash.key?(name)
350
350
  end
351
351
 
352
352
  end
@@ -439,7 +439,7 @@ module PgGraph::Type
439
439
  def primary_key?() @postgres_column && @primary_key end
440
440
 
441
441
  # Return true/false or nil if postgres_column is an identity column.
442
- # Sub-keys are primary keys but not identity keys
442
+ # Sub-keys are primary keys but not identity keys
443
443
  def identity?() @postgres_column && @identity end
444
444
 
445
445
  # Return true/false or nil
@@ -462,8 +462,8 @@ module PgGraph::Type
462
462
 
463
463
  protected
464
464
  def initialize(
465
- record_type, name, postgres_column, type,
466
- primary_key: false, identity: false,
465
+ record_type, name, postgres_column, type,
466
+ primary_key: false, identity: false,
467
467
  reference: false, kind: false,
468
468
  nullable: true, unique: false, readonly: false, generated: false)
469
469
  constrain record_type, RecordType, NilClass
@@ -531,8 +531,8 @@ module PgGraph::Type
531
531
  forward_method :kind_column, :literal?
532
532
 
533
533
  def initialize(
534
- record_type, name, postgres_column, type,
535
- this_link_column, that_link_column,
534
+ record_type, name, postgres_column, type,
535
+ this_link_column, that_link_column,
536
536
  kind_column, **opts)
537
537
  constrain kind_column, SimpleColumn
538
538
  super(record_type, name, postgres_column, type, this_link_column, that_link_column, kind: true, **opts)
@@ -1,3 +1,3 @@
1
1
  module PgGraph
2
- VERSION = "0.5.0"
2
+ VERSION = "0.5.2"
3
3
  end
data/lib/pg_graph.rb CHANGED
@@ -53,12 +53,12 @@ module PgGraph
53
53
  def self.new(arg, reflections = nil, schema = nil, ignore: [])
54
54
  constrain arg, PgMeta, PgConn
55
55
  constrain reflections, Reflector, Array, String, PgConn, NilClass
56
- meta =
56
+ meta =
57
57
  case arg
58
58
  when PgMeta; arg
59
59
  when PgConn; PgMeta.new(arg)
60
60
  end
61
- reflector =
61
+ reflector =
62
62
  case reflections
63
63
  when Reflector; reflections
64
64
  when Array; Reflector.load_yaml(reflections)
@@ -78,7 +78,7 @@ module PgGraph
78
78
  # instantiate(hash)
79
79
  # instantiate(yaml)
80
80
  # instantiate(pg_conn)
81
- #
81
+ #
82
82
  def instantiate(arg = nil)
83
83
  constrain arg, NilClass, Hash, PgConn
84
84
  Data.new(self, arg)
@@ -94,7 +94,7 @@ module PgGraph
94
94
  # new(type, hash = {})
95
95
  # new(type, yaml = {})
96
96
  # new(type, pg_conn = nil)
97
- #
97
+ #
98
98
  # Note that together with ::=== and Data::Database#is_a? this makes
99
99
  # Data::Database pretend it is an instance of the Data module
100
100
  def self.new(type, arg)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pg_graph
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.5.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Claus Rasmussen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-06-05 00:00:00.000000000 Z
11
+ date: 2024-09-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: boolean