merb_activerecord 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (29) hide show
  1. data/LICENSE +20 -0
  2. data/README +7 -0
  3. data/Rakefile +36 -0
  4. data/TODO +5 -0
  5. data/activerecord_generators/database_sessions_migration/USAGE +5 -0
  6. data/activerecord_generators/database_sessions_migration/database_sessions_migration_generator.rb +51 -0
  7. data/activerecord_generators/database_sessions_migration/templates/sessions_migration.erb +15 -0
  8. data/activerecord_generators/migration/USAGE +5 -0
  9. data/activerecord_generators/migration/migration_generator.rb +14 -0
  10. data/activerecord_generators/migration/templates/new_migration.erb +15 -0
  11. data/activerecord_generators/model/USAGE +4 -0
  12. data/activerecord_generators/model/model_generator.rb +16 -0
  13. data/activerecord_generators/model/templates/new_model.erb +2 -0
  14. data/activerecord_generators/resource_controller/USAGE +0 -0
  15. data/activerecord_generators/resource_controller/resource_controller_generator.rb +26 -0
  16. data/activerecord_generators/resource_controller/templates/controller.rb +54 -0
  17. data/activerecord_generators/resource_controller/templates/edit.html.erb +1 -0
  18. data/activerecord_generators/resource_controller/templates/helper.rb +5 -0
  19. data/activerecord_generators/resource_controller/templates/index.html.erb +1 -0
  20. data/activerecord_generators/resource_controller/templates/new.html.erb +1 -0
  21. data/activerecord_generators/resource_controller/templates/show.html.erb +1 -0
  22. data/lib/merb/orms/active_record/connection.rb +56 -0
  23. data/lib/merb/orms/active_record/database.sample.yml +17 -0
  24. data/lib/merb/orms/active_record/tasks/databases.rb +285 -0
  25. data/lib/merb/session/active_record_session.rb +128 -0
  26. data/lib/merb_activerecord.rb +11 -0
  27. data/specs/merb_active_record_spec.rb +7 -0
  28. data/specs/spec_helper.rb +2 -0
  29. 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
@@ -0,0 +1,5 @@
1
+ TODO:
2
+ Fix LICENSE with your name
3
+ Fix Rakefile with your name and contact info
4
+ Add your code to lib/merb_active_record.rb
5
+ Add your Merb rake tasks to lib/merb_active_record/merbtasks.rb
@@ -0,0 +1,5 @@
1
+ Description:
2
+
3
+
4
+ Usage:
5
+
@@ -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,15 @@
1
+ class DatabaseSessions < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :sessions do |t|
4
+ t.column :session_id, :text
5
+ t.column :data, :text
6
+ end
7
+ end
8
+
9
+ def self.down
10
+ drop_table :sessions
11
+ end
12
+ end
13
+
14
+
15
+
@@ -0,0 +1,5 @@
1
+ Description:
2
+
3
+
4
+ Usage:
5
+
@@ -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,4 @@
1
+ Description:
2
+
3
+
4
+ Usage:
@@ -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
@@ -0,0 +1,2 @@
1
+ class <%= class_name %> < ActiveRecord::Base
2
+ 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,5 @@
1
+ module Merb
2
+ module <%= class_name %>Helper
3
+
4
+ end
5
+ end
@@ -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
@@ -0,0 +1,7 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe "merb_active_record" do
4
+ it "should do nothing" do
5
+ true.should == true
6
+ end
7
+ end
@@ -0,0 +1,2 @@
1
+ $TESTING=true
2
+ $:.push File.join(File.dirname(__FILE__), '..', 'lib')
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: