Feb 19 2010

ActiveRecord Migrations for Sinatra

Sinatra ActiveRecord MYSQL ORM | comments

I have learned that Sequel ORM was simple and is the preferred ORM for Sinatra developers. But I feel so attached to ActiveRecord right now. Basically some of the gems I am using are actually extensions to ActiveRecord and I have grown to love these Ruby gems despite being ActiveRecord-centric. They wouldn't work with DataMapper or anything else.

Creating migrations in Sinatra is simple. Just create db/migrate folder. Create a db/config.yml which is similar to database.yml in Rails.

Example config file:

              
              development:
                adapter: mysql
                encoding: utf8
                database: mywayorthehighway
                username: root
                password: 
              
              

Of course, you can have other environments there.

The very lengthy code below is the magic that makes migrations work. Add them up on the Rakefile.

              
              require 'rake'
              require 'active_record'
              require 'yaml'
              require 'logger'
              
              desc "Import DB"
              task :import => :environment do
              url = ENV['URL'] or raise "No url specified, use URL="
              
              require 'rest_client'
              posts = YAML.load RestClient.get(url)
              
              posts.each do |post|
              DB[:posts] << post
              end
              end
              
              task :default => :dbsetup
              
              task :loadconfig do
              DBconfig = YAML::load( File.open('db/config.yml') )['development']
              end
              
              desc "Setup db"
              task :dbsetup => :loadconfig do
              create(DBconfig)
              migrate(DBconfig)
              end
              
              desc "Do migrations"
              task :migrate => :loadconfig do
              migrate(DBconfig)
              end
              
              def create( config )
              begin
              if config['adapter'] =~ /sqlite/
              if File.exist?(config['database'])
              $stderr.puts "#{config['database']} already exists"
              else
              begin
              # Create the SQLite database
              ActiveRecord::Base.establish_connection(config)
              ActiveRecord::Base.connection
              rescue
              $stderr.puts $!, *($!.backtrace)
              $stderr.puts "Couldn't create database for #{config.inspect}"
              end
              end
              return # Skip the else clause of begin/rescue
              else
              ActiveRecord::Base.establish_connection(config)
              ActiveRecord::Base.connection
              end
              rescue
              case config['adapter']
              when 'mysql'
              @charset = ENV['CHARSET'] || 'utf8'
              @collation = ENV['COLLATION'] || 'utf8_general_ci'
              begin
              ActiveRecord::Base.establish_connection(config.merge('database' => nil))
              ActiveRecord::Base.connection.create_database(config['database'], :charset => (config['charset'] || @charset), 
              :collation => (config['collation'] || @collation))
              ActiveRecord::Base.establish_connection(config)
              rescue
              $stderr.puts "Couldn't create database for #{config.inspect}, charset: #{config['charset'] || @charset}, 
              collation: #{config['collation'] || @collation}"
              end
              when 'postgresql'
              @encoding = config[:encoding] || ENV['CHARSET'] || 'utf8'
              begin
              ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres', 'schema_search_path' => 'public'))
              ActiveRecord::Base.connection.create_database(config['database'], config.merge('encoding' => @encoding))
              ActiveRecord::Base.establish_connection(config)
              rescue
              $stderr.puts $!, *($!.backtrace)
              $stderr.puts "Couldn't create database for #{config.inspect}"
              end
              end
              else
              $stderr.puts "#{config['database']} already exists"
              end
              end
              
              def migrate( config )
              ActiveRecord::Base.logger = Logger.new(STDOUT)
              ActiveRecord::Base.establish_connection(config)
              ActiveRecord::Migrator.up "db/migrate/"
              end
              
              

So let's check that before running "rake."

              rake -T
              (in /Users/katz/web/bridgeutopiaweb)
              rake dbsetup  # Setup db
              rake import   # Import DB
              rake migrate  # Do migrations
              rake start    # Start the app server
              rake stop     # Stop the app server