mysql_view_support 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,55 @@
|
|
1
|
+
require_dependency 'active_record/connection_adapters/mysql_adapter'
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
class Base
|
5
|
+
class << self
|
6
|
+
def mysql_with_views_connection(config) # :nodoc:
|
7
|
+
ConnectionAdapters::MysqlWithViewsAdapter.new(config)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class ConnectionAdapters::MysqlWithViewsAdapter < DelegateClass(ActiveRecord::ConnectionAdapters::MysqlAdapter)
|
13
|
+
attr_reader :view_options
|
14
|
+
def initialize(config)
|
15
|
+
super ActiveRecord::Base.mysql_connection(config)
|
16
|
+
@view_options = (config.symbolize_keys[:view_options] || {}).symbolize_keys.freeze
|
17
|
+
end
|
18
|
+
|
19
|
+
def create_view(name, column_names = nil, options = {})
|
20
|
+
raise ArgumentError, "You must provide the SQL statement that defines the view." unless block_given?
|
21
|
+
select_statement = yield
|
22
|
+
command = ["CREATE"]
|
23
|
+
command << "OR REPLACE" if options[:force]
|
24
|
+
command << "VIEW #{quote_table_name(name)}"
|
25
|
+
command << "(" + [column_names].flatten.join(", ") + ")" if column_names
|
26
|
+
command << "AS #{select_statement}"
|
27
|
+
execute command.join(" ")
|
28
|
+
end
|
29
|
+
|
30
|
+
def update_view(name, column_names = nil, options = {}, &block)
|
31
|
+
create_view name, column_names, options.merge(:force => true), &block
|
32
|
+
end
|
33
|
+
|
34
|
+
def drop_view(name)
|
35
|
+
execute "DROP VIEW #{quote_table_name(name)}"
|
36
|
+
end
|
37
|
+
|
38
|
+
def views(name = nil) #:nodoc:
|
39
|
+
tables = []
|
40
|
+
result = execute("SHOW FULL TABLES", name)
|
41
|
+
result.each { |field| tables << field[0] if field[1] == 'VIEW' }
|
42
|
+
result.free
|
43
|
+
tables
|
44
|
+
end
|
45
|
+
|
46
|
+
def pk_and_sequence_for(table)
|
47
|
+
if table_key = super(table)
|
48
|
+
table_key
|
49
|
+
elsif views.include?( table.to_s ) and columns(table).any?{|col| col.name == 'id'}
|
50
|
+
view_key = ['id', nil]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
data/tasks/views.rake
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
unless defined? remove_task
|
2
|
+
Rake::TaskManager.class_eval do
|
3
|
+
def remove_task(task_name)
|
4
|
+
@tasks.delete(task_name.to_s)
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
def remove_task(task_name)
|
9
|
+
Rake.application.remove_task(task_name)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
alias drop_database_without_view_support drop_database
|
14
|
+
def drop_database(config)
|
15
|
+
drop_database_without_view_support(config.merge('adapter' => config['adapter'].gsub(/_with_views/, "")))
|
16
|
+
end
|
17
|
+
|
18
|
+
alias create_database_without_view_support create_database
|
19
|
+
def create_database(config)
|
20
|
+
create_database_without_view_support(config.merge('adapter' => config['adapter'].gsub(/_with_views/, "")))
|
21
|
+
end
|
22
|
+
|
23
|
+
namespace :db do
|
24
|
+
namespace :views do
|
25
|
+
desc "Run views migration from db/views"
|
26
|
+
task :update => :environment do
|
27
|
+
view_migration_classes = Dir.glob(File.join(Rails.root, "db", "views", "*.rb")).map{|view_migration|
|
28
|
+
if File.basename(view_migration) =~ /[0-9]+_([^.]+).rb/
|
29
|
+
require view_migration
|
30
|
+
view_migration_class = "create_#{$1}_migration".camelize.constantize
|
31
|
+
end
|
32
|
+
}
|
33
|
+
|
34
|
+
view_migration_classes.each{|mc|
|
35
|
+
mc.migrate(:up)
|
36
|
+
}
|
37
|
+
end
|
38
|
+
end
|
39
|
+
namespace :test do
|
40
|
+
original_purge_task = Rake::Task["db:test:purge"]
|
41
|
+
remove_task "db:test:purge"
|
42
|
+
|
43
|
+
desc "Empty the test database"
|
44
|
+
task :purge => :environment do
|
45
|
+
abcs = ActiveRecord::Base.configurations
|
46
|
+
if abcs["test"]["adapter"] == "mysql_with_views"
|
47
|
+
ActiveRecord::Base.establish_connection(:test)
|
48
|
+
ActiveRecord::Base.connection.recreate_database(abcs["test"]["database"], abcs["test"])
|
49
|
+
else
|
50
|
+
original_purge_task.invoke
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
# We need to invoke the db:views:update task IMIDIATELY after the db:migrate task.
|
58
|
+
# Failure to do so will cause broken schema dumps to happen.
|
59
|
+
Rake::Task["db:migrate"].actions.unshift lambda{Rake::Task["db:views:update"].invoke}
|
60
|
+
|
61
|
+
|
62
|
+
|
metadata
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mysql_view_support
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Tom Lea
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2010-01-08 00:00:00 +00:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description:
|
17
|
+
email: contrib@tomlea.co.uk
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files: []
|
23
|
+
|
24
|
+
files:
|
25
|
+
- tasks/views.rake
|
26
|
+
- generators/sql_view_migration/sql_view_migration_generator.rb
|
27
|
+
- generators/sql_view_migration/templates/migration.rb
|
28
|
+
- lib/active_record/connection_adapters/mysql_with_views_adapter.rb
|
29
|
+
has_rdoc: true
|
30
|
+
homepage: http://labs.reevoo.com
|
31
|
+
licenses: []
|
32
|
+
|
33
|
+
post_install_message:
|
34
|
+
rdoc_options: []
|
35
|
+
|
36
|
+
require_paths:
|
37
|
+
- lib
|
38
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: "0"
|
43
|
+
version:
|
44
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: "0"
|
49
|
+
version:
|
50
|
+
requirements: []
|
51
|
+
|
52
|
+
rubyforge_project:
|
53
|
+
rubygems_version: 1.3.5
|
54
|
+
signing_key:
|
55
|
+
specification_version: 3
|
56
|
+
summary: Provides view support to rails.
|
57
|
+
test_files: []
|
58
|
+
|