pg_graph 0.4.2 → 0.5.1

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: 829bab0e543f48a02760b6a6888967bce94f2d5a4456fc6af81f43a084275532
4
- data.tar.gz: 0ca91b04090f570ef3bac358791e37f911e030c3dc334edb941a739896099057
3
+ metadata.gz: 3605f3dc16a65459725b3890e9dc85d4c7f4bf3fbdbf216526a12a1c843ef6f7
4
+ data.tar.gz: 34a6d5f23cf5914d43f53835f817aedb79f9699104c807d20d30fb9507633162
5
5
  SHA512:
6
- metadata.gz: 5fc04dbdebdf415b9c6e51e5af2a398689c517c7becae479a4f8eee9f5fcafa5bcd78d52e370fbfc8b893d86fa09e2cc14b41b8f161c55f67fed1f0caa749d84
7
- data.tar.gz: dec4aad67d9eba1236688baca32f013889748083ecec306b081dafd9c119c20fc05cdac422e0aa13e40da7417335681d791173c5d24113b0d5f21ab178398435
6
+ metadata.gz: e5e870b7ecd6ec71a8c0b8e5196511963402a372374efa003c522b847ec3b92ba50904c36046451930a79f6265455f0ba33f2f65547bd6b39a79ab88dc7ba30c
7
+ data.tar.gz: ec4d637a227f5a94beda42b2075240e9ecc1d70af3eaf1fa3c9c9c7c4d5990f269b70751985aa17482f3210c3ffbb635ed92638f8d5b5d69906c7e57fcc9526e
data/TODO CHANGED
@@ -1,4 +1,5 @@
1
1
 
2
+ o Fix that tables are not deleted in dependency order
2
3
  o Propagate super table relations to sub-tables
3
4
  o Provide a way to exclude certain schemas from the model (eg. prick/postspec/etc.)
4
5
  o Move SimpleType to PgCatalog schema
data/exe/pg_graph CHANGED
@@ -16,7 +16,7 @@ SPEC = %(
16
16
  ('psql') or by the Postgres library exec() call ('exec', 'sql'). It can also
17
17
  read and write Yaml data ('yaml') that is useful for exchanging data with
18
18
  other programs
19
-
19
+
20
20
  Note that when you're loading or dumping data in one of the SQL formats,
21
21
  you're almost always better off using postgres' own tools
22
22
  (pg_dump/pg_restore/pg_sql), except in the special case when the data
@@ -44,8 +44,8 @@ SPEC = %(
44
44
  Read/write reflections in the given table. The table argument can be both a
45
45
  full UID (eg. "my_schema.my_reflections") or just a table name in the public
46
46
  schema. Default is "public.reflections". The table and schema is created
47
- if not present.
48
-
47
+ if not present.
48
+
49
49
  If this option is used together with the --reflections option, the
50
50
  reflections are read from th e given file and written back to the database.
51
51
  If both options are missing, pg_graph will look for the default table and
@@ -74,7 +74,7 @@ SPEC = %(
74
74
  extension but can also be set explicitly using the --format option. Reads
75
75
  from standard input if FILE is missing
76
76
 
77
- dump! -- DATABASE
77
+ dump! -- DATABASE
78
78
  Dumps data on standard output. Default is to dump the type system in yaml
79
79
  format but this can be explicitly set using the --kind and --format options
80
80
 
@@ -96,7 +96,7 @@ def load_type(timer, opts, database)
96
96
  PgMeta.new(conn)
97
97
  end
98
98
  }
99
- reflector = tg.time("reflector") {
99
+ reflector = tg.time("reflector") {
100
100
  table, schema = opts.reflections_table&.split(".")&.reverse
101
101
  schema ||= PgGraph::Reflector::REFLECTIONS_SCHEMA
102
102
  table ||= PgGraph::Reflector::REFLECTIONS_TABLE
@@ -115,7 +115,7 @@ def load_type(timer, opts, database)
115
115
  end
116
116
  end
117
117
  }
118
-
118
+
119
119
  type = timer.time("type") { PgGraph::Type.new(meta, reflector, ignore: opts.ignore) }
120
120
  [conn, type]
121
121
  end
@@ -133,7 +133,7 @@ case opts.subcommand || :dump!
133
133
  if opts.format?
134
134
  format = opts.format
135
135
  else
136
- format =
136
+ format =
137
137
  case File.extname(file)
138
138
  when ".sql"; "sql"
139
139
  when ".yaml", ".yml"; "yaml"
@@ -143,7 +143,7 @@ case opts.subcommand || :dump!
143
143
  end
144
144
 
145
145
  case format
146
- when "sql", "exec";
146
+ when "sql", "exec";
147
147
  connection = timer.time("connect") { PgConn.new(database) }
148
148
  timer.time("load file") {
149
149
  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
 
@@ -124,17 +124,17 @@ module PgGraph::Data
124
124
  def to_yaml() @impl.map { |k,v| [k, v.to_yaml] }.to_h end
125
125
 
126
126
  # Note that #to_sql in derived classes should be deleted FIXME
127
- def to_sql(format: :sql, ids: {}, delete: :all, files: [])
128
- render = SqlRender.new(self, format, ids: ids, delete: delete, files: files)
127
+ def to_sql(format: :sql, ids: {}, delete: :all, truncate: :none, files: [])
128
+ render = SqlRender.new(self, format, ids: ids, delete: delete, truncate: truncate, files: files)
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
@@ -16,7 +16,13 @@ module PgGraph::Data
16
16
  # recursive - delete data for table in the fox file including recursively depending tables
17
17
  # all - delete data from the whole database
18
18
  attr_reader :delete
19
-
19
+
20
+ # Which data to truncate:
21
+ # none - don't delete any data
22
+ # touched - delete data for tables in the fox file
23
+ # all - delete data from the whole database
24
+ attr_reader :truncate
25
+
20
26
  # +ids+ is a map from table UID to ID. Records with larger IDs will
21
27
  # be emitted as insert statements, records with IDs less or equal to the
22
28
  # given ID is emitted as update statements
@@ -25,10 +31,15 @@ module PgGraph::Data
25
31
  # :recursive, :all Only records with an ID greater than the corresponding
26
32
  # ID from +ids+ will be deleted
27
33
  #
34
+ # +truncate+ acts as +delete+ that has the major drawback that it doesn't
35
+ # delete records in dependency order (FIXME This is an error). You can use
36
+ # the SQL truncate statement instead of delete using this option but note
37
+ # that +ids+ should be empty for this to work
38
+ #
28
39
  # +files+ is a list of source file names to be included in the psql SQL
29
40
  # header as documentation. It can be set explicitly when #to_a or #to_h is
30
41
  # called (FIXME: is this used?)
31
- def initialize(database, format, ids: {}, delete: :all, files: [])
42
+ def initialize(database, format, ids: {}, delete: :all, truncate: :none, files: [])
32
43
  # puts "SqlRender#initialize"
33
44
  # puts " format: #{format.inspect}"
34
45
  # puts " ids: #{ids.inspect}"
@@ -36,10 +47,13 @@ module PgGraph::Data
36
47
  # puts " files: #{files.inspect}"
37
48
  constrain database, Database
38
49
  constrain ids, { String => Integer }
50
+ constrain ids.empty? || truncate == :none, true
51
+ constrain delete == :none || truncate == :none, true
39
52
  @database = database
40
53
  self.format = format
41
54
  (@ids = ids.dup).default = 0
42
55
  @delete = delete
56
+ @truncate = truncate
43
57
  @files = files
44
58
 
45
59
  @tables = database.schemas.map(&:tables).flatten.sort
@@ -71,7 +85,7 @@ module PgGraph::Data
71
85
  case format
72
86
  when :sql; to_a.join("\n")
73
87
  when :exec; to_a.join("\n")
74
- 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")
75
89
  end
76
90
  end
77
91
 
@@ -79,6 +93,7 @@ module PgGraph::Data
79
93
  @to_h ||= {
80
94
  disable: render_triggers(:disable),
81
95
  delete: render_deletes(delete),
96
+ truncate: render_truncates(truncate),
82
97
  update: render_updates,
83
98
  insert: render_inserts,
84
99
  restart: render_restart_sequences,
@@ -90,7 +105,11 @@ module PgGraph::Data
90
105
  protected
91
106
  # Returns a single-element array of array of SQL statements
92
107
  def to_sql
93
- [to_h[:delete] + to_h[:update] + to_h[:insert]]
108
+ if delete != :none
109
+ [to_h[:delete] + to_h[:update] + to_h[:insert]]
110
+ else
111
+ [to_h[:truncate] + to_h[:update] + to_h[:insert]]
112
+ end
94
113
  end
95
114
 
96
115
  # Returns an array of non-empty arrays of SQL statements
@@ -115,7 +134,7 @@ module PgGraph::Data
115
134
  ]
116
135
  end
117
136
 
118
- def render_begin()
137
+ def render_begin()
119
138
  [ "begin;" ]
120
139
  end
121
140
 
@@ -135,7 +154,7 @@ module PgGraph::Data
135
154
  end
136
155
 
137
156
  def render_deletes(kind)
138
- table_uids =
157
+ table_uids =
139
158
  case kind
140
159
  when :none; []
141
160
  when :touched; @tables.reject(&:empty?).map(&:uid)
@@ -146,6 +165,8 @@ module PgGraph::Data
146
165
  else
147
166
  raise ArgumentError
148
167
  end
168
+
169
+ # FIXME: Not in dependency order
149
170
  table_uids.map { |uid|
150
171
  if !@ids.key?(uid)
151
172
  "delete from #{uid};"
@@ -155,14 +176,38 @@ module PgGraph::Data
155
176
  }
156
177
  end
157
178
 
179
+ def render_truncates(kind)
180
+ table_uids =
181
+ case kind
182
+ when :none; []
183
+ when :touched; @tables.reject(&:empty?).map(&:uid)
184
+ when :all; @tables.map(&:uid)
185
+ else
186
+ raise ArgumentError
187
+ end
188
+ table_uids.map { |uid| "truncate #{uid} cascade;" }
189
+ end
190
+
158
191
  def render_updates
159
192
  @update_records.map { |record|
160
- "update #{record.table.uid} set " \
161
- + record.value_columns
162
- .select { |column| !column.type.primary_key? }
163
- .map { |column| "#{column.name} = #{render_value(column)}" }
164
- .join(", ") + " " \
165
- + "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};"
166
211
  }
167
212
  end
168
213
 
@@ -229,7 +274,7 @@ module PgGraph::Data
229
274
  end
230
275
  end
231
276
 
232
- def render_commit()
277
+ def render_commit()
233
278
  [ "commit;" ]
234
279
  end
235
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
 
@@ -10,7 +10,7 @@ module PgGraph
10
10
  # Template for 'this' field name. Can be nil
11
11
  attr_reader :this
12
12
 
13
- # Template for 'that' field name or false if the field shouldn't be
13
+ # Template for 'that' field name or false if the field should not be
14
14
  # included in the model. Can be nil
15
15
  attr_reader :that
16
16
 
@@ -30,7 +30,7 @@ module PgGraph
30
30
  attr_reader :pluralize
31
31
 
32
32
  # RE corresponding to #match. #re always match a full UID
33
- attr_reader :re
33
+ attr_reader :re
34
34
 
35
35
  # Number of name components (database, schema, table, column). It can be
36
36
  # between one and four. By ordering reflections from highest to lowest
@@ -67,9 +67,9 @@ module PgGraph
67
67
  end
68
68
 
69
69
  def to_yaml
70
- {
71
- match: match, this: this, that: that, multi: multi, pluralize: pluralize,
72
- default_reflection: default_reflection
70
+ {
71
+ match: match, this: this, that: that, multi: multi, pluralize: pluralize,
72
+ default_reflection: default_reflection
73
73
  }
74
74
  end
75
75
 
@@ -82,8 +82,8 @@ module PgGraph
82
82
  # +hash+ has the keys :match, :this, :that, and :pluralize. The keys can
83
83
  # also be strings
84
84
  def self.load_yaml(hash)
85
- Reflection.new *METHODS.map { |key|
86
- value = hash[key].nil? ? hash[key.to_s] : hash[key]
85
+ Reflection.new *METHODS.map { |key|
86
+ value = hash[key].nil? ? hash[key.to_s] : hash[key]
87
87
  value == "nil" ? nil : value
88
88
  }
89
89
  end
@@ -117,7 +117,7 @@ module PgGraph
117
117
  def dup() Reflector.new(reflections.dup) end
118
118
 
119
119
  # Return true if the Reflector has no reflections
120
- def empty?()
120
+ def empty?()
121
121
  @reflection_list ? reflections.empty? : !@reflections.values.all?(:empty?)
122
122
  end
123
123
 
@@ -126,8 +126,8 @@ module PgGraph
126
126
  def add(*reflections)
127
127
  @reflection_list = nil
128
128
  # reverse makes it possible to use #insert but keep order:
129
- Array(reflections).flatten.reverse.each { |reflection|
130
- @reflections[reflection.components].insert(0, reflection)
129
+ Array(reflections).flatten.reverse.each { |reflection|
130
+ @reflections[reflection.components].insert(0, reflection)
131
131
  }
132
132
  end
133
133
 
@@ -193,14 +193,14 @@ module PgGraph
193
193
  table ||= REFLECTIONS_TABLE
194
194
  self.class.ensure_table(conn, schema, table)
195
195
  values = reflections.select { |r| !r.default_reflection }.map.with_index { |reflection, i|
196
- values = "(" + Reflection::METHODS.map { |m|
196
+ values = "(" + Reflection::METHODS.map { |m|
197
197
  v = reflection.send(m)
198
198
  v.nil? ? "null" : "'#{v}'"
199
199
  }.join(", ") + ", #{i})"
200
200
  }.join(",\n")
201
201
 
202
202
  conn.exec %(
203
- insert into #{schema}.#{table}
203
+ insert into #{schema}.#{table}
204
204
  (match, this, that, multi, pluralize, default_reflection, ordinal)
205
205
  values
206
206
  #{values}
@@ -215,14 +215,14 @@ module PgGraph
215
215
  {"match"=>"/parent_(\\w+)_id/", "that"=>"child_$1"},
216
216
  {"match"=>"/child_(\\w+)_id/", "that"=>"parent_$1"},
217
217
  {"match"=>"kind", "this"=>"kind", "that"=>"$$"},
218
- {"match"=>"/(\\w+)_kind/", "this"=>"$1", "that"=>"$$"},
218
+ {"match"=>"/(\\w+)_kind/", "this"=>"$1", "that"=>"$$"},
219
219
  {"match"=>"/(\\w+)_by_id/", "this"=>"$1_by", "that"=>"$1_$$", pluralize: true},
220
220
  {"match"=>"/(\\w+)_id/", "this"=>"$1", "that"=>"$$", multi: false},
221
221
  {"match"=>"/(\\w+)_id/", "this"=>"$1", "that"=>"$1_of", multi: true, pluralize: false},
222
222
  {"match"=>"/(\\w+)/", "this"=>"$1", "that"=>"$$"}, # Kind fields w/o explicit 'kind'
223
223
  ]
224
- initializers.map { |initializer|
225
- Reflection.load_yaml initializer.merge(default_reflection: true)
224
+ initializers.map { |initializer|
225
+ Reflection.load_yaml initializer.merge(default_reflection: true)
226
226
  }
227
227
  end
228
228
  end
@@ -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
@@ -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.4.2"
2
+ VERSION = "0.5.1"
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.4.2
4
+ version: 0.5.1
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-04-20 00:00:00.000000000 Z
11
+ date: 2024-07-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: boolean