Module: Sequel::Plugins::Bitemporal::InstanceMethods

Defined in:
lib/sequel/plugins/bitemporal.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#pending_versionObject (readonly)

Returns the value of attribute pending_version.



294
295
296
# File 'lib/sequel/plugins/bitemporal.rb', line 294

def pending_version
  @pending_version
end

Instance Method Details

#after_createObject



362
363
364
365
366
367
368
# File 'lib/sequel/plugins/bitemporal.rb', line 362

def after_create
  super
  if @create_version
    @create_version = nil
    return false unless save_pending_version
  end
end

#after_saveObject



378
379
380
381
# File 'lib/sequel/plugins/bitemporal.rb', line 378

def after_save
  super
  _refresh_set_values @values
end

#attributesObject



316
317
318
319
320
321
322
323
324
# File 'lib/sequel/plugins/bitemporal.rb', line 316

def attributes
  if pending_version
    pending_version.values
  elsif current_version
    current_version.values
  else
    initial_version.values
  end
end

#attributes=(attributes) ⇒ Object



326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
# File 'lib/sequel/plugins/bitemporal.rb', line 326

def attributes=(attributes)
  @pending_version ||= begin
    current_attributes =
      if composite_primary_key?
        version_values
      else
        { master_id: id }
      end

    current_version.columns.each do |key|
      next if excluded_columns.include? key
      current_attributes[key] = current_version.public_send key
    end if current_version?
    model.version_class.new current_attributes
  end
  pending_version.set_all attributes
end

#audited?Boolean

Returns:



296
297
298
# File 'lib/sequel/plugins/bitemporal.rb', line 296

def audited?
  !!self.class.audit_class
end

#before_createObject



357
358
359
360
# File 'lib/sequel/plugins/bitemporal.rb', line 357

def before_create
  @create_version = pending_version_holds_changes?
  super
end

#before_updateObject



370
371
372
373
374
375
376
# File 'lib/sequel/plugins/bitemporal.rb', line 370

def before_update
  if pending_version_holds_changes?
    expire_previous_versions
    return false unless save_pending_version
  end
  super
end

#before_validationObject



300
301
302
303
# File 'lib/sequel/plugins/bitemporal.rb', line 300

def before_validation
  prepare_pending_version
  super
end

#composite_primary_key?Boolean

Returns:



383
384
385
# File 'lib/sequel/plugins/bitemporal.rb', line 383

def composite_primary_key?
  [*primary_key].size > 1
end

#deleted?Boolean

Returns:



425
426
427
# File 'lib/sequel/plugins/bitemporal.rb', line 425

def deleted?
  !new? && !current_version
end

#destroyObject



387
388
389
390
391
392
393
394
# File 'lib/sequel/plugins/bitemporal.rb', line 387

def destroy
  point_in_time = ::Sequel::Plugins::Bitemporal.point_in_time
  versions_dataset.where(
    expired_at: nil
  ).where(
    Sequel.lit("valid_to>valid_from")
  ).update expired_at: point_in_time
end

#destroy_version(version, expand_previous_version) ⇒ Object



396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
# File 'lib/sequel/plugins/bitemporal.rb', line 396

def destroy_version(version, expand_previous_version)
  now = ::Sequel::Plugins::Bitemporal.now
  point_in_time = ::Sequel::Plugins::Bitemporal.point_in_time
  return false if version.valid_to.to_datetime<=now
  associations.delete :current_version
  model.db.transaction do
    success = true
    version_was_valid = now>=version.valid_from.to_datetime
    if expand_previous_version
      previous = versions_dataset.where({
        expired_at: nil,
        valid_to: version.valid_from,
      }).where(Sequel.lit("valid_to>valid_from")).first
      if previous
        if version_was_valid
          success &&= save_fossil previous, created_at: point_in_time, valid_from: now, valid_to: version.valid_to
        else
          success &&= save_fossil previous, created_at: point_in_time, valid_to: version.valid_to
          success &&= previous.update expired_at: point_in_time
        end
      end
    end
    success &&= save_fossil version, created_at: point_in_time, valid_to: now if version_was_valid
    success &&= version.update expired_at: point_in_time
    raise Sequel::Rollback unless success
    success
  end
end

#last_versionObject



429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
# File 'lib/sequel/plugins/bitemporal.rb', line 429

def last_version
  @last_version ||= begin
    return if new?
    t = ::Sequel::Plugins::Bitemporal.point_in_time
    n = ::Sequel::Plugins::Bitemporal.now
    if use_ranges = self.class.use_ranges
      range_conditions = self.class.existence_range_contains t
    end
    versions_dataset.where do
      if use_ranges
        range_conditions
      else
        (created_at <= t) &
        Sequel.|({expired_at=>nil}, expired_at > t)
      end & (valid_from <= n)
    end.order(Sequel.desc(:valid_to), Sequel.desc(:created_at)).first
  end
end

#next_versionObject



448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
# File 'lib/sequel/plugins/bitemporal.rb', line 448

def next_version
  @next_version ||= begin
    return if new?
    t = ::Sequel::Plugins::Bitemporal.point_in_time
    n = ::Sequel::Plugins::Bitemporal.now
    if use_ranges = self.class.use_ranges
      range_conditions = self.class.existence_range_contains t
    end
    versions_dataset.where do
      if use_ranges
        range_conditions
      else
        (created_at <= t) &
        Sequel.|({expired_at=>nil}, expired_at > t)
      end & (valid_from > n)
    end.order(Sequel.asc(:valid_to), Sequel.desc(:created_at)).first
  end
end

#pending_or_current_versionObject



312
313
314
# File 'lib/sequel/plugins/bitemporal.rb', line 312

def pending_or_current_version
  pending_version || current_version || initial_version
end

#propagated_during_last_saveObject



490
491
492
# File 'lib/sequel/plugins/bitemporal.rb', line 490

def propagated_during_last_save
  @propagated_during_last_save ||= []
end

#reloadObject



482
483
484
485
486
487
488
# File 'lib/sequel/plugins/bitemporal.rb', line 482

def reload
  @last_version = nil
  @current_version_values = nil
  @pending_version = nil
  @initial_version = nil
  super
end

#restore(attrs = {}) ⇒ Object



467
468
469
470
471
472
473
474
475
476
477
478
479
480
# File 'lib/sequel/plugins/bitemporal.rb', line 467

def restore(attrs={})
  return false unless deleted?
  last_version_attributes = if last_version
    last_version.columns.each_with_object({}) do |column, hash|
      unless excluded_columns.include? column
        hash[column] = last_version.public_send column
      end
    end
  else
    {}
  end
  update_attributes last_version_attributes.merge attrs
  @last_version = nil
end

#update_attributes(attributes = {}) ⇒ Object



348
349
350
351
352
353
354
355
# File 'lib/sequel/plugins/bitemporal.rb', line 348

def update_attributes(attributes={})
  self.attributes = attributes
  if save raise_on_failure: false
    self
  else
    false
  end
end

#validateObject



305
306
307
308
309
310
# File 'lib/sequel/plugins/bitemporal.rb', line 305

def validate
  super
  pending_version.errors.each do |key, key_errors|
    key_errors.each{|error| errors.add key, error}
  end if pending_version_holds_changes? && !pending_version.valid?
end

#version_foreign_keysObject



494
495
496
# File 'lib/sequel/plugins/bitemporal.rb', line 494

def version_foreign_keys
  composite_primary_key? ? primary_key : :master_id
end

#version_valuesObject



344
345
346
# File 'lib/sequel/plugins/bitemporal.rb', line 344

def version_values
  version_foreign_keys.map { |k| [k, public_send(k)] }.to_h
end