Add high_precision_current_timestamp to adapters

CURRENT_TIMESTAMP provides differing precision on different databases.

This method can be used in queries instead to provide a high precision
current time regardless of the database being connected to.

CURRENT_TIMESTAMP continues to be used as the default, unless overriden.
This commit is contained in:
Sam Bostock 2021-08-19 18:19:56 -04:00
parent b5fcf15383
commit da41061b4e
No known key found for this signature in database
GPG Key ID: 96D854C4833F2660
4 changed files with 39 additions and 0 deletions

View File

@ -441,6 +441,19 @@ module ActiveRecord
end
end
# This is a safe default, even if not high precision on all databases
HIGH_PRECISION_CURRENT_TIMESTAMP = Arel.sql("CURRENT_TIMESTAMP").freeze # :nodoc:
private_constant :HIGH_PRECISION_CURRENT_TIMESTAMP
# Returns an Arel SQL literal for the CURRENT_TIMESTAMP for usage with
# arbitrary precision date/time columns.
#
# Adapters supporting datetime with precision should override this to
# provide as much precision as is available.
def high_precision_current_timestamp
HIGH_PRECISION_CURRENT_TIMESTAMP
end
private
def execute_batch(statements, name = nil)
statements.each do |statement|

View File

@ -79,6 +79,15 @@ module ActiveRecord
end
alias :exec_update :exec_delete
# https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_current-timestamp
# https://dev.mysql.com/doc/refman/5.7/en/date-and-time-type-syntax.html
HIGH_PRECISION_CURRENT_TIMESTAMP = Arel.sql("CURRENT_TIMESTAMP(6)").freeze # :nodoc:
private_constant :HIGH_PRECISION_CURRENT_TIMESTAMP
def high_precision_current_timestamp
HIGH_PRECISION_CURRENT_TIMESTAMP
end
private
def execute_batch(statements, name = nil)
combine_multi_statements(statements).each do |statement|

View File

@ -122,6 +122,14 @@ module ActiveRecord
execute("ROLLBACK", "TRANSACTION")
end
# From https://www.postgresql.org/docs/current/functions-datetime.html#FUNCTIONS-DATETIME-CURRENT
HIGH_PRECISION_CURRENT_TIMESTAMP = Arel.sql("CURRENT_TIMESTAMP").freeze # :nodoc:
private_constant :HIGH_PRECISION_CURRENT_TIMESTAMP
def high_precision_current_timestamp
HIGH_PRECISION_CURRENT_TIMESTAMP
end
private
def execute_batch(statements, name = nil)
execute(combine_multi_statements(statements))

View File

@ -95,6 +95,15 @@ module ActiveRecord
reset_read_uncommitted
end
# https://stackoverflow.com/questions/17574784
# https://www.sqlite.org/lang_datefunc.html
HIGH_PRECISION_CURRENT_TIMESTAMP = Arel.sql("STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')").freeze # :nodoc:
private_constant :HIGH_PRECISION_CURRENT_TIMESTAMP
def high_precision_current_timestamp
HIGH_PRECISION_CURRENT_TIMESTAMP
end
private
def reset_read_uncommitted
read_uncommitted = Thread.current.thread_variable_get("read_uncommitted")