hairtrigger 0.2.6 → 0.2.7
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 +12 -25
- data/lib/hair_trigger.rb +1 -1
- data/lib/hair_trigger/builder.rb +35 -4
- data/lib/hair_trigger/migration_reader.rb +3 -0
- data/lib/hair_trigger/schema_dumper.rb +5 -1
- data/lib/hair_trigger/version.rb +1 -1
- data/spec/builder_spec.rb +40 -0
- data/spec/migrations_spec.rb +21 -1
- metadata +135 -153
data/README.md
CHANGED
@@ -7,31 +7,8 @@ and a simple rake task does all the dirty work for you.
|
|
7
7
|
|
8
8
|
## Installation
|
9
9
|
|
10
|
-
|
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).
|
10
|
+
If you are using Rails 3 or beyond, just add `gem 'hairtrigger'` to your
|
11
|
+
Gemfile. For Rails 2, it's [slightly more involved](RAILS2.md)
|
35
12
|
|
36
13
|
## Usage
|
37
14
|
|
@@ -135,6 +112,11 @@ For MySQL, this will just create a single trigger with conditional logic
|
|
135
112
|
distinct triggers. This same notation is also used within trigger migrations.
|
136
113
|
MySQL does not currently support nested trigger groups.
|
137
114
|
|
115
|
+
Because of these differences in how the triggers are created, take care
|
116
|
+
when setting the `name` for triggers or groups. In other words,
|
117
|
+
PostgreSQL/SQLite will use the `name`s specified on the individual
|
118
|
+
triggers; MySQL will use the `name` specified on the group.
|
119
|
+
|
138
120
|
### Database-specific trigger bodies
|
139
121
|
|
140
122
|
Although HairTrigger aims to be totally db-agnostic, at times you do need a
|
@@ -173,6 +155,11 @@ create_trigger(:compatibility => 1).on(:users).after(:insert) do
|
|
173
155
|
end
|
174
156
|
```
|
175
157
|
|
158
|
+
Because `create_trigger` may drop an existing trigger of the same name,
|
159
|
+
you need to actually implement `up`/`down` methods in your migration
|
160
|
+
(rather than `change`) so that it does the right thing when
|
161
|
+
rolling back.
|
162
|
+
|
176
163
|
#### Manual triggers and :compatibility
|
177
164
|
|
178
165
|
As bugs are fixed and features are implemented in hairtrigger, it's possible
|
data/lib/hair_trigger.rb
CHANGED
@@ -70,7 +70,7 @@ module HairTrigger
|
|
70
70
|
if previous_schema = (options.has_key?(:previous_schema) ? options[:previous_schema] : File.exist?(schema_rb_path) && File.read(schema_rb_path))
|
71
71
|
base_triggers = MigrationReader.get_triggers(previous_schema, options)
|
72
72
|
unless base_triggers.empty?
|
73
|
-
version = (previous_schema =~ /ActiveRecord::Schema\.define\(
|
73
|
+
version = (previous_schema =~ /ActiveRecord::Schema\.define\(.*?(\d+)\)/) && $1.to_i
|
74
74
|
migrations.unshift [OpenStruct.new({:version => version}), base_triggers]
|
75
75
|
end
|
76
76
|
end
|
data/lib/hair_trigger/builder.rb
CHANGED
@@ -15,6 +15,7 @@ module HairTrigger
|
|
15
15
|
@options = {}
|
16
16
|
@chained_calls = []
|
17
17
|
@errors = []
|
18
|
+
@warnings = []
|
18
19
|
set_name(name) if name
|
19
20
|
{:timing => :after, :for_each => :row}.update(options).each do |key, value|
|
20
21
|
if respond_to?("set_#{key}")
|
@@ -30,6 +31,7 @@ module HairTrigger
|
|
30
31
|
@triggers = nil
|
31
32
|
@chained_calls = []
|
32
33
|
@errors = []
|
34
|
+
@warnings = []
|
33
35
|
@options = @options.dup
|
34
36
|
@options.delete(:name) # this will be inferred (or set further down the line)
|
35
37
|
@options.each do |key, value|
|
@@ -112,9 +114,15 @@ module HairTrigger
|
|
112
114
|
[prepared_name] + (@triggers ? @triggers.map(&:prepared_name) : [])
|
113
115
|
end
|
114
116
|
|
117
|
+
def all_triggers(include_self = true)
|
118
|
+
triggers = []
|
119
|
+
triggers << self if include_self
|
120
|
+
(@triggers || []).map(&:all_triggers).inject(triggers, &:concat)
|
121
|
+
end
|
122
|
+
|
115
123
|
def self.chainable_methods(*methods)
|
116
124
|
methods.each do |method|
|
117
|
-
class_eval <<-METHOD
|
125
|
+
class_eval <<-METHOD, __FILE__, __LINE__ + 1
|
118
126
|
alias #{method}_orig #{method}
|
119
127
|
def #{method}(*args)
|
120
128
|
@chained_calls << :#{method}
|
@@ -128,7 +136,7 @@ module HairTrigger
|
|
128
136
|
@chained_calls.pop # the subtrigger will get this, we don't need it
|
129
137
|
@chained_calls = @chained_calls.uniq
|
130
138
|
@triggers << trigger = clone
|
131
|
-
trigger.#{method}(*args, &Proc.new)
|
139
|
+
trigger.#{method}(*args, &(block_given? ? Proc.new : nil))
|
132
140
|
else
|
133
141
|
#{method}_orig(*args)
|
134
142
|
maybe_execute(&Proc.new) if block_given?
|
@@ -160,6 +168,10 @@ module HairTrigger
|
|
160
168
|
raise GenerationError, error if adapters.include?(adapter_name)
|
161
169
|
$stderr.puts "WARNING: " + error if self.class.show_warnings
|
162
170
|
end
|
171
|
+
@warnings.each do |(error, *adapters)|
|
172
|
+
$stderr.puts "WARNING: " + error if adapters.include?(adapter_name) && self.class.show_warnings
|
173
|
+
end
|
174
|
+
|
163
175
|
if direction != :up
|
164
176
|
@triggers.each{ |t| t.validate!(:down) } if @triggers
|
165
177
|
end
|
@@ -247,7 +259,11 @@ module HairTrigger
|
|
247
259
|
end
|
248
260
|
|
249
261
|
def errors
|
250
|
-
(@triggers || []).inject(@errors
|
262
|
+
(@triggers || []).map(&:errors).inject(@errors, &:+)
|
263
|
+
end
|
264
|
+
|
265
|
+
def warnings
|
266
|
+
(@triggers || []).map(&:warnings).inject(@warnings, &:+)
|
251
267
|
end
|
252
268
|
|
253
269
|
private
|
@@ -289,10 +305,25 @@ module HairTrigger
|
|
289
305
|
end
|
290
306
|
end
|
291
307
|
# only the top-most block actually executes
|
292
|
-
|
308
|
+
if !@trigger_group
|
309
|
+
validate_names!
|
310
|
+
if options[:execute]
|
311
|
+
Array(generate).each{ |action| adapter.execute(action)}
|
312
|
+
end
|
313
|
+
end
|
293
314
|
self
|
294
315
|
end
|
295
316
|
|
317
|
+
def validate_names!
|
318
|
+
subtriggers = all_triggers(false)
|
319
|
+
named_subtriggers = subtriggers.select{ |t| t.options[:name] }
|
320
|
+
if named_subtriggers.present? && !options[:name]
|
321
|
+
@warnings << ["nested triggers have explicit names, but trigger group does not. trigger name will be inferred", :mysql]
|
322
|
+
elsif subtriggers.present? && !named_subtriggers.present? && options[:name]
|
323
|
+
@warnings << ["trigger group has an explicit name, but nested triggers do not. trigger names will be inferred", :postgresql, :sqlite]
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
296
327
|
def adapter_name
|
297
328
|
@adapter_name ||= HairTrigger.adapter_name_for(adapter)
|
298
329
|
end
|
@@ -23,6 +23,7 @@ module HairTrigger
|
|
23
23
|
# find the block of the up method
|
24
24
|
sexps = sexps.last if sexps.last.is_a?(Sexp) && sexps.last[0] == :block
|
25
25
|
sexps = sexps.detect{ |s| s.is_a?(Sexp) && (s[0] == :defs && s[1] && s[1][0] == :self && s[2] == :up || s[0] == :defn && s[1] == :up) }
|
26
|
+
return [] unless sexps # no `up` method... unsupported `change` perhaps?
|
26
27
|
sexps.each do |sexp|
|
27
28
|
next unless (method = extract_method_call(sexp)) && [:create_trigger, :drop_trigger].include?(method)
|
28
29
|
trigger = instance_eval("generate_" + generator.process(sexp))
|
@@ -32,6 +33,7 @@ module HairTrigger
|
|
32
33
|
triggers
|
33
34
|
rescue
|
34
35
|
$stderr.puts "Error reading triggers in #{source.filename rescue "schema.rb"}: #{$!}"
|
36
|
+
[]
|
35
37
|
end
|
36
38
|
|
37
39
|
private
|
@@ -48,6 +50,7 @@ module HairTrigger
|
|
48
50
|
def generate_create_trigger(*arguments)
|
49
51
|
arguments.unshift({}) if arguments.empty?
|
50
52
|
arguments.unshift(nil) if arguments.first.is_a?(Hash)
|
53
|
+
arguments.push({}) if arguments.size == 1
|
51
54
|
arguments[1][:compatibility] ||= HairTrigger::Builder.base_compatibility
|
52
55
|
::HairTrigger::Builder.new(*arguments)
|
53
56
|
end
|
@@ -1,8 +1,12 @@
|
|
1
1
|
module HairTrigger
|
2
2
|
module SchemaDumper
|
3
3
|
def trailer_with_triggers(stream)
|
4
|
+
orig_show_warnings = Builder.show_warnings
|
5
|
+
Builder.show_warnings = false # we already show them when running the migration
|
4
6
|
triggers(stream)
|
5
7
|
trailer_without_triggers(stream)
|
8
|
+
ensure
|
9
|
+
Builder.show_warnings = orig_show_warnings
|
6
10
|
end
|
7
11
|
|
8
12
|
def triggers(stream)
|
@@ -84,4 +88,4 @@ module HairTrigger
|
|
84
88
|
end
|
85
89
|
end
|
86
90
|
end
|
87
|
-
end
|
91
|
+
end
|
data/lib/hair_trigger/version.rb
CHANGED
data/spec/builder_spec.rb
CHANGED
@@ -60,6 +60,19 @@ describe "builder" do
|
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
63
|
+
describe "groups" do
|
64
|
+
it "should allow chained methods" do
|
65
|
+
triggers = builder.on(:foos){ |t|
|
66
|
+
t.where('bar=1').name('bar'){ 'BAR;' }
|
67
|
+
t.where('baz=1').name('baz'){ 'BAZ;' }
|
68
|
+
}.triggers
|
69
|
+
triggers.map(&:prepare!)
|
70
|
+
triggers.map(&:prepared_name).should == ['bar', 'baz']
|
71
|
+
triggers.map(&:prepared_where).should == ['bar=1', 'baz=1']
|
72
|
+
triggers.map(&:prepared_actions).should == ['BAR;', 'BAZ;']
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
63
76
|
context "adapter-specific actions" do
|
64
77
|
before(:each) do
|
65
78
|
@adapter = MockAdapter.new("mysql")
|
@@ -112,6 +125,15 @@ describe "builder" do
|
|
112
125
|
}.should raise_error
|
113
126
|
end
|
114
127
|
|
128
|
+
it "should warn on explicit subtrigger names and no group name" do
|
129
|
+
trigger = builder.on(:foos){ |t|
|
130
|
+
t.where('bar=1').name('bar'){ 'BAR;' }
|
131
|
+
t.where('baz=1').name('baz'){ 'BAZ;' }
|
132
|
+
}
|
133
|
+
trigger.warnings.size.should == 1
|
134
|
+
trigger.warnings.first.first.should =~ /nested triggers have explicit names/
|
135
|
+
end
|
136
|
+
|
115
137
|
it "should accept security" do
|
116
138
|
builder.on(:foos).after(:update).security(:definer){ "FOO" }.generate.
|
117
139
|
grep(/DEFINER/).size.should eql(0) # default, so we don't include it
|
@@ -170,6 +192,15 @@ describe "builder" do
|
|
170
192
|
trigger.generate.grep(/CREATE.*TRIGGER/).size.should eql(3)
|
171
193
|
end
|
172
194
|
|
195
|
+
it "should warn on an explicit group names and no subtrigger names" do
|
196
|
+
trigger = builder.on(:foos).name('foos'){ |t|
|
197
|
+
t.where('bar=1'){ 'BAR;' }
|
198
|
+
t.where('baz=1'){ 'BAZ;' }
|
199
|
+
}
|
200
|
+
trigger.warnings.size.should == 1
|
201
|
+
trigger.warnings.first.first.should =~ /trigger group has an explicit name/
|
202
|
+
end
|
203
|
+
|
173
204
|
it "should accept security" do
|
174
205
|
builder.on(:foos).after(:update).security(:invoker){ "FOO" }.generate.
|
175
206
|
grep(/SECURITY/).size.should eql(0) # default, so we don't include it
|
@@ -251,6 +282,15 @@ describe "builder" do
|
|
251
282
|
trigger.generate.grep(/CREATE.*TRIGGER/).size.should eql(3)
|
252
283
|
end
|
253
284
|
|
285
|
+
it "should warn on an explicit group names and no subtrigger names" do
|
286
|
+
trigger = builder.on(:foos).name('foos'){ |t|
|
287
|
+
t.where('bar=1'){ 'BAR;' }
|
288
|
+
t.where('baz=1'){ 'BAZ;' }
|
289
|
+
}
|
290
|
+
trigger.warnings.size.should == 1
|
291
|
+
trigger.warnings.first.first.should =~ /trigger group has an explicit name/
|
292
|
+
end
|
293
|
+
|
254
294
|
it "should reject security" do
|
255
295
|
lambda {
|
256
296
|
builder.on(:foos).after(:update).security(:definer){ "FOO" }.generate
|
data/spec/migrations_spec.rb
CHANGED
@@ -6,9 +6,9 @@ require 'spec_helper'
|
|
6
6
|
|
7
7
|
describe "migrations" do
|
8
8
|
include_context "hairtrigger utils"
|
9
|
+
let(:adapter) { :sqlite3 }
|
9
10
|
|
10
11
|
describe "migrations_current?" do
|
11
|
-
let(:adapter) { :sqlite3 }
|
12
12
|
|
13
13
|
it "should return false if there are pending model triggers" do
|
14
14
|
reset_tmp(:migration_glob => "*initial_tables*")
|
@@ -37,4 +37,24 @@ describe "migrations" do
|
|
37
37
|
HairTrigger.should be_migrations_current
|
38
38
|
end
|
39
39
|
end
|
40
|
+
|
41
|
+
describe "current_triggers" do
|
42
|
+
it "should be inferred from self.up methods" do
|
43
|
+
reset_tmp(:migration_glob => "20110331212*")
|
44
|
+
initialize_db
|
45
|
+
|
46
|
+
migrations = HairTrigger.current_migrations
|
47
|
+
migrations.size.should == 1
|
48
|
+
migrations[0][1].prepared_name.should == "users_after_insert_row_when_new_name_bob__tr"
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should not be inferred from change methods" do
|
52
|
+
reset_tmp(:migration_glob => "*manual*")
|
53
|
+
replace_file_contents("tmp/migrations/20110417185102_manual_user_trigger.rb", "def up", "def change")
|
54
|
+
initialize_db
|
55
|
+
|
56
|
+
migrations = HairTrigger.current_migrations
|
57
|
+
migrations.size.should == 0
|
58
|
+
end
|
59
|
+
end
|
40
60
|
end
|
metadata
CHANGED
@@ -1,172 +1,167 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: hairtrigger
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.7
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 2
|
9
|
-
- 6
|
10
|
-
version: 0.2.6
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Jon Jensen
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
dependencies:
|
21
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2014-04-04 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
22
15
|
name: activerecord
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
hash: 5
|
30
|
-
segments:
|
31
|
-
- 2
|
32
|
-
- 3
|
33
|
-
version: "2.3"
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '2.3'
|
34
22
|
type: :runtime
|
35
|
-
version_requirements: *id001
|
36
|
-
- !ruby/object:Gem::Dependency
|
37
|
-
name: ruby_parser
|
38
23
|
prerelease: false
|
39
|
-
|
40
|
-
none: false
|
41
|
-
requirements:
|
42
|
-
- -
|
43
|
-
- !ruby/object:Gem::Version
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '2.3'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: ruby_parser
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '3.5'
|
49
38
|
type: :runtime
|
50
|
-
version_requirements: *id002
|
51
|
-
- !ruby/object:Gem::Dependency
|
52
|
-
name: ruby2ruby
|
53
39
|
prerelease: false
|
54
|
-
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '3.5'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: ruby2ruby
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
55
49
|
none: false
|
56
|
-
requirements:
|
50
|
+
requirements:
|
57
51
|
- - ~>
|
58
|
-
- !ruby/object:Gem::Version
|
59
|
-
hash: 3
|
60
|
-
segments:
|
61
|
-
- 2
|
62
|
-
- 0
|
63
|
-
- 6
|
52
|
+
- !ruby/object:Gem::Version
|
64
53
|
version: 2.0.6
|
65
54
|
type: :runtime
|
66
|
-
version_requirements: *id003
|
67
|
-
- !ruby/object:Gem::Dependency
|
68
|
-
name: rake
|
69
55
|
prerelease: false
|
70
|
-
|
71
|
-
none: false
|
72
|
-
requirements:
|
73
|
-
- -
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 2.0.6
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rake
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
79
70
|
type: :development
|
80
|
-
version_requirements: *id004
|
81
|
-
- !ruby/object:Gem::Dependency
|
82
|
-
name: rspec
|
83
71
|
prerelease: false
|
84
|
-
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
73
|
none: false
|
86
|
-
requirements:
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: rspec
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
87
83
|
- - ~>
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
hash: 63
|
90
|
-
segments:
|
91
|
-
- 2
|
92
|
-
- 12
|
93
|
-
- 0
|
84
|
+
- !ruby/object:Gem::Version
|
94
85
|
version: 2.12.0
|
95
86
|
type: :development
|
96
|
-
version_requirements: *id005
|
97
|
-
- !ruby/object:Gem::Dependency
|
98
|
-
name: mysql
|
99
87
|
prerelease: false
|
100
|
-
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: 2.12.0
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: mysql
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
101
97
|
none: false
|
102
|
-
requirements:
|
98
|
+
requirements:
|
103
99
|
- - ~>
|
104
|
-
- !ruby/object:Gem::Version
|
105
|
-
hash: 41
|
106
|
-
segments:
|
107
|
-
- 2
|
108
|
-
- 9
|
109
|
-
- 1
|
100
|
+
- !ruby/object:Gem::Version
|
110
101
|
version: 2.9.1
|
111
102
|
type: :development
|
112
|
-
version_requirements: *id006
|
113
|
-
- !ruby/object:Gem::Dependency
|
114
|
-
name: mysql2
|
115
103
|
prerelease: false
|
116
|
-
|
117
|
-
none: false
|
118
|
-
requirements:
|
119
|
-
- -
|
120
|
-
- !ruby/object:Gem::Version
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ~>
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: 2.9.1
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: mysql2
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
126
117
|
version: 0.3.11
|
127
118
|
type: :development
|
128
|
-
version_requirements: *id007
|
129
|
-
- !ruby/object:Gem::Dependency
|
130
|
-
name: pg
|
131
119
|
prerelease: false
|
132
|
-
|
133
|
-
none: false
|
134
|
-
requirements:
|
135
|
-
- -
|
136
|
-
- !ruby/object:Gem::Version
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: 0.3.11
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: pg
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ! '>='
|
132
|
+
- !ruby/object:Gem::Version
|
142
133
|
version: 0.15.1
|
143
134
|
type: :development
|
144
|
-
version_requirements: *id008
|
145
|
-
- !ruby/object:Gem::Dependency
|
146
|
-
name: sqlite3
|
147
135
|
prerelease: false
|
148
|
-
|
149
|
-
none: false
|
150
|
-
requirements:
|
151
|
-
- -
|
152
|
-
- !ruby/object:Gem::Version
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ! '>='
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: 0.15.1
|
142
|
+
- !ruby/object:Gem::Dependency
|
143
|
+
name: sqlite3
|
144
|
+
requirement: !ruby/object:Gem::Requirement
|
145
|
+
none: false
|
146
|
+
requirements:
|
147
|
+
- - ! '>='
|
148
|
+
- !ruby/object:Gem::Version
|
158
149
|
version: 1.3.7
|
159
150
|
type: :development
|
160
|
-
|
161
|
-
|
151
|
+
prerelease: false
|
152
|
+
version_requirements: !ruby/object:Gem::Requirement
|
153
|
+
none: false
|
154
|
+
requirements:
|
155
|
+
- - ! '>='
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: 1.3.7
|
158
|
+
description: allows you to declare database triggers in ruby in your models, and then
|
159
|
+
generate appropriate migrations as they change
|
162
160
|
email: jenseng@gmail.com
|
163
161
|
executables: []
|
164
|
-
|
165
162
|
extensions: []
|
166
|
-
|
167
163
|
extra_rdoc_files: []
|
168
|
-
|
169
|
-
files:
|
164
|
+
files:
|
170
165
|
- LICENSE.txt
|
171
166
|
- Rakefile
|
172
167
|
- README.md
|
@@ -193,43 +188,30 @@ files:
|
|
193
188
|
- spec/models/user.rb
|
194
189
|
- spec/schema_dumper_spec.rb
|
195
190
|
- spec/spec_helper.rb
|
196
|
-
has_rdoc: true
|
197
191
|
homepage: http://github.com/jenseng/hair_trigger
|
198
|
-
licenses:
|
192
|
+
licenses:
|
199
193
|
- MIT
|
200
194
|
post_install_message:
|
201
195
|
rdoc_options: []
|
202
|
-
|
203
|
-
require_paths:
|
196
|
+
require_paths:
|
204
197
|
- lib
|
205
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
198
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
206
199
|
none: false
|
207
|
-
requirements:
|
208
|
-
- -
|
209
|
-
- !ruby/object:Gem::Version
|
210
|
-
hash: 57
|
211
|
-
segments:
|
212
|
-
- 1
|
213
|
-
- 8
|
214
|
-
- 7
|
200
|
+
requirements:
|
201
|
+
- - ! '>='
|
202
|
+
- !ruby/object:Gem::Version
|
215
203
|
version: 1.8.7
|
216
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
204
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
217
205
|
none: false
|
218
|
-
requirements:
|
219
|
-
- -
|
220
|
-
- !ruby/object:Gem::Version
|
221
|
-
hash: 17
|
222
|
-
segments:
|
223
|
-
- 1
|
224
|
-
- 3
|
225
|
-
- 5
|
206
|
+
requirements:
|
207
|
+
- - ! '>='
|
208
|
+
- !ruby/object:Gem::Version
|
226
209
|
version: 1.3.5
|
227
210
|
requirements: []
|
228
|
-
|
229
211
|
rubyforge_project:
|
230
|
-
rubygems_version: 1.
|
212
|
+
rubygems_version: 1.8.23
|
231
213
|
signing_key:
|
232
214
|
specification_version: 3
|
233
215
|
summary: easy database triggers for active record
|
234
216
|
test_files: []
|
235
|
-
|
217
|
+
has_rdoc:
|