El Problemo
When issuing a ‘rake db:schema:dump’ (or a simple ‘rake test’ since it uses db:schema:dump) on the legacy oracle db mentioned in the previous post the schema.rb contained some weird entries like:
t.column "timestamp", :datetime, :default => #<date : 4903089/2,0,2299161>, :null => false
The culprits were basically field defaults (like the above, using ‘sysdate’ as default) that aren’t handled properly (not even sure if they should). Since this is a legacy db accessed by tons of mainly C/C++ code on which I’m tacking a web ui, changing this to something that suits Rails is usually not possible.
Any other rake tasks using the schema.rb stumbled over these entries so I was basically unable to do a simple ‘rake test’.
Unfortunately I only found the occasional mention of this issue but not a real solution (yet).
El (hack’n’slash) Solution
Basically all I needed db:schema:dump to work correctly for was being able to run tests. For a variety of accidental reasons I choose to run these tests on a mysql db on a w2k box. (at work I’m using xwin under cygwin on a wxp installation to connect to a CentOS server for my rails development… so this might not seem a logical decision… but explaining the reason behind choosing mysql to run the tests is really totally out of scope of this post)
Easiest solution was to filter the badies (renegades and outlaws) out of schema.rb before it was used for something else.
I made an extra db:schema:clean task to read/filter/write schema.rb, called it from db:schema:dump and put these in a file called ‘databases.rake’ in my Rails lib/tasks folder.
databases.rake:
namespace :db do
namespace :schema do
desc "Create a db/schema.rb file that can be portably used against any DB supported by AR"
task :dump => :environment do
require 'active_record/schema_dumper'
File.open(ENV['SCHEMA'] || "db/schema.rb", "w") do |file|
ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file)
end
Rake::Task["db:schema:clean"].invoke
end
desc "Fix the sysdate timestamps from an oracle schema.rb"
task :clean => :environment do
File.open(ENV['SCHEMA'] || "db/schema.rb", 'r+') do |f|
lines = f.readlines
lines.each do |it|
it.gsub!(/:default => #<date : 4903089\/2,0,2299161>,/, '')
it.gsub!(/:default => "EMPTY_BLOB\(\)",/, '')
end
f.pos = 0
f.print lines
f.truncate(f.pos)
end
end
end
end
(blame WordPress for losing indentation… at least I do!)
Ok… probably really basic stuff for the harcore Railsers out there, but I hope this will help some ‘nuby’ Railsers save some time hunting for where/what/how with this great framework.
(2nd post today, I’ve got another one up my sleeve but will stop now before someone asks me to take a ‘doping test’)