-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
sequel
executable file
·198 lines (168 loc) · 5.42 KB
/
sequel
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
#!/usr/bin/env ruby
require 'rubygems'
require 'optparse'
require 'sequel'
db_opts = {}
copy_databases = nil
dump_migration = nil
echo = nil
env = nil
logfile = nil
migrate_dir = nil
migrate_ver = nil
backtrace = nil
test_connection = true
load_dirs = []
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
end
opts.on("-D", "--dump-migration-same-db", "print database migration to STDOUT without type translation") do
dump_migration = :same_db
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("-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
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
test_connection = false
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 -D or -d with -m"] if dump_migration && migrate_dir
error_proc["Error: Cannot specify -C with -d, -D, or -m"] if copy_databases && (dump_migration || migrate_dir)
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?
db = Sequel::Database.new(:quote_identifiers=>false)
def db.connect(*args); Object.new; end
db.identifier_input_method = nil
db.identifier_output_method = nil
db
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.test_connection if test_connection
db
end
begin
DB = connect_proc[db]
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 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
puts "Databases connections successful"
schema_migration = eval(DB.dump_schema_migration(:indexes=>false, :same_db=>same_db))
index_migration = eval(DB.dump_indexes_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"
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
load_dirs.each{|d| Dir["#{d}/**/*.rb"].each{|f| load(f)}}
require 'irb'
puts "Your database is stored in DB..."
IRB.start