Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

executable file 228 lines (194 sloc) 6.425 kB
#!/usr/bin/env ruby
require 'rubygems'
require 'optparse'
require 'sequel'
db_opts = {:test=>true}
copy_databases = nil
dump_migration = nil
dump_schema = nil
echo = nil
env = nil
logfile = nil
migrate_dir = nil
migrate_ver = nil
backtrace = nil
load_dirs = []
exclusive_options = []
opts = OptionParser.new do |opts|
opts.banner = "Sequel: The Database Toolkit for Ruby"
opts.define_head "Usage: sequel <uri|path> [options]"
opts.separator ""
opts.separator "Examples:"
opts.separator " sequel sqlite://blog.db"
opts.separator " sequel postgres://localhost/my_blog"
opts.separator " sequel config/database.yml"
opts.separator ""
opts.separator "For more information see http://sequel.rubyforge.org"
opts.separator ""
opts.separator "Options:"
opts.on_tail("-h", "-?", "--help", "Show this message") do
puts opts
exit
end
opts.on("-C", "--copy-databases", "copy one database to another") do
copy_databases = true
end
opts.on("-d", "--dump-migration", "print database migration to STDOUT") do
dump_migration = true
exclusive_options << :d
end
opts.on("-D", "--dump-migration-same-db", "print database migration to STDOUT without type translation") do
dump_migration = :same_db
exclusive_options << :D
end
opts.on("-e", "--env ENV", "use environment config for database") do |v|
env = v
end
opts.on("-E", "--echo", "echo SQL statements") do
echo = true
end
opts.on("-I", "--include dir", "specify $LOAD_PATH directory") do |v|
$: << v
end
opts.on("-l", "--log logfile", "log SQL statements to log file") do |v|
logfile = v
end
opts.on("-L", "--load-dir DIR", "loads all *.rb under specifed directory") do |v|
load_dirs << v
end
opts.on("-m", "--migrate-directory DIR", "run the migrations in directory") do |v|
migrate_dir = v
exclusive_options << :m
end
opts.on("-M", "--migrate-version VER", "migrate the database to version given") do |v|
migrate_ver = Integer(v)
end
opts.on("-N", "--no-test-connection", "do not test the connection") do
db_opts[:test] = false
end
opts.on("-r", "--require lib", "require the library, before executing your script") do |v|
load_dirs << [v]
end
opts.on("-S", "--dump-schema filename", "dump the schema for all tables to the file") do |v|
dump_schema = v
exclusive_options << :S
end
opts.on("-t", "--trace", "Output the full backtrace if an exception is raised") do
backtrace = true
end
opts.on_tail("-v", "--version", "Show version") do
puts "sequel #{Sequel.version}"
exit
end
end
opts.parse!
db = ARGV.shift
error_proc = lambda do |msg|
$stderr.puts(msg)
exit 1
end
error_proc["Error: Must specify -m if using -M"] if migrate_ver && !migrate_dir
error_proc["Error: Cannot specify #{exclusive_options.map{|v| "-#{v}"}.join(' and ')} together"] if exclusive_options.length > 1
if logfile || echo
require 'logger'
db_opts[:loggers] = []
db_opts[:loggers] << Logger.new(logfile) if logfile
db_opts[:loggers] << Logger.new($stdout) if echo
end
connect_proc = lambda do |database|
db = if database.nil? || database.empty?
Sequel.connect('mock:///', db_opts)
elsif File.exist?(database)
require 'yaml'
env ||= "development"
db_config = YAML.load_file(database)
db_config = db_config[env] || db_config[env.to_sym] || db_config
db_config.keys.each{|k| db_config[k.to_sym] = db_config.delete(k)}
Sequel.connect(db_config.merge!(db_opts))
else
Sequel.connect(database, db_opts)
end
db
end
begin
DB = connect_proc[db]
load_dirs.each{|d| d.is_a?(Array) ? require(d.first) : Dir["#{d}/**/*.rb"].each{|f| load(f)}}
if migrate_dir
Sequel.extension :migration
Sequel::Migrator.apply(DB, migrate_dir, migrate_ver)
exit
end
if dump_migration
Sequel.extension :schema_dumper
puts DB.dump_schema_migration(:same_db=>dump_migration==:same_db)
exit
end
if dump_schema
Sequel.extension :schema_caching
DB.tables.each{|t| DB.schema(Sequel::SQL::Identifier.new(t))}
DB.dump_schema_cache(dump_schema)
exit
end
if copy_databases
Sequel.extension :migration, :schema_dumper
db2 = ARGV.shift
error_proc["Error: Must specify database connection string or path to yaml file as second argument for database you want to copy to"] if db2.nil? || db2.empty?
start_time = Time.now
TO_DB = connect_proc[db2]
same_db = DB.database_type==TO_DB.database_type
index_opts = {:same_db=>same_db}
index_opts[:index_names] = :namespace if !DB.global_index_namespace? && TO_DB.global_index_namespace?
puts "Databases connections successful"
schema_migration = eval(DB.dump_schema_migration(:indexes=>false, :same_db=>same_db))
index_migration = eval(DB.dump_indexes_migration(index_opts))
fk_migration = eval(DB.dump_foreign_key_migration(:same_db=>same_db))
puts "Migrations dumped successfully"
schema_migration.apply(TO_DB, :up)
puts "Tables created"
puts "Begin copying data"
DB.transaction do
TO_DB.transaction do
DB.tables.each do |table|
puts "Begin copying records for table: #{table}"
time = Time.now
to_ds = TO_DB.from(table)
j = 0
DB.from(table).each do |record|
if Time.now - time > 5
puts "Status: #{j} records copied"
time = Time.now
end
to_ds.insert(record)
j += 1
end
puts "Finished copying #{j} records for table: #{table}"
end
end
end
puts "Finished copying data"
puts "Begin creating indexes"
index_migration.apply(TO_DB, :up)
puts "Finished creating indexes"
puts "Begin adding foreign key constraints"
fk_migration.apply(TO_DB, :up)
puts "Finished adding foreign key constraints"
if TO_DB.database_type == :postgres
TO_DB.tables.each{|t| TO_DB.reset_primary_key_sequence(t)}
puts "Primary key sequences reset successfully"
end
puts "Database copy finished in #{Time.now - start_time} seconds"
exit
end
rescue => e
raise e if backtrace
error_proc["Error: #{e.class}: #{e.message}#{e.backtrace.first}"]
end
if !ARGV.empty?
ARGV.each{|v| load(v)}
elsif !$stdin.isatty
eval($stdin.read)
else
require 'irb'
puts "Your database is stored in DB..."
IRB.start
end
Jump to Line
Something went wrong with that request. Please try again.