rails_sql_views 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/CHANGELOG +2 -0
- data/README +44 -0
- data/Rakefile +115 -0
- data/lib/rails_sql_views/connection_adapters/abstract/schema_definitions.rb +29 -0
- data/lib/rails_sql_views/connection_adapters/abstract/schema_statements.rb +38 -0
- data/lib/rails_sql_views/connection_adapters/abstract_adapter.rb +15 -0
- data/lib/rails_sql_views/connection_adapters/mysql_adapter.rb +22 -0
- data/lib/rails_sql_views/schema_dumper.rb +62 -0
- data/lib/rails_sql_views/version.rb +9 -0
- data/lib/rails_sql_views.rb +44 -0
- metadata +67 -0
data/CHANGELOG
ADDED
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,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:
|