forked from jeremyevans/sequel
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add thread_local_timezones extension, and refactor timezone support i…
…n modules The thread_local_timezones extension allows you to set a per-thread timezone that will override the default global timezone while the thread is executing. The main use case is for web applications that execute each request in its own thread, and want to set the timezones based on the request. The most common example is having the database always store time in UTC, but have the application deal with the timezone of the current user. That can be done with: Sequel.database_timezone = :utc # In each thread: Sequel.thread_application_timezone = current_user.timezone This extension is designed to work with the named_timezones extension. This extension adds the thread_application_timezone=, thread_database_timezone=, and thread_typecast_timezone= methods to the Sequel module. It overrides the application_timezone, database_timezone, and typecast_timezone methods to check the related thread local timezone first, and use it if present. If the related thread local timezone is not present, it falls back to the default global timezone. There is one special case of note. If you have a default global timezone and you want to have a nil thread local timezone, you have to set the thread local value to :nil instead of nil: Sequel.application_timezone = :utc Sequel.thread_application_timezone = nil Sequel.application_timezone # => :utc Sequel.thread_application_timezone = :nil Sequel.application_timezone # => nil In order to implement this more easily, and just for generally better design, the timezone support in the main Sequel module was separated into the Sequel::Timezones module, which extends the main Sequel module. The named_timezones extension now uses a NamedTimezones module which also extends Sequel. And the new thread_local_timezones extension adds a ThreadLocalTimezones which also extends Sequel. A new private convert_timezone_setter_arg method was added to ease implementation and allow the thread_local_timezones and named_timezones extensions to work better together.
- Loading branch information
1 parent
97c11f0
commit f899e55
Showing
7 changed files
with
290 additions
and
170 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
# The thread_local_timezones extension allows you to set a per-thread timezone that | ||
# will override the default global timezone while the thread is executing. The | ||
# main use case is for web applications that execute each request in its own thread, | ||
# and want to set the timezones based on the request. The most common example | ||
# is having the database always store time in UTC, but have the application deal | ||
# with the timezone of the current user. That can be done with: | ||
# | ||
# Sequel.database_timezone = :utc | ||
# # In each thread: | ||
# Sequel.thread_application_timezone = current_user.timezone | ||
# | ||
# This extension is designed to work with the named_timezones extension. | ||
# | ||
# This extension adds the thread_application_timezone=, thread_database_timezone=, | ||
# and thread_typecast_timezone= methods to the Sequel module. It overrides | ||
# the application_timezone, database_timezone, and typecast_timezone | ||
# methods to check the related thread local timezone first, and use it if present. | ||
# If the related thread local timezone is not present, it falls back to the | ||
# default global timezone. | ||
# | ||
# There is one special case of note. If you have a default global timezone | ||
# and you want to have a nil thread local timezone, you have to set the thread | ||
# local value to :nil instead of nil: | ||
# | ||
# Sequel.application_timezone = :utc | ||
# Sequel.thread_application_timezone = nil | ||
# Sequel.application_timezone # => :utc | ||
# Sequel.thread_application_timezone = :nil | ||
# Sequel.application_timezone # => nil | ||
|
||
module Sequel | ||
module ThreadLocalTimezones | ||
%w'application database typecast'.each do |t| | ||
class_eval("def thread_#{t}_timezone=(tz); Thread.current[:#{t}_timezone] = convert_timezone_setter_arg(tz); end", __FILE__, __LINE__) | ||
class_eval(<<END, __FILE__, __LINE__) | ||
def #{t}_timezone | ||
if tz = Thread.current[:#{t}_timezone] | ||
tz unless tz == :nil | ||
else | ||
super | ||
end | ||
end | ||
END | ||
end | ||
end | ||
|
||
extend ThreadLocalTimezones | ||
end |
Oops, something went wrong.