merb_activerecord 0.4.2
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -0
- data/README +7 -0
- data/Rakefile +36 -0
- data/TODO +5 -0
- data/activerecord_generators/database_sessions_migration/USAGE +5 -0
- data/activerecord_generators/database_sessions_migration/database_sessions_migration_generator.rb +51 -0
- data/activerecord_generators/database_sessions_migration/templates/sessions_migration.erb +15 -0
- data/activerecord_generators/migration/USAGE +5 -0
- data/activerecord_generators/migration/migration_generator.rb +14 -0
- data/activerecord_generators/migration/templates/new_migration.erb +15 -0
- data/activerecord_generators/model/USAGE +4 -0
- data/activerecord_generators/model/model_generator.rb +16 -0
- data/activerecord_generators/model/templates/new_model.erb +2 -0
- data/activerecord_generators/resource_controller/USAGE +0 -0
- data/activerecord_generators/resource_controller/resource_controller_generator.rb +26 -0
- data/activerecord_generators/resource_controller/templates/controller.rb +54 -0
- data/activerecord_generators/resource_controller/templates/edit.html.erb +1 -0
- data/activerecord_generators/resource_controller/templates/helper.rb +5 -0
- data/activerecord_generators/resource_controller/templates/index.html.erb +1 -0
- data/activerecord_generators/resource_controller/templates/new.html.erb +1 -0
- data/activerecord_generators/resource_controller/templates/show.html.erb +1 -0
- data/lib/merb/orms/active_record/connection.rb +56 -0
- data/lib/merb/orms/active_record/database.sample.yml +17 -0
- data/lib/merb/orms/active_record/tasks/databases.rb +285 -0
- data/lib/merb/session/active_record_session.rb +128 -0
- data/lib/merb_activerecord.rb +11 -0
- data/specs/merb_active_record_spec.rb +7 -0
- data/specs/spec_helper.rb +2 -0
- metadata +96 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2007 YOUR NAME
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
merb_active_record
|
2
|
+
=================
|
3
|
+
|
4
|
+
A plugin for the Merb framework that provides active record access
|
5
|
+
|
6
|
+
After you install the plugin, you have access to the ar_migration generator in your merb projects
|
7
|
+
example: /merb/root/script/generate ar_migration new_migration
|
data/Rakefile
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake/gempackagetask'
|
3
|
+
|
4
|
+
PLUGIN = "merb_activerecord"
|
5
|
+
NAME = "merb_activerecord"
|
6
|
+
VERSION = "0.4.2"
|
7
|
+
AUTHOR = "Duane Johnson"
|
8
|
+
EMAIL = "canadaduane@gmail.com"
|
9
|
+
HOMEPAGE = "http://merbivore.com"
|
10
|
+
SUMMARY = "Merb plugin that provides ActiveRecord support for Merb"
|
11
|
+
|
12
|
+
spec = Gem::Specification.new do |s|
|
13
|
+
s.name = NAME
|
14
|
+
s.version = VERSION
|
15
|
+
s.platform = Gem::Platform::RUBY
|
16
|
+
s.has_rdoc = true
|
17
|
+
s.extra_rdoc_files = ["README", "LICENSE", 'TODO']
|
18
|
+
s.summary = SUMMARY
|
19
|
+
s.description = s.summary
|
20
|
+
s.author = AUTHOR
|
21
|
+
s.email = EMAIL
|
22
|
+
s.homepage = HOMEPAGE
|
23
|
+
s.add_dependency('merb', '>= 0.4.0')
|
24
|
+
s.require_path = 'lib'
|
25
|
+
s.autorequire = PLUGIN
|
26
|
+
s.files = %w(LICENSE README Rakefile TODO) + Dir.glob("{lib,specs,activerecord_generators}/**/*")
|
27
|
+
end
|
28
|
+
|
29
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
30
|
+
pkg.gem_spec = spec
|
31
|
+
end
|
32
|
+
|
33
|
+
task :install do
|
34
|
+
sh %{rake package}
|
35
|
+
sh %{sudo gem install pkg/#{NAME}-#{VERSION}}
|
36
|
+
end
|
data/TODO
ADDED
data/activerecord_generators/database_sessions_migration/database_sessions_migration_generator.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'merb'
|
2
|
+
class DatabaseSessionsMigrationGenerator < RubiGen::Base
|
3
|
+
|
4
|
+
default_options :author => nil
|
5
|
+
|
6
|
+
def initialize(runtime_args, runtime_options = {})
|
7
|
+
super
|
8
|
+
@name = 'database_sessions'
|
9
|
+
end
|
10
|
+
|
11
|
+
def manifest
|
12
|
+
record do |m|
|
13
|
+
# Ensure appropriate folder(s) exists
|
14
|
+
m.directory 'schema/migrations'
|
15
|
+
|
16
|
+
# Create stubs
|
17
|
+
highest_migration = Dir[Dir.pwd+'/schema/migrations/*'].map{|f| File.basename(f) =~ /^(\d+)/; $1}.max
|
18
|
+
filename = format("%03d_%s", (highest_migration.to_i+1), @name.snake_case)
|
19
|
+
m.template "sessions_migration.erb", "schema/migrations/#{filename}.rb"
|
20
|
+
puts banner
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
protected
|
26
|
+
def banner
|
27
|
+
<<-EOS
|
28
|
+
A migration to add sessions to your database has been created.
|
29
|
+
Run 'rake db:migrate' to add the sessions migration to your database.
|
30
|
+
|
31
|
+
EOS
|
32
|
+
end
|
33
|
+
|
34
|
+
def add_options!(opts)
|
35
|
+
# opts.separator ''
|
36
|
+
# opts.separator 'Options:'
|
37
|
+
# For each option below, place the default
|
38
|
+
# at the top of the file next to "default_options"
|
39
|
+
# opts.on("-a", "--author=\"Your Name\"", String,
|
40
|
+
# "Some comment about this option",
|
41
|
+
# "Default: none") { |options[:author]| }
|
42
|
+
# opts.on("-v", "--version", "Show the #{File.basename($0)} version number and quit.")
|
43
|
+
end
|
44
|
+
|
45
|
+
def extract_options
|
46
|
+
# for each option, extract it into a local variable (and create an "attr_reader :author" at the top)
|
47
|
+
# Templates can access these value via the attr_reader-generated methods, but not the
|
48
|
+
# raw instance variable value.
|
49
|
+
# @author = options[:author]
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'merb/generators/merb_generator_helpers'
|
2
|
+
|
3
|
+
class MigrationGenerator < Merb::GeneratorHelpers::MigrationGeneratorBase
|
4
|
+
|
5
|
+
def initialize( *args )
|
6
|
+
super( *args )
|
7
|
+
@migration_template_name = "new_migration.erb"
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.superclass
|
11
|
+
RubiGen::Base
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class <%= class_name.snake_case.camel_case %> < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
<%= "create_table :#{table_name} do |t|" if table_name %>
|
4
|
+
<% for attribute in table_attributes -%>
|
5
|
+
t.column :<%= attribute.name %>, :<%= attribute.type %>
|
6
|
+
<% end -%>
|
7
|
+
<%= "end" if table_name %>
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.down
|
11
|
+
<% if table_name -%>
|
12
|
+
drop_table :<%= table_name %>
|
13
|
+
<% end -%>
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'merb/generators/merb_generator_helpers'
|
2
|
+
|
3
|
+
class ModelGenerator < Merb::GeneratorHelpers::ModelGeneratorBase
|
4
|
+
|
5
|
+
def initialize( *args )
|
6
|
+
super( *args )
|
7
|
+
@model_template_name = "new_model.erb"
|
8
|
+
@migration_generator_name = "migration"
|
9
|
+
@model_test_generator_name = "merb_model_test"
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.superclass
|
13
|
+
RubiGen::Base
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
File without changes
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'merb/generators/merb_generator_helpers'
|
2
|
+
|
3
|
+
class ResourceControllerGenerator < Merb::GeneratorHelpers::ControllerGeneratorBase
|
4
|
+
|
5
|
+
def initialize(*args)
|
6
|
+
runtime_options = args.last.is_a?(Hash) ? args.pop : {}
|
7
|
+
name, *actions = args.flatten
|
8
|
+
runtime_options[:actions] = %w[index show new edit]
|
9
|
+
runtime_options[:test_stub_generator] = "merb_controller_test"
|
10
|
+
super( [name], runtime_options )
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.superclass
|
14
|
+
RubiGen::Base
|
15
|
+
end
|
16
|
+
|
17
|
+
protected
|
18
|
+
def banner
|
19
|
+
<<-EOS
|
20
|
+
Creates a Merb controller, views and specs using Active Record Models
|
21
|
+
|
22
|
+
USAGE: #{$0} #{spec.name} resource_name"
|
23
|
+
EOS
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
<% klass = class_name.singularize -%>
|
2
|
+
<% ivar = class_name.snake_case.singularize -%>
|
3
|
+
class <%= class_name %> < Application
|
4
|
+
provides :xml, :js, :yaml
|
5
|
+
|
6
|
+
def index
|
7
|
+
@<%= ivar %>s = <%= klass %>.find(:all)
|
8
|
+
render @<%= ivar %>s
|
9
|
+
end
|
10
|
+
|
11
|
+
def show
|
12
|
+
@<%= ivar %> = <%= klass %>.find(params[:id])
|
13
|
+
render @<%= ivar %>
|
14
|
+
end
|
15
|
+
|
16
|
+
def new
|
17
|
+
only_provides :html
|
18
|
+
@<%= ivar %> = <%= klass %>.new(params[:<%= ivar %>])
|
19
|
+
render
|
20
|
+
end
|
21
|
+
|
22
|
+
def create
|
23
|
+
@<%= ivar %> = <%= klass %>.new(params[:<%= ivar %>])
|
24
|
+
if @<%= ivar %>.save
|
25
|
+
redirect url(:<%= ivar %>, @<%= ivar %>)
|
26
|
+
else
|
27
|
+
render :action => :new
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def edit
|
32
|
+
only_provides :html
|
33
|
+
@<%= ivar %> = <%= klass %>.find(params[:id])
|
34
|
+
render
|
35
|
+
end
|
36
|
+
|
37
|
+
def update
|
38
|
+
@<%= ivar %> = <%= klass %>.find(params[:id])
|
39
|
+
if @<%= ivar %>.update_attributes(params[:<%= ivar %>])
|
40
|
+
redirect url(:<%= ivar %>, @<%= ivar %>)
|
41
|
+
else
|
42
|
+
raise BadRequest
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def destroy
|
47
|
+
@<%= ivar %> = <%= klass %>.find(params[:id])
|
48
|
+
if @<%= ivar %>.destroy
|
49
|
+
redirect url(:<%= ivar %>s)
|
50
|
+
else
|
51
|
+
raise BadRequest
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
Edit for <%= class_name %>
|
@@ -0,0 +1 @@
|
|
1
|
+
Index for <%= class_name %>
|
@@ -0,0 +1 @@
|
|
1
|
+
New for <%= class_name %>
|
@@ -0,0 +1 @@
|
|
1
|
+
Show for <%= class_name %>
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'active_record'
|
3
|
+
|
4
|
+
module Merb
|
5
|
+
module Orms
|
6
|
+
module ActiveRecord
|
7
|
+
class << self
|
8
|
+
def config_file() MERB_ROOT / "config" / "database.yml" end
|
9
|
+
def sample_dest() MERB_ROOT / "config" / "database.sample.yml" end
|
10
|
+
def sample_source() File.dirname(__FILE__) / "database.sample.yml" end
|
11
|
+
|
12
|
+
def copy_sample_config
|
13
|
+
FileUtils.cp sample_source, sample_dest unless File.exists?(sample_dest)
|
14
|
+
end
|
15
|
+
|
16
|
+
def config
|
17
|
+
@config ||=
|
18
|
+
begin
|
19
|
+
# Convert string keys to symbols
|
20
|
+
full_config = Erubis.load_yaml_file(config_file)
|
21
|
+
config = (Merb::Plugins.config[:merb_active_record] = {})
|
22
|
+
(full_config[MERB_ENV.to_sym] || full_config[MERB_ENV]).each { |k, v| config[k.to_sym] = v }
|
23
|
+
::ActiveRecord::Base.configurations= full_config
|
24
|
+
config
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Database connects as soon as the gem is loaded
|
29
|
+
def connect
|
30
|
+
if File.exists?(config_file)
|
31
|
+
puts "Connecting to database..."
|
32
|
+
|
33
|
+
Thread.new{ loop{ sleep(60*60); ::ActiveRecord::Base.verify_active_connections! } }.priority = -10
|
34
|
+
|
35
|
+
::ActiveRecord::Base.verification_timeout = 14400
|
36
|
+
::ActiveRecord::Base.logger = MERB_LOGGER
|
37
|
+
::ActiveRecord::Base.establish_connection config
|
38
|
+
else
|
39
|
+
copy_sample_config
|
40
|
+
puts "No database.yml file found in #{MERB_ROOT}/config."
|
41
|
+
puts "A sample file was created called database.sample.yml for you to copy and edit."
|
42
|
+
exit(1)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Registering this ORM lets the user choose active_record as a session
|
47
|
+
# in merb.yml's session_store: option.
|
48
|
+
def register_session_type
|
49
|
+
Merb::Server.register_session_type("active_record",
|
50
|
+
"merb/session/active_record_session",
|
51
|
+
"Using ActiveRecord database sessions")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
---
|
2
|
+
# This is a sample database file for the ActiveRecord ORM
|
3
|
+
:development: &defaults
|
4
|
+
:adapter: mysql
|
5
|
+
:database: sample_development
|
6
|
+
:username: the_user
|
7
|
+
:password: secrets
|
8
|
+
:host: localhost
|
9
|
+
:socket: /tmp/mysql.sock
|
10
|
+
|
11
|
+
:test:
|
12
|
+
<<: *defaults
|
13
|
+
:database: sample_test
|
14
|
+
|
15
|
+
:production:
|
16
|
+
<<: *defaults
|
17
|
+
:database: sample_production
|
@@ -0,0 +1,285 @@
|
|
1
|
+
task :environment do
|
2
|
+
MERB_ENV = ( ENV['MERB_ENV'] || MERB_ENV ).to_sym
|
3
|
+
end
|
4
|
+
|
5
|
+
namespace :db do
|
6
|
+
namespace :create do
|
7
|
+
desc 'Create all the local databases defined in config/database.yml'
|
8
|
+
task :all => :environment do
|
9
|
+
ActiveRecord::Base.configurations.each_value do |config|
|
10
|
+
create_local_database(config)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
desc 'Create the local database defined in config/database.yml for the current MERB_ENV'
|
16
|
+
task :create => :environment do
|
17
|
+
create_local_database(ActiveRecord::Base.configurations[MERB_ENV])
|
18
|
+
end
|
19
|
+
|
20
|
+
def create_local_database(config)
|
21
|
+
# Only connect to local databases
|
22
|
+
if config[:host] == 'localhost' || config[:host].blank?
|
23
|
+
begin
|
24
|
+
ActiveRecord::Base.establish_connection(config)
|
25
|
+
ActiveRecord::Base.connection
|
26
|
+
rescue
|
27
|
+
case config[:adapter]
|
28
|
+
when 'mysql'
|
29
|
+
#~ @charset = ENV['CHARSET'] || 'utf8'
|
30
|
+
#~ @collation = ENV['COLLATION'] || 'utf8_general_ci'
|
31
|
+
begin
|
32
|
+
ActiveRecord::Base.establish_connection(config.merge({:database => nil}))
|
33
|
+
ActiveRecord::Base.connection.create_database(config[:database]) #, {:charset => @charset, :collation => @collation})
|
34
|
+
ActiveRecord::Base.establish_connection(config)
|
35
|
+
p "MySQL #{config[:database]} database succesfully created"
|
36
|
+
rescue
|
37
|
+
$stderr.puts "Couldn't create database for #{config.inspect}"
|
38
|
+
end
|
39
|
+
when 'postgresql'
|
40
|
+
`createdb "#{config[:database]}" -E utf8`
|
41
|
+
when 'sqlite'
|
42
|
+
`sqlite "#{config[:database]}"`
|
43
|
+
when 'sqlite3'
|
44
|
+
`sqlite3 "#{config[:database]}"`
|
45
|
+
end
|
46
|
+
else
|
47
|
+
p "#{config[:database]} already exists"
|
48
|
+
end
|
49
|
+
else
|
50
|
+
p "This task only creates local databases. #{config[:database]} is on a remote host."
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
desc 'Drops the database for the current environment'
|
55
|
+
task :drop => :environment do
|
56
|
+
config = ActiveRecord::Base.configurations[MERB_ENV || :development]
|
57
|
+
p config
|
58
|
+
case config[:adapter]
|
59
|
+
when 'mysql'
|
60
|
+
ActiveRecord::Base.connection.drop_database config[:database]
|
61
|
+
when /^sqlite/
|
62
|
+
FileUtils.rm_f File.join(MERB_ROOT, config[:database])
|
63
|
+
when 'postgresql'
|
64
|
+
`dropdb "#{config[:database]}"`
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
desc "Migrate the database through scripts in schema/migrations. Target specific version with VERSION=x"
|
69
|
+
task :migrate => :environment do
|
70
|
+
ActiveRecord::Migrator.migrate("schema/migrations/", ENV["VERSION"] ? ENV["VERSION"].to_i : nil)
|
71
|
+
Rake::Task["db:schema:dump"].invoke if ActiveRecord::Base.schema_format == :ruby
|
72
|
+
end
|
73
|
+
|
74
|
+
desc 'Drops, creates and then migrates the database for the current environment. Target specific version with VERSION=x'
|
75
|
+
task :reset => ['db:drop', 'db:create', 'db:migrate']
|
76
|
+
|
77
|
+
# desc "Retrieves the charset for the current environment's database"
|
78
|
+
# task :charset => :environment do
|
79
|
+
# config = ActiveRecord::Base.configurations[MERB_ENV || :development]
|
80
|
+
# case config[:adapter]
|
81
|
+
# when 'mysql'
|
82
|
+
# ActiveRecord::Base.establish_connection(config)
|
83
|
+
# puts ActiveRecord::Base.connection.charset
|
84
|
+
# else
|
85
|
+
# puts 'sorry, your database adapter is not supported yet, feel free to submit a patch'
|
86
|
+
# end
|
87
|
+
# end
|
88
|
+
|
89
|
+
# desc "Retrieves the collation for the current environment's database"
|
90
|
+
# task :collation => :environment do
|
91
|
+
# config = ActiveRecord::Base.configurations[MERB_ENV || :development]
|
92
|
+
# case config[:adapter]
|
93
|
+
# when 'mysql'
|
94
|
+
# ActiveRecord::Base.establish_connection(config)
|
95
|
+
# puts ActiveRecord::Base.connection.collation
|
96
|
+
# else
|
97
|
+
# puts 'sorry, your database adapter is not supported yet, feel free to submit a patch'
|
98
|
+
# end
|
99
|
+
# end
|
100
|
+
|
101
|
+
desc "Retrieves the current schema version number"
|
102
|
+
task :version => :environment do
|
103
|
+
puts "Current version: #{ActiveRecord::Migrator.current_version}"
|
104
|
+
end
|
105
|
+
|
106
|
+
namespace :fixtures do
|
107
|
+
desc "Load fixtures into the current environment's database. Load specific fixtures using FIXTURES=x,y"
|
108
|
+
task :load => :environment do
|
109
|
+
require 'active_record/fixtures'
|
110
|
+
ActiveRecord::Base.establish_connection(MERB_ENV.to_sym)
|
111
|
+
(ENV['FIXTURES'] ? ENV['FIXTURES'].split(/,/) : Dir.glob(File.join(MERB_ROOT, 'test', 'fixtures', '*.{yml,csv}'))).each do |fixture_file|
|
112
|
+
Fixtures.create_fixtures('test/fixtures', File.basename(fixture_file, '.*'))
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
namespace :schema do
|
118
|
+
desc "Create a schema/schema.rb file that can be portably used against any DB supported by AR"
|
119
|
+
task :dump => :environment do
|
120
|
+
require 'active_record/schema_dumper'
|
121
|
+
File.open(ENV['SCHEMA'] || "schema/schema.rb", "w") do |file|
|
122
|
+
ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
desc "Load a schema.rb file into the database"
|
127
|
+
task :load => :environment do
|
128
|
+
file = ENV['SCHEMA'] || "schema/schema.rb"
|
129
|
+
load(file)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
namespace :structure do
|
134
|
+
desc "Dump the database structure to a SQL file"
|
135
|
+
task :dump => :environment do
|
136
|
+
abcs = ActiveRecord::Base.configurations
|
137
|
+
case abcs[MERB_ENV][:adapter]
|
138
|
+
when "mysql", "oci", "oracle"
|
139
|
+
ActiveRecord::Base.establish_connection(abcs[MERB_ENV])
|
140
|
+
File.open("schema/#{MERB_ENV}_structure.sql", "w+") { |f| f << ActiveRecord::Base.connection.structure_dump }
|
141
|
+
when "postgresql"
|
142
|
+
ENV['PGHOST'] = abcs[MERB_ENV]["host"] if abcs[MERB_ENV]["host"]
|
143
|
+
ENV['PGPORT'] = abcs[MERB_ENV]["port"].to_s if abcs[MERB_ENV]["port"]
|
144
|
+
ENV['PGPASSWORD'] = abcs[MERB_ENV]["password"].to_s if abcs[MERB_ENV]["password"]
|
145
|
+
search_path = abcs[MERB_ENV]["schema_search_path"]
|
146
|
+
search_path = "--schema=#{search_path}" if search_path
|
147
|
+
`pg_dump -i -U "#{abcs[MERB_ENV]["username"]}" -s -x -O -f schema/#{MERB_ENV}_structure.sql #{search_path} #{abcs[MERB_ENV]["database"]}`
|
148
|
+
raise "Error dumping database" if $?.exitstatus == 1
|
149
|
+
when "sqlite", "sqlite3"
|
150
|
+
dbfile = abcs[MERB_ENV]["database"] || abcs[MERB_ENV]["dbfile"]
|
151
|
+
`#{abcs[MERB_ENV]["adapter"]} #{dbfile} .schema > schema/#{MERB_ENV}_structure.sql`
|
152
|
+
when "sqlserver"
|
153
|
+
`scptxfr /s #{abcs[MERB_ENV]["host"]} /d #{abcs[MERB_ENV]["database"]} /I /f db\\#{MERB_ENV}_structure.sql /q /A /r`
|
154
|
+
`scptxfr /s #{abcs[MERB_ENV]["host"]} /d #{abcs[MERB_ENV]["database"]} /I /F db\ /q /A /r`
|
155
|
+
when "firebird"
|
156
|
+
set_firebird_env(abcs[MERB_ENV])
|
157
|
+
db_string = firebird_db_string(abcs[MERB_ENV])
|
158
|
+
sh "isql -a #{db_string} > schema/#{MERB_ENV}_structure.sql"
|
159
|
+
else
|
160
|
+
raise "Task not supported by '#{abcs[MERB_ENV][:adapter]}'"
|
161
|
+
end
|
162
|
+
|
163
|
+
if ActiveRecord::Base.connection.supports_migrations?
|
164
|
+
File.open("schema/#{MERB_ENV}_structure.sql", "a") { |f| f << ActiveRecord::Base.connection.dump_schema_information }
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
namespace :test do
|
170
|
+
desc "Recreate the test database from the current environment's database schema"
|
171
|
+
task :clone => %w(db:schema:dump db:test:purge) do
|
172
|
+
ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations['test'])
|
173
|
+
ActiveRecord::Schema.verbose = false
|
174
|
+
Rake::Task["db:schema:load"].invoke
|
175
|
+
end
|
176
|
+
|
177
|
+
|
178
|
+
desc "Recreate the test databases from the development structure"
|
179
|
+
task :clone_structure => [ "db:structure:dump", "db:test:purge" ] do
|
180
|
+
abcs = ActiveRecord::Base.configurations
|
181
|
+
case abcs["test"]["adapter"]
|
182
|
+
when "mysql"
|
183
|
+
ActiveRecord::Base.establish_connection(:test)
|
184
|
+
ActiveRecord::Base.connection.execute('SET foreign_key_checks = 0')
|
185
|
+
IO.readlines("schema/#{MERB_ENV}_structure.sql").join.split("\n\n").each do |table|
|
186
|
+
ActiveRecord::Base.connection.execute(table)
|
187
|
+
end
|
188
|
+
when "postgresql"
|
189
|
+
ENV['PGHOST'] = abcs["test"]["host"] if abcs["test"]["host"]
|
190
|
+
ENV['PGPORT'] = abcs["test"]["port"].to_s if abcs["test"]["port"]
|
191
|
+
ENV['PGPASSWORD'] = abcs["test"]["password"].to_s if abcs["test"]["password"]
|
192
|
+
`psql -U "#{abcs["test"]["username"]}" -f schema/#{MERB_ENV}_structure.sql #{abcs["test"]["database"]}`
|
193
|
+
when "sqlite", "sqlite3"
|
194
|
+
dbfile = abcs["test"]["database"] || abcs["test"]["dbfile"]
|
195
|
+
`#{abcs["test"]["adapter"]} #{dbfile} < schema/#{MERB_ENV}_structure.sql`
|
196
|
+
when "sqlserver"
|
197
|
+
`osql -E -S #{abcs["test"]["host"]} -d #{abcs["test"]["database"]} -i db\\#{MERB_ENV}_structure.sql`
|
198
|
+
when "oci", "oracle"
|
199
|
+
ActiveRecord::Base.establish_connection(:test)
|
200
|
+
IO.readlines("schema/#{MERB_ENV}_structure.sql").join.split(";\n\n").each do |ddl|
|
201
|
+
ActiveRecord::Base.connection.execute(ddl)
|
202
|
+
end
|
203
|
+
when "firebird"
|
204
|
+
set_firebird_env(abcs["test"])
|
205
|
+
db_string = firebird_db_string(abcs["test"])
|
206
|
+
sh "isql -i schema/#{MERB_ENV}_structure.sql #{db_string}"
|
207
|
+
else
|
208
|
+
raise "Task not supported by '#{abcs["test"]["adapter"]}'"
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
desc "Empty the test database"
|
213
|
+
task :purge => :environment do
|
214
|
+
abcs = ActiveRecord::Base.configurations
|
215
|
+
case abcs["test"]["adapter"]
|
216
|
+
when "mysql"
|
217
|
+
ActiveRecord::Base.establish_connection(:test)
|
218
|
+
ActiveRecord::Base.connection.recreate_database(abcs["test"]["database"])
|
219
|
+
when "postgresql"
|
220
|
+
ENV['PGHOST'] = abcs["test"]["host"] if abcs["test"]["host"]
|
221
|
+
ENV['PGPORT'] = abcs["test"]["port"].to_s if abcs["test"]["port"]
|
222
|
+
ENV['PGPASSWORD'] = abcs["test"]["password"].to_s if abcs["test"]["password"]
|
223
|
+
enc_option = "-E #{abcs["test"]["encoding"]}" if abcs["test"]["encoding"]
|
224
|
+
|
225
|
+
ActiveRecord::Base.clear_active_connections!
|
226
|
+
`dropdb -U "#{abcs["test"]["username"]}" #{abcs["test"]["database"]}`
|
227
|
+
`createdb #{enc_option} -U "#{abcs["test"]["username"]}" #{abcs["test"]["database"]}`
|
228
|
+
when "sqlite","sqlite3"
|
229
|
+
dbfile = abcs["test"]["database"] || abcs["test"]["dbfile"]
|
230
|
+
File.delete(dbfile) if File.exist?(dbfile)
|
231
|
+
when "sqlserver"
|
232
|
+
dropfkscript = "#{abcs["test"]["host"]}.#{abcs["test"]["database"]}.DP1".gsub(/\\/,'-')
|
233
|
+
`osql -E -S #{abcs["test"]["host"]} -d #{abcs["test"]["database"]} -i db\\#{dropfkscript}`
|
234
|
+
`osql -E -S #{abcs["test"]["host"]} -d #{abcs["test"]["database"]} -i db\\#{MERB_ENV}_structure.sql`
|
235
|
+
when "oci", "oracle"
|
236
|
+
ActiveRecord::Base.establish_connection(:test)
|
237
|
+
ActiveRecord::Base.connection.structure_drop.split(";\n\n").each do |ddl|
|
238
|
+
ActiveRecord::Base.connection.execute(ddl)
|
239
|
+
end
|
240
|
+
when "firebird"
|
241
|
+
ActiveRecord::Base.establish_connection(:test)
|
242
|
+
ActiveRecord::Base.connection.recreate_database!
|
243
|
+
else
|
244
|
+
raise "Task not supported by '#{abcs["test"]["adapter"]}'"
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
desc 'Prepare the test database and load the schema'
|
249
|
+
task :prepare => :environment do
|
250
|
+
if defined?(ActiveRecord::Base) && !ActiveRecord::Base.configurations.blank?
|
251
|
+
Rake::Task[{ :sql => "db:test:clone_structure", :ruby => "db:test:clone" }[ActiveRecord::Base.schema_format]].invoke
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
namespace :sessions do
|
257
|
+
# desc "Creates a sessions migration for use with CGI::Session::ActiveRecordStore"
|
258
|
+
# task :create => :environment do
|
259
|
+
# raise "Task unavailable to this database (no migration support)" unless ActiveRecord::Base.connection.supports_migrations?
|
260
|
+
# require 'rails_generator'
|
261
|
+
# require 'rails_generator/scripts/generate'
|
262
|
+
# Rails::Generator::Scripts::Generate.new.run(["session_migration", ENV["MIGRATION"] || "AddSessions"])
|
263
|
+
# end
|
264
|
+
|
265
|
+
desc "Clear the sessions table"
|
266
|
+
task :clear => :environment do
|
267
|
+
session_table = 'session'
|
268
|
+
session_table = Inflector.pluralize(session_table) if ActiveRecord::Base.pluralize_table_names
|
269
|
+
ActiveRecord::Base.connection.execute "DELETE FROM #{session_table}"
|
270
|
+
end
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
def session_table_name
|
275
|
+
ActiveRecord::Base.pluralize_table_names ? :sessions : :session
|
276
|
+
end
|
277
|
+
|
278
|
+
def set_firebird_env(config)
|
279
|
+
ENV["ISC_USER"] = config["username"].to_s if config["username"]
|
280
|
+
ENV["ISC_PASSWORD"] = config["password"].to_s if config["password"]
|
281
|
+
end
|
282
|
+
|
283
|
+
def firebird_db_string(config)
|
284
|
+
FireRuby::Database.db_string_for(config.symbolize_keys)
|
285
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
|
3
|
+
module Merb
|
4
|
+
module SessionMixin
|
5
|
+
def setup_session
|
6
|
+
MERB_LOGGER.info("Setting up session")
|
7
|
+
before = cookies[_session_id_key]
|
8
|
+
@_session, cookies[_session_id_key] = Merb::ActiveRecordSession.persist(cookies[_session_id_key])
|
9
|
+
@_fingerprint = Marshal.dump(@_session.data).hash
|
10
|
+
@_new_cookie = cookies[_session_id_key] != before
|
11
|
+
end
|
12
|
+
|
13
|
+
def finalize_session
|
14
|
+
MERB_LOGGER.info("Finalize session")
|
15
|
+
@_session.save if @_fingerprint != Marshal.dump(@_session.data).hash
|
16
|
+
set_cookie(_session_id_key, @_session.session_id, _session_expiry) if (@_new_cookie || @_session.needs_new_cookie)
|
17
|
+
end
|
18
|
+
end # ActiveRecordMixin
|
19
|
+
|
20
|
+
class ActiveRecordSession < ::ActiveRecord::Base
|
21
|
+
set_table_name 'sessions'
|
22
|
+
# Customizable data column name. Defaults to 'data'.
|
23
|
+
cattr_accessor :data_column_name
|
24
|
+
self.data_column_name = 'data'
|
25
|
+
before_save :marshal_data!
|
26
|
+
before_save :raise_on_session_data_overflow!
|
27
|
+
attr_accessor :needs_new_cookie
|
28
|
+
|
29
|
+
class << self
|
30
|
+
# Generates a new session ID and creates a row for the new session in the database.
|
31
|
+
def generate
|
32
|
+
create(:session_id => Merb::SessionMixin::rand_uuid, :data => {})
|
33
|
+
end
|
34
|
+
|
35
|
+
# Gets the existing session based on the <tt>session_id</tt> available in cookies.
|
36
|
+
# If none is found, generates a new session.
|
37
|
+
def persist(session_id)
|
38
|
+
if session_id
|
39
|
+
session = find_by_session_id(session_id)
|
40
|
+
end
|
41
|
+
unless session
|
42
|
+
session = generate
|
43
|
+
end
|
44
|
+
[session, session.session_id]
|
45
|
+
end
|
46
|
+
|
47
|
+
# Don't try to reload ARStore::Session in dev mode.
|
48
|
+
def reloadable? #:nodoc:
|
49
|
+
false
|
50
|
+
end
|
51
|
+
|
52
|
+
def data_column_size_limit
|
53
|
+
@data_column_size_limit ||= columns_hash[@@data_column_name].limit
|
54
|
+
end
|
55
|
+
|
56
|
+
def marshal(data) Base64.encode64(Marshal.dump(data)) if data end
|
57
|
+
def unmarshal(data) Marshal.load(Base64.decode64(data)) if data end
|
58
|
+
|
59
|
+
def create_table!
|
60
|
+
connection.execute <<-end_sql
|
61
|
+
CREATE TABLE #{table_name} (
|
62
|
+
id INTEGER PRIMARY KEY,
|
63
|
+
#{connection.quote_column_name('session_id')} TEXT UNIQUE,
|
64
|
+
#{connection.quote_column_name(@@data_column_name)} TEXT(255)
|
65
|
+
)
|
66
|
+
end_sql
|
67
|
+
end
|
68
|
+
|
69
|
+
def drop_table!
|
70
|
+
connection.execute "DROP TABLE #{table_name}"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# Regenerate the Session ID
|
75
|
+
def regenerate
|
76
|
+
update_attributes(:session_id => Merb::SessionMixin::rand_uuid)
|
77
|
+
self.needs_new_cookie = true
|
78
|
+
end
|
79
|
+
|
80
|
+
# Recreates the cookie with the default expiration time
|
81
|
+
# Useful during log in for pushing back the expiration date
|
82
|
+
def refresh_expiration
|
83
|
+
self.needs_new_cookie = true
|
84
|
+
end
|
85
|
+
|
86
|
+
# Lazy-delete of session data
|
87
|
+
def delete
|
88
|
+
self.data = {}
|
89
|
+
end
|
90
|
+
|
91
|
+
def [](key)
|
92
|
+
data[key]
|
93
|
+
end
|
94
|
+
|
95
|
+
def []=(key, val)
|
96
|
+
data[key] = val
|
97
|
+
end
|
98
|
+
|
99
|
+
# Lazy-unmarshal session state.
|
100
|
+
def data
|
101
|
+
@data ||= self.class.unmarshal(read_attribute(@@data_column_name)) || {}
|
102
|
+
end
|
103
|
+
|
104
|
+
# Has the session been loaded yet?
|
105
|
+
def loaded?
|
106
|
+
!! @data
|
107
|
+
end
|
108
|
+
|
109
|
+
private
|
110
|
+
attr_writer :data
|
111
|
+
|
112
|
+
def marshal_data!
|
113
|
+
return false if !loaded?
|
114
|
+
write_attribute(@@data_column_name, self.class.marshal(self.data))
|
115
|
+
end
|
116
|
+
|
117
|
+
# Ensures that the data about to be stored in the database is not
|
118
|
+
# larger than the data storage column. Raises
|
119
|
+
# ActionController::SessionOverflowError.
|
120
|
+
def raise_on_session_data_overflow!
|
121
|
+
return false if !loaded?
|
122
|
+
limit = self.class.data_column_size_limit
|
123
|
+
if loaded? and limit and read_attribute(@@data_column_name).size > limit
|
124
|
+
raise MerbController::SessionOverflowError
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end # ActiveRecordSessionMixin
|
128
|
+
end # Merb
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# make sure we're running inside Merb
|
2
|
+
if defined?(Merb::Plugins)
|
3
|
+
if Merb::Server.app_loaded?
|
4
|
+
puts "Warning: The merb_active_record gem must be loaded before the application"
|
5
|
+
else
|
6
|
+
require "merb/orms/active_record/connection"
|
7
|
+
Merb::Orms::ActiveRecord.connect
|
8
|
+
Merb::Orms::ActiveRecord.register_session_type
|
9
|
+
end
|
10
|
+
Merb::Plugins.add_rakefiles "merb/orms/active_record/tasks/databases"
|
11
|
+
end
|
metadata
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.9.2
|
3
|
+
specification_version: 1
|
4
|
+
name: merb_activerecord
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 0.4.2
|
7
|
+
date: 2007-11-06 00:00:00 -06:00
|
8
|
+
summary: Merb plugin that provides ActiveRecord support for Merb
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: canadaduane@gmail.com
|
12
|
+
homepage: http://merbivore.com
|
13
|
+
rubyforge_project:
|
14
|
+
description: Merb plugin that provides ActiveRecord support for Merb
|
15
|
+
autorequire: merb_activerecord
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: true
|
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
|
+
- Duane Johnson
|
31
|
+
files:
|
32
|
+
- LICENSE
|
33
|
+
- README
|
34
|
+
- Rakefile
|
35
|
+
- TODO
|
36
|
+
- lib/merb
|
37
|
+
- lib/merb_activerecord.rb
|
38
|
+
- lib/merb/orms
|
39
|
+
- lib/merb/session
|
40
|
+
- lib/merb/orms/active_record
|
41
|
+
- lib/merb/orms/active_record/connection.rb
|
42
|
+
- lib/merb/orms/active_record/database.sample.yml
|
43
|
+
- lib/merb/orms/active_record/tasks
|
44
|
+
- lib/merb/orms/active_record/tasks/databases.rb
|
45
|
+
- lib/merb/session/active_record_session.rb
|
46
|
+
- specs/merb_active_record_spec.rb
|
47
|
+
- specs/spec_helper.rb
|
48
|
+
- activerecord_generators/database_sessions_migration
|
49
|
+
- activerecord_generators/migration
|
50
|
+
- activerecord_generators/model
|
51
|
+
- activerecord_generators/resource_controller
|
52
|
+
- activerecord_generators/database_sessions_migration/database_sessions_migration_generator.rb
|
53
|
+
- activerecord_generators/database_sessions_migration/templates
|
54
|
+
- activerecord_generators/database_sessions_migration/USAGE
|
55
|
+
- activerecord_generators/database_sessions_migration/templates/sessions_migration.erb
|
56
|
+
- activerecord_generators/migration/migration_generator.rb
|
57
|
+
- activerecord_generators/migration/templates
|
58
|
+
- activerecord_generators/migration/USAGE
|
59
|
+
- activerecord_generators/migration/templates/new_migration.erb
|
60
|
+
- activerecord_generators/model/model_generator.rb
|
61
|
+
- activerecord_generators/model/templates
|
62
|
+
- activerecord_generators/model/USAGE
|
63
|
+
- activerecord_generators/model/templates/new_model.erb
|
64
|
+
- activerecord_generators/resource_controller/resource_controller_generator.rb
|
65
|
+
- activerecord_generators/resource_controller/templates
|
66
|
+
- activerecord_generators/resource_controller/USAGE
|
67
|
+
- activerecord_generators/resource_controller/templates/controller.rb
|
68
|
+
- activerecord_generators/resource_controller/templates/edit.html.erb
|
69
|
+
- activerecord_generators/resource_controller/templates/helper.rb
|
70
|
+
- activerecord_generators/resource_controller/templates/index.html.erb
|
71
|
+
- activerecord_generators/resource_controller/templates/new.html.erb
|
72
|
+
- activerecord_generators/resource_controller/templates/show.html.erb
|
73
|
+
test_files: []
|
74
|
+
|
75
|
+
rdoc_options: []
|
76
|
+
|
77
|
+
extra_rdoc_files:
|
78
|
+
- README
|
79
|
+
- LICENSE
|
80
|
+
- TODO
|
81
|
+
executables: []
|
82
|
+
|
83
|
+
extensions: []
|
84
|
+
|
85
|
+
requirements: []
|
86
|
+
|
87
|
+
dependencies:
|
88
|
+
- !ruby/object:Gem::Dependency
|
89
|
+
name: merb
|
90
|
+
version_requirement:
|
91
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: 0.4.0
|
96
|
+
version:
|