schedule_fu 0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.rdoc +34 -0
  3. data/Rakefile +40 -0
  4. data/app/models/calendar.rb +26 -0
  5. data/app/models/calendar_date.rb +76 -0
  6. data/app/models/calendar_event.rb +157 -0
  7. data/app/models/calendar_event_date.rb +8 -0
  8. data/app/models/calendar_event_mod.rb +8 -0
  9. data/app/models/calendar_event_type.rb +3 -0
  10. data/app/models/calendar_recurrence.rb +9 -0
  11. data/config/routes.rb +2 -0
  12. data/db/migrate/20120121210741_add_schedule_fu_tables.rb +167 -0
  13. data/lib/schedule_fu.rb +8 -0
  14. data/lib/schedule_fu/calendar_helper.rb +247 -0
  15. data/lib/schedule_fu/engine.rb +5 -0
  16. data/lib/schedule_fu/finder.rb +16 -0
  17. data/lib/schedule_fu/parser.rb +108 -0
  18. data/lib/schedule_fu/schedule_fu_helper.rb +17 -0
  19. data/lib/schedule_fu/version.rb +3 -0
  20. data/lib/tasks/schedule_fu_tasks.rake +4 -0
  21. data/test/calendar_event_test.rb +229 -0
  22. data/test/dummy/README.rdoc +261 -0
  23. data/test/dummy/Rakefile +7 -0
  24. data/test/dummy/app/assets/javascripts/application.js +15 -0
  25. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  26. data/test/dummy/app/controllers/application_controller.rb +3 -0
  27. data/test/dummy/app/helpers/application_helper.rb +2 -0
  28. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  29. data/test/dummy/config.ru +4 -0
  30. data/test/dummy/config/application.rb +56 -0
  31. data/test/dummy/config/boot.rb +10 -0
  32. data/test/dummy/config/database.yml +9 -0
  33. data/test/dummy/config/environment.rb +5 -0
  34. data/test/dummy/config/environments/development.rb +37 -0
  35. data/test/dummy/config/environments/production.rb +67 -0
  36. data/test/dummy/config/environments/test.rb +37 -0
  37. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  38. data/test/dummy/config/initializers/inflections.rb +15 -0
  39. data/test/dummy/config/initializers/mime_types.rb +5 -0
  40. data/test/dummy/config/initializers/secret_token.rb +7 -0
  41. data/test/dummy/config/initializers/session_store.rb +8 -0
  42. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  43. data/test/dummy/config/locales/en.yml +5 -0
  44. data/test/dummy/config/routes.rb +4 -0
  45. data/test/dummy/db/migrate/20120121220057_add_schedule_fu_tables.schedule_fu.rb +168 -0
  46. data/test/dummy/db/schema.rb +82 -0
  47. data/test/dummy/log/development.log +283 -0
  48. data/test/dummy/log/test.log +2224 -0
  49. data/test/dummy/public/404.html +26 -0
  50. data/test/dummy/public/422.html +26 -0
  51. data/test/dummy/public/500.html +25 -0
  52. data/test/dummy/public/favicon.ico +0 -0
  53. data/test/dummy/script/rails +6 -0
  54. data/test/factories/calendar.rb +5 -0
  55. data/test/factories/calendar_event.rb +35 -0
  56. data/test/test_helper.rb +20 -0
  57. metadata +215 -0
@@ -0,0 +1,67 @@
1
+ Dummy::Application.configure do
2
+ # Settings specified here will take precedence over those in config/application.rb
3
+
4
+ # Code is not reloaded between requests
5
+ config.cache_classes = true
6
+
7
+ # Full error reports are disabled and caching is turned on
8
+ config.consider_all_requests_local = false
9
+ config.action_controller.perform_caching = true
10
+
11
+ # Disable Rails's static asset server (Apache or nginx will already do this)
12
+ config.serve_static_assets = false
13
+
14
+ # Compress JavaScripts and CSS
15
+ config.assets.compress = true
16
+
17
+ # Don't fallback to assets pipeline if a precompiled asset is missed
18
+ config.assets.compile = false
19
+
20
+ # Generate digests for assets URLs
21
+ config.assets.digest = true
22
+
23
+ # Defaults to Rails.root.join("public/assets")
24
+ # config.assets.manifest = YOUR_PATH
25
+
26
+ # Specifies the header that your server uses for sending files
27
+ # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache
28
+ # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx
29
+
30
+ # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
31
+ # config.force_ssl = true
32
+
33
+ # See everything in the log (default is :info)
34
+ # config.log_level = :debug
35
+
36
+ # Prepend all log lines with the following tags
37
+ # config.log_tags = [ :subdomain, :uuid ]
38
+
39
+ # Use a different logger for distributed setups
40
+ # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new)
41
+
42
+ # Use a different cache store in production
43
+ # config.cache_store = :mem_cache_store
44
+
45
+ # Enable serving of images, stylesheets, and JavaScripts from an asset server
46
+ # config.action_controller.asset_host = "http://assets.example.com"
47
+
48
+ # Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added)
49
+ # config.assets.precompile += %w( search.js )
50
+
51
+ # Disable delivery errors, bad email addresses will be ignored
52
+ # config.action_mailer.raise_delivery_errors = false
53
+
54
+ # Enable threaded mode
55
+ # config.threadsafe!
56
+
57
+ # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
58
+ # the I18n.default_locale when a translation can not be found)
59
+ config.i18n.fallbacks = true
60
+
61
+ # Send deprecation notices to registered listeners
62
+ config.active_support.deprecation = :notify
63
+
64
+ # Log the query plan for queries taking more than this (works
65
+ # with SQLite, MySQL, and PostgreSQL)
66
+ # config.active_record.auto_explain_threshold_in_seconds = 0.5
67
+ end
@@ -0,0 +1,37 @@
1
+ Dummy::Application.configure do
2
+ # Settings specified here will take precedence over those in config/application.rb
3
+
4
+ # The test environment is used exclusively to run your application's
5
+ # test suite. You never need to work with it otherwise. Remember that
6
+ # your test database is "scratch space" for the test suite and is wiped
7
+ # and recreated between test runs. Don't rely on the data there!
8
+ config.cache_classes = true
9
+
10
+ # Configure static asset server for tests with Cache-Control for performance
11
+ config.serve_static_assets = true
12
+ config.static_cache_control = "public, max-age=3600"
13
+
14
+ # Log error messages when you accidentally call methods on nil
15
+ config.whiny_nils = true
16
+
17
+ # Show full error reports and disable caching
18
+ config.consider_all_requests_local = true
19
+ config.action_controller.perform_caching = false
20
+
21
+ # Raise exceptions instead of rendering exception templates
22
+ config.action_dispatch.show_exceptions = false
23
+
24
+ # Disable request forgery protection in test environment
25
+ config.action_controller.allow_forgery_protection = false
26
+
27
+ # Tell Action Mailer not to deliver emails to the real world.
28
+ # The :test delivery method accumulates sent emails in the
29
+ # ActionMailer::Base.deliveries array.
30
+ config.action_mailer.delivery_method = :test
31
+
32
+ # Raise exception on mass assignment protection for Active Record models
33
+ config.active_record.mass_assignment_sanitizer = :strict
34
+
35
+ # Print deprecation notices to the stderr
36
+ config.active_support.deprecation = :stderr
37
+ end
@@ -0,0 +1,7 @@
1
+ # Be sure to restart your server when you modify this file.
2
+
3
+ # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
4
+ # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
5
+
6
+ # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
7
+ # Rails.backtrace_cleaner.remove_silencers!
@@ -0,0 +1,15 @@
1
+ # Be sure to restart your server when you modify this file.
2
+
3
+ # Add new inflection rules using the following format
4
+ # (all these examples are active by default):
5
+ # ActiveSupport::Inflector.inflections do |inflect|
6
+ # inflect.plural /^(ox)$/i, '\1en'
7
+ # inflect.singular /^(ox)en/i, '\1'
8
+ # inflect.irregular 'person', 'people'
9
+ # inflect.uncountable %w( fish sheep )
10
+ # end
11
+ #
12
+ # These inflection rules are supported but not enabled by default:
13
+ # ActiveSupport::Inflector.inflections do |inflect|
14
+ # inflect.acronym 'RESTful'
15
+ # end
@@ -0,0 +1,5 @@
1
+ # Be sure to restart your server when you modify this file.
2
+
3
+ # Add new mime types for use in respond_to blocks:
4
+ # Mime::Type.register "text/richtext", :rtf
5
+ # Mime::Type.register_alias "text/html", :iphone
@@ -0,0 +1,7 @@
1
+ # Be sure to restart your server when you modify this file.
2
+
3
+ # Your secret key for verifying the integrity of signed cookies.
4
+ # If you change this key, all old signed cookies will become invalid!
5
+ # Make sure the secret is at least 30 characters and all random,
6
+ # no regular words or you'll be exposed to dictionary attacks.
7
+ Dummy::Application.config.secret_token = '402333f7d61d46b096153aead1d37da22c905cb954cd239907fe72b1e26997fe84fdbda2c9aaed63663106fe0dafa4b143b9ceabd1d023cd898c7fdc2df9fce5'
@@ -0,0 +1,8 @@
1
+ # Be sure to restart your server when you modify this file.
2
+
3
+ Dummy::Application.config.session_store :cookie_store, key: '_dummy_session'
4
+
5
+ # Use the database for sessions instead of the cookie-based default,
6
+ # which shouldn't be used to store highly confidential information
7
+ # (create the session table with "rails generate session_migration")
8
+ # Dummy::Application.config.session_store :active_record_store
@@ -0,0 +1,14 @@
1
+ # Be sure to restart your server when you modify this file.
2
+ #
3
+ # This file contains settings for ActionController::ParamsWrapper which
4
+ # is enabled by default.
5
+
6
+ # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
7
+ ActiveSupport.on_load(:action_controller) do
8
+ wrap_parameters format: [:json]
9
+ end
10
+
11
+ # Disable root element in JSON by default.
12
+ ActiveSupport.on_load(:active_record) do
13
+ self.include_root_in_json = false
14
+ end
@@ -0,0 +1,5 @@
1
+ # Sample localization file for English. Add more files in this directory for other locales.
2
+ # See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
3
+
4
+ en:
5
+ hello: "Hello world"
@@ -0,0 +1,4 @@
1
+ Rails.application.routes.draw do
2
+
3
+ mount ScheduleFu::Engine => "/schedule_fu"
4
+ end
@@ -0,0 +1,168 @@
1
+ # This migration comes from schedule_fu (originally 20120121210741)
2
+ require 'calendar'
3
+ require 'calendar_event_type'
4
+
5
+ class AddScheduleFuTables < ActiveRecord::Migration
6
+ def self.up
7
+ create_table :calendars do |t|
8
+ t.column :desc, :text
9
+ end
10
+ Calendar.create
11
+
12
+ create_table :calendar_dates do |t|
13
+ t.column :value, :date, :null=>false
14
+ t.column :weekday, :integer, :limit => 1, :null=>false
15
+ t.column :monthweek, :integer, :limit => 1, :null=>false
16
+ t.column :monthday, :integer, :limit => 1, :null=>false
17
+ t.column :month, :integer, :limit => 1, :null=>false
18
+ t.column :lastweek, :boolean, :null=>false, :default=>false
19
+ end
20
+ add_index :calendar_dates, :value, :unique => true
21
+
22
+ create_table :calendar_event_types do |t|
23
+ t.column :name, :string
24
+ t.column :desc, :string
25
+ end
26
+ norepeat_id = create_event_type("norepeat", "Does not repeat").id
27
+ weekdays_id = create_event_type("weekdays", "Weekdays (M-F)").id
28
+ daily_id = create_event_type("daily", "Daily").id
29
+ weekly_id = create_event_type("weekly", "Weekly").id
30
+ monthly_id = create_event_type("monthly", "Monthly").id
31
+ yearly_id = create_event_type("yearly", "Yearly").id
32
+
33
+ create_table :calendar_events do |t|
34
+ t.column :calendar_id, :integer, :null=>false
35
+ t.column :calendar_event_type_id, :integer
36
+ t.column :by_day_of_month, :boolean, :null => false, :default => false
37
+ t.column :start_date, :date
38
+ t.column :end_date, :date
39
+ t.column :start_time, :time
40
+ t.column :end_time, :time
41
+ t.column :desc, :text
42
+ t.column :long_desc, :text
43
+ end
44
+
45
+ create_table :calendar_event_mods do |t|
46
+ t.column :calendar_event_id, :integer, :null=>false
47
+ t.column :calendar_date_id, :integer, :null=>false
48
+ t.column :start_time, :time
49
+ t.column :end_time, :time
50
+ t.column :desc, :text
51
+ t.column :long_desc, :text
52
+ t.column :removed, :boolean, :null=>false, :default=>false
53
+ end
54
+ add_index :calendar_event_mods, [:calendar_event_id, :calendar_date_id],
55
+ :unique => true, :name => "calendar_event_mods_for_event_and_date"
56
+
57
+ create_table :calendar_recurrences do |t|
58
+ t.column :calendar_event_id, :integer, :null=>false
59
+ t.column :weekday, :integer, :limit => 1
60
+ t.column :monthweek, :integer, :limit => 1
61
+ t.column :monthday, :integer, :limit => 1
62
+ t.column :month, :integer, :limit => 1
63
+ end
64
+
65
+ monthly_and_yearly_where_sql = "
66
+ (
67
+ ce.by_day_of_month = false
68
+ AND cr.weekday = cd.weekday
69
+ AND (
70
+ cr.monthweek = cd.monthweek
71
+ OR (
72
+ cr.monthweek = -1
73
+ AND cd.lastweek = true
74
+ )
75
+ )
76
+ ) OR (
77
+ ce.by_day_of_month = true AND cr.monthday = cd.monthday
78
+ )
79
+ "
80
+
81
+ execute <<-END_SQL
82
+ CREATE VIEW calendar_event_dates AS
83
+ SELECT
84
+ ce.id
85
+ AS calendar_event_id,
86
+ cd.id
87
+ AS calendar_date_id,
88
+ cem.id
89
+ AS calendar_event_mod_id,
90
+ cd.value
91
+ AS date_value,
92
+ COALESCE(cem.start_time, ce.start_time)
93
+ AS start_time,
94
+ COALESCE(cem.end_time, ce.end_time)
95
+ AS end_time,
96
+ COALESCE(cem.desc, ce.desc)
97
+ AS 'desc',
98
+ COALESCE(cem.long_desc, ce.long_desc)
99
+ AS long_desc,
100
+ ((ce.calendar_event_type_id IN (4,5,6) AND cr.id IS NULL)
101
+ OR (ce.start_date IS NOT NULL AND cd.value < ce.start_date)
102
+ OR (ce.end_date IS NOT NULL AND cd.value > ce.end_date)
103
+ OR (ce.calendar_event_type_id = #{weekdays_id} AND cd.weekday not in (1,2,3,4,5)))
104
+ AS added,
105
+ (cem.id IS NOT NULL AND cem.removed = true)
106
+ AS removed,
107
+ (cem.id IS NOT NULL AND cem.removed = false AND
108
+ (cem.start_time IS NOT NULL OR cem.end_time IS NOT NULL
109
+ OR cem.desc IS NOT NULL OR cem.long_desc IS NOT NULL))
110
+ AS modified
111
+ FROM calendar_dates cd
112
+ LEFT OUTER JOIN calendar_events ce ON
113
+ (ce.start_date IS NULL OR ce.start_date IS NOT NULL)
114
+ LEFT OUTER JOIN calendar_event_mods cem
115
+ ON cem.calendar_date_id = cd.id
116
+ AND cem.calendar_event_id = ce.id
117
+ LEFT OUTER JOIN calendar_recurrences cr ON cr.calendar_event_id = ce.id
118
+ AND ce.calendar_event_type_id IN (#{weekly_id},#{monthly_id},#{yearly_id})
119
+ WHERE
120
+ (
121
+ cd.id IS NOT NULL OR cem.id IS NOT NULL
122
+ ) AND (
123
+ ((ce.start_date IS NULL OR cd.value >= ce.start_date)
124
+ AND (ce.end_date IS NULL OR cd.value <= ce.end_date))
125
+ OR cem.id IS NOT NULL
126
+ ) AND (
127
+ cem.id IS NOT NULL
128
+ OR (
129
+ ce.calendar_event_type_id = #{norepeat_id}
130
+ AND ce.start_date = cd.value
131
+ ) OR (
132
+ ce.calendar_event_type_id = #{weekdays_id} AND cd.weekday IN (1,2,3,4,5)
133
+ ) OR (
134
+ ce.calendar_event_type_id = #{daily_id}
135
+ ) OR (
136
+ ce.calendar_event_type_id = #{weekly_id}
137
+ AND cr.weekday = cd.weekday
138
+ ) OR (
139
+ ce.calendar_event_type_id = #{monthly_id}
140
+ AND (
141
+ #{monthly_and_yearly_where_sql}
142
+ ) OR (
143
+ ce.calendar_event_type_id = #{yearly_id}
144
+ AND cd.month = cr.month
145
+ AND (
146
+ #{monthly_and_yearly_where_sql}
147
+ )
148
+ )
149
+ )
150
+ );
151
+ END_SQL
152
+ end
153
+
154
+ def self.down
155
+ execute "DROP VIEW calendar_event_dates"
156
+ drop_table :calendar_recurrences
157
+ drop_table :calendar_event_mods
158
+ drop_table :calendar_events
159
+ drop_table :calendar_event_types
160
+ remove_index :calendar_dates, :value
161
+ drop_table :calendar_dates
162
+ drop_table :calendars
163
+ end
164
+
165
+ def self.create_event_type(name, desc)
166
+ CalendarEventType.create(:name => name, :desc => desc)
167
+ end
168
+ end
@@ -0,0 +1,82 @@
1
+ # encoding: UTF-8
2
+ # This file is auto-generated from the current state of the database. Instead
3
+ # of editing this file, please use the migrations feature of Active Record to
4
+ # incrementally modify your database, and then regenerate this schema definition.
5
+ #
6
+ # Note that this schema.rb definition is the authoritative source for your
7
+ # database schema. If you need to create the application database on another
8
+ # system, you should be using db:schema:load, not running all the migrations
9
+ # from scratch. The latter is a flawed and unsustainable approach (the more migrations
10
+ # you'll amass, the slower it'll run and the greater likelihood for issues).
11
+ #
12
+ # It's strongly recommended to check this file into your version control system.
13
+
14
+ ActiveRecord::Schema.define(:version => 20120121220057) do
15
+
16
+ create_table "calendar_dates", :force => true do |t|
17
+ t.date "value", :null => false
18
+ t.integer "weekday", :limit => 1, :null => false
19
+ t.integer "monthweek", :limit => 1, :null => false
20
+ t.integer "monthday", :limit => 1, :null => false
21
+ t.integer "month", :limit => 1, :null => false
22
+ t.boolean "lastweek", :default => false, :null => false
23
+ end
24
+
25
+ add_index "calendar_dates", ["value"], :name => "index_calendar_dates_on_value", :unique => true
26
+
27
+ create_table "calendar_event_dates", :id => false, :force => true do |t|
28
+ t.integer "calendar_event_id", :default => 0
29
+ t.integer "calendar_date_id", :default => 0, :null => false
30
+ t.integer "calendar_event_mod_id", :default => 0
31
+ t.date "date_value", :null => false
32
+ t.time "start_time"
33
+ t.time "end_time"
34
+ t.text "desc", :limit => 2147483647
35
+ t.text "long_desc", :limit => 2147483647
36
+ t.integer "added"
37
+ t.integer "removed"
38
+ t.integer "modified"
39
+ end
40
+
41
+ create_table "calendar_event_mods", :force => true do |t|
42
+ t.integer "calendar_event_id", :null => false
43
+ t.integer "calendar_date_id", :null => false
44
+ t.time "start_time"
45
+ t.time "end_time"
46
+ t.text "desc"
47
+ t.text "long_desc"
48
+ t.boolean "removed", :default => false, :null => false
49
+ end
50
+
51
+ add_index "calendar_event_mods", ["calendar_event_id", "calendar_date_id"], :name => "calendar_event_mods_for_event_and_date", :unique => true
52
+
53
+ create_table "calendar_event_types", :force => true do |t|
54
+ t.string "name"
55
+ t.string "desc"
56
+ end
57
+
58
+ create_table "calendar_events", :force => true do |t|
59
+ t.integer "calendar_id", :null => false
60
+ t.integer "calendar_event_type_id"
61
+ t.boolean "by_day_of_month", :default => false, :null => false
62
+ t.date "start_date"
63
+ t.date "end_date"
64
+ t.time "start_time"
65
+ t.time "end_time"
66
+ t.text "desc"
67
+ t.text "long_desc"
68
+ end
69
+
70
+ create_table "calendar_recurrences", :force => true do |t|
71
+ t.integer "calendar_event_id", :null => false
72
+ t.integer "weekday", :limit => 1
73
+ t.integer "monthweek", :limit => 1
74
+ t.integer "monthday", :limit => 1
75
+ t.integer "month", :limit => 1
76
+ end
77
+
78
+ create_table "calendars", :force => true do |t|
79
+ t.text "desc"
80
+ end
81
+
82
+ end
@@ -0,0 +1,283 @@
1
+  (0.3ms) SELECT `schema_migrations`.`version` FROM `schema_migrations` 
2
+  (0.2ms) SELECT `schema_migrations`.`version` FROM `schema_migrations` 
3
+ Migrating to AddScheduleFuTables (20120121210741)
4
+  (0.2ms) SELECT `schema_migrations`.`version` FROM `schema_migrations` 
5
+ Migrating to AddScheduleFuTables (20120121210741)
6
+  (2.5ms) SELECT `schema_migrations`.`version` FROM `schema_migrations` 
7
+ Migrating to AddScheduleFuTables (20120121210741)
8
+  (0.1ms) SELECT `schema_migrations`.`version` FROM `schema_migrations` 
9
+ Migrating to AddScheduleFuTables (20120121210741)
10
+  (177.1ms) CREATE TABLE `calendars` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `desc` text) ENGINE=InnoDB
11
+  (0.1ms) BEGIN
12
+ SQL (0.3ms) INSERT INTO `calendars` (`desc`) VALUES (NULL)
13
+  (84.0ms) COMMIT
14
+  (165.7ms) CREATE TABLE `calendar_dates` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `value` date NOT NULL, `weekday` tinyint NOT NULL, `monthweek` tinyint NOT NULL, `monthday` tinyint NOT NULL, `month` tinyint NOT NULL, `lastweek` tinyint(1) DEFAULT 0 NOT NULL) ENGINE=InnoDB
15
+  (322.6ms) CREATE UNIQUE INDEX `index_calendar_dates_on_value` ON `calendar_dates` (`value`)
16
+  (166.4ms) CREATE TABLE `calendar_event_types` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `name` varchar(255), `desc` varchar(255)) ENGINE=InnoDB
17
+  (0.1ms) BEGIN
18
+ SQL (0.3ms) INSERT INTO `calendar_event_types` (`desc`, `name`) VALUES ('Does not repeat', 'norepeat')
19
+  (88.0ms) COMMIT
20
+  (0.1ms) BEGIN
21
+ SQL (0.2ms) INSERT INTO `calendar_event_types` (`desc`, `name`) VALUES ('Weekdays (M-F)', 'weekdays')
22
+  (52.8ms) COMMIT
23
+  (0.1ms) BEGIN
24
+ SQL (0.2ms) INSERT INTO `calendar_event_types` (`desc`, `name`) VALUES ('Daily', 'daily')
25
+  (53.7ms) COMMIT
26
+  (0.1ms) BEGIN
27
+ SQL (0.2ms) INSERT INTO `calendar_event_types` (`desc`, `name`) VALUES ('Weekly', 'weekly')
28
+  (53.7ms) COMMIT
29
+  (0.1ms) BEGIN
30
+ SQL (0.2ms) INSERT INTO `calendar_event_types` (`desc`, `name`) VALUES ('Monthly', 'monthly')
31
+  (53.7ms) COMMIT
32
+  (0.1ms) BEGIN
33
+ SQL (0.2ms) INSERT INTO `calendar_event_types` (`desc`, `name`) VALUES ('Yearly', 'yearly')
34
+  (53.3ms) COMMIT
35
+  (255.7ms) CREATE TABLE `calendar_events` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `calendar_id` int(11) NOT NULL, `calendar_event_type_id` int(11), `by_day_of_month` tinyint(1) DEFAULT 0 NOT NULL, `start_date` date, `end_date` date, `start_time` time, `end_time` time, `desc` text, `long_desc` text) ENGINE=InnoDB
36
+  (189.8ms) CREATE TABLE `calendar_event_mods` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `calendar_event_id` int(11) NOT NULL, `calendar_date_id` int(11) NOT NULL, `start_time` time, `end_time` time, `desc` text, `long_desc` text, `removed` tinyint(1) DEFAULT 0 NOT NULL) ENGINE=InnoDB
37
+  (311.7ms) CREATE UNIQUE INDEX `calendar_event_mods_for_event_and_date` ON `calendar_event_mods` (`calendar_event_id`, `calendar_date_id`)
38
+  (166.2ms) CREATE TABLE `calendar_recurrences` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `calendar_event_id` int(11) NOT NULL, `weekday` tinyint, `monthweek` tinyint, `monthday` tinyint, `month` tinyint) ENGINE=InnoDB
39
+  (122.4ms)  CREATE VIEW calendar_event_dates AS
40
+ SELECT
41
+ ce.id
42
+ AS calendar_event_id,
43
+ cd.id
44
+ AS calendar_date_id,
45
+ cem.id
46
+ AS calendar_event_mod_id,
47
+ cd.value
48
+ AS date_value,
49
+ COALESCE(cem.start_time, ce.start_time)
50
+ AS start_time,
51
+ COALESCE(cem.end_time, ce.end_time)
52
+ AS end_time,
53
+ COALESCE(cem.desc, ce.desc)
54
+ AS 'desc',
55
+ COALESCE(cem.long_desc, ce.long_desc)
56
+ AS long_desc,
57
+ ((ce.calendar_event_type_id IN (4,5,6) AND cr.id IS NULL)
58
+ OR (ce.start_date IS NOT NULL AND cd.value < ce.start_date)
59
+ OR (ce.end_date IS NOT NULL AND cd.value > ce.end_date)
60
+ OR (ce.calendar_event_type_id = 2 AND cd.weekday not in (1,2,3,4,5)))
61
+ AS added,
62
+ (cem.id IS NOT NULL AND cem.removed = true)
63
+ AS removed,
64
+ (cem.id IS NOT NULL AND cem.removed = false AND
65
+ (cem.start_time IS NOT NULL OR cem.end_time IS NOT NULL
66
+ OR cem.desc IS NOT NULL OR cem.long_desc IS NOT NULL))
67
+ AS modified
68
+ FROM calendar_dates cd
69
+ LEFT OUTER JOIN calendar_events ce ON
70
+ (ce.start_date IS NULL OR ce.start_date IS NOT NULL)
71
+ LEFT OUTER JOIN calendar_event_mods cem
72
+ ON cem.calendar_date_id = cd.id
73
+ AND cem.calendar_event_id = ce.id
74
+ LEFT OUTER JOIN calendar_recurrences cr ON cr.calendar_event_id = ce.id
75
+ AND ce.calendar_event_type_id IN (4,5,6)
76
+ WHERE
77
+ (
78
+ cd.id IS NOT NULL OR cem.id IS NOT NULL
79
+ ) AND (
80
+ ((ce.start_date IS NULL OR cd.value >= ce.start_date)
81
+ AND (ce.end_date IS NULL OR cd.value <= ce.end_date))
82
+ OR cem.id IS NOT NULL
83
+ ) AND (
84
+ cem.id IS NOT NULL
85
+ OR (
86
+ ce.calendar_event_type_id = 1
87
+ AND ce.start_date = cd.value
88
+ ) OR (
89
+ ce.calendar_event_type_id = 2 AND cd.weekday IN (1,2,3,4,5)
90
+ ) OR (
91
+ ce.calendar_event_type_id = 3
92
+ ) OR (
93
+ ce.calendar_event_type_id = 4
94
+ AND cr.weekday = cd.weekday
95
+ ) OR (
96
+ ce.calendar_event_type_id = 5
97
+ AND (
98
+
99
+ (
100
+ ce.by_day_of_month = false
101
+ AND cr.weekday = cd.weekday
102
+ AND (
103
+ cr.monthweek = cd.monthweek
104
+ OR (
105
+ cr.monthweek = -1
106
+ AND cd.lastweek = true
107
+ )
108
+ )
109
+ ) OR (
110
+ ce.by_day_of_month = true AND cr.monthday = cd.monthday
111
+ )
112
+
113
+ ) OR (
114
+ ce.calendar_event_type_id = 6
115
+ AND cd.month = cr.month
116
+ AND (
117
+
118
+ (
119
+ ce.by_day_of_month = false
120
+ AND cr.weekday = cd.weekday
121
+ AND (
122
+ cr.monthweek = cd.monthweek
123
+ OR (
124
+ cr.monthweek = -1
125
+ AND cd.lastweek = true
126
+ )
127
+ )
128
+ ) OR (
129
+ ce.by_day_of_month = true AND cr.monthday = cd.monthday
130
+ )
131
+
132
+ )
133
+ )
134
+ )
135
+ );
136
+ 
137
+  (55.1ms) INSERT INTO `schema_migrations` (`version`) VALUES ('20120121210741')
138
+  (0.2ms) SELECT `schema_migrations`.`version` FROM `schema_migrations` 
139
+  (0.1ms) SELECT `schema_migrations`.`version` FROM `schema_migrations` 
140
+  (0.1ms) SELECT `schema_migrations`.`version` FROM `schema_migrations`
141
+ Migrating to AddScheduleFuTables (20120121210741)
142
+  (0.3ms) DROP VIEW calendar_event_dates
143
+  (59.9ms) DROP TABLE `calendar_recurrences`
144
+  (77.7ms) DROP TABLE `calendar_event_mods`
145
+  (68.3ms) DROP TABLE `calendar_events`
146
+  (66.8ms) DROP TABLE `calendar_event_types`
147
+  (332.1ms) DROP INDEX `index_calendar_dates_on_value` ON `calendar_dates`
148
+  (66.3ms) DROP TABLE `calendar_dates`
149
+  (66.9ms) DROP TABLE `calendars`
150
+  (66.1ms) DELETE FROM `schema_migrations` WHERE `schema_migrations`.`version` = '20120121210741'
151
+  (0.3ms) SELECT `schema_migrations`.`version` FROM `schema_migrations`
152
+  (0.1ms) SELECT `schema_migrations`.`version` FROM `schema_migrations` 
153
+  (0.1ms) SELECT `schema_migrations`.`version` FROM `schema_migrations` 
154
+ Migrating to AddScheduleFuTables (20120121220057)
155
+  (204.5ms) CREATE TABLE `calendars` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `desc` text) ENGINE=InnoDB
156
+  (0.1ms) BEGIN
157
+ SQL (0.3ms) INSERT INTO `calendars` (`desc`) VALUES (NULL)
158
+  (93.1ms) COMMIT
159
+  (165.4ms) CREATE TABLE `calendar_dates` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `value` date NOT NULL, `weekday` tinyint NOT NULL, `monthweek` tinyint NOT NULL, `monthday` tinyint NOT NULL, `month` tinyint NOT NULL, `lastweek` tinyint(1) DEFAULT 0 NOT NULL) ENGINE=InnoDB
160
+  (311.5ms) CREATE UNIQUE INDEX `index_calendar_dates_on_value` ON `calendar_dates` (`value`)
161
+  (155.1ms) CREATE TABLE `calendar_event_types` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `name` varchar(255), `desc` varchar(255)) ENGINE=InnoDB
162
+  (0.2ms) BEGIN
163
+ SQL (0.3ms) INSERT INTO `calendar_event_types` (`desc`, `name`) VALUES ('Does not repeat', 'norepeat')
164
+  (74.8ms) COMMIT
165
+  (0.1ms) BEGIN
166
+ SQL (0.2ms) INSERT INTO `calendar_event_types` (`desc`, `name`) VALUES ('Weekdays (M-F)', 'weekdays')
167
+  (41.7ms) COMMIT
168
+  (0.1ms) BEGIN
169
+ SQL (0.2ms) INSERT INTO `calendar_event_types` (`desc`, `name`) VALUES ('Daily', 'daily')
170
+  (42.5ms) COMMIT
171
+  (0.1ms) BEGIN
172
+ SQL (0.2ms) INSERT INTO `calendar_event_types` (`desc`, `name`) VALUES ('Weekly', 'weekly')
173
+  (42.7ms) COMMIT
174
+  (0.1ms) BEGIN
175
+ SQL (0.2ms) INSERT INTO `calendar_event_types` (`desc`, `name`) VALUES ('Monthly', 'monthly')
176
+  (42.5ms) COMMIT
177
+  (0.1ms) BEGIN
178
+ SQL (0.2ms) INSERT INTO `calendar_event_types` (`desc`, `name`) VALUES ('Yearly', 'yearly')
179
+  (42.6ms) COMMIT
180
+  (154.9ms) CREATE TABLE `calendar_events` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `calendar_id` int(11) NOT NULL, `calendar_event_type_id` int(11), `by_day_of_month` tinyint(1) DEFAULT 0 NOT NULL, `start_date` date, `end_date` date, `start_time` time, `end_time` time, `desc` text, `long_desc` text) ENGINE=InnoDB
181
+  (156.6ms) CREATE TABLE `calendar_event_mods` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `calendar_event_id` int(11) NOT NULL, `calendar_date_id` int(11) NOT NULL, `start_time` time, `end_time` time, `desc` text, `long_desc` text, `removed` tinyint(1) DEFAULT 0 NOT NULL) ENGINE=InnoDB
182
+  (322.7ms) CREATE UNIQUE INDEX `calendar_event_mods_for_event_and_date` ON `calendar_event_mods` (`calendar_event_id`, `calendar_date_id`)
183
+  (144.1ms) CREATE TABLE `calendar_recurrences` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `calendar_event_id` int(11) NOT NULL, `weekday` tinyint, `monthweek` tinyint, `monthday` tinyint, `month` tinyint) ENGINE=InnoDB
184
+  (44.7ms)  CREATE VIEW calendar_event_dates AS
185
+ SELECT
186
+ ce.id
187
+ AS calendar_event_id,
188
+ cd.id
189
+ AS calendar_date_id,
190
+ cem.id
191
+ AS calendar_event_mod_id,
192
+ cd.value
193
+ AS date_value,
194
+ COALESCE(cem.start_time, ce.start_time)
195
+ AS start_time,
196
+ COALESCE(cem.end_time, ce.end_time)
197
+ AS end_time,
198
+ COALESCE(cem.desc, ce.desc)
199
+ AS 'desc',
200
+ COALESCE(cem.long_desc, ce.long_desc)
201
+ AS long_desc,
202
+ ((ce.calendar_event_type_id IN (4,5,6) AND cr.id IS NULL)
203
+ OR (ce.start_date IS NOT NULL AND cd.value < ce.start_date)
204
+ OR (ce.end_date IS NOT NULL AND cd.value > ce.end_date)
205
+ OR (ce.calendar_event_type_id = 2 AND cd.weekday not in (1,2,3,4,5)))
206
+ AS added,
207
+ (cem.id IS NOT NULL AND cem.removed = true)
208
+ AS removed,
209
+ (cem.id IS NOT NULL AND cem.removed = false AND
210
+ (cem.start_time IS NOT NULL OR cem.end_time IS NOT NULL
211
+ OR cem.desc IS NOT NULL OR cem.long_desc IS NOT NULL))
212
+ AS modified
213
+ FROM calendar_dates cd
214
+ LEFT OUTER JOIN calendar_events ce ON
215
+ (ce.start_date IS NULL OR ce.start_date IS NOT NULL)
216
+ LEFT OUTER JOIN calendar_event_mods cem
217
+ ON cem.calendar_date_id = cd.id
218
+ AND cem.calendar_event_id = ce.id
219
+ LEFT OUTER JOIN calendar_recurrences cr ON cr.calendar_event_id = ce.id
220
+ AND ce.calendar_event_type_id IN (4,5,6)
221
+ WHERE
222
+ (
223
+ cd.id IS NOT NULL OR cem.id IS NOT NULL
224
+ ) AND (
225
+ ((ce.start_date IS NULL OR cd.value >= ce.start_date)
226
+ AND (ce.end_date IS NULL OR cd.value <= ce.end_date))
227
+ OR cem.id IS NOT NULL
228
+ ) AND (
229
+ cem.id IS NOT NULL
230
+ OR (
231
+ ce.calendar_event_type_id = 1
232
+ AND ce.start_date = cd.value
233
+ ) OR (
234
+ ce.calendar_event_type_id = 2 AND cd.weekday IN (1,2,3,4,5)
235
+ ) OR (
236
+ ce.calendar_event_type_id = 3
237
+ ) OR (
238
+ ce.calendar_event_type_id = 4
239
+ AND cr.weekday = cd.weekday
240
+ ) OR (
241
+ ce.calendar_event_type_id = 5
242
+ AND (
243
+
244
+ (
245
+ ce.by_day_of_month = false
246
+ AND cr.weekday = cd.weekday
247
+ AND (
248
+ cr.monthweek = cd.monthweek
249
+ OR (
250
+ cr.monthweek = -1
251
+ AND cd.lastweek = true
252
+ )
253
+ )
254
+ ) OR (
255
+ ce.by_day_of_month = true AND cr.monthday = cd.monthday
256
+ )
257
+
258
+ ) OR (
259
+ ce.calendar_event_type_id = 6
260
+ AND cd.month = cr.month
261
+ AND (
262
+
263
+ (
264
+ ce.by_day_of_month = false
265
+ AND cr.weekday = cd.weekday
266
+ AND (
267
+ cr.monthweek = cd.monthweek
268
+ OR (
269
+ cr.monthweek = -1
270
+ AND cd.lastweek = true
271
+ )
272
+ )
273
+ ) OR (
274
+ ce.by_day_of_month = true AND cr.monthday = cd.monthday
275
+ )
276
+
277
+ )
278
+ )
279
+ )
280
+ );
281
+ 
282
+  (77.2ms) INSERT INTO `schema_migrations` (`version`) VALUES ('20120121220057')
283
+  (0.2ms) SELECT `schema_migrations`.`version` FROM `schema_migrations`