lib/pg_graph/data/render.rb in pg_graph-0.4.2 vs lib/pg_graph/data/render.rb in pg_graph-0.5.0

- old
+ new

@@ -14,34 +14,48 @@ # none - don't delete any data # touched - delete data for tables in the fox file # recursive - delete data for table in the fox file including recursively depending tables # all - delete data from the whole database attr_reader :delete - + + # Which data to truncate: + # none - don't delete any data + # touched - delete data for tables in the fox file + # all - delete data from the whole database + attr_reader :truncate + # +ids+ is a map from table UID to ID. Records with larger IDs will # be emitted as insert statements, records with IDs less or equal to the # given ID is emitted as update statements # # +delete+ control which tables are deleted. It can be :none, :touched, # :recursive, :all Only records with an ID greater than the corresponding # ID from +ids+ will be deleted # + # +truncate+ acts as +delete+ that has the major drawback that it doesn't + # delete records in dependency order (FIXME This is an error). You can use + # the SQL truncate statement instead of delete using this option but note + # that +ids+ should be empty for this to work + # # +files+ is a list of source file names to be included in the psql SQL # header as documentation. It can be set explicitly when #to_a or #to_h is # called (FIXME: is this used?) - def initialize(database, format, ids: {}, delete: :all, files: []) + def initialize(database, format, ids: {}, delete: :all, truncate: :none, files: []) # puts "SqlRender#initialize" # puts " format: #{format.inspect}" # puts " ids: #{ids.inspect}" # puts " delete: #{delete.inspect}" # puts " files: #{files.inspect}" constrain database, Database constrain ids, { String => Integer } + constrain ids.empty? || truncate == :none, true + constrain delete == :none || truncate == :none, true @database = database self.format = format (@ids = ids.dup).default = 0 @delete = delete + @truncate = truncate @files = files @tables = database.schemas.map(&:tables).flatten.sort @insert_tables = [] @update_tables = [] @@ -77,10 +91,11 @@ def to_h @to_h ||= { disable: render_triggers(:disable), delete: render_deletes(delete), + truncate: render_truncates(truncate), update: render_updates, insert: render_inserts, restart: render_restart_sequences, enable: render_triggers(:enable), refresh: render_refresh_materialized_views @@ -88,11 +103,15 @@ end protected # Returns a single-element array of array of SQL statements def to_sql - [to_h[:delete] + to_h[:update] + to_h[:insert]] + if delete != :none + [to_h[:delete] + to_h[:update] + to_h[:insert]] + else + [to_h[:truncate] + to_h[:update] + to_h[:insert]] + end end # Returns an array of non-empty arrays of SQL statements def to_exec() to_h.values.reject(&:empty?) end @@ -144,16 +163,30 @@ (tables.map(&:uid) + tables.map { |table| table.type.depending_tables.map(&:uid) }.flatten).uniq when :all; @tables.map(&:uid) else raise ArgumentError end + + # FIXME: Not in dependency order table_uids.map { |uid| if !@ids.key?(uid) "delete from #{uid};" else "delete from #{uid} where id > #{@ids[uid]};" end } + end + + def render_truncates(kind) + table_uids = + case kind + when :none; [] + when :touched; @tables.reject(&:empty?).map(&:uid) + when :all; @tables.map(&:uid) + else + raise ArgumentError + end + table_uids.map { |uid| "truncate #{uid} cascade;" } end def render_updates @update_records.map { |record| "update #{record.table.uid} set " \