module TransactionTimestamps::Timestamp
Public Class Methods
included(base)
click to toggle source
# File lib/transaction_timestamps/timestamp.rb, line 5 def self.included(base) base.class_eval do # override the original timestamp with one our own that returns transaction-based timestamps alias_method :original_current_time_from_proper_timezone, :current_time_from_proper_timezone def current_time_from_proper_timezone if use_transaction_timestamps? current_transaction_time else original_current_time_from_proper_timezone end end end end
Public Instance Methods
current_time_from_proper_timezone()
click to toggle source
# File lib/transaction_timestamps/timestamp.rb, line 9 def current_time_from_proper_timezone if use_transaction_timestamps? current_transaction_time else original_current_time_from_proper_timezone end end
current_transaction_time()
click to toggle source
# File lib/transaction_timestamps/timestamp.rb, line 19 def current_transaction_time if new_transaction? @@cached_timestamp = adjust_time_to_timezone(db_transaction_time) else @@cached_timestamp end end
Private Instance Methods
adjust_time_to_timezone(time)
click to toggle source
# File lib/transaction_timestamps/timestamp.rb, line 66 def adjust_time_to_timezone(time) # do exactly the same time adjustment as performed in ActiveRecord::Timestamp self.class.default_timezone == :utc ? time.utc : time.getlocal end
db_transaction_time()
click to toggle source
# File lib/transaction_timestamps/timestamp.rb, line 50 def db_transaction_time if postgresql? time_str = ActiveRecord::Base.connection.select_one("SELECT transaction_timestamp();")['transaction_timestamp'] Time.parse(time_str) else # other databases (MySQL, sqlite) don't support retrieval of the actual transaction time, so the best we can # do is to use the current system time (and cache this until the transaction changes) Time.now end end
new_transaction?()
click to toggle source
# File lib/transaction_timestamps/timestamp.rb, line 35 def new_transaction? # check whether the transaction object id has changed since the last time we checked current_transaction_id = transaction_id is_new = !defined?(@@prev_transaction_id) || (current_transaction_id != @@prev_transaction_id) @@prev_transaction_id = current_transaction_id is_new end
postgresql?()
click to toggle source
# File lib/transaction_timestamps/timestamp.rb, line 61 def postgresql? defined?(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter) && ActiveRecord::Base.connection.instance_of?(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter) end
transaction_id()
click to toggle source
# File lib/transaction_timestamps/timestamp.rb, line 44 def transaction_id # use the transaction object id as a unique identifier for whether the transaction has changed manager = ActiveRecord::Base.connection.instance_variable_get(:@transaction_manager) manager.current_transaction.object_id end
use_transaction_timestamps?()
click to toggle source
# File lib/transaction_timestamps/timestamp.rb, line 28 def use_transaction_timestamps? # Timecop doesn't play well transaction timestamps, so don't enable them when using Timecop # and the time is frozen TransactionTimestamps.enabled && !(defined?(Timecop) && Timecop.frozen?) end