triggerhappy 0.0.6 → 0.1.0
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 +3 -1
- data/lib/core_ext/module.rb +11 -0
- data/lib/triggerhappy/connection_adapters/abstract/schema_definitions.rb +12 -1
- data/lib/triggerhappy/connection_adapters/abstract/schema_statements.rb +26 -1
- data/lib/triggerhappy/connection_adapters/abstract_adapter.rb +16 -1
- data/lib/triggerhappy/connection_adapters/sqlserver_adapter.rb +33 -3
- data/lib/triggerhappy/schema_dumper.rb +45 -3
- data/lib/triggerhappy/version.rb +2 -2
- metadata +12 -14
- data/triggerhappy-0.0.4.gem +0 -0
- data/triggerhappy-0.0.5.gem +0 -0
- data/triggerhappy.gemspec +0 -14
data/README
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
Library which adds SQL Triggers to Rails. Adds create_trigger and drop_trigger to the ActiveRecord::ConnectionAdapters::AbstractAdapter (which makes them available to migrations) and adds support for dumping triggers in the ActiveRecord::SchemaDumper.
|
4
4
|
|
5
|
+
Now supports creation / removal of stored procedures in migrations!
|
6
|
+
|
5
7
|
== Installation
|
6
8
|
|
7
9
|
To install:
|
@@ -69,4 +71,4 @@ If you find any issues please send an email to stewbawka@gmail.com .
|
|
69
71
|
|
70
72
|
== Contributing
|
71
73
|
|
72
|
-
If you would like to implement trigger support for other adapters then please drop me an email. Better yet, write up the adapter modifications and send them to me. :-)
|
74
|
+
If you would like to implement trigger support for other adapters then please drop me an email. Better yet, write up the adapter modifications and send them to me. :-)
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# This is required for 1.1.6 support
|
2
|
+
class Module
|
3
|
+
def alias_method_chain(target, feature)
|
4
|
+
# Strip out punctuation on predicates or bang methods since
|
5
|
+
# e.g. target?_without_feature is not a valid method name.
|
6
|
+
aliased_target, punctuation = target.to_s.sub(/([?!=])$/, ''), $1
|
7
|
+
yield(aliased_target, punctuation) if block_given?
|
8
|
+
alias_method "#{aliased_target}_without_#{feature}#{punctuation}", target
|
9
|
+
alias_method target, "#{aliased_target}_with_#{feature}#{punctuation}"
|
10
|
+
end
|
11
|
+
end
|
@@ -24,6 +24,31 @@ module Triggerhappy
|
|
24
24
|
execute drop_sql
|
25
25
|
end
|
26
26
|
end
|
27
|
+
|
28
|
+
# Create a proc.
|
29
|
+
def create_proc(name, sql, options={})
|
30
|
+
if supports_procs?
|
31
|
+
proc_definition = ProcDefinition.new(self, name, sql)
|
32
|
+
|
33
|
+
if options[:force]
|
34
|
+
drop_proc(name) rescue nil
|
35
|
+
end
|
36
|
+
|
37
|
+
create_sql = "CREATE PROCEDURE "
|
38
|
+
create_sql << "#{name}"
|
39
|
+
create_sql << proc_definition.sql
|
40
|
+
execute create_sql
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Drop a proc.
|
45
|
+
def drop_proc(name, options={})
|
46
|
+
if supports_procs?
|
47
|
+
drop_sql = "DROP PROCEDURE #{name}"
|
48
|
+
execute drop_sql
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
27
52
|
end
|
28
53
|
end
|
29
|
-
end
|
54
|
+
end
|
@@ -26,6 +26,21 @@ module ActiveRecord
|
|
26
26
|
raise NotImplementedError, "trigger_events is an abstract method"
|
27
27
|
end
|
28
28
|
|
29
|
+
# Subclasses should override and return true if they support procs.
|
30
|
+
def supports_procs?
|
31
|
+
return false
|
32
|
+
end
|
33
|
+
|
34
|
+
# Get a list of all procs for the current database
|
35
|
+
def procs(name = nil)
|
36
|
+
raise NotImplementedError, "procs is an abstract method"
|
37
|
+
end
|
38
|
+
|
39
|
+
# Get the code for the specified proc
|
40
|
+
def proc_code(proc, name=nil)
|
41
|
+
raise NotImplementedError, "proc_code is an abstract method"
|
42
|
+
end
|
43
|
+
|
29
44
|
end
|
30
45
|
end
|
31
|
-
end
|
46
|
+
end
|
@@ -1,16 +1,26 @@
|
|
1
1
|
module ActiveRecord
|
2
2
|
module ConnectionAdapters
|
3
3
|
class SQLServerAdapter
|
4
|
-
# Returns true as this adapter supports views.
|
5
4
|
def supports_triggers?
|
6
5
|
true
|
7
6
|
end
|
7
|
+
|
8
|
+
def supports_procs?
|
9
|
+
true
|
10
|
+
end
|
11
|
+
|
8
12
|
|
9
13
|
# Returns all the trigger names from the currently connected schema.
|
10
14
|
def triggers(name = nil)
|
11
15
|
select_values("SELECT name FROM sys.triggers", name)
|
12
16
|
end
|
13
17
|
|
18
|
+
# Returns all the proc names from the currently connected schema.
|
19
|
+
def procs(name = nil)
|
20
|
+
select_values("SELECT name FROM sysobjects WHERE type = 'P'", name)
|
21
|
+
end
|
22
|
+
|
23
|
+
|
14
24
|
def trigger_sp_helptext(trigger, name=nil)
|
15
25
|
q =<<-ENDSQL
|
16
26
|
SELECT OBJECT_DEFINITION(OBJECT_ID('#{trigger}'));
|
@@ -43,7 +53,27 @@ ENDSQL
|
|
43
53
|
trigger_def = trigger_sp_helptext(trigger, name)
|
44
54
|
trigger_def.sub(/^CREATE.* AS /, '')
|
45
55
|
end
|
46
|
-
|
56
|
+
|
57
|
+
def proc_sp_helptext(proc, name=nil)
|
58
|
+
q =<<-ENDSQL
|
59
|
+
SELECT OBJECT_DEFINITION(OBJECT_ID('#{proc}'));
|
60
|
+
ENDSQL
|
61
|
+
|
62
|
+
proc_def = select_value(q, name)
|
63
|
+
|
64
|
+
if !proc_def.blank?
|
65
|
+
return proc_def
|
66
|
+
else
|
67
|
+
raise "No proc called #{proc} found"
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
def proc_code(proc, name=nil)
|
73
|
+
proc_def = proc_sp_helptext(proc, name)
|
74
|
+
proc_def.sub(/^CREATE PROCEDURE \w+\s+/, '')
|
75
|
+
end
|
76
|
+
|
47
77
|
end
|
48
78
|
end
|
49
|
-
end
|
79
|
+
end
|
@@ -5,20 +5,25 @@ module ActiveRecord
|
|
5
5
|
# Acceptable values are strings as well as regexp.
|
6
6
|
# This setting is only used if ActiveRecord::Base.schema_format == :ruby
|
7
7
|
cattr_accessor :ignore_triggers
|
8
|
+
cattr_accessor :ignore_procs
|
8
9
|
@@ignore_triggers = []
|
10
|
+
@@ignore_procs = []
|
9
11
|
|
10
12
|
def trailer_with_triggers(stream)
|
11
13
|
# do nothing...we'll call this later
|
12
14
|
end
|
13
15
|
alias_method_chain :trailer, :triggers
|
14
16
|
|
15
|
-
# Add triggers to the end of the dump stream
|
17
|
+
# Add triggers/procs to the end of the dump stream
|
16
18
|
def dump_with_triggers(stream)
|
17
19
|
dump_without_triggers(stream)
|
18
20
|
begin
|
19
21
|
if @connection.supports_triggers?
|
20
22
|
triggers(stream)
|
21
23
|
end
|
24
|
+
if @connection.supports_procs?
|
25
|
+
procs(stream)
|
26
|
+
end
|
22
27
|
rescue => e
|
23
28
|
ActiveRecord::Base.logger.error "Unable to dump triggers: #{e}"
|
24
29
|
end
|
@@ -35,12 +40,28 @@ module ActiveRecord
|
|
35
40
|
when String: t == ignored
|
36
41
|
when Regexp: t =~ ignored
|
37
42
|
else
|
38
|
-
raise StandardError, 'ActiveRecord::SchemaDumper.
|
43
|
+
raise StandardError, 'ActiveRecord::SchemaDumper.ignore_triggers accepts an array of String and / or Regexp values.'
|
39
44
|
end
|
40
45
|
end
|
41
46
|
trigger(t, stream)
|
42
47
|
end
|
43
48
|
end
|
49
|
+
|
50
|
+
# Add procs to the stream
|
51
|
+
def procs(stream)
|
52
|
+
@connection.procs.sort.each do |p|
|
53
|
+
next if [ignore_procs].flatten.any? do |ignored|
|
54
|
+
case ignored
|
55
|
+
when String: p == ignored
|
56
|
+
when Regexp: p =~ ignored
|
57
|
+
else
|
58
|
+
raise StandardError, 'ActiveRecord::SchemaDumper.ignore_procs accepts an array of String and / or Regexp values.'
|
59
|
+
end
|
60
|
+
end
|
61
|
+
proc(p, stream)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
44
65
|
|
45
66
|
# Add the specified trigger to the stream
|
46
67
|
def trigger(trigger, stream)
|
@@ -64,5 +85,26 @@ module ActiveRecord
|
|
64
85
|
|
65
86
|
stream
|
66
87
|
end
|
88
|
+
|
89
|
+
# Add the specified proc to the stream
|
90
|
+
def proc(proc, stream)
|
91
|
+
begin
|
92
|
+
t = StringIO.new
|
93
|
+
t.print " proc_code = <<EOSQL\n"
|
94
|
+
t.print @connection.proc_code(proc)
|
95
|
+
t.print "EOSQL\n"
|
96
|
+
t.print " create_proc(#{proc.to_sym.inspect}, "
|
97
|
+
t.print "proc_code, "
|
98
|
+
t.print ":force => true)\n"
|
99
|
+
t.rewind
|
100
|
+
stream.print t.read
|
101
|
+
rescue => e
|
102
|
+
stream.puts "# Could not dump proc #{proc.inspect} because of following #{e.class}"
|
103
|
+
stream.puts "# #{e.message}"
|
104
|
+
stream.puts "# #{e.trace}"
|
105
|
+
end
|
106
|
+
|
107
|
+
stream
|
108
|
+
end
|
67
109
|
end
|
68
|
-
end
|
110
|
+
end
|
data/lib/triggerhappy/version.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: triggerhappy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 27
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
+
- 1
|
8
9
|
- 0
|
9
|
-
|
10
|
-
version: 0.0.6
|
10
|
+
version: 0.1.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Stuart Wade
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-08-11 00:00:00 -03:00
|
19
19
|
default_executable:
|
20
20
|
dependencies: []
|
21
21
|
|
@@ -28,20 +28,18 @@ extensions: []
|
|
28
28
|
extra_rdoc_files: []
|
29
29
|
|
30
30
|
files:
|
31
|
-
- lib/
|
32
|
-
- lib/triggerhappy
|
33
|
-
- lib/triggerhappy/
|
31
|
+
- lib/core_ext/module.rb
|
32
|
+
- lib/triggerhappy.rb
|
33
|
+
- lib/triggerhappy/version.rb
|
34
|
+
- lib/triggerhappy/schema_dumper.rb
|
34
35
|
- lib/triggerhappy/connection_adapters/mysql_adapter.rb
|
35
36
|
- lib/triggerhappy/connection_adapters/sqlserver_adapter.rb
|
36
|
-
- lib/triggerhappy/
|
37
|
-
- lib/triggerhappy/
|
38
|
-
- lib/triggerhappy.rb
|
37
|
+
- lib/triggerhappy/connection_adapters/abstract_adapter.rb
|
38
|
+
- lib/triggerhappy/connection_adapters/abstract/schema_statements.rb
|
39
|
+
- lib/triggerhappy/connection_adapters/abstract/schema_definitions.rb
|
39
40
|
- CHANGELOG
|
40
41
|
- Rakefile
|
41
42
|
- README
|
42
|
-
- triggerhappy-0.0.4.gem
|
43
|
-
- triggerhappy-0.0.5.gem
|
44
|
-
- triggerhappy.gemspec
|
45
43
|
has_rdoc: true
|
46
44
|
homepage: http://blog.stewbawka.com
|
47
45
|
licenses: []
|
@@ -74,7 +72,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
74
72
|
requirements: []
|
75
73
|
|
76
74
|
rubyforge_project: triggerhappy
|
77
|
-
rubygems_version: 1.5.
|
75
|
+
rubygems_version: 1.5.3
|
78
76
|
signing_key:
|
79
77
|
specification_version: 3
|
80
78
|
summary: sql triggers in migrations
|
data/triggerhappy-0.0.4.gem
DELETED
Binary file
|
data/triggerhappy-0.0.5.gem
DELETED
Binary file
|
data/triggerhappy.gemspec
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
Gem::Specification.new do |s|
|
2
|
-
s.name = "triggerhappy"
|
3
|
-
s.version = "0.0.6"
|
4
|
-
s.author = "Stuart Wade"
|
5
|
-
s.email = "stewbawka@gmail.com"
|
6
|
-
s.homepage = "http://blog.stewbawka.com"
|
7
|
-
s.summary = "sql triggers in migrations"
|
8
|
-
s.description = "Provide create_trigger and drop_trigger in migrations. Also extends SchemaDumper to clue in about triggers"
|
9
|
-
s.files = Dir["{lib,test}/**/*"] + Dir["[A-Z]*"]
|
10
|
-
s.require_path = "lib"
|
11
|
-
|
12
|
-
s.rubyforge_project = s.name
|
13
|
-
s.required_rubygems_version = ">= 1.3.4"
|
14
|
-
end
|