rails_sql_views 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG ADDED
@@ -0,0 +1,2 @@
1
+ 0.1.0 -
2
+ * Initial release
data/README ADDED
@@ -0,0 +1,44 @@
1
+ == Rails SQL Views
2
+
3
+ Library which adds SQL Views to Rails. Adds create_view and drop_view to the ActiveRecord::ConnectionAdapters::AbstractAdapter.
4
+
5
+ == Installation
6
+
7
+ To install:
8
+
9
+ gem install rails_sql_views
10
+
11
+ Then add the following to your Rails config/environment.rb:
12
+
13
+ require_gem 'rails_sql_views'
14
+ require 'rails_sql_views'
15
+
16
+ == Usage
17
+
18
+ You can then use create_view and drop_view in your migrations. For example:
19
+
20
+ class CreatePersonView < ActiveRecord::Migration
21
+ def self.up
22
+ create_view :v_people, "select * from people" do |t|
23
+ t.column :id
24
+ t.column :name
25
+ t.column :social_security
26
+ end
27
+ end
28
+
29
+ def self.down
30
+ drop_view :v_people
31
+ end
32
+ end
33
+
34
+ This extension also adds support for views in the ActiveRecord::SchemaDumper class, however currently only MySQL is supported.
35
+
36
+ == Known Issues
37
+
38
+ * None
39
+
40
+ If you find any issues please send an email to anthonyeden@gmail.com .
41
+
42
+ == Contributing
43
+
44
+ If you would like to implement view support for other adapters then please drop me an email. Better yet, write up the adapter modifications and send them to me. :-)
data/Rakefile ADDED
@@ -0,0 +1,115 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+ require 'rake/packagetask'
5
+ require 'rake/gempackagetask'
6
+ require 'rake/contrib/rubyforgepublisher'
7
+
8
+ require File.join(File.dirname(__FILE__), 'lib/rails_sql_views', 'version')
9
+
10
+ PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : ''
11
+ PKG_NAME = 'rails_sql_views'
12
+ PKG_VERSION = RailsSqlViews::VERSION::STRING + PKG_BUILD
13
+ PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
14
+ PKG_DESTINATION = ENV["PKG_DESTINATION"] || "../#{PKG_NAME}"
15
+
16
+ RELEASE_NAME = "REL #{PKG_VERSION}"
17
+
18
+ RUBY_FORGE_PROJECT = "activewarehouse"
19
+ RUBY_FORGE_USER = "aeden"
20
+
21
+ desc 'Default: run unit tests.'
22
+ task :default => :test
23
+
24
+ desc 'Test the library.'
25
+ Rake::TestTask.new(:test) do |t|
26
+ t.libs << 'lib'
27
+ t.pattern = 'test/**/*_test.rb'
28
+ t.verbose = true
29
+ end
30
+
31
+ desc 'Generate documentation library.'
32
+ Rake::RDocTask.new(:rdoc) do |rdoc|
33
+ rdoc.rdoc_dir = 'rdoc'
34
+ rdoc.title = 'Rails SQL Views'
35
+ rdoc.options << '--line-numbers' << '--inline-source'
36
+ rdoc.rdoc_files.include('README')
37
+ rdoc.rdoc_files.include('lib/**/*.rb')
38
+ end
39
+
40
+ PKG_FILES = FileList[
41
+ 'CHANGELOG',
42
+ 'README',
43
+ 'Rakefile',
44
+ 'bin/**/*',
45
+ 'lib/**/*',
46
+ ] - [ 'test' ]
47
+
48
+ spec = Gem::Specification.new do |s|
49
+ s.name = 'rails_sql_views'
50
+ s.version = PKG_VERSION
51
+ s.summary = "Adds SQL Views to Rails."
52
+ s.description = <<-EOF
53
+ Library which adds SQL Views to Rails.
54
+ EOF
55
+
56
+ s.add_dependency('activerecord', '>= 1.14.4')
57
+
58
+ s.rdoc_options << '--exclude' << '.'
59
+ s.has_rdoc = false
60
+
61
+ s.files = PKG_FILES.to_a.delete_if {|f| f.include?('.svn')}
62
+ s.require_path = 'lib'
63
+
64
+ s.author = "Anthony Eden"
65
+ s.email = "anthonyeden@gmail.com"
66
+ s.homepage = "http://activewarehouse.rubyforge.org/rails_sql_views"
67
+ s.rubyforge_project = "activewarehouse"
68
+ end
69
+
70
+ Rake::GemPackageTask.new(spec) do |pkg|
71
+ pkg.gem_spec = spec
72
+ pkg.need_tar = true
73
+ pkg.need_zip = true
74
+ end
75
+
76
+ desc "Generate code statistics"
77
+ task :lines do
78
+ lines, codelines, total_lines, total_codelines = 0, 0, 0, 0
79
+
80
+ for file_name in FileList["lib/**/*.rb"]
81
+ next if file_name =~ /vendor/
82
+ f = File.open(file_name)
83
+
84
+ while line = f.gets
85
+ lines += 1
86
+ next if line =~ /^\s*$/
87
+ next if line =~ /^\s*#/
88
+ codelines += 1
89
+ end
90
+ puts "L: #{sprintf("%4d", lines)}, LOC #{sprintf("%4d", codelines)} | #{file_name}"
91
+
92
+ total_lines += lines
93
+ total_codelines += codelines
94
+
95
+ lines, codelines = 0, 0
96
+ end
97
+
98
+ puts "Total: Lines #{total_lines}, LOC #{total_codelines}"
99
+ end
100
+
101
+ desc "Publish the release files to RubyForge."
102
+ task :release => [ :package ] do
103
+ `rubyforge login`
104
+
105
+ for ext in %w( gem tgz zip )
106
+ release_command = "rubyforge add_release activewarehouse #{PKG_NAME} 'REL #{PKG_VERSION}' pkg/#{PKG_NAME}-#{PKG_VERSION}.#{ext}"
107
+ puts release_command
108
+ system(release_command)
109
+ end
110
+ end
111
+
112
+ desc "Publish the API documentation"
113
+ task :pdoc => [:rdoc] do
114
+ Rake::SshDirPublisher.new("aeden@rubyforge.org", "/var/www/gforge-projects/activewarehouse/rails_sql_views/rdoc", "rdoc").upload
115
+ end
@@ -0,0 +1,29 @@
1
+ module RailsSqlViews
2
+ module ConnectionAdapters #:nodoc:
3
+ # Abstract definition of a View
4
+ class ViewDefinition
5
+ attr_accessor :columns, :select_query
6
+
7
+ def initialize(base, select_query)
8
+ @columns = []
9
+ @base = base
10
+ @select_query = select_query
11
+ end
12
+
13
+ def [](name)
14
+ @columns[name.to_s]
15
+ end
16
+
17
+ def column(name)
18
+ column = name.to_s
19
+ @columns << column unless @columns.include? column
20
+ self
21
+ end
22
+
23
+ def to_sql
24
+ @columns * ', '
25
+ end
26
+
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,38 @@
1
+ module RailsSqlViews
2
+ module ConnectionAdapters # :nodoc:
3
+ module SchemaStatements
4
+ # Create a view.
5
+ # The +options+ hash can include the following keys:
6
+ # [<tt>:check_option</tt>]
7
+ # Specify restrictions for inserts or updates in updatable views. ANSI SQL 92 defines two check option
8
+ # values: CASCADED and LOCAL. See your database documentation for allowed values.
9
+ def create_view(name, select_query, options={})
10
+ view_definition = ViewDefinition.new(self, select_query)
11
+
12
+ yield view_definition
13
+
14
+ if options[:force]
15
+ drop_view(name) rescue nil
16
+ end
17
+
18
+ create_sql = "CREATE VIEW "
19
+ create_sql << "#{name} ("
20
+ create_sql << view_definition.to_sql
21
+ create_sql << ") AS #{view_definition.select_query}"
22
+ create_sql << " WITH #{options[:check_option]} CHECK OPTION" if options[:check_option]
23
+ execute create_sql
24
+ end
25
+
26
+ # Drop a view.
27
+ # The +options+ hash can include the following keys:
28
+ # [<tt>:drop_behavior</tt>]
29
+ # Specify the drop behavior. ANSI SQL 92 defines two drop behaviors, CASCADE and RESTRICT. See your
30
+ # database documentation to determine what drop behaviors are available.
31
+ def drop_view(name, options={})
32
+ drop_sql = "DROP VIEW #{name}"
33
+ drop_sql << " #{options[:drop_behavior]}" if options[:drop_behavior]
34
+ execute drop_sql
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,15 @@
1
+ module ActiveRecord
2
+ module ConnectionAdapters
3
+ class AbstractAdapter
4
+ # Subclasses should override and return true if they support views.
5
+ def supports_views?
6
+ return false
7
+ end
8
+
9
+ # Get a list of all views for the current database
10
+ def views(name = nil) #:nodoc:
11
+ raise NotImplementedError, "views is an abstract method"
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,22 @@
1
+ module ActiveRecord
2
+ module ConnectionAdapters
3
+ class MysqlAdapter
4
+ # Returns true as this adapter supports views.
5
+ def supports_views?
6
+ true
7
+ end
8
+
9
+ def tables(name = nil) #:nodoc:
10
+ tables = []
11
+ execute("SHOW TABLE STATUS", name).each { |field| tables << field[0] if field[17] != 'VIEW' }
12
+ tables
13
+ end
14
+
15
+ def views(name = nil) #:nodoc:
16
+ views = []
17
+ execute("SHOW TABLE STATUS", name).each { |field| views << field[0] if field[17] == 'VIEW' }
18
+ views
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,62 @@
1
+ module ActiveRecord
2
+ class SchemaDumper
3
+
4
+ # A list of views which should not be dumped to the schema.
5
+ # Acceptable values are strings as well as regexp.
6
+ # This setting is only used if ActiveRecord::Base.schema_format == :ruby
7
+ cattr_accessor :ignore_views
8
+ @@ignore_views = []
9
+
10
+ # Add views to the end of the dump stream
11
+ def dump_with_views(stream)
12
+ dump_without_views(stream)
13
+ views(stream)
14
+ stream
15
+ end
16
+ alias_method_chain :dump, :views
17
+
18
+ # Add views to the stream
19
+ def views(stream)
20
+ @connection.views.sort.each do |v|
21
+ next if ["schema_info", ignore_views].flatten.any? do |ignored|
22
+ case ignored
23
+ when String: v == ignored
24
+ when Regexp: v =~ ignored
25
+ else
26
+ raise StandardError, 'ActiveRecord::SchemaDumper.ignore_views accepts an array of String and / or Regexp values.'
27
+ end
28
+ end
29
+ view(v, stream)
30
+ end
31
+ end
32
+
33
+ # Add the specified view to the stream
34
+ def view(view, stream)
35
+ columns = @connection.columns(view).collect { |c| c.name }
36
+ begin
37
+ v = StringIO.new
38
+
39
+ v.print " create_view #{view.inspect}"
40
+ v.print ", :force => true"
41
+ v.puts " do |v|"
42
+
43
+ columns.each do |column|
44
+ v.print " v.column :#{column}"
45
+ v.puts
46
+ end
47
+
48
+ v.puts " end"
49
+ v.puts
50
+
51
+ v.rewind
52
+ stream.print v.read
53
+ rescue => e
54
+ stream.puts "# Could not dump view #{view.inspect} because of following #{e.class}"
55
+ stream.puts "# #{e.message}"
56
+ stream.puts
57
+ end
58
+
59
+ stream
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,9 @@
1
+ module RailsSqlViews
2
+ module VERSION #:nodoc:
3
+ MAJOR = 0
4
+ MINOR = 1
5
+ TINY = 0
6
+
7
+ STRING = [MAJOR, MINOR, TINY].join('.')
8
+ end
9
+ end
@@ -0,0 +1,44 @@
1
+ #--
2
+ # Copyright (c) 2006 Anthony Eden
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+
24
+ $:.unshift(File.dirname(__FILE__)) unless
25
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
26
+
27
+ unless defined?(ActiveRecord)
28
+ begin
29
+ $:.unshift(File.dirname(__FILE__) + "/../../activerecord/lib")
30
+ require 'active_record'
31
+ rescue LoadError
32
+ require 'rubygems'
33
+ require_gem 'activerecord'
34
+ end
35
+ end
36
+
37
+ require 'rails_sql_views/connection_adapters/abstract/schema_definitions'
38
+ require 'rails_sql_views/connection_adapters/abstract/schema_statements'
39
+ require 'rails_sql_views/connection_adapters/mysql_adapter'
40
+ require 'rails_sql_views/schema_dumper'
41
+
42
+ class ActiveRecord::ConnectionAdapters::AbstractAdapter
43
+ include RailsSqlViews::ConnectionAdapters::SchemaStatements
44
+ end
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.0
3
+ specification_version: 1
4
+ name: rails_sql_views
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.1.0
7
+ date: 2006-12-27 00:00:00 -05:00
8
+ summary: Adds SQL Views to Rails.
9
+ require_paths:
10
+ - lib
11
+ email: anthonyeden@gmail.com
12
+ homepage: http://activewarehouse.rubyforge.org/rails_sql_views
13
+ rubyforge_project: activewarehouse
14
+ description: Library which adds SQL Views to Rails.
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: false
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Anthony Eden
31
+ files:
32
+ - CHANGELOG
33
+ - README
34
+ - Rakefile
35
+ - lib/rails_sql_views
36
+ - lib/rails_sql_views.rb
37
+ - lib/rails_sql_views/connection_adapters
38
+ - lib/rails_sql_views/schema_dumper.rb
39
+ - lib/rails_sql_views/version.rb
40
+ - lib/rails_sql_views/connection_adapters/abstract
41
+ - lib/rails_sql_views/connection_adapters/abstract_adapter.rb
42
+ - lib/rails_sql_views/connection_adapters/mysql_adapter.rb
43
+ - lib/rails_sql_views/connection_adapters/abstract/schema_definitions.rb
44
+ - lib/rails_sql_views/connection_adapters/abstract/schema_statements.rb
45
+ test_files: []
46
+
47
+ rdoc_options:
48
+ - --exclude
49
+ - .
50
+ extra_rdoc_files: []
51
+
52
+ executables: []
53
+
54
+ extensions: []
55
+
56
+ requirements: []
57
+
58
+ dependencies:
59
+ - !ruby/object:Gem::Dependency
60
+ name: activerecord
61
+ version_requirement:
62
+ version_requirements: !ruby/object:Gem::Version::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: 1.14.4
67
+ version: