Make database offline mode work

This commit is contained in:
Tom Hughes 2010-06-15 10:07:39 +01:00
parent f980e7e4a6
commit 8af14faa49
8 changed files with 106 additions and 84 deletions

View file

@ -51,7 +51,9 @@ Rails::Initializer.run do |config|
# config.gem "bj" # config.gem "bj"
# config.gem "hpricot", :version => '0.6', :source => "http://code.whytheluckystiff.net" # config.gem "hpricot", :version => '0.6', :source => "http://code.whytheluckystiff.net"
# config.gem "aws-s3", :lib => "aws/s3" # config.gem "aws-s3", :lib => "aws/s3"
config.gem 'composite_primary_keys', :version => '2.2.2' unless OSM_STATUS == :database_offline
config.gem 'composite_primary_keys', :version => '2.2.2'
end
config.gem 'libxml-ruby', :version => '>= 1.1.1', :lib => 'libxml' config.gem 'libxml-ruby', :version => '>= 1.1.1', :lib => 'libxml'
config.gem 'rmagick', :lib => 'RMagick' config.gem 'rmagick', :lib => 'RMagick'
config.gem 'oauth', :version => '>= 0.3.6' config.gem 'oauth', :version => '>= 0.3.6'
@ -86,7 +88,9 @@ Rails::Initializer.run do |config|
# Use the database for sessions instead of the cookie-based default, # Use the database for sessions instead of the cookie-based default,
# which shouldn't be used to store highly confidential information # which shouldn't be used to store highly confidential information
# (create the session table with 'rake db:sessions:create') # (create the session table with 'rake db:sessions:create')
config.action_controller.session_store = :sql_session_store unless OSM_STATUS == :database_offline
config.action_controller.session_store = :sql_session_store
end
# Use SQL instead of Active Record's schema dumper when creating the test database. # Use SQL instead of Active Record's schema dumper when creating the test database.
# This is necessary if your schema can't be completely dumped by the schema dumper, # This is necessary if your schema can't be completely dumped by the schema dumper,

View file

@ -1,24 +1,26 @@
module ActiveRecord if defined?(ActionRecord::ConnectionAdaptors::AbstractAdaptor)
module ConnectionAdapters module ActiveRecord
class AbstractAdapter module ConnectionAdapters
protected class AbstractAdapter
alias_method :old_log, :log protected
alias_method :old_log, :log
def log(sql, name)
if block_given? def log(sql, name)
old_log(sql, name) do if block_given?
yield old_log(sql, name) do
yield
end
else
old_log(sql, name)
end
rescue ActiveRecord::StatementInvalid => ex
if ex.message =~ /^OSM::APITimeoutError: /
raise OSM::APITimeoutError.new
elsif ex.message =~ /^Timeout::Error: /
raise Timeout::Error.new("time's up!")
else
raise
end end
else
old_log(sql, name)
end
rescue ActiveRecord::StatementInvalid => ex
if ex.message =~ /^OSM::APITimeoutError: /
raise OSM::APITimeoutError.new
elsif ex.message =~ /^Timeout::Error: /
raise Timeout::Error.new("time's up!")
else
raise
end end
end end
end end

View file

@ -1,54 +1,56 @@
module ActiveRecord if defined?(ActionRecord::ConnectionAdaptors::PostgreSQLAdaptor)
module ConnectionAdapters module ActiveRecord
class PostgreSQLAdapter module ConnectionAdapters
def pk_and_sequence_for(table) class PostgreSQLAdapter
# First try looking for a sequence with a dependency on the def pk_and_sequence_for(table)
# given table's primary key. # First try looking for a sequence with a dependency on the
result = query(<<-end_sql, 'PK and serial sequence')[0] # given table's primary key.
SELECT attr.attname, seq.relname result = query(<<-end_sql, 'PK and serial sequence')[0]
FROM pg_class seq, SELECT attr.attname, seq.relname
pg_attribute attr, FROM pg_class seq,
pg_depend dep, pg_attribute attr,
pg_namespace name, pg_depend dep,
pg_constraint cons pg_namespace name,
WHERE seq.oid = dep.objid pg_constraint cons
AND seq.relkind = 'S' WHERE seq.oid = dep.objid
AND attr.attrelid = dep.refobjid AND seq.relkind = 'S'
AND attr.attnum = dep.refobjsubid AND attr.attrelid = dep.refobjid
AND attr.attrelid = cons.conrelid AND attr.attnum = dep.refobjsubid
AND attr.attnum = cons.conkey[1] AND attr.attrelid = cons.conrelid
AND cons.contype = 'p' AND attr.attnum = cons.conkey[1]
AND dep.classid = '"pg_class"'::regclass AND cons.contype = 'p'
AND dep.refclassid = '"pg_class"'::regclass AND dep.classid = '"pg_class"'::regclass
AND dep.refobjid = '#{quote_table_name(table)}'::regclass AND dep.refclassid = '"pg_class"'::regclass
end_sql AND dep.refobjid = '#{quote_table_name(table)}'::regclass
if result.nil? or result.empty?
# If that fails, try parsing the primary key's default value.
# Support the 7.x and 8.0 nextval('foo'::text) as well as
# the 8.1+ nextval('foo'::regclass).
result = query(<<-end_sql, 'PK and custom sequence')[0]
SELECT attr.attname,
CASE
WHEN split_part(def.adsrc, '''', 2) ~ '.' THEN
substr(split_part(def.adsrc, '''', 2),
strpos(split_part(def.adsrc, '''', 2), '.')+1)
ELSE split_part(def.adsrc, '''', 2)
END
FROM pg_class t
JOIN pg_attribute attr ON (t.oid = attrelid)
JOIN pg_attrdef def ON (adrelid = attrelid AND adnum = attnum)
JOIN pg_constraint cons ON (conrelid = adrelid AND adnum = conkey[1])
WHERE t.oid = '#{quote_table_name(table)}'::regclass
AND cons.contype = 'p'
AND def.adsrc ~* 'nextval'
end_sql end_sql
if result.nil? or result.empty?
# If that fails, try parsing the primary key's default value.
# Support the 7.x and 8.0 nextval('foo'::text) as well as
# the 8.1+ nextval('foo'::regclass).
result = query(<<-end_sql, 'PK and custom sequence')[0]
SELECT attr.attname,
CASE
WHEN split_part(def.adsrc, '''', 2) ~ '.' THEN
substr(split_part(def.adsrc, '''', 2),
strpos(split_part(def.adsrc, '''', 2), '.')+1)
ELSE split_part(def.adsrc, '''', 2)
END
FROM pg_class t
JOIN pg_attribute attr ON (t.oid = attrelid)
JOIN pg_attrdef def ON (adrelid = attrelid AND adnum = attnum)
JOIN pg_constraint cons ON (conrelid = adrelid AND adnum = conkey[1])
WHERE t.oid = '#{quote_table_name(table)}'::regclass
AND cons.contype = 'p'
AND def.adsrc ~* 'nextval'
end_sql
end
# [primary_key, sequence]
[result.first, result.last]
rescue
nil
end end
# [primary_key, sequence]
[result.first, result.last]
rescue
nil
end end
end end
end end

View file

@ -1,10 +1,12 @@
module ActiveRecord if defined?(ActionRecord::ConnectionAdaptors::QueryCache)
module ConnectionAdapters module ActiveRecord
module QueryCache module ConnectionAdapters
private module QueryCache
def cache_sql(sql) private
yield def cache_sql(sql)
end yield
end
end
end end
end end
end end

View file

@ -4,4 +4,6 @@ adapter = Rails.configuration.database_configuration[environment]["adapter"]
session_class = adapter + "_session" session_class = adapter + "_session"
# Configure SqlSessionStore # Configure SqlSessionStore
SqlSessionStore.session_class = session_class.camelize.constantize unless OSM_STATUS == :database_offline
SqlSessionStore.session_class = session_class.camelize.constantize
end

View file

@ -1,2 +1,5 @@
require 'deadlock_retry' require 'deadlock_retry'
ActiveRecord::Base.send :include, DeadlockRetry
if defined?(ActionRecord::Base)
ActiveRecord::Base.send :include, DeadlockRetry
end

View file

@ -8,6 +8,11 @@ require 'file_column_helper'
require 'validations' require 'validations'
require 'test_case' require 'test_case'
ActiveRecord::Base.send(:include, FileColumn) if defined?(ActionRecord::Base)
ActionView::Base.send(:include, FileColumnHelper) ActiveRecord::Base.send(:include, FileColumn)
ActiveRecord::Base.send(:include, FileColumn::Validations) ActiveRecord::Base.send(:include, FileColumn::Validations)
end
if defined?(ActionView::Base)
ActionView::Base.send(:include, FileColumnHelper)
end

View file

@ -1 +1,3 @@
require 'validates_email_format_of' if defined?(ActionRecord::Base)
require 'validates_email_format_of'
end