hairtrigger 0.2.4 → 0.2.5

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.
data/README.md ADDED
@@ -0,0 +1,290 @@
1
+ # HairTrigger
2
+ [<img src="https://secure.travis-ci.org/jenseng/hair_trigger.png?branch=master" />](http://travis-ci.org/jenseng/hair_trigger)
3
+
4
+ HairTrigger lets you create and manage database triggers in a concise,
5
+ db-agnostic, Rails-y way. You declare triggers right in your models in Ruby,
6
+ and a simple rake task does all the dirty work for you.
7
+
8
+ ## Installation
9
+
10
+ ### Rails 3 or 4
11
+
12
+ If you are using Rails 3 or 4, just `gem 'hairtrigger'`
13
+
14
+ ### Rails 2
15
+
16
+ #### Step 1.
17
+
18
+ Put hairtrigger in your Gemfile, or if you're not using bundler, you can
19
+ `gem install hairtrigger` and then put hairtrigger in environment.rb
20
+
21
+ #### Step 2.
22
+
23
+ Create lib/tasks/hair_trigger.rake with the following:
24
+
25
+ ```ruby
26
+ $VERBOSE = nil
27
+ Dir["#{Gem::Specification.find_by_name('hairtrigger').full_gem_path}/lib/tasks/*.rake"].each { |ext| load ext }
28
+ ```
29
+
30
+ This will give you the `db:generate_trigger_migration` task, and will ensure
31
+ that hairtrigger hooks into `db:schema:dump`.
32
+
33
+ If you are unpacking the gem in vendor/plugins, this step is not needed
34
+ (though you'll then want to delete its Gemfile to avoid possible conflicts).
35
+
36
+ ## Usage
37
+
38
+ ### Models
39
+
40
+ Declare triggers in your models and use a rake task to auto-generate the
41
+ appropriate migration. For example:
42
+
43
+ ```ruby
44
+ class AccountUser < ActiveRecord::Base
45
+ trigger.after(:insert) do
46
+ "UPDATE accounts SET user_count = user_count + 1 WHERE id = NEW.account_id;"
47
+ end
48
+ end
49
+ ```
50
+
51
+ and then:
52
+
53
+ ```bash
54
+ rake db:generate_trigger_migration
55
+ ```
56
+
57
+ This will create a db-agnostic migration for the trigger that mirrors the
58
+ model declaration. The end result in MySQL will be something like this:
59
+
60
+ ```sql
61
+ CREATE TRIGGER account_users_after_insert_row_tr AFTER INSERT ON account_users
62
+ FOR EACH ROW
63
+ BEGIN
64
+ UPDATE accounts SET user_count = user_count + 1 WHERE id = NEW.account_id;
65
+ END
66
+ ```
67
+
68
+ Note that these auto-generated `create_trigger` statements in the migration
69
+ contain the `:generated => true` option, indicating that they were created
70
+ from the model definition. This is important, as the rake task will also
71
+ generate appropriate drop/create statements for any model triggers that get
72
+ removed or updated. It does this by diffing the current model trigger
73
+ declarations and any auto-generated triggers in schema.rb (and subsequent
74
+ migrations).
75
+
76
+ ### Chainable Methods
77
+
78
+ Triggers are built by chaining several methods together, ending in a block
79
+ that specifies the SQL to be run when the trigger fires. Supported methods
80
+ include:
81
+
82
+ #### name(trigger_name)
83
+ Optional, inferred from other calls.
84
+
85
+ #### on(table_name)
86
+ Ignored in models, required in migrations.
87
+
88
+ #### for_each(item)
89
+ Defaults to `:row`, PostgreSQL allows `:statement`.
90
+
91
+ #### before(*events)
92
+ Shorthand for `timing(:before).events(*events)`.
93
+
94
+ #### after(*events)
95
+ Shorthand for `timing(:after).events(*events)`.
96
+
97
+ #### where(conditions)
98
+ Optional, SQL snippet limiting when the trigger will fire. Supports delayed interpolation of variables.
99
+
100
+ #### security(user)
101
+ Permissions/role to check when calling trigger. PostgreSQL supports `:invoker` (default) and `:definer`, MySQL supports `:definer` (default) and arbitrary users (syntax: `'user'@'host'`).
102
+
103
+ #### timing(timing)
104
+ Required (but may be satisified by `before`/`after`). Possible values are `:before`/`:after`.
105
+
106
+ #### events(*events)
107
+ Required (but may be satisified by `before`/`after`). Possible values are `:insert`/`:update`/`:delete`/`:truncate`. MySQL/SQLite only support one action per trigger, and don't support `:truncate`.
108
+
109
+ #### all
110
+ Noop, useful for trigger groups (see below).
111
+
112
+ ### Trigger Groups
113
+
114
+ Trigger groups allow you to use a slightly more concise notation if you have
115
+ several triggers that fire on a given model. This is also important for MySQL,
116
+ since it does not support multiple triggers on a table for the same action
117
+ and timing. For example:
118
+
119
+ ```ruby
120
+ trigger.after(:update) do |t|
121
+ t.all do # every row
122
+ # some sql
123
+ end
124
+ t.where("OLD.foo != NEW.foo") do
125
+ # some more sql
126
+ end
127
+ t.where("OLD.bar != NEW.bar") do
128
+ # some other sql
129
+ end
130
+ end
131
+ ```
132
+
133
+ For MySQL, this will just create a single trigger with conditional logic
134
+ (since it doesn't support multiple triggers). PostgreSQL and SQLite will have
135
+ distinct triggers. This same notation is also used within trigger migrations.
136
+ MySQL does not currently support nested trigger groups.
137
+
138
+ ### Database-specific trigger bodies
139
+
140
+ Although HairTrigger aims to be totally db-agnostic, at times you do need a
141
+ little more control over the body of the trigger. You can tailor it for
142
+ specific databases by returning a hash rather than a string. Make sure to set
143
+ a `:default` value if you aren't explicitly specifying all of them.
144
+
145
+ For example, MySQL generally performs poorly with subselects in `UPDATE`
146
+ statements, and it has its own proprietary syntax for multi-table `UPDATE`s. So
147
+ you might do something like the following:
148
+
149
+ ```ruby
150
+ trigger.after(:insert) do
151
+ {:default => <<-DEFAULT_SQL, :mysql => <<-MYSQL}
152
+
153
+ UPDATE users SET item_count = item_count + 1
154
+ WHERE id IN (SELECT user_id FROM buckets WHERE id = NEW.bucket_id)
155
+ DEFAULT_SQL
156
+
157
+ UPDATE users, buckets SET item_count = item_count + 1
158
+ WHERE users.id = user_id AND buckets.id = NEW.bucket_id
159
+ MYSQL
160
+ end
161
+ ```
162
+
163
+ ### Manual Migrations
164
+
165
+ You can also manage triggers manually in your migrations via `create_trigger` and
166
+ `drop_trigger`. They are a little more verbose than model triggers, and they can
167
+ be more work since you need to figure out the up/down create/drop logic when
168
+ you change things. A sample trigger:
169
+
170
+ ```ruby
171
+ create_trigger(:compatibility => 1).on(:users).after(:insert) do
172
+ "UPDATE accounts SET user_count = user_count + 1 WHERE id = NEW.account_id;"
173
+ end
174
+ ```
175
+
176
+ #### Manual triggers and :compatibility
177
+
178
+ As bugs are fixed and features are implemented in hairtrigger, it's possible
179
+ that the generated trigger SQL will change (this has only happened once so
180
+ far). If you upgrade to a newer version of hairtrigger, it needs a way of
181
+ knowing which previous version generated the original trigger. You only need
182
+ to worry about this for manual trigger migrations, as the model ones
183
+ automatically take care of this. For your manual triggers you can either:
184
+
185
+ * pass `:compatibility => x` to your `create_trigger` statement, where x is
186
+ whatever HairTrigger::Builder.compatiblity is (1 for this version).
187
+ * set `HairTrigger::Builder.base_compatibility = x` in an initializer, where
188
+ x is whatever HairTrigger::Builder.compatiblity is. This is like doing the
189
+ first option on every `create_trigger`. Note that once the compatibility
190
+ changes, you'll need to set `:compatibility` on new triggers (unless you
191
+ just redo all your triggers and bump the `base_compatibility`).
192
+
193
+ If you upgrade to a newer version of hairtrigger and see that the SQL
194
+ compatibility has changed, you'll need to set the appropriate compatibility
195
+ on any new triggers that you create.
196
+
197
+ ## rake db:schema:dump
198
+
199
+ HairTrigger hooks into `rake db:schema:dump` (and rake tasks that call it) to
200
+ make it trigger-aware. A newly generated schema.rb will contain:
201
+
202
+ * `create_trigger` statements for any database triggers that exactly match a
203
+ `create_trigger` statement in an applied migration or in the previous
204
+ schema.rb file. this includes both generated and manual `create_trigger`
205
+ calls.
206
+ * adapter-specific `execute('CREATE TRIGGER..')` statements for any unmatched
207
+ database triggers.
208
+
209
+ As long as you don't delete old migrations and schema.rb prior to running
210
+ `rake db:schema:dump`, the result should be what you expect (and portable).
211
+ If you have deleted all trigger migrations, you can regenerate a new
212
+ baseline for model triggers via rake db:generate_trigger_migration.
213
+
214
+ ## Testing
215
+
216
+ To stay on top of things, it's strongly recommended that you add a test or
217
+ spec to ensure your migrations/schema.rb match your models. This is as simple
218
+ as:
219
+
220
+ ```ruby
221
+ assert HairTrigger::migrations_current?
222
+ ```
223
+
224
+ This way you'll know if there are any outstanding migrations you need to
225
+ create.
226
+
227
+ ## Warnings and Errors
228
+
229
+ There are a couple classes of errors: declaration errors and generation
230
+ errors/warnings.
231
+
232
+ Declaration errors happen if your trigger declaration is obviously wrong, and
233
+ will cause a runtime error in your model or migration class. An example would
234
+ be `trigger.after(:never)`, since `:never` is not a valid event.
235
+
236
+ Generation errors happen if you try something that your adapter doesn't
237
+ support. An example would be something like `trigger.security(:invoker)` for
238
+ MySQL. These errors only happen when the trigger is actually generated, e.g.
239
+ when you attempt to run the migration.
240
+
241
+ Generation warnings are similar but they don't stop the trigger from being
242
+ generated. If you do something adapter-specific supported by your database,
243
+ you will still get a warning ($stderr) that your trigger is not portable. You
244
+ can silence warnings via `HairTrigger::Builder.show_warnings = false`
245
+
246
+ You can validate your triggers beforehand using the `Builder#validate!` method.
247
+ It will throw the appropriate errors/warnings so that you know what to fix,
248
+ e.g.
249
+
250
+ ```ruby
251
+ User.triggers.each(&:validate!)
252
+ ```
253
+
254
+ HairTrigger does not validate your SQL, so be sure to test it in all databases
255
+ you want to support.
256
+
257
+ ## Gotchas
258
+
259
+ * As is the case with ActiveRecord::Base.update_all or any direct SQL you do,
260
+ be careful to reload updated objects from the database. For example, the
261
+ following code will display the wrong count since we aren't reloading the
262
+ account:
263
+
264
+ ```ruby
265
+ a = Account.find(123)
266
+ a.account_users.create(:name => 'bob')
267
+ puts "count is now #{a.user_count}"
268
+ ```
269
+ * For repeated chained calls, the last one wins, there is currently no
270
+ merging.
271
+ * If you want your code to be portable, the trigger actions should be
272
+ limited to `INSERT`/`UPDATE`/`DELETE`/`SELECT`, and conditional logic should be
273
+ handled through the `:where` option/method. Otherwise you'll likely run into
274
+ trouble due to differences in syntax and supported features.
275
+ * Manual `create_trigger` statements have some gotchas. See the section
276
+ "Manual triggers and :compatibility"
277
+
278
+ ## Compatibility
279
+
280
+ * Ruby 1.8.7+
281
+ * Rails 2.3+
282
+ * Postgres 8.0+
283
+ * MySQL 5.0.10+
284
+ * SQLite 3.3.8+
285
+
286
+ ## [Changelog](blob/master/CHANGELOG.md)
287
+
288
+ ## Copyright
289
+
290
+ Copyright (c) 2011-2014 Jon Jensen. See LICENSE.txt for further details.
@@ -1,5 +1,5 @@
1
1
  module HairTrigger
2
- VERSION = "0.2.4"
2
+ VERSION = "0.2.5"
3
3
 
4
4
  def VERSION.<=>(other)
5
5
  split(/\./).map(&:to_i) <=> other.split(/\./).map(&:to_i)
data/spec/builder_spec.rb CHANGED
@@ -14,8 +14,8 @@ class MockAdapter
14
14
  end
15
15
  end
16
16
 
17
- def builder
18
- HairTrigger::Builder.new(nil, :adapter => @adapter)
17
+ def builder(name = nil)
18
+ HairTrigger::Builder.new(name, :adapter => @adapter)
19
19
  end
20
20
 
21
21
  describe "builder" do
@@ -48,6 +48,20 @@ describe "builder" do
48
48
  end
49
49
  end
50
50
 
51
+ describe "name" do
52
+ it "should be inferred if none is provided" do
53
+ builder.on(:foos).after(:update){ "foo" }.prepared_name.
54
+ should == "foos_after_update_row_tr"
55
+ end
56
+
57
+ it "should respect the last chained name" do
58
+ builder("lolwut").on(:foos).after(:update){ "foo" }.prepared_name.
59
+ should == "lolwut"
60
+ builder("lolwut").on(:foos).name("zomg").after(:update).name("yolo"){ "foo" }.prepared_name.
61
+ should == "yolo"
62
+ end
63
+ end
64
+
51
65
  context "adapter-specific actions" do
52
66
  before(:each) do
53
67
  @adapter = MockAdapter.new("mysql")
@@ -263,4 +277,4 @@ describe "builder" do
263
277
  }.should raise_error
264
278
  end
265
279
  end
266
- end
280
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hairtrigger
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.2.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-07-12 00:00:00.000000000 Z
12
+ date: 2014-03-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
@@ -34,7 +34,7 @@ dependencies:
34
34
  requirements:
35
35
  - - ~>
36
36
  - !ruby/object:Gem::Version
37
- version: 3.2.2
37
+ version: '3.4'
38
38
  type: :runtime
39
39
  prerelease: false
40
40
  version_requirements: !ruby/object:Gem::Requirement
@@ -42,7 +42,7 @@ dependencies:
42
42
  requirements:
43
43
  - - ~>
44
44
  - !ruby/object:Gem::Version
45
- version: 3.2.2
45
+ version: '3.4'
46
46
  - !ruby/object:Gem::Dependency
47
47
  name: ruby2ruby
48
48
  requirement: !ruby/object:Gem::Requirement
@@ -160,12 +160,11 @@ description: allows you to declare database triggers in ruby in your models, and
160
160
  email: jenseng@gmail.com
161
161
  executables: []
162
162
  extensions: []
163
- extra_rdoc_files:
164
- - README.rdoc
163
+ extra_rdoc_files: []
165
164
  files:
166
165
  - LICENSE.txt
167
166
  - Rakefile
168
- - README.rdoc
167
+ - README.md
169
168
  - lib/hair_trigger/adapter.rb
170
169
  - lib/hair_trigger/base.rb
171
170
  - lib/hair_trigger/builder.rb
@@ -208,7 +207,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
208
207
  version: 1.3.5
209
208
  requirements: []
210
209
  rubyforge_project:
211
- rubygems_version: 1.8.25
210
+ rubygems_version: 1.8.23
212
211
  signing_key:
213
212
  specification_version: 3
214
213
  summary: easy database triggers for active record
data/README.rdoc DELETED
@@ -1,289 +0,0 @@
1
- = HairTrigger
2
- {<img src="https://secure.travis-ci.org/jenseng/hair_trigger.png?branch=master" />}[http://travis-ci.org/jenseng/hair_trigger]
3
-
4
- HairTrigger lets you create and manage database triggers in a concise,
5
- db-agnostic, Rails-y way. You declare triggers right in your models in Ruby,
6
- and a simple rake task does all the dirty work for you.
7
-
8
- == Installation
9
-
10
- === Rails 3 or 4
11
-
12
- If you are using Rails 3 or 4, just put hairtrigger in your Gemfile.
13
-
14
- === Rails 2
15
-
16
- ==== Step 1.
17
-
18
- Put hairtrigger in your Gemfile, or if you're not using bundler, you can
19
- "gem install hairtrigger" and then put hairtrigger in environment.rb
20
-
21
- ==== Step 2.
22
-
23
- Create lib/tasks/hair_trigger.rake with the following:
24
-
25
- $VERBOSE = nil
26
- Dir["#{Gem::Specification.find_by_name('hairtrigger').full_gem_path}/lib/tasks/*.rake"].each { |ext| load ext }
27
-
28
- This will give you the db:generate_trigger_migration task, and will ensure
29
- that hairtrigger hooks into db:schema:dump.
30
-
31
- If you are unpacking the gem in vendor/plugins, this step is not needed
32
- (though you'll then want to delete its Gemfile to avoid possible conflicts).
33
-
34
- == Usage
35
-
36
- === Models
37
-
38
- Declare triggers in your models and use a rake task to auto-generate the
39
- appropriate migration. For example:
40
-
41
- class AccountUser < ActiveRecord::Base
42
- trigger.after(:insert) do
43
- "UPDATE accounts SET user_count = user_count + 1 WHERE id = NEW.account_id;"
44
- end
45
- end
46
-
47
- and then:
48
-
49
- rake db:generate_trigger_migration
50
-
51
- This will create a db-agnostic migration for the trigger that mirrors the
52
- model declaration. The end result in MySQL will be something like this:
53
-
54
- CREATE TRIGGER account_users_after_insert_row_tr AFTER INSERT ON account_users
55
- FOR EACH ROW
56
- BEGIN
57
- UPDATE accounts SET user_count = user_count + 1 WHERE id = NEW.account_id;
58
- END
59
-
60
- Note that these auto-generated create_trigger statements in the migration
61
- contain the ":generated => true" option, indicating that they were created
62
- from the model definition. This is important, as the rake task will also
63
- generate appropriate drop/create statements for any model triggers that get
64
- removed or updated. It does this by diffing the current model trigger
65
- declarations and any auto-generated triggers in schema.rb (and subsequent
66
- migrations).
67
-
68
- === Chainable Methods
69
-
70
- Triggers are built by chaining several methods together, ending in a block
71
- that specifies the SQL to be run when the trigger fires. Supported methods
72
- include:
73
-
74
- ==== name(trigger_name)
75
- Optional, inferred from other calls.
76
-
77
- ==== on(table_name)
78
- Ignored in models, required in migrations.
79
-
80
- ==== for_each(item)
81
- Defaults to :row, PostgreSQL allows :statement.
82
-
83
- ==== before(*events)
84
- Shorthand for timing(:before).events(*events).
85
-
86
- ==== after(*events)
87
- Shorthand for timing(:after).events(*events).
88
-
89
- ==== where(conditions)
90
- Optional, SQL snippet limiting when the trigger will fire. Supports delayed interpolation of variables.
91
-
92
- ==== security(user)
93
- Permissions/role to check when calling trigger. PostgreSQL supports :invoker (default) and :definer, MySQL supports :definer (default) and arbitrary users (syntax: 'user'@'host').
94
-
95
- ==== timing(timing)
96
- Required (but may be satisified by before/after). Possible values are :before/:after.
97
-
98
- ==== events(*events)
99
- Required (but may be satisified by before/after). Possible values are :insert/:update/:delete/:truncate. MySQL/SQLite only support one action per trigger, and don't support :truncate.
100
-
101
- ==== all
102
- Noop, useful for trigger groups (see below).
103
-
104
- === Trigger Groups
105
-
106
- Trigger groups allow you to use a slightly more concise notation if you have
107
- several triggers that fire on a given model. This is also important for MySQL,
108
- since it does not support multiple triggers on a table for the same action
109
- and timing. For example:
110
-
111
- trigger.after(:update) do |t|
112
- t.all do # every row
113
- # some sql
114
- end
115
- t.where("OLD.foo != NEW.foo") do
116
- # some more sql
117
- end
118
- t.where("OLD.bar != NEW.bar") do
119
- # some other sql
120
- end
121
- end
122
-
123
- For MySQL, this will just create a single trigger with conditional logic
124
- (since it doesn't support multiple triggers). PostgreSQL and SQLite will have
125
- distinct triggers. This same notation is also used within trigger migrations.
126
- MySQL does not currently support nested trigger groups.
127
-
128
- === Database-specific trigger bodies
129
-
130
- Although HairTrigger aims to be totally db-agnostic, at times you do need a
131
- little more control over the body of the trigger. You can tailor it for
132
- specific databases by returning a hash rather than a string. Make sure to set
133
- a :default value if you aren't explicitly specifying all of them.
134
-
135
- For example, MySQL generally performs poorly with subselects in UPDATE
136
- statements, and it has its own proprietary syntax for multi-table UPDATEs. So
137
- you might do something like the following:
138
-
139
- trigger.after(:insert) do
140
- {:default => <<-DEFAULT_SQL, :mysql => <<-MYSQL}
141
-
142
- UPDATE users SET item_count = item_count + 1
143
- WHERE id IN (SELECT user_id FROM buckets WHERE id = NEW.bucket_id)
144
- DEFAULT_SQL
145
-
146
- UPDATE users, buckets SET item_count = item_count + 1
147
- WHERE users.id = user_id AND buckets.id = NEW.bucket_id
148
- MYSQL
149
- end
150
-
151
- === Manual Migrations
152
-
153
- You can also manage triggers manually in your migrations via create_trigger and
154
- drop_trigger. They are a little more verbose than model triggers, and they can
155
- be more work since you need to figure out the up/down create/drop logic when
156
- you change things. A sample trigger:
157
-
158
- create_trigger(:compatibility => 1).on(:users).after(:insert) do
159
- "UPDATE accounts SET user_count = user_count + 1 WHERE id = NEW.account_id;"
160
- end
161
-
162
- ==== Manual triggers and :compatibility
163
-
164
- As bugs are fixed and features are implemented in hairtrigger, it's possible
165
- that the generated trigger SQL will change (this has only happened once so
166
- far). If you upgrade to a newer version of hairtrigger, it needs a way of
167
- knowing which previous version generated the original trigger. You only need
168
- to worry about this for manual trigger migrations, as the model ones
169
- automatically take care of this. For your manual triggers you can either:
170
-
171
- * pass ":compatibility => x" to your create_trigger statement, where x is
172
- whatever HairTrigger::Builder.compatiblity is (1 for this version).
173
- * set "HairTrigger::Builder.base_compatibility = x" in an initializer, where
174
- x is whatever HairTrigger::Builder.compatiblity is. This is like doing the
175
- first option on every create_trigger. Note that once the compatibility
176
- changes, you'll need to set :compatibility on new triggers (unless you
177
- just redo all your triggers and bump the base_compatibility).
178
-
179
- If you upgrade to a newer version of hairtrigger and see that the SQL
180
- compatibility has changed, you'll need to set the appropriate compatibility
181
- on any new triggers that you create.
182
-
183
- == rake db:schema:dump
184
-
185
- HairTrigger hooks into rake db:schema:dump (and rake tasks that call it) to
186
- make it trigger-aware. A newly generated schema.rb will contain:
187
-
188
- * create_trigger statements for any database triggers that exactly match a
189
- create_trigger statement in an applied migration or in the previous
190
- schema.rb file. this includes both generated and manual create_trigger
191
- calls.
192
- * adapter-specific execute('CREATE TRIGGER..') statements for any unmatched
193
- database triggers.
194
-
195
- As long as you don't delete old migrations and schema.rb prior to running
196
- rake db:schema:dump, the result should be what you expect (and portable).
197
- If you have deleted all trigger migrations, you can regenerate a new
198
- baseline for model triggers via rake db:generate_trigger_migration.
199
-
200
- == Testing
201
-
202
- To stay on top of things, it's strongly recommended that you add a test or
203
- spec to ensure your migrations/schema.rb match your models. This is as simple
204
- as:
205
-
206
- assert HairTrigger::migrations_current?
207
-
208
- This way you'll know if there are any outstanding migrations you need to
209
- create.
210
-
211
- == Warnings and Errors
212
-
213
- There are a couple classes of errors: declaration errors and generation
214
- errors/warnings.
215
-
216
- Declaration errors happen if your trigger declaration is obviously wrong, and
217
- will cause a runtime error in your model or migration class. An example would
218
- be "trigger.after(:never)", since :never is not a valid event.
219
-
220
- Generation errors happen if you try something that your adapter doesn't
221
- support. An example would be something like "trigger.security(:invoker)" for
222
- MySQL. These errors only happen when the trigger is actually generated, e.g.
223
- when you attempt to run the migration.
224
-
225
- Generation warnings are similar but they don't stop the trigger from being
226
- generated. If you do something adapter-specific supported by your database,
227
- you will still get a warning ($stderr) that your trigger is not portable. You
228
- can silence warnings via "HairTrigger::Builder.show_warnings = false"
229
-
230
- You can validate your triggers beforehand using the Builder#validate! method.
231
- It will throw the appropriate errors/warnings so that you know what to fix,
232
- e.g.
233
-
234
- > User.triggers.each(&:validate!)
235
-
236
- HairTrigger does not validate your SQL, so be sure to test it in all databases
237
- you want to support.
238
-
239
- == Gotchas
240
-
241
- * As is the case with ActiveRecord::Base.update_all or any direct SQL you do,
242
- be careful to reload updated objects from the database. For example, the
243
- following code will display the wrong count since we aren't reloading the
244
- account:
245
- a = Account.find(123)
246
- a.account_users.create(:name => 'bob')
247
- puts "count is now #{a.user_count}"
248
- * For repeated chained calls, the last one wins, there is currently no
249
- merging.
250
- * If you want your code to be portable, the trigger actions should be
251
- limited to INSERT/UPDATE/DELETE/SELECT, and conditional logic should be
252
- handled through the :where option/method. Otherwise you'll likely run into
253
- trouble due to differences in syntax and supported features.
254
- * Manual create_trigger statements have some gotchas. See the section
255
- "Manual triggers and :compatibility"
256
-
257
- == Compatibility
258
-
259
- * Ruby 1.8.7+
260
- * Rails 2.3+
261
- * Postgres 8.0+
262
- * MySQL 5.0.10+
263
- * SQLite 3.3.8+
264
-
265
- == Version History
266
-
267
- * 0.2.4 Rails 4 and Ruby 2 support
268
- * 0.2.3 Better 1.9 support, update parsing gems
269
- * 0.2.2 PostGIS support
270
- * 0.2.1 Bugfix for adapter-specific warnings, loosen parser dependencies
271
- * 0.2.0 Rails 3.1+ support, easier installation, ruby 1.9 fix, travis-ci
272
- * 0.1.14 sqlite + ruby1.9 bugfix
273
- * 0.1.13 drop_trigger fix
274
- * 0.1.12 DB-specific trigger body support, bugfixes
275
- * 0.1.11 Safer migration loading, some speedups
276
- * 0.1.10 Sped up migration evaluation
277
- * 0.1.9 MySQL fixes for inferred root@localhost
278
- * 0.1.7 Rails 3 support, fixed a couple manual create_trigger bugs
279
- * 0.1.6 rake db:schema:dump support, respect non-timestamped migrations
280
- * 0.1.4 Compatibility tracking, fixed Postgres return bug, ensure last action
281
- has a semicolon
282
- * 0.1.3 Better error handling, Postgres 8.x support, updated docs
283
- * 0.1.2 Fixed Builder#security, updated docs
284
- * 0.1.1 Fixed bug in HairTrigger.migrations_current?, fixed up Gemfile
285
- * 0.1.0 Initial release
286
-
287
- == Copyright
288
-
289
- Copyright (c) 2011-2013 Jon Jensen. See LICENSE.txt for further details.