lib/sequel/plugins/bitemporal.rb in sequel_bitemporal-0.6.2 vs lib/sequel/plugins/bitemporal.rb in sequel_bitemporal-0.6.3
- old
+ new
@@ -33,10 +33,14 @@
def self.bitemporal_version_columns
@bitemporal_version_columns ||= [:master_id, :valid_from, :valid_to, :created_at, :expired_at]
end
+ def self.bitemporal_excluded_columns
+ @bitemporal_excluded_columns ||= [:id, *bitemporal_version_columns]
+ end
+
def self.configure(master, opts = {})
version = opts[:version_class]
raise Error, "please specify version class to use for bitemporal plugin" unless version
missing = bitemporal_version_columns - version.columns
raise Error, "bitemporal plugin requires the following missing column#{"s" if missing.size>1} on version class: #{missing.join(", ")}" unless missing.empty?
@@ -147,15 +151,12 @@
def attributes=(attributes)
if attributes_hold_changes? attributes
@pending_version ||= begin
current_attributes = {}
current_version.keys.each do |key|
- case key
- when :id, :valid_from, :valid_to, :created_at, :expired_at
- else
- current_attributes[key] = current_version.send key
- end
+ next if excluded_columns.include? key
+ current_attributes[key] = current_version.send key
end if current_version?
model.version_class.new current_attributes
end
pending_version.set attributes
end
@@ -212,10 +213,46 @@
raise Sequel::Rollback unless success
success
end
end
+ def deleted?
+ !new? && !current_version
+ end
+
+ def last_version
+ @last_version ||= begin
+ return if new?
+ t = ::Sequel::Plugins::Bitemporal.point_in_time
+ n = ::Sequel::Plugins::Bitemporal.now
+ versions_dataset.where do
+ (created_at <= t) & ({expired_at=>nil} | (expired_at > t)) &
+ (valid_from <= n)
+ end.order(:valid_to.desc).first
+ end
+ end
+
+ def restore(attrs={})
+ return false unless deleted?
+ last_version_attributes = if last_version
+ last_version.values.reject do |column, _|
+ excluded_columns.include? column
+ end
+ else
+ {}
+ end
+ update_attributes last_version_attributes.merge attrs
+ @last_version = nil
+ end
+
+ def reload
+ @last_version = nil
+ @current_version_values = nil
+ @pending_version = nil
+ super
+ end
+
private
def prepare_pending_version
return unless pending_version
now = ::Sequel::Plugins::Bitemporal.now
@@ -252,11 +289,10 @@
futures = futures.exclude "valid_from=valid_to"
futures = futures.exclude "valid_to<=?", pending_version.valid_from
futures = futures.where "valid_from>?", pending_version.valid_from
futures = futures.order(:valid_from).all
- excluded_columns = Sequel::Plugins::Bitemporal.bitemporal_version_columns + [:id]
to_check_columns = self.class.version_class.columns - excluded_columns
updated_by = (send(self.class.audit_updated_by_method) if audited?)
previous_values = @current_version_values
current_version_values = pending_version.values
@@ -338,16 +374,26 @@
attributes.detect do |key, new_value|
case key
when :id, :master_id, :created_at, :expired_at
false
when :valid_from
- new_value && new_value<current_version.valid_from
+ new_value && (
+ new_value<current_version.valid_from ||
+ (
+ current_version.valid_to &&
+ new_value>current_version.valid_to
+ )
+ )
when :valid_to
new_value || new_value!=current_version.valid_to
else
current_version.send(key)!=new_value
end
end
+ end
+
+ def excluded_columns
+ Sequel::Plugins::Bitemporal.bitemporal_excluded_columns
end
end
end
end