/usr/lib/ruby/vendor_ruby/sequel/plugins/serialization_modification_detection.rb is in ruby-sequel 4.15.0-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | module Sequel
module Plugins
# This plugin extends the serialization plugin and enables it to detect
# changes in serialized values by checking whether the current
# deserialized value is the same as the original deserialized value.
# The serialization plugin does not do such checks by default, as they
# often aren't needed and can hurt performance.
#
# Note that for this plugin to work correctly, the values you are
# serializing must roundtrip correctly (i.e. deserialize(serialize(value))
# should equal value). This is true in most cases, but not in all. For
# example, ruby symbols round trip through yaml, but not json (as they get
# turned into strings in json).
#
# == Example
#
# require 'sequel'
# require 'json'
# class User < Sequel::Model
# plugin :serialization, :json, :permissions
# plugin :serialization_modification_detection
# end
# user = User.create(:permissions => {})
# user.permissions[:global] = 'read-only'
# user.save_changes
module SerializationModificationDetection
# Load the serialization plugin automatically.
def self.apply(model)
model.plugin :serialization
end
module InstanceMethods
# Clear the cache of original deserialized values after saving so that it doesn't
# show the column is modified after saving.
def after_save
super
@original_deserialized_values = @deserialized_values
end
# Detect which serialized columns have changed.
def changed_columns
cc = super
cc = cc.dup if frozen?
deserialized_values.each{|c, v| cc << c if !cc.include?(c) && original_deserialized_value(c) != v}
cc
end
# Freeze the original deserialized values when freezing the instance.
def freeze
@original_deserialized_values ||= {}
@original_deserialized_values.freeze
super
end
private
# Duplicate the original deserialized values when duplicating instance.
def initialize_copy(other)
super
if o = other.instance_variable_get(:@original_deserialized_values)
@original_deserialized_values = o.dup
end
self
end
# For new objects, serialize any existing deserialized values so that changes can
# be detected.
def initialize_set(values)
super
serialize_deserialized_values
end
# Return the original deserialized value of the column, caching it to improve performance.
def original_deserialized_value(column)
if frozen?
@original_deserialized_values[column] || deserialize_value(column, self[column])
else
(@original_deserialized_values ||= {})[column] ||= deserialize_value(column, self[column])
end
end
end
end
end
end
|