Module: TableDiffer::ClassMethods
- Defined in:
- lib/table_differ.rb
Instance Method Summary collapse
-
#create_snapshot(suggestion = Time.now) ⇒ Object
creates a new snapshot.
-
#delete_snapshot(name) ⇒ Object
deletes the named snapshot.
-
#delete_snapshots(snaps) ⇒ Object
deletes every snapshot named in the array Model.delete_snapshots(:all) deletes all snapshots.
-
#diff_snapshot(options = {}) ⇒ Object
ignore: %w[ created_at updated_at id ].
-
#snapshot_name(name) ⇒ Object
pass a date or name fragment, receive the full snapshot name.
-
#snapshots ⇒ Object
returns an array of the snapshot names that currently exist.
- #table_differ_remap_objects(params, records, table) ⇒ Object
Instance Method Details
#create_snapshot(suggestion = Time.now) ⇒ Object
creates a new snapshot
35 36 37 38 39 |
# File 'lib/table_differ.rb', line 35 def create_snapshot suggestion=Time.now name = snapshot_name(suggestion) connection.execute("CREATE TABLE #{name} AS SELECT * FROM #{table_name}") name end |
#delete_snapshot(name) ⇒ Object
deletes the named snapshot
42 43 44 |
# File 'lib/table_differ.rb', line 42 def delete_snapshot name connection.execute("DROP TABLE #{snapshot_name(name)}") end |
#delete_snapshots(snaps) ⇒ Object
deletes every snapshot named in the array Model.delete_snapshots(:all) deletes all snapshots
48 49 50 51 |
# File 'lib/table_differ.rb', line 48 def delete_snapshots snaps snaps = self.snapshots if snaps == :all snaps.each { |name| delete_snapshot(name) } end |
#diff_snapshot(options = {}) ⇒ Object
ignore: %w[ created_at updated_at id ]
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/table_differ.rb', line 79 def diff_snapshot ={} oldtable = snapshot_name([:old]) || snapshots.last newtable = snapshot_name([:new]) || table_name ignore = [] if [:ignore] ignore = Array([:ignore]).map(&:to_s) end columns = column_names - ignore cols = columns.map { |c| "#{c} as #{c}" }.join(", ") added = find_by_sql("SELECT #{cols} FROM #{newtable} EXCEPT SELECT #{cols} FROM #{oldtable}") removed = find_by_sql("SELECT #{cols} from #{oldtable} EXCEPT SELECT #{cols} FROM #{newtable}") # hm, none of this seems to matter... TODO: mark appropriate objects read-only: obj.readonly! # AR always thinks the record is persisted in the db, even when it obviously isn't # added.each { |o| o.instance_variable_set("@new_record", true) } unless table_name == oldtable # removed.each { |o| o.instance_variable_set("@new_record", true) } unless table_name == newtable # actually, it's probably more reliable just to use the presence of an id to determine if the record can be saved # [*added, *removed].select { |o| !o.id }.each { |o| o.instance_variable_set("@new_record", true) } if [:unique_by] added = table_differ_remap_objects([:unique_by], added, newtable) removed = table_differ_remap_objects([:unique_by], removed, oldtable) end changed = added & removed changed.each do |obj| orig = removed.find { |r| r == obj } raise "this is impossible" if orig.nil? obj.original_attributes = (orig.original_attributes || orig.attributes).except(*ignore) end added -= changed removed -= changed [*added, *removed].each { |o| o.original_attributes = nil } [added, removed, changed] end |
#snapshot_name(name) ⇒ Object
pass a date or name fragment, receive the full snapshot name. it’s ok to pass a snapshot name; it will be returned unchaged.
15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/table_differ.rb', line 15 def snapshot_name name return nil if name.nil? if name.kind_of?(Date) || name.kind_of?(Time) name = name.strftime("%Y%m%d_%H%M%S") end unless name.index(table_name) == 0 name = "#{table_name}_#{name}" end name end |
#snapshots ⇒ Object
returns an array of the snapshot names that currently exist
30 31 32 |
# File 'lib/table_differ.rb', line 30 def snapshots connection.tables.grep(/^#{table_name}_/).sort end |
#table_differ_remap_objects(params, records, table) ⇒ Object
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/table_differ.rb', line 53 def table_differ_remap_objects params, records, table model = self if table != table_name model = Class.new(self) model.table_name = table end params = Array(params) records.map do |record| result = record if record.id.nil? # don't look up real ActiveRecord object if we already have one args = params.inject({}) { |hash,key| hash[key] = record[key]; hash } real_record = model.where(args).first if real_record if model != self real_record = self.new(real_record.attributes) # convert fake model to real model end real_record.original_attributes = record.attributes result = real_record end end result end end |