ardb 0.28.3 → 0.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -7
- data/Gemfile +4 -9
- data/README.md +252 -3
- data/ardb.gemspec +8 -7
- data/bin/ardb +1 -1
- data/lib/ardb.rb +35 -34
- data/lib/ardb/adapter/base.rb +34 -30
- data/lib/ardb/adapter/mysql.rb +2 -17
- data/lib/ardb/adapter/postgresql.rb +24 -30
- data/lib/ardb/adapter/sqlite.rb +4 -8
- data/lib/ardb/adapter_spy.rb +2 -16
- data/lib/ardb/cli.rb +15 -15
- data/lib/ardb/cli/clirb.rb +14 -17
- data/lib/ardb/cli/commands.rb +204 -114
- data/lib/ardb/db_tests.rb +2 -4
- data/lib/ardb/default_order_by.rb +3 -13
- data/lib/ardb/migration.rb +9 -13
- data/lib/ardb/record_spy.rb +7 -26
- data/lib/ardb/relation_spy.rb +0 -6
- data/lib/ardb/require_autoloaded_active_record_files.rb +103 -58
- data/lib/ardb/test_helpers.rb +2 -5
- data/lib/ardb/use_db_default.rb +4 -15
- data/lib/ardb/version.rb +1 -1
- data/script/determine_autoloaded_active_record_files.rb +11 -8
- data/test/helper.rb +4 -13
- data/test/support/factory.rb +2 -2
- data/test/support/postgresql/migrations/{.gitkeep → .keep} +0 -0
- data/test/support/postgresql/schema.rb +0 -1
- data/test/support/postgresql/setup_test_db.rb +14 -15
- data/test/system/.keep +0 -0
- data/test/unit/adapter/base_tests.rb +73 -53
- data/test/unit/adapter/mysql_tests.rb +2 -19
- data/test/unit/adapter/postgresql_tests.rb +14 -23
- data/test/unit/adapter/sqlite_tests.rb +3 -11
- data/test/unit/adapter_spy_tests.rb +2 -16
- data/test/unit/ardb_tests.rb +43 -43
- data/test/unit/cli_tests.rb +220 -158
- data/test/unit/db_tests_tests.rb +3 -6
- data/test/unit/default_order_by_tests.rb +4 -8
- data/test/unit/migration_tests.rb +11 -15
- data/test/unit/record_spy_tests.rb +17 -22
- data/test/unit/relation_spy_tests.rb +17 -46
- data/test/unit/test_helpers_tests.rb +3 -14
- data/test/unit/use_db_default_tests.rb +7 -11
- metadata +100 -84
- data/lib/ardb/has_slug.rb +0 -107
- data/lib/ardb/migration_helpers.rb +0 -77
- data/lib/ardb/pg_json.rb +0 -90
- data/test/support/postgresql/pg_json_migrations/20160519133432_create_pg_json_migrate_test.rb +0 -13
- data/test/system/pg_json_tests.rb +0 -85
- data/test/unit/has_slug_tests.rb +0 -341
- data/test/unit/migration_helpers_tests.rb +0 -65
- data/test/unit/pg_json_tests.rb +0 -39
data/lib/ardb/adapter/base.rb
CHANGED
@@ -1,14 +1,13 @@
|
|
1
|
-
require
|
1
|
+
require "ardb"
|
2
2
|
|
3
3
|
module Ardb; end
|
4
4
|
module Ardb::Adapter
|
5
|
-
|
6
5
|
class Base
|
7
|
-
|
8
6
|
attr_reader :config
|
9
7
|
|
10
8
|
def initialize(config)
|
11
9
|
@config = config
|
10
|
+
validate!
|
12
11
|
end
|
13
12
|
|
14
13
|
def connect_hash; self.config.activerecord_connect_hash; end
|
@@ -33,9 +32,6 @@ module Ardb::Adapter
|
|
33
32
|
pattern
|
34
33
|
end
|
35
34
|
|
36
|
-
def foreign_key_add_sql(*args); raise NotImplementedError; end
|
37
|
-
def foreign_key_drop_sql(*args); raise NotImplementedError; end
|
38
|
-
|
39
35
|
def create_db(*args); raise NotImplementedError; end
|
40
36
|
def drop_db(*args); raise NotImplementedError; end
|
41
37
|
|
@@ -43,33 +39,34 @@ module Ardb::Adapter
|
|
43
39
|
|
44
40
|
def connect_db
|
45
41
|
ActiveRecord::Base.establish_connection(self.connect_hash)
|
46
|
-
# checkout a connection to ensure we can connect to the DB, we don
|
42
|
+
# checkout a connection to ensure we can connect to the DB, we don"t do
|
47
43
|
# anything with the connection and immediately check it back in
|
48
44
|
ActiveRecord::Base.connection_pool.with_connection{ }
|
49
45
|
end
|
50
46
|
|
51
47
|
def migrate_db
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
if defined?(ActiveRecord::Migration::CommandRecorder)
|
56
|
-
require 'ardb/migration_helpers'
|
57
|
-
ActiveRecord::Migration::CommandRecorder.class_eval do
|
58
|
-
include Ardb::MigrationHelpers::RecorderMixin
|
59
|
-
end
|
60
|
-
end
|
48
|
+
migrate_db_up
|
49
|
+
end
|
61
50
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
51
|
+
def migrate_db_up(target_version = nil)
|
52
|
+
migration_context.up(target_version)
|
53
|
+
end
|
54
|
+
|
55
|
+
def migrate_db_down(target_version = nil)
|
56
|
+
migration_context.down(target_version)
|
57
|
+
end
|
58
|
+
|
59
|
+
def migrate_db_forward(steps = 1)
|
60
|
+
migration_context.forward(steps)
|
61
|
+
end
|
62
|
+
|
63
|
+
def migrate_db_backward(steps = 1)
|
64
|
+
migration_context.rollback(steps)
|
67
65
|
end
|
68
66
|
|
69
67
|
def load_schema
|
70
|
-
# silence STDOUT
|
71
|
-
|
72
|
-
$stdout = File.new('/dev/null', 'w')
|
68
|
+
current_stdout = $stdout.dup # silence STDOUT
|
69
|
+
$stdout = File.new("/dev/null", "w")
|
73
70
|
load_ruby_schema if self.schema_format == Ardb::Config::RUBY_SCHEMA_FORMAT
|
74
71
|
load_sql_schema if self.schema_format == Ardb::Config::SQL_SCHEMA_FORMAT
|
75
72
|
$stdout = current_stdout
|
@@ -84,18 +81,17 @@ module Ardb::Adapter
|
|
84
81
|
end
|
85
82
|
|
86
83
|
def dump_schema
|
87
|
-
# silence STDOUT
|
88
|
-
|
89
|
-
$stdout = File.new('/dev/null', 'w')
|
84
|
+
current_stdout = $stdout.dup # silence STDOUT
|
85
|
+
$stdout = File.new("/dev/null", "w")
|
90
86
|
dump_ruby_schema
|
91
87
|
dump_sql_schema if self.schema_format == Ardb::Config::SQL_SCHEMA_FORMAT
|
92
88
|
$stdout = current_stdout
|
93
89
|
end
|
94
90
|
|
95
91
|
def dump_ruby_schema
|
96
|
-
require
|
92
|
+
require "active_record/schema_dumper"
|
97
93
|
FileUtils.mkdir_p File.dirname(self.ruby_schema_path)
|
98
|
-
File.open(self.ruby_schema_path,
|
94
|
+
File.open(self.ruby_schema_path, "w:utf-8") do |file|
|
99
95
|
ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file)
|
100
96
|
end
|
101
97
|
end
|
@@ -112,6 +108,14 @@ module Ardb::Adapter
|
|
112
108
|
end
|
113
109
|
end
|
114
110
|
|
115
|
-
|
111
|
+
private
|
116
112
|
|
113
|
+
def validate!
|
114
|
+
# override as needed
|
115
|
+
end
|
116
|
+
|
117
|
+
def migration_context
|
118
|
+
ActiveRecord::MigrationContext.new(migrations_path)
|
119
|
+
end
|
120
|
+
end
|
117
121
|
end
|
data/lib/ardb/adapter/mysql.rb
CHANGED
@@ -1,21 +1,6 @@
|
|
1
|
-
require
|
1
|
+
require "ardb/adapter/base"
|
2
2
|
|
3
3
|
module Ardb::Adapter
|
4
|
-
|
5
|
-
class Mysql < Base
|
6
|
-
|
7
|
-
def foreign_key_add_sql
|
8
|
-
"ALTER TABLE :from_table"\
|
9
|
-
" ADD CONSTRAINT :name"\
|
10
|
-
" FOREIGN KEY (:from_column)"\
|
11
|
-
" REFERENCES :to_table (:to_column)"
|
12
|
-
end
|
13
|
-
|
14
|
-
def foreign_key_drop_sql
|
15
|
-
"ALTER TABLE :from_table"\
|
16
|
-
" DROP FOREIGN KEY :name"
|
17
|
-
end
|
18
|
-
|
4
|
+
class Mysql < Ardb::Adapter::Base
|
19
5
|
end
|
20
|
-
|
21
6
|
end
|
@@ -1,16 +1,14 @@
|
|
1
|
-
require
|
1
|
+
require "ardb/adapter/base"
|
2
2
|
|
3
3
|
module Ardb::Adapter
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
# the 'postgres' db is a "public" (doesn't typically require auth/grants to
|
4
|
+
class Postgresql < Ardb::Adapter::Base
|
5
|
+
# the "postgres" db is a "public" (doesn"t typically require auth/grants to
|
8
6
|
# connect to) db that typically exists for all postgres installations; the
|
9
7
|
# adapter uses it to create/drop other databases
|
10
8
|
def public_connect_hash
|
11
9
|
@public_connect_hash ||= self.connect_hash.merge({
|
12
|
-
|
13
|
-
|
10
|
+
"database" => "postgres",
|
11
|
+
"schema_search_path" => "public"
|
14
12
|
})
|
15
13
|
end
|
16
14
|
|
@@ -42,47 +40,43 @@ module Ardb::Adapter
|
|
42
40
|
tables = conn.execute "SELECT table_name"\
|
43
41
|
" FROM information_schema.tables"\
|
44
42
|
" WHERE table_schema = 'public';"
|
45
|
-
tables.each{ |row| conn.execute "DROP TABLE #{row[
|
43
|
+
tables.each{ |row| conn.execute "DROP TABLE #{row["table_name"]} CASCADE" }
|
46
44
|
end
|
47
45
|
end
|
48
46
|
|
49
|
-
def foreign_key_add_sql
|
50
|
-
"ALTER TABLE :from_table"\
|
51
|
-
" ADD CONSTRAINT :name"\
|
52
|
-
" FOREIGN KEY (:from_column)"\
|
53
|
-
" REFERENCES :to_table (:to_column)"
|
54
|
-
end
|
55
|
-
|
56
|
-
def foreign_key_drop_sql
|
57
|
-
"ALTER TABLE :from_table"\
|
58
|
-
" DROP CONSTRAINT :name"
|
59
|
-
end
|
60
|
-
|
61
47
|
def load_sql_schema
|
62
|
-
require
|
48
|
+
require "scmd"
|
63
49
|
cmd_str = "psql -f \"#{self.sql_schema_path}\" #{self.database}"
|
64
50
|
cmd = Scmd.new(cmd_str, :env => env_var_hash).tap(&:run)
|
65
|
-
raise
|
51
|
+
raise "Error loading database" unless cmd.success?
|
66
52
|
end
|
67
53
|
|
68
54
|
def dump_sql_schema
|
69
|
-
require
|
55
|
+
require "scmd"
|
70
56
|
cmd_str = "pg_dump -i -s -x -O -f \"#{self.sql_schema_path}\" #{self.database}"
|
71
57
|
cmd = Scmd.new(cmd_str, :env => env_var_hash).tap(&:run)
|
72
|
-
raise
|
58
|
+
raise "Error dumping database" unless cmd.success?
|
73
59
|
end
|
74
60
|
|
75
61
|
private
|
76
62
|
|
63
|
+
def validate!
|
64
|
+
if self.database =~ /\W/
|
65
|
+
raise(
|
66
|
+
Ardb::ConfigurationError,
|
67
|
+
"database value must not contain non-word characters. "\
|
68
|
+
"Given: #{self.database.inspect}."
|
69
|
+
)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
77
73
|
def env_var_hash
|
78
74
|
@env_var_hash ||= {
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
75
|
+
"PGHOST" => self.connect_hash["host"],
|
76
|
+
"PGPORT" => self.connect_hash["port"],
|
77
|
+
"PGUSER" => self.connect_hash["username"],
|
78
|
+
"PGPASSWORD" => self.connect_hash["password"]
|
83
79
|
}
|
84
80
|
end
|
85
|
-
|
86
81
|
end
|
87
|
-
|
88
82
|
end
|
data/lib/ardb/adapter/sqlite.rb
CHANGED
@@ -1,11 +1,9 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require "fileutils"
|
2
|
+
require "ardb"
|
3
|
+
require "ardb/adapter/base"
|
4
4
|
|
5
5
|
module Ardb::Adapter
|
6
|
-
|
7
|
-
class Sqlite < Base
|
8
|
-
|
6
|
+
class Sqlite < Ardb::Adapter::Base
|
9
7
|
def db_file_path
|
10
8
|
File.expand_path(self.database, self.config.root_path)
|
11
9
|
end
|
@@ -25,7 +23,5 @@ module Ardb::Adapter
|
|
25
23
|
def drop_db
|
26
24
|
FileUtils.rm(self.db_file_path) if File.exist?(self.db_file_path)
|
27
25
|
end
|
28
|
-
|
29
26
|
end
|
30
|
-
|
31
27
|
end
|
data/lib/ardb/adapter_spy.rb
CHANGED
@@ -1,10 +1,8 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "ardb"
|
2
|
+
require "ardb/adapter/base"
|
3
3
|
|
4
4
|
module Ardb
|
5
|
-
|
6
5
|
class AdapterSpy < Ardb::Adapter::Base
|
7
|
-
|
8
6
|
attr_accessor :drop_tables_called_count
|
9
7
|
attr_accessor :dump_schema_called_count, :load_schema_called_count
|
10
8
|
attr_accessor :drop_db_called_count, :create_db_called_count
|
@@ -51,16 +49,6 @@ module Ardb
|
|
51
49
|
|
52
50
|
# Overwritten `Adapter::Base` methods
|
53
51
|
|
54
|
-
def foreign_key_add_sql
|
55
|
-
"FAKE ADD FOREIGN KEY SQL :from_table :from_column " \
|
56
|
-
":to_table :to_column :name"
|
57
|
-
end
|
58
|
-
|
59
|
-
def foreign_key_drop_sql
|
60
|
-
"FAKE DROP FOREIGN KEY SQL :from_table :from_column " \
|
61
|
-
":to_table :to_column :name"
|
62
|
-
end
|
63
|
-
|
64
52
|
def create_db(*args, &block)
|
65
53
|
self.create_db_called_count += 1
|
66
54
|
end
|
@@ -88,7 +76,5 @@ module Ardb
|
|
88
76
|
def dump_schema(*args, &block)
|
89
77
|
self.dump_schema_called_count += 1
|
90
78
|
end
|
91
|
-
|
92
79
|
end
|
93
|
-
|
94
80
|
end
|
data/lib/ardb/cli.rb
CHANGED
@@ -1,17 +1,19 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require "ardb/cli/clirb"
|
2
|
+
require "ardb/cli/commands"
|
3
|
+
require "ardb/version"
|
4
4
|
|
5
5
|
module Ardb
|
6
|
-
|
7
6
|
class CLI
|
8
|
-
|
9
7
|
COMMANDS = CommandSet.new{ |unknown| InvalidCommand.new(unknown) }.tap do |c|
|
10
|
-
c.add(ConnectCommand
|
11
|
-
c.add(CreateCommand
|
12
|
-
c.add(DropCommand
|
13
|
-
c.add(
|
14
|
-
c.add(
|
8
|
+
c.add(ConnectCommand)
|
9
|
+
c.add(CreateCommand)
|
10
|
+
c.add(DropCommand)
|
11
|
+
c.add(GenerateMigrationCommand)
|
12
|
+
c.add(MigrateCommand)
|
13
|
+
c.add(MigrateUpCommand)
|
14
|
+
c.add(MigrateDownCommand)
|
15
|
+
c.add(MigrateForwardCommand)
|
16
|
+
c.add(MigrateBackwardCommand)
|
15
17
|
end
|
16
18
|
|
17
19
|
def self.run(args)
|
@@ -32,13 +34,13 @@ module Ardb
|
|
32
34
|
cmd = COMMANDS[cmd_name]
|
33
35
|
cmd.run(args)
|
34
36
|
rescue CLIRB::HelpExit
|
35
|
-
@stdout.puts cmd.
|
37
|
+
@stdout.puts cmd.command_help
|
36
38
|
rescue CLIRB::VersionExit
|
37
39
|
@stdout.puts Ardb::VERSION
|
38
40
|
rescue CLIRB::Error, ArgumentError, InvalidCommandError => exception
|
39
41
|
display_debug(exception)
|
40
42
|
@stderr.puts "#{exception.message}\n\n"
|
41
|
-
@stdout.puts cmd.
|
43
|
+
@stdout.puts cmd.command_help
|
42
44
|
@kernel.exit 1
|
43
45
|
rescue CommandExitError
|
44
46
|
@kernel.exit 1
|
@@ -53,12 +55,10 @@ module Ardb
|
|
53
55
|
private
|
54
56
|
|
55
57
|
def display_debug(exception)
|
56
|
-
if ENV[
|
58
|
+
if ENV["DEBUG"]
|
57
59
|
@stderr.puts "#{exception.class}: #{exception.message}"
|
58
60
|
@stderr.puts exception.backtrace.join("\n")
|
59
61
|
end
|
60
62
|
end
|
61
|
-
|
62
63
|
end
|
63
|
-
|
64
64
|
end
|
data/lib/ardb/cli/clirb.rb
CHANGED
@@ -1,20 +1,19 @@
|
|
1
1
|
module Ardb; end
|
2
2
|
class Ardb::CLI
|
3
|
-
|
4
|
-
class CLIRB # Version 1.0.0, https://github.com/redding/cli.rb
|
3
|
+
class CLIRB # Version 1.1.0, https://github.com/redding/cli.rb
|
5
4
|
Error = Class.new(RuntimeError);
|
6
5
|
HelpExit = Class.new(RuntimeError); VersionExit = Class.new(RuntimeError)
|
7
6
|
attr_reader :argv, :args, :opts, :data
|
8
7
|
|
9
8
|
def initialize(&block)
|
10
9
|
@options = []; instance_eval(&block) if block
|
11
|
-
require
|
10
|
+
require "optparse"
|
12
11
|
@data, @args, @opts = [], [], {}; @parser = OptionParser.new do |p|
|
13
|
-
p.banner =
|
12
|
+
p.banner = ""; @options.each do |o|
|
14
13
|
@opts[o.name] = o.value; p.on(*o.parser_args){ |v| @opts[o.name] = v }
|
15
14
|
end
|
16
|
-
p.on_tail(
|
17
|
-
p.on_tail(
|
15
|
+
p.on_tail("--version", ""){ |v| raise VersionExit, v.to_s }
|
16
|
+
p.on_tail("--help", ""){ |v| raise HelpExit, v.to_s }
|
18
17
|
end
|
19
18
|
end
|
20
19
|
|
@@ -27,33 +26,31 @@ class Ardb::CLI
|
|
27
26
|
end
|
28
27
|
def to_s; @parser.to_s; end
|
29
28
|
def inspect
|
30
|
-
"#<#{self.class}:#{
|
29
|
+
"#<#{self.class}:#{"0x0%x" % (object_id << 1)} @data=#{@data.inspect}>"
|
31
30
|
end
|
32
31
|
|
33
32
|
class Option
|
34
33
|
attr_reader :name, :opt_name, :desc, :abbrev, :value, :klass, :parser_args
|
35
34
|
|
36
|
-
def initialize(name,
|
37
|
-
|
38
|
-
@
|
39
|
-
@value, @klass = gvalinfo(
|
35
|
+
def initialize(name, desc = nil, abbrev: nil, value: nil)
|
36
|
+
@name, @desc = name, desc || ""
|
37
|
+
@opt_name, @abbrev = parse_name_values(name, abbrev)
|
38
|
+
@value, @klass = gvalinfo(value)
|
40
39
|
@parser_args = if [TrueClass, FalseClass, NilClass].include?(@klass)
|
41
40
|
["-#{@abbrev}", "--[no-]#{@opt_name}", @desc]
|
42
41
|
else
|
43
|
-
["-#{@abbrev}", "--#{@opt_name}
|
42
|
+
["-#{@abbrev}", "--#{@opt_name} VALUE", @klass, @desc]
|
44
43
|
end
|
45
44
|
end
|
46
45
|
|
47
46
|
private
|
48
47
|
|
49
48
|
def parse_name_values(name, custom_abbrev)
|
50
|
-
[ (processed_name = name.to_s.strip.downcase)
|
51
|
-
custom_abbrev || processed_name.gsub(/[^a-z]/,
|
49
|
+
[ (processed_name = name.to_s.strip.downcase).gsub("_", "-"),
|
50
|
+
custom_abbrev || processed_name.gsub(/[^a-z]/, "").chars.first || "a"
|
52
51
|
]
|
53
52
|
end
|
54
|
-
def gvalinfo(v); v.kind_of?(Class) ? [nil,
|
55
|
-
def gklass(k); k == Fixnum ? Integer : k; end
|
53
|
+
def gvalinfo(v); v.kind_of?(Class) ? [nil,v] : [v,v.class]; end
|
56
54
|
end
|
57
55
|
end
|
58
|
-
|
59
56
|
end
|
data/lib/ardb/cli/commands.rb
CHANGED
@@ -1,15 +1,13 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require "ardb"
|
2
|
+
require "ardb/cli/clirb"
|
3
|
+
require "much-plugin"
|
4
4
|
|
5
5
|
module Ardb; end
|
6
6
|
class Ardb::CLI
|
7
|
-
|
8
7
|
InvalidCommandError = Class.new(ArgumentError)
|
9
8
|
CommandExitError = Class.new(RuntimeError)
|
10
9
|
|
11
10
|
class InvalidCommand
|
12
|
-
|
13
11
|
attr_reader :name, :clirb
|
14
12
|
|
15
13
|
def initialize(name)
|
@@ -22,27 +20,26 @@ class Ardb::CLI
|
|
22
20
|
def run(argv)
|
23
21
|
@clirb.parse!([@name, argv].flatten.compact)
|
24
22
|
raise CLIRB::HelpExit if @name.to_s.empty?
|
25
|
-
raise InvalidCommandError, "
|
23
|
+
raise InvalidCommandError, "\"#{self.name}\" is not a command."
|
26
24
|
end
|
27
25
|
|
28
|
-
def
|
26
|
+
def command_help
|
29
27
|
"Usage: ardb [COMMAND] [options]\n\n" \
|
30
28
|
"Options: #{@clirb}\n" \
|
31
29
|
"Commands:\n" \
|
32
30
|
"#{COMMANDS.to_s.split("\n").map{ |l| " #{l}" }.join("\n")}\n"
|
33
31
|
end
|
34
|
-
|
35
32
|
end
|
36
33
|
|
37
34
|
module ValidCommand
|
38
35
|
include MuchPlugin
|
39
36
|
|
40
|
-
|
41
|
-
|
37
|
+
plugin_class_methods do
|
38
|
+
def command_name; raise NotImplementedError; end
|
39
|
+
def command_summary; ""; end
|
42
40
|
end
|
43
41
|
|
44
|
-
|
45
|
-
|
42
|
+
plugin_instance_methods do
|
46
43
|
def initialize(&clirb_build)
|
47
44
|
@clirb = CLIRB.new(&clirb_build)
|
48
45
|
end
|
@@ -55,24 +52,34 @@ class Ardb::CLI
|
|
55
52
|
@stderr = stderr || $stderr
|
56
53
|
end
|
57
54
|
|
58
|
-
def
|
59
|
-
|
60
|
-
end
|
55
|
+
def command_name; self.class.command_name; end
|
56
|
+
def command_summary; self.class.command_summary; end
|
61
57
|
|
58
|
+
def command_help
|
59
|
+
"Usage: ardb #{self.command_name} [options]\n\n" \
|
60
|
+
"Options: #{self.clirb}\n" \
|
61
|
+
"Description:\n" \
|
62
|
+
" #{self.command_summary}"
|
63
|
+
end
|
62
64
|
end
|
63
|
-
|
64
65
|
end
|
65
66
|
|
66
67
|
class ConnectCommand
|
67
68
|
include ValidCommand
|
68
69
|
|
70
|
+
def self.command_name; "connect"; end
|
71
|
+
def self.command_summary; "Connect to the configured DB"; end
|
72
|
+
|
69
73
|
def run(argv, *args)
|
70
74
|
super
|
71
75
|
|
72
|
-
Ardb.init(false)
|
73
76
|
begin
|
77
|
+
Ardb.init(false)
|
74
78
|
Ardb.adapter.connect_db
|
75
|
-
@stdout.puts "connected to #{Ardb.config.adapter} db
|
79
|
+
@stdout.puts "connected to #{Ardb.config.adapter} db #{Ardb.config.database.inspect}"
|
80
|
+
rescue ActiveRecord::NoDatabaseError => e
|
81
|
+
@stderr.puts "error: database #{Ardb.config.database.inspect} "\
|
82
|
+
"does not exist"
|
76
83
|
rescue StandardError => e
|
77
84
|
@stderr.puts e
|
78
85
|
@stderr.puts e.backtrace.join("\n")
|
@@ -81,150 +88,237 @@ class Ardb::CLI
|
|
81
88
|
raise CommandExitError
|
82
89
|
end
|
83
90
|
end
|
84
|
-
|
85
|
-
def summary
|
86
|
-
"Connect to the configured DB"
|
87
|
-
end
|
88
|
-
|
89
|
-
def help
|
90
|
-
"Usage: ardb connect [options]\n\n" \
|
91
|
-
"Options: #{@clirb}\n" \
|
92
|
-
"Description:\n" \
|
93
|
-
" #{self.summary}"
|
94
|
-
end
|
95
|
-
|
96
91
|
end
|
97
92
|
|
98
93
|
class CreateCommand
|
99
94
|
include ValidCommand
|
100
95
|
|
96
|
+
def self.command_name; "create"; end
|
97
|
+
def self.command_summary; "Create the configured DB"; end
|
98
|
+
|
101
99
|
def run(argv, *args)
|
102
100
|
super
|
103
101
|
|
104
|
-
Ardb.init(false)
|
105
102
|
begin
|
103
|
+
Ardb.init(false)
|
106
104
|
Ardb.adapter.create_db
|
107
|
-
@stdout.puts "created #{Ardb.config.adapter} db
|
105
|
+
@stdout.puts "created #{Ardb.config.adapter} db #{Ardb.config.database.inspect}"
|
106
|
+
rescue ActiveRecord::StatementInvalid => e
|
107
|
+
@stderr.puts "error: database #{Ardb.config.database.inspect} "\
|
108
|
+
"already exists"
|
108
109
|
rescue StandardError => e
|
109
110
|
@stderr.puts e
|
110
111
|
@stderr.puts "error creating #{Ardb.config.database.inspect} database"
|
111
112
|
raise CommandExitError
|
112
113
|
end
|
113
114
|
end
|
114
|
-
|
115
|
-
def summary
|
116
|
-
"Create the configured DB"
|
117
|
-
end
|
118
|
-
|
119
|
-
def help
|
120
|
-
"Usage: ardb create [options]\n\n" \
|
121
|
-
"Options: #{@clirb}\n" \
|
122
|
-
"Description:\n" \
|
123
|
-
" #{self.summary}"
|
124
|
-
end
|
125
|
-
|
126
115
|
end
|
127
116
|
|
128
117
|
class DropCommand
|
129
118
|
include ValidCommand
|
130
119
|
|
120
|
+
def self.command_name; "drop"; end
|
121
|
+
def self.command_summary; "Drop the configured DB"; end
|
122
|
+
|
131
123
|
def run(argv, *args)
|
132
124
|
super
|
133
125
|
|
134
|
-
Ardb.init(true)
|
135
126
|
begin
|
127
|
+
Ardb.init(true)
|
136
128
|
Ardb.adapter.drop_db
|
137
|
-
@stdout.puts "dropped #{Ardb.config.adapter} db
|
129
|
+
@stdout.puts "dropped #{Ardb.config.adapter} db #{Ardb.config.database.inspect}"
|
130
|
+
rescue ActiveRecord::NoDatabaseError => e
|
131
|
+
@stderr.puts "error: database #{Ardb.config.database.inspect} "\
|
132
|
+
"does not exist"
|
138
133
|
rescue StandardError => e
|
139
134
|
@stderr.puts e
|
140
135
|
@stderr.puts "error dropping #{Ardb.config.database.inspect} database"
|
141
136
|
raise CommandExitError
|
142
137
|
end
|
143
138
|
end
|
144
|
-
|
145
|
-
def summary
|
146
|
-
"Drop the configured DB"
|
147
|
-
end
|
148
|
-
|
149
|
-
def help
|
150
|
-
"Usage: ardb drop [options]\n\n" \
|
151
|
-
"Options: #{@clirb}\n" \
|
152
|
-
"Description:\n" \
|
153
|
-
" #{self.summary}"
|
154
|
-
end
|
155
|
-
|
156
139
|
end
|
157
140
|
|
158
|
-
class
|
141
|
+
class GenerateMigrationCommand
|
159
142
|
include ValidCommand
|
160
143
|
|
144
|
+
def self.command_name; "generate-migration"; end
|
145
|
+
def self.command_summary; "Generate a MIGRATION-NAME migration file"; end
|
146
|
+
|
161
147
|
def run(argv, *args)
|
162
148
|
super
|
163
149
|
|
164
|
-
Ardb.init(true)
|
165
150
|
begin
|
166
|
-
Ardb.
|
167
|
-
|
151
|
+
Ardb.init(false)
|
152
|
+
|
153
|
+
require "ardb/migration"
|
154
|
+
migration = Ardb::Migration.new(Ardb.config, @clirb.args.first)
|
155
|
+
migration.save!
|
156
|
+
@stdout.puts "generated #{migration.file_path}"
|
157
|
+
rescue Ardb::Migration::NoIdentifierError => exception
|
158
|
+
error = ArgumentError.new("MIGRATION-NAME must be provided")
|
159
|
+
error.set_backtrace(exception.backtrace)
|
160
|
+
raise error
|
168
161
|
rescue StandardError => e
|
169
162
|
@stderr.puts e
|
170
163
|
@stderr.puts e.backtrace.join("\n")
|
171
|
-
@stderr.puts "error
|
164
|
+
@stderr.puts "error generating migration"
|
172
165
|
raise CommandExitError
|
173
166
|
end
|
174
167
|
end
|
175
168
|
|
176
|
-
def
|
177
|
-
"
|
169
|
+
def command_help
|
170
|
+
"Usage: ardb #{self.command_name} MIGRATION-NAME [options]\n\n" \
|
171
|
+
"Options: #{self.clirb}\n" \
|
172
|
+
"Description:\n" \
|
173
|
+
" #{self.command_summary}"
|
178
174
|
end
|
175
|
+
end
|
179
176
|
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
177
|
+
module MigrateCommandBehaviors
|
178
|
+
include MuchPlugin
|
179
|
+
|
180
|
+
plugin_included do
|
181
|
+
include ValidCommand
|
185
182
|
end
|
186
183
|
|
184
|
+
plugin_instance_methods do
|
185
|
+
def migrate; raise NotImplementedError; end
|
186
|
+
|
187
|
+
def run(argv, *args)
|
188
|
+
super
|
189
|
+
|
190
|
+
begin
|
191
|
+
Ardb.init(true)
|
192
|
+
self.migrate
|
193
|
+
Ardb.adapter.dump_schema unless ENV["ARDB_MIGRATE_NO_SCHEMA"]
|
194
|
+
rescue ActiveRecord::NoDatabaseError => e
|
195
|
+
@stderr.puts "error: database #{Ardb.config.database.inspect} "\
|
196
|
+
"does not exist"
|
197
|
+
rescue StandardError => e
|
198
|
+
@stderr.puts e
|
199
|
+
@stderr.puts e.backtrace.join("\n")
|
200
|
+
@stderr.puts "error migrating #{Ardb.config.database.inspect} database"
|
201
|
+
raise CommandExitError
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
187
205
|
end
|
188
206
|
|
189
|
-
class
|
190
|
-
include
|
207
|
+
class MigrateCommand
|
208
|
+
include MigrateCommandBehaviors
|
191
209
|
|
192
|
-
def
|
193
|
-
|
210
|
+
def self.command_name; "migrate"; end
|
211
|
+
def self.command_summary; "Migrate the configured DB"; end
|
194
212
|
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
213
|
+
def migrate
|
214
|
+
Ardb.adapter.migrate_db
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
module MigrateStyleBehaviors
|
219
|
+
include MuchPlugin
|
220
|
+
|
221
|
+
plugin_included do
|
222
|
+
include MigrateCommandBehaviors
|
223
|
+
end
|
224
|
+
|
225
|
+
plugin_class_methods do
|
226
|
+
def command_style; raise NotImplementedError; end
|
227
|
+
|
228
|
+
def command_name; "migrate-#{self.command_style}"; end
|
229
|
+
def command_summary; "Migrate the configured DB #{self.command_style}"; end
|
230
|
+
end
|
231
|
+
|
232
|
+
plugin_instance_methods do
|
233
|
+
def migrate
|
234
|
+
Ardb.adapter.send("migrate_db_#{self.class.command_style}", *migrate_args)
|
210
235
|
end
|
236
|
+
|
237
|
+
private
|
238
|
+
|
239
|
+
def migrate_args; raise NotImplementedError; end
|
211
240
|
end
|
241
|
+
end
|
212
242
|
|
213
|
-
|
214
|
-
|
243
|
+
module MigrateDirectionBehaviors
|
244
|
+
include MuchPlugin
|
245
|
+
|
246
|
+
plugin_included do
|
247
|
+
include MigrateStyleBehaviors
|
215
248
|
end
|
216
249
|
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
250
|
+
plugin_class_methods do
|
251
|
+
def command_style; self.command_direction; end
|
252
|
+
def command_direction; raise NotImplementedError; end
|
253
|
+
end
|
254
|
+
|
255
|
+
plugin_instance_methods do
|
256
|
+
def initialize
|
257
|
+
super do
|
258
|
+
option(:target_version, "version to migrate to", value: String)
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
private
|
263
|
+
|
264
|
+
def migrate_args
|
265
|
+
[@clirb.opts[:target_version]]
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
module MigrateStepDirectionBehaviors
|
271
|
+
include MuchPlugin
|
272
|
+
|
273
|
+
plugin_included do
|
274
|
+
include MigrateStyleBehaviors
|
275
|
+
end
|
276
|
+
|
277
|
+
plugin_class_methods do
|
278
|
+
def command_style; self.command_direction; end
|
279
|
+
def command_direction; raise NotImplementedError; end
|
222
280
|
end
|
223
281
|
|
282
|
+
plugin_instance_methods do
|
283
|
+
def initialize
|
284
|
+
super do
|
285
|
+
option(:steps, "number of migrations to migrate", value: 1)
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
private
|
290
|
+
|
291
|
+
def migrate_args
|
292
|
+
[@clirb.opts[:steps]]
|
293
|
+
end
|
294
|
+
end
|
224
295
|
end
|
225
296
|
|
226
|
-
class
|
297
|
+
class MigrateUpCommand
|
298
|
+
include MigrateDirectionBehaviors
|
299
|
+
|
300
|
+
def self.command_direction; "up"; end
|
301
|
+
end
|
302
|
+
|
303
|
+
class MigrateDownCommand
|
304
|
+
include MigrateDirectionBehaviors
|
227
305
|
|
306
|
+
def self.command_direction; "down"; end
|
307
|
+
end
|
308
|
+
|
309
|
+
class MigrateForwardCommand
|
310
|
+
include MigrateStepDirectionBehaviors
|
311
|
+
|
312
|
+
def self.command_direction; "forward"; end
|
313
|
+
end
|
314
|
+
|
315
|
+
class MigrateBackwardCommand
|
316
|
+
include MigrateStepDirectionBehaviors
|
317
|
+
|
318
|
+
def self.command_direction; "backward"; end
|
319
|
+
end
|
320
|
+
|
321
|
+
class CommandSet
|
228
322
|
def initialize(&unknown_cmd_block)
|
229
323
|
@lookup = Hash.new{ |h,k| unknown_cmd_block.call(k) }
|
230
324
|
@names = []
|
@@ -232,29 +326,28 @@ class Ardb::CLI
|
|
232
326
|
@summaries = {}
|
233
327
|
end
|
234
328
|
|
235
|
-
def add(klass
|
329
|
+
def add(klass)
|
236
330
|
begin
|
237
331
|
cmd = klass.new
|
238
|
-
rescue StandardError
|
239
|
-
# don
|
332
|
+
rescue StandardError
|
333
|
+
# don"t add any commands you can"t initialize
|
240
334
|
else
|
241
|
-
|
335
|
+
@lookup[cmd.command_name] = cmd
|
242
336
|
@to_s = nil
|
243
|
-
@names <<
|
244
|
-
@
|
245
|
-
@summaries[name] = cmd.summary.to_s.empty? ? '' : "# #{cmd.summary}"
|
337
|
+
@names << cmd.command_name
|
338
|
+
@summaries[cmd.command_name] = cmd.command_summary.to_s
|
246
339
|
end
|
247
340
|
end
|
248
341
|
|
249
|
-
def remove(
|
250
|
-
@lookup.delete(
|
251
|
-
@names.delete(
|
252
|
-
@
|
342
|
+
def remove(klass)
|
343
|
+
@lookup.delete(klass.command_name)
|
344
|
+
@names.delete(klass.command_name)
|
345
|
+
@summaries.delete(klass.command_name)
|
253
346
|
@to_s = nil
|
254
347
|
end
|
255
348
|
|
256
|
-
def [](
|
257
|
-
@lookup[
|
349
|
+
def [](cmd_name)
|
350
|
+
@lookup[cmd_name]
|
258
351
|
end
|
259
352
|
|
260
353
|
def size
|
@@ -263,13 +356,10 @@ class Ardb::CLI
|
|
263
356
|
|
264
357
|
def to_s
|
265
358
|
max_name_size = @names.map{ |n| n.size }.max || 0
|
266
|
-
max_alias_size = @aliases.values.map{ |v| v.size }.max || 0
|
267
359
|
|
268
360
|
@to_s ||= @names.map do |n|
|
269
|
-
"#{n.ljust(max_name_size)} #{@
|
361
|
+
"#{n.ljust(max_name_size)} #{@summaries[n]}"
|
270
362
|
end.join("\n")
|
271
363
|
end
|
272
|
-
|
273
364
|
end
|
274
|
-
|
275
365
|
end
|