hairtrigger 0.2.7 → 0.2.8
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/hair_trigger.rb +5 -1
- data/lib/hair_trigger/adapter.rb +12 -1
- data/lib/hair_trigger/migrator.rb +16 -5
- data/lib/hair_trigger/version.rb +1 -1
- data/spec/adapter_spec.rb +47 -0
- data/spec/spec_helper.rb +9 -1
- metadata +5 -4
data/lib/hair_trigger.rb
CHANGED
@@ -201,6 +201,10 @@ end
|
|
201
201
|
end
|
202
202
|
|
203
203
|
ActiveRecord::Base.send :extend, HairTrigger::Base
|
204
|
-
ActiveRecord::
|
204
|
+
if ActiveRecord::VERSION::STRING < "4.1."
|
205
|
+
ActiveRecord::Migrator.send :extend, HairTrigger::Migrator
|
206
|
+
else
|
207
|
+
ActiveRecord::Migration.send :include, HairTrigger::Migrator
|
208
|
+
end
|
205
209
|
ActiveRecord::ConnectionAdapters::AbstractAdapter.class_eval { include HairTrigger::Adapter }
|
206
210
|
ActiveRecord::SchemaDumper.class_eval { include HairTrigger::SchemaDumper }
|
data/lib/hair_trigger/adapter.rb
CHANGED
@@ -12,6 +12,16 @@ module HairTrigger
|
|
12
12
|
::HairTrigger::Builder.new(name, options.merge(:execute => true, :drop => true, :table => table, :adapter => self)).all{}
|
13
13
|
end
|
14
14
|
|
15
|
+
def normalize_mysql_definer(definer)
|
16
|
+
user, host = definer.split('@')
|
17
|
+
host = @config[:host] || 'localhost' if host == '%'
|
18
|
+
"'#{user}'@'#{host}'" # SHOW TRIGGERS doesn't quote them, but we need quotes for creating a trigger
|
19
|
+
end
|
20
|
+
|
21
|
+
def implicit_mysql_definer
|
22
|
+
"'#{@config[:username] || 'root'}'@'#{@config[:host] || 'localhost'}'"
|
23
|
+
end
|
24
|
+
|
15
25
|
def triggers(options = {})
|
16
26
|
triggers = {}
|
17
27
|
name_clause = options[:only] ? "IN ('" + options[:only].join("', '") + "')" : nil
|
@@ -23,9 +33,10 @@ module HairTrigger
|
|
23
33
|
end
|
24
34
|
when :mysql
|
25
35
|
select_rows("SHOW TRIGGERS").each do |(name, event, table, actions, timing, created, sql_mode, definer)|
|
36
|
+
definer = normalize_mysql_definer(definer)
|
26
37
|
next if options[:only] && !options[:only].include?(name)
|
27
38
|
triggers[name.strip] = <<-SQL
|
28
|
-
CREATE #{definer !=
|
39
|
+
CREATE #{definer != implicit_mysql_definer ? "DEFINER = #{definer} " : ""}TRIGGER #{name} #{timing} #{event} ON #{table}
|
29
40
|
FOR EACH ROW
|
30
41
|
#{actions}
|
31
42
|
SQL
|
@@ -1,11 +1,22 @@
|
|
1
1
|
module HairTrigger
|
2
2
|
module Migrator
|
3
|
-
def proper_table_name_with_hash_awareness(
|
4
|
-
name
|
3
|
+
def proper_table_name_with_hash_awareness(*args)
|
4
|
+
name = args.first
|
5
|
+
return name if name.is_a?(Hash)
|
6
|
+
proper_table_name_without_hash_awareness(*args)
|
5
7
|
end
|
6
|
-
|
7
|
-
|
8
|
-
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def extended(base)
|
11
|
+
base.class_eval do
|
12
|
+
class << self
|
13
|
+
alias_method_chain :proper_table_name, :hash_awareness
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def included(base)
|
19
|
+
base.instance_eval do
|
9
20
|
alias_method_chain :proper_table_name, :hash_awareness
|
10
21
|
end
|
11
22
|
end
|
data/lib/hair_trigger/version.rb
CHANGED
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
# for this spec to work, you need to have postgres and mysql installed (in
|
4
|
+
# addition to the gems), and you should make sure that you have set up
|
5
|
+
# appropriate users and permissions. see database.yml for more info
|
6
|
+
|
7
|
+
describe "adapter" do
|
8
|
+
include_context "hairtrigger utils"
|
9
|
+
|
10
|
+
describe ".triggers" do
|
11
|
+
before do
|
12
|
+
reset_tmp(:migration_glob => "*initial_tables*")
|
13
|
+
initialize_db
|
14
|
+
migrate_db
|
15
|
+
end
|
16
|
+
|
17
|
+
shared_examples_for "mysql" do
|
18
|
+
# have to stub SHOW TRIGGERS to get back a '%' host, since GRANTs
|
19
|
+
# and such get a little dicey for testing (local vs travis, etc.)
|
20
|
+
it "matches the generated trigger with a '%' grant" do
|
21
|
+
conn.instance_variable_get(:@config)[:host] = "somehost" # wheeeee!
|
22
|
+
implicit_definer = "'root'@'somehost'"
|
23
|
+
show_triggers_definer = "root@%"
|
24
|
+
|
25
|
+
builder = trigger.on(:users).before(:insert){ "UPDATE foos SET bar = 1" }
|
26
|
+
triggers = builder.generate.select{|t|t !~ /\ADROP/}
|
27
|
+
expect(conn).to receive(:implicit_mysql_definer).and_return(implicit_definer)
|
28
|
+
expect(conn).to receive(:select_rows).with("SHOW TRIGGERS").and_return([
|
29
|
+
['users_before_insert_row_tr', 'INSERT', 'users', "BEGIN\n UPDATE foos SET bar = 1;\nEND", 'BEFORE', 'NULL', 'STRICT_ALL_TABLES', show_triggers_definer]
|
30
|
+
])
|
31
|
+
|
32
|
+
expect(db_triggers).to eq(triggers)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "mysql" do
|
37
|
+
let(:adapter) { :mysql }
|
38
|
+
it_behaves_like "mysql"
|
39
|
+
end
|
40
|
+
|
41
|
+
context "mysql2" do
|
42
|
+
let(:adapter) { :mysql2 }
|
43
|
+
it_behaves_like "mysql"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
data/spec/spec_helper.rb
CHANGED
@@ -72,8 +72,16 @@ shared_context "hairtrigger utils" do
|
|
72
72
|
io.read
|
73
73
|
end
|
74
74
|
|
75
|
+
def trigger(*args)
|
76
|
+
HairTrigger::Builder.new(*args)
|
77
|
+
end
|
78
|
+
|
79
|
+
def conn
|
80
|
+
ActiveRecord::Base.connection
|
81
|
+
end
|
82
|
+
|
75
83
|
def db_triggers
|
76
|
-
|
84
|
+
conn.triggers.values
|
77
85
|
end
|
78
86
|
|
79
87
|
def replace_file_contents(path, source, replacement)
|
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
|
+
version: 0.2.8
|
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: 2014-04-
|
12
|
+
date: 2014-04-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|
@@ -82,7 +82,7 @@ dependencies:
|
|
82
82
|
requirements:
|
83
83
|
- - ~>
|
84
84
|
- !ruby/object:Gem::Version
|
85
|
-
version: 2.
|
85
|
+
version: 2.14.0
|
86
86
|
type: :development
|
87
87
|
prerelease: false
|
88
88
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -90,7 +90,7 @@ dependencies:
|
|
90
90
|
requirements:
|
91
91
|
- - ~>
|
92
92
|
- !ruby/object:Gem::Version
|
93
|
-
version: 2.
|
93
|
+
version: 2.14.0
|
94
94
|
- !ruby/object:Gem::Dependency
|
95
95
|
name: mysql
|
96
96
|
requirement: !ruby/object:Gem::Requirement
|
@@ -176,6 +176,7 @@ files:
|
|
176
176
|
- lib/hair_trigger.rb
|
177
177
|
- lib/hairtrigger.rb
|
178
178
|
- lib/tasks/hair_trigger.rake
|
179
|
+
- spec/adapter_spec.rb
|
179
180
|
- spec/builder_spec.rb
|
180
181
|
- spec/migrations/20110331212003_initial_tables.rb
|
181
182
|
- spec/migrations/20110331212631_user_trigger.rb
|