merb_active_record 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -0
- data/README +4 -0
- data/Rakefile +31 -0
- data/TODO +5 -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 +287 -0
- data/lib/merb/session/active_record_session.rb +128 -0
- data/lib/merb_active_record.rb +11 -0
- data/specs/merb_active_record_spec.rb +7 -0
- data/specs/spec_helper.rb +2 -0
- metadata +63 -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
data/Rakefile
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake/gempackagetask'
|
3
|
+
|
4
|
+
PLUGIN = "merb_active_record"
|
5
|
+
NAME = "merb_active_record"
|
6
|
+
VERSION = "0.0.1"
|
7
|
+
AUTHOR = "Duane Johnson"
|
8
|
+
EMAIL = "canadaduane@gmail.com"
|
9
|
+
HOMEPAGE = "http://merb-plugins.rubyforge.org/merb_active_record/"
|
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.requirements << 'merb'
|
24
|
+
s.require_path = 'lib'
|
25
|
+
s.autorequire = PLUGIN
|
26
|
+
s.files = %w(LICENSE README Rakefile TODO) + Dir.glob("{lib,specs}/**/*")
|
27
|
+
end
|
28
|
+
|
29
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
30
|
+
pkg.gem_spec = spec
|
31
|
+
end
|
data/TODO
ADDED
@@ -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 Sequel ORM
|
3
|
+
:development: &defaults
|
4
|
+
:adapter: mysql
|
5
|
+
:database: sample_development
|
6
|
+
:username: teh_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,287 @@
|
|
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
|
+
p ActiveRecord::Base.configurations
|
18
|
+
p MERB_ENV
|
19
|
+
create_local_database(ActiveRecord::Base.configurations[MERB_ENV])
|
20
|
+
end
|
21
|
+
|
22
|
+
def create_local_database(config)
|
23
|
+
# Only connect to local databases
|
24
|
+
if config[:host] == 'localhost' || config[:host].blank?
|
25
|
+
begin
|
26
|
+
ActiveRecord::Base.establish_connection(config)
|
27
|
+
ActiveRecord::Base.connection
|
28
|
+
rescue
|
29
|
+
case config[:adapter]
|
30
|
+
when 'mysql'
|
31
|
+
#~ @charset = ENV['CHARSET'] || 'utf8'
|
32
|
+
#~ @collation = ENV['COLLATION'] || 'utf8_general_ci'
|
33
|
+
begin
|
34
|
+
ActiveRecord::Base.establish_connection(config.merge({:database => nil}))
|
35
|
+
ActiveRecord::Base.connection.create_database(config[:database]) #, {:charset => @charset, :collation => @collation})
|
36
|
+
ActiveRecord::Base.establish_connection(config)
|
37
|
+
p "MySQL #{config[:database]} database succesfully created"
|
38
|
+
rescue
|
39
|
+
$stderr.puts "Couldn't create database for #{config.inspect}"
|
40
|
+
end
|
41
|
+
when 'postgresql'
|
42
|
+
`createdb "#{config[:database]}" -E utf8`
|
43
|
+
when 'sqlite'
|
44
|
+
`sqlite "#{config[:database]}"`
|
45
|
+
when 'sqlite3'
|
46
|
+
`sqlite3 "#{config[:database]}"`
|
47
|
+
end
|
48
|
+
else
|
49
|
+
p "#{config[:database]} already exists"
|
50
|
+
end
|
51
|
+
else
|
52
|
+
p "This task only creates local databases. #{config[:database]} is on a remote host."
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
desc 'Drops the database for the current environment'
|
57
|
+
task :drop => :environment do
|
58
|
+
config = ActiveRecord::Base.configurations[MERB_ENV || :development]
|
59
|
+
p config
|
60
|
+
case config[:adapter]
|
61
|
+
when 'mysql'
|
62
|
+
ActiveRecord::Base.connection.drop_database config[:database]
|
63
|
+
when /^sqlite/
|
64
|
+
FileUtils.rm_f File.join(MERB_ROOT, config[:database])
|
65
|
+
when 'postgresql'
|
66
|
+
`dropdb "#{config[:database]}"`
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
desc "Migrate the database through scripts in schema/migrations. Target specific version with VERSION=x"
|
71
|
+
task :migrate => :environment do
|
72
|
+
ActiveRecord::Migrator.migrate("schema/migrations/", ENV["VERSION"] ? ENV["VERSION"].to_i : nil)
|
73
|
+
Rake::Task["db:schema:dump"].invoke if ActiveRecord::Base.schema_format == :ruby
|
74
|
+
end
|
75
|
+
|
76
|
+
desc 'Drops, creates and then migrates the database for the current environment. Target specific version with VERSION=x'
|
77
|
+
task :reset => ['db:drop', 'db:create', 'db:migrate']
|
78
|
+
|
79
|
+
# desc "Retrieves the charset for the current environment's database"
|
80
|
+
# task :charset => :environment do
|
81
|
+
# config = ActiveRecord::Base.configurations[MERB_ENV || :development]
|
82
|
+
# case config[:adapter]
|
83
|
+
# when 'mysql'
|
84
|
+
# ActiveRecord::Base.establish_connection(config)
|
85
|
+
# puts ActiveRecord::Base.connection.charset
|
86
|
+
# else
|
87
|
+
# puts 'sorry, your database adapter is not supported yet, feel free to submit a patch'
|
88
|
+
# end
|
89
|
+
# end
|
90
|
+
|
91
|
+
# desc "Retrieves the collation for the current environment's database"
|
92
|
+
# task :collation => :environment do
|
93
|
+
# config = ActiveRecord::Base.configurations[MERB_ENV || :development]
|
94
|
+
# case config[:adapter]
|
95
|
+
# when 'mysql'
|
96
|
+
# ActiveRecord::Base.establish_connection(config)
|
97
|
+
# puts ActiveRecord::Base.connection.collation
|
98
|
+
# else
|
99
|
+
# puts 'sorry, your database adapter is not supported yet, feel free to submit a patch'
|
100
|
+
# end
|
101
|
+
# end
|
102
|
+
|
103
|
+
desc "Retrieves the current schema version number"
|
104
|
+
task :version => :environment do
|
105
|
+
puts "Current version: #{ActiveRecord::Migrator.current_version}"
|
106
|
+
end
|
107
|
+
|
108
|
+
namespace :fixtures do
|
109
|
+
desc "Load fixtures into the current environment's database. Load specific fixtures using FIXTURES=x,y"
|
110
|
+
task :load => :environment do
|
111
|
+
require 'active_record/fixtures'
|
112
|
+
ActiveRecord::Base.establish_connection(MERB_ENV.to_sym)
|
113
|
+
(ENV['FIXTURES'] ? ENV['FIXTURES'].split(/,/) : Dir.glob(File.join(MERB_ROOT, 'test', 'fixtures', '*.{yml,csv}'))).each do |fixture_file|
|
114
|
+
Fixtures.create_fixtures('test/fixtures', File.basename(fixture_file, '.*'))
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
namespace :schema do
|
120
|
+
desc "Create a schema/schema.rb file that can be portably used against any DB supported by AR"
|
121
|
+
task :dump => :environment do
|
122
|
+
require 'active_record/schema_dumper'
|
123
|
+
File.open(ENV['SCHEMA'] || "schema/schema.rb", "w") do |file|
|
124
|
+
ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
desc "Load a schema.rb file into the database"
|
129
|
+
task :load => :environment do
|
130
|
+
file = ENV['SCHEMA'] || "schema/schema.rb"
|
131
|
+
load(file)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
namespace :structure do
|
136
|
+
desc "Dump the database structure to a SQL file"
|
137
|
+
task :dump => :environment do
|
138
|
+
abcs = ActiveRecord::Base.configurations
|
139
|
+
case abcs[MERB_ENV][:adapter]
|
140
|
+
when "mysql", "oci", "oracle"
|
141
|
+
ActiveRecord::Base.establish_connection(abcs[MERB_ENV])
|
142
|
+
File.open("schema/#{MERB_ENV}_structure.sql", "w+") { |f| f << ActiveRecord::Base.connection.structure_dump }
|
143
|
+
when "postgresql"
|
144
|
+
ENV['PGHOST'] = abcs[MERB_ENV]["host"] if abcs[MERB_ENV]["host"]
|
145
|
+
ENV['PGPORT'] = abcs[MERB_ENV]["port"].to_s if abcs[MERB_ENV]["port"]
|
146
|
+
ENV['PGPASSWORD'] = abcs[MERB_ENV]["password"].to_s if abcs[MERB_ENV]["password"]
|
147
|
+
search_path = abcs[MERB_ENV]["schema_search_path"]
|
148
|
+
search_path = "--schema=#{search_path}" if search_path
|
149
|
+
`pg_dump -i -U "#{abcs[MERB_ENV]["username"]}" -s -x -O -f schema/#{MERB_ENV}_structure.sql #{search_path} #{abcs[MERB_ENV]["database"]}`
|
150
|
+
raise "Error dumping database" if $?.exitstatus == 1
|
151
|
+
when "sqlite", "sqlite3"
|
152
|
+
dbfile = abcs[MERB_ENV]["database"] || abcs[MERB_ENV]["dbfile"]
|
153
|
+
`#{abcs[MERB_ENV]["adapter"]} #{dbfile} .schema > schema/#{MERB_ENV}_structure.sql`
|
154
|
+
when "sqlserver"
|
155
|
+
`scptxfr /s #{abcs[MERB_ENV]["host"]} /d #{abcs[MERB_ENV]["database"]} /I /f db\\#{MERB_ENV}_structure.sql /q /A /r`
|
156
|
+
`scptxfr /s #{abcs[MERB_ENV]["host"]} /d #{abcs[MERB_ENV]["database"]} /I /F db\ /q /A /r`
|
157
|
+
when "firebird"
|
158
|
+
set_firebird_env(abcs[MERB_ENV])
|
159
|
+
db_string = firebird_db_string(abcs[MERB_ENV])
|
160
|
+
sh "isql -a #{db_string} > schema/#{MERB_ENV}_structure.sql"
|
161
|
+
else
|
162
|
+
raise "Task not supported by '#{abcs[MERB_ENV][:adapter]}'"
|
163
|
+
end
|
164
|
+
|
165
|
+
if ActiveRecord::Base.connection.supports_migrations?
|
166
|
+
File.open("schema/#{MERB_ENV}_structure.sql", "a") { |f| f << ActiveRecord::Base.connection.dump_schema_information }
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
namespace :test do
|
172
|
+
desc "Recreate the test database from the current environment's database schema"
|
173
|
+
task :clone => %w(db:schema:dump db:test:purge) do
|
174
|
+
ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations['test'])
|
175
|
+
ActiveRecord::Schema.verbose = false
|
176
|
+
Rake::Task["db:schema:load"].invoke
|
177
|
+
end
|
178
|
+
|
179
|
+
|
180
|
+
desc "Recreate the test databases from the development structure"
|
181
|
+
task :clone_structure => [ "db:structure:dump", "db:test:purge" ] do
|
182
|
+
abcs = ActiveRecord::Base.configurations
|
183
|
+
case abcs["test"]["adapter"]
|
184
|
+
when "mysql"
|
185
|
+
ActiveRecord::Base.establish_connection(:test)
|
186
|
+
ActiveRecord::Base.connection.execute('SET foreign_key_checks = 0')
|
187
|
+
IO.readlines("schema/#{MERB_ENV}_structure.sql").join.split("\n\n").each do |table|
|
188
|
+
ActiveRecord::Base.connection.execute(table)
|
189
|
+
end
|
190
|
+
when "postgresql"
|
191
|
+
ENV['PGHOST'] = abcs["test"]["host"] if abcs["test"]["host"]
|
192
|
+
ENV['PGPORT'] = abcs["test"]["port"].to_s if abcs["test"]["port"]
|
193
|
+
ENV['PGPASSWORD'] = abcs["test"]["password"].to_s if abcs["test"]["password"]
|
194
|
+
`psql -U "#{abcs["test"]["username"]}" -f schema/#{MERB_ENV}_structure.sql #{abcs["test"]["database"]}`
|
195
|
+
when "sqlite", "sqlite3"
|
196
|
+
dbfile = abcs["test"]["database"] || abcs["test"]["dbfile"]
|
197
|
+
`#{abcs["test"]["adapter"]} #{dbfile} < schema/#{MERB_ENV}_structure.sql`
|
198
|
+
when "sqlserver"
|
199
|
+
`osql -E -S #{abcs["test"]["host"]} -d #{abcs["test"]["database"]} -i db\\#{MERB_ENV}_structure.sql`
|
200
|
+
when "oci", "oracle"
|
201
|
+
ActiveRecord::Base.establish_connection(:test)
|
202
|
+
IO.readlines("schema/#{MERB_ENV}_structure.sql").join.split(";\n\n").each do |ddl|
|
203
|
+
ActiveRecord::Base.connection.execute(ddl)
|
204
|
+
end
|
205
|
+
when "firebird"
|
206
|
+
set_firebird_env(abcs["test"])
|
207
|
+
db_string = firebird_db_string(abcs["test"])
|
208
|
+
sh "isql -i schema/#{MERB_ENV}_structure.sql #{db_string}"
|
209
|
+
else
|
210
|
+
raise "Task not supported by '#{abcs["test"]["adapter"]}'"
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
desc "Empty the test database"
|
215
|
+
task :purge => :environment do
|
216
|
+
abcs = ActiveRecord::Base.configurations
|
217
|
+
case abcs["test"]["adapter"]
|
218
|
+
when "mysql"
|
219
|
+
ActiveRecord::Base.establish_connection(:test)
|
220
|
+
ActiveRecord::Base.connection.recreate_database(abcs["test"]["database"])
|
221
|
+
when "postgresql"
|
222
|
+
ENV['PGHOST'] = abcs["test"]["host"] if abcs["test"]["host"]
|
223
|
+
ENV['PGPORT'] = abcs["test"]["port"].to_s if abcs["test"]["port"]
|
224
|
+
ENV['PGPASSWORD'] = abcs["test"]["password"].to_s if abcs["test"]["password"]
|
225
|
+
enc_option = "-E #{abcs["test"]["encoding"]}" if abcs["test"]["encoding"]
|
226
|
+
|
227
|
+
ActiveRecord::Base.clear_active_connections!
|
228
|
+
`dropdb -U "#{abcs["test"]["username"]}" #{abcs["test"]["database"]}`
|
229
|
+
`createdb #{enc_option} -U "#{abcs["test"]["username"]}" #{abcs["test"]["database"]}`
|
230
|
+
when "sqlite","sqlite3"
|
231
|
+
dbfile = abcs["test"]["database"] || abcs["test"]["dbfile"]
|
232
|
+
File.delete(dbfile) if File.exist?(dbfile)
|
233
|
+
when "sqlserver"
|
234
|
+
dropfkscript = "#{abcs["test"]["host"]}.#{abcs["test"]["database"]}.DP1".gsub(/\\/,'-')
|
235
|
+
`osql -E -S #{abcs["test"]["host"]} -d #{abcs["test"]["database"]} -i db\\#{dropfkscript}`
|
236
|
+
`osql -E -S #{abcs["test"]["host"]} -d #{abcs["test"]["database"]} -i db\\#{MERB_ENV}_structure.sql`
|
237
|
+
when "oci", "oracle"
|
238
|
+
ActiveRecord::Base.establish_connection(:test)
|
239
|
+
ActiveRecord::Base.connection.structure_drop.split(";\n\n").each do |ddl|
|
240
|
+
ActiveRecord::Base.connection.execute(ddl)
|
241
|
+
end
|
242
|
+
when "firebird"
|
243
|
+
ActiveRecord::Base.establish_connection(:test)
|
244
|
+
ActiveRecord::Base.connection.recreate_database!
|
245
|
+
else
|
246
|
+
raise "Task not supported by '#{abcs["test"]["adapter"]}'"
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
desc 'Prepare the test database and load the schema'
|
251
|
+
task :prepare => :environment do
|
252
|
+
if defined?(ActiveRecord::Base) && !ActiveRecord::Base.configurations.blank?
|
253
|
+
Rake::Task[{ :sql => "db:test:clone_structure", :ruby => "db:test:clone" }[ActiveRecord::Base.schema_format]].invoke
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
namespace :sessions do
|
259
|
+
# desc "Creates a sessions migration for use with CGI::Session::ActiveRecordStore"
|
260
|
+
# task :create => :environment do
|
261
|
+
# raise "Task unavailable to this database (no migration support)" unless ActiveRecord::Base.connection.supports_migrations?
|
262
|
+
# require 'rails_generator'
|
263
|
+
# require 'rails_generator/scripts/generate'
|
264
|
+
# Rails::Generator::Scripts::Generate.new.run(["session_migration", ENV["MIGRATION"] || "AddSessions"])
|
265
|
+
# end
|
266
|
+
|
267
|
+
desc "Clear the sessions table"
|
268
|
+
task :clear => :environment do
|
269
|
+
session_table = 'session'
|
270
|
+
session_table = Inflector.pluralize(session_table) if ActiveRecord::Base.pluralize_table_names
|
271
|
+
ActiveRecord::Base.connection.execute "DELETE FROM #{session_table}"
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
def session_table_name
|
277
|
+
ActiveRecord::Base.pluralize_table_names ? :sessions : :session
|
278
|
+
end
|
279
|
+
|
280
|
+
def set_firebird_env(config)
|
281
|
+
ENV["ISC_USER"] = config["username"].to_s if config["username"]
|
282
|
+
ENV["ISC_PASSWORD"] = config["password"].to_s if config["password"]
|
283
|
+
end
|
284
|
+
|
285
|
+
def firebird_db_string(config)
|
286
|
+
FireRuby::Database.db_string_for(config.symbolize_keys)
|
287
|
+
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,63 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.9.1
|
3
|
+
specification_version: 1
|
4
|
+
name: merb_active_record
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 0.0.1
|
7
|
+
date: 2007-09-24 00:00:00 -07:00
|
8
|
+
summary: Merb plugin that provides ActiveRecord support for Merb
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: canadaduane@gmail.com
|
12
|
+
homepage: http://merb-plugins.rubyforge.org/merb_active_record/
|
13
|
+
rubyforge_project:
|
14
|
+
description: Merb plugin that provides ActiveRecord support for Merb
|
15
|
+
autorequire: merb_active_record
|
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_active_record.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
|
+
test_files: []
|
49
|
+
|
50
|
+
rdoc_options: []
|
51
|
+
|
52
|
+
extra_rdoc_files:
|
53
|
+
- README
|
54
|
+
- LICENSE
|
55
|
+
- TODO
|
56
|
+
executables: []
|
57
|
+
|
58
|
+
extensions: []
|
59
|
+
|
60
|
+
requirements:
|
61
|
+
- merb
|
62
|
+
dependencies: []
|
63
|
+
|