triggerhappy 0.0.6 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -12,5 +12,16 @@ module Triggerhappy
12
12
  @sql = sql
13
13
  end
14
14
  end
15
+
16
+ class ProcDefinition
17
+ attr_accessor :name, :sql
18
+
19
+ def initialize(base, name, sql)
20
+ @base = base
21
+ @name = name
22
+ @sql = sql
23
+ end
24
+ end
25
+
15
26
  end
16
- end
27
+ 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.ignore_views accepts an array of String and / or Regexp values.'
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
@@ -1,8 +1,8 @@
1
1
  module TriggerHappy
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
- MINOR = 0
5
- TINY = 1
4
+ MINOR = 1
5
+ TINY = 0
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
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: 19
4
+ hash: 27
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
+ - 1
8
9
  - 0
9
- - 6
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-05-13 00:00:00 -03:00
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/triggerhappy/connection_adapters/abstract/schema_definitions.rb
32
- - lib/triggerhappy/connection_adapters/abstract/schema_statements.rb
33
- - lib/triggerhappy/connection_adapters/abstract_adapter.rb
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/schema_dumper.rb
37
- - lib/triggerhappy/version.rb
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.2
75
+ rubygems_version: 1.5.3
78
76
  signing_key:
79
77
  specification_version: 3
80
78
  summary: sql triggers in migrations
Binary file
Binary file
@@ -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