SQL Database Design For Developers at php[tek] 2024
Gem and I: Runt
1. Runt
Ruby gem for building temporal expressions
squeejee Chris Lee
2. Getting started
Install from the command line:
$ sudo gem install runt
Include the library in your project
require 'rubygems' #(not necessary in Rails)
require 'runt'
include Runt
squeejee Chris Lee
3. What's a temporal expression?
For our purposes, a temporal expression can be described as a pattern*
that uses set expressions to describe recurring events or dates.
* http://martinfowler.com/apsupp/recurring.pdf
squeejee Chris Lee
4. Simple expressions
Every
week EveryTE.new(Time.now, 1, DPrecision::Precision.week)
Tues,
Thurs DIWeek.new(2) | DIWeek(Thursday)
Except
Holidays Date.new(2008, 11, 27), Date.new(2008, 12, 25)
squeejee Chris Lee
5. Putting it together
Every Tues, Except
temporal_expression week Thurs Holidays
weekly_interval = EveryTE.new(Time.now, 1, DPrecision::Precision.week)
days_in_week = DIWeek.new(2) | DIWeek.new(Thursday)
holidays = Date.new(2008, 11, 27), Date.new(2008, 12, 25)
temporal_expression = weekly_interval & days_in_week - holidays
squeejee Chris Lee
6. Matching
temporal_expression = weekly_interval & days_in_week - holidays
temporal_expression.to_s
# => quot;every 1 weeks starting Fri Oct 10
11:14:32 2008 and every Tuesday or Thursday
except for 2008-11-272008-12-25quot;
temporal_expression.include?(Date.new(2008, 10, 6)) # => false, monday
temporal_expression.include?(Date.new(2008, 10, 7)) # => true, tuesday
temporal_expression.include?(Date.new(2008, 11, 20)) # => true, thursday
temporal_expression.include?(Date.new(2008, 11, 27)) # => false # thanksgiving
temporal_expression.include?(Date.new(2008, 9, 25))
# => false why? It’s a thursday
# Use quot;REWeek.new(0, 6)quot; instead if there is no base date.
squeejee Chris Lee
7. Date ranges
Create an event that occurs every week, on Tuesdays and Thursdays, except
Thanksgiving and Christmas, for 1 year (2008).
temporal_expression.dates(DateRange.new(
PDate.day(2008, 1, 1), # start date
PDate.day(2008, 12, 31)) # end date
).each do |date
a = Activity.new(
:scheduled_at => Time.utc(date.year, date.month, date.day)
a.save
end
squeejee Chris Lee
8. More expressions
“Every 3 months, starting this month”
EveryTE.new(Time.now, 3, DPrecision::Precision.month)
“The last Thursday of a month”
DIMonth.new(Last, Thursday)
“The 12th-15th of a month”
REMonth.new(12, 15)
“December 25th of a year”
REYear.new(12, 25, 12, 25)
“3pm – 5:30pm, every Mon, Wed, and Fri”
(DIWeek.new(1) | DIWeek.new(3) | DIWeek.new(5)) & REDay.new(15,00,17,30)
squeejee Chris Lee
9. Expression builder
“Daily 8:45am to 9:30 and Fridays or Saturday except not the last Friday of
the month”
Option 1
temporal_expression = REDay.new(8,45,9,30) & DIWeek.new(Friday) |
DIWeek.new(Saturday) - DIMonth.new(Last, Friday)
Option 2
temporal_expression = ExpressionBuilder.new.define do
occurs daily_8_45am_to_9_30am
on friday
possibly saturday
except last_friday
end
squeejee Chris Lee
10. Runt resources
Rubyforge: http://runt.rubyforge.org/
Practical Ruby Gems:
Chapter 22: ‘Handling Recurring Events with runt’
squeejee Chris Lee
11. Thanks!
Drop me a line: chris.lee@squeejee.com
Web: http://squeejee.com
Blog: http://locomotivation.com
Code: http://github.com/squeejee
http://github.com/cglee
Twitter: cglee
squeejee Chris Lee