ardb 0.28.3 → 0.30.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/.l.yml +9 -0
- data/.rubocop.yml +3 -0
- data/.ruby-version +1 -0
- data/.t.yml +6 -0
- data/Gemfile +24 -8
- data/README.md +252 -3
- data/ardb.gemspec +14 -10
- data/bin/ardb +3 -1
- data/lib/ardb/adapter/base.rb +72 -47
- data/lib/ardb/adapter/mysql.rb +4 -17
- data/lib/ardb/adapter/postgresql.rb +51 -46
- data/lib/ardb/adapter/sqlite.rb +11 -15
- data/lib/ardb/adapter_spy.rb +18 -30
- data/lib/ardb/cli/clirb.rb +16 -18
- data/lib/ardb/cli/commands.rb +308 -129
- data/lib/ardb/cli.rb +29 -24
- data/lib/ardb/db_tests.rb +4 -4
- data/lib/ardb/default_order_by.rb +13 -21
- data/lib/ardb/migration.rb +15 -16
- data/lib/ardb/record_spy.rb +46 -61
- data/lib/ardb/relation_spy.rb +28 -32
- data/lib/ardb/require_autoloaded_active_record_files.rb +258 -57
- data/lib/ardb/test_helpers.rb +33 -29
- data/lib/ardb/use_db_default.rb +13 -21
- data/lib/ardb/version.rb +3 -1
- data/lib/ardb.rb +105 -86
- data/script/determine_autoloaded_active_record_files.rb +31 -24
- data/test/helper.rb +6 -13
- data/test/support/factory.rb +4 -3
- data/test/support/fake_schema.rb +3 -1
- data/test/support/postgresql/migrations/{.gitkeep → .keep} +0 -0
- data/test/support/postgresql/schema.rb +2 -1
- data/test/support/postgresql/setup_test_db.rb +23 -21
- data/test/support/relative_require_test_db_file.rb +1 -0
- data/test/support/require_test_db_file.rb +1 -0
- data/test/system/.keep +0 -0
- data/test/unit/adapter/base_tests.rb +80 -55
- data/test/unit/adapter/mysql_tests.rb +4 -19
- data/test/unit/adapter/postgresql_tests.rb +21 -30
- data/test/unit/adapter/sqlite_tests.rb +5 -11
- data/test/unit/adapter_spy_tests.rb +6 -17
- data/test/unit/ardb_tests.rb +75 -53
- data/test/unit/cli_tests.rb +234 -158
- data/test/unit/db_tests_tests.rb +7 -7
- data/test/unit/default_order_by_tests.rb +26 -24
- data/test/unit/migration_tests.rb +17 -18
- data/test/unit/record_spy_tests.rb +45 -41
- data/test/unit/relation_spy_tests.rb +40 -63
- data/test/unit/test_helpers_tests.rb +7 -15
- data/test/unit/use_db_default_tests.rb +35 -27
- metadata +109 -87
- 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
@@ -1,39 +1,45 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
class Postgresql < Base
|
3
|
+
require "ardb/adapter/base"
|
6
4
|
|
7
|
-
|
5
|
+
module Ardb::Adapter
|
6
|
+
class Postgresql < Ardb::Adapter::Base
|
7
|
+
# the "postgres" db is a "public" (doesn"t typically require auth/grants to
|
8
8
|
# connect to) db that typically exists for all postgres installations; the
|
9
9
|
# adapter uses it to create/drop other databases
|
10
10
|
def public_connect_hash
|
11
|
-
@public_connect_hash ||=
|
12
|
-
|
13
|
-
|
11
|
+
@public_connect_hash ||= connect_hash.merge({
|
12
|
+
"database" => "postgres",
|
13
|
+
"schema_search_path" => "public",
|
14
14
|
})
|
15
15
|
end
|
16
16
|
|
17
17
|
def create_db
|
18
|
-
ActiveRecord::Base.establish_connection(
|
19
|
-
ActiveRecord::Base.connection.create_database(
|
20
|
-
|
18
|
+
ActiveRecord::Base.establish_connection(public_connect_hash)
|
19
|
+
ActiveRecord::Base.connection.create_database(
|
20
|
+
database,
|
21
|
+
connect_hash,
|
22
|
+
)
|
23
|
+
ActiveRecord::Base.establish_connection(connect_hash)
|
21
24
|
end
|
22
25
|
|
23
26
|
def drop_db
|
24
27
|
begin
|
25
|
-
ActiveRecord::Base.establish_connection(
|
28
|
+
ActiveRecord::Base.establish_connection(public_connect_hash)
|
26
29
|
ActiveRecord::Base.connection.tap do |conn|
|
27
|
-
conn.execute
|
28
|
-
|
29
|
-
|
30
|
+
conn.execute(
|
31
|
+
"UPDATE pg_catalog.pg_database"\
|
32
|
+
" SET datallowconn=false WHERE datname='#{database}'",
|
33
|
+
)
|
34
|
+
# this SELECT actually runs a command: it terminates all the
|
35
|
+
# connections
|
30
36
|
# http://www.postgresql.org/docs/9.2/static/functions-admin.html#FUNCTIONS-ADMIN-SIGNAL-TABLE
|
31
37
|
conn.execute "SELECT pg_terminate_backend(pid)"\
|
32
|
-
" FROM pg_stat_activity WHERE datname='#{
|
33
|
-
conn.execute "DROP DATABASE IF EXISTS #{
|
38
|
+
" FROM pg_stat_activity WHERE datname='#{database}'"
|
39
|
+
conn.execute "DROP DATABASE IF EXISTS #{database}"
|
34
40
|
end
|
35
|
-
rescue PG::Error =>
|
36
|
-
raise
|
41
|
+
rescue PG::Error => ex
|
42
|
+
raise ex unless ex.message =~ /does not exist/
|
37
43
|
end
|
38
44
|
end
|
39
45
|
|
@@ -42,47 +48,46 @@ module Ardb::Adapter
|
|
42
48
|
tables = conn.execute "SELECT table_name"\
|
43
49
|
" FROM information_schema.tables"\
|
44
50
|
" WHERE table_schema = 'public';"
|
45
|
-
tables.each
|
51
|
+
tables.each do |row|
|
52
|
+
conn.execute "DROP TABLE #{row["table_name"]} CASCADE"
|
53
|
+
end
|
46
54
|
end
|
47
55
|
end
|
48
56
|
|
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
57
|
def load_sql_schema
|
62
|
-
require
|
63
|
-
cmd_str = "psql -f \"#{
|
64
|
-
cmd = Scmd.new(cmd_str, :
|
65
|
-
raise
|
58
|
+
require "scmd"
|
59
|
+
cmd_str = "psql -f \"#{sql_schema_path}\" #{database}"
|
60
|
+
cmd = Scmd.new(cmd_str, env: env_var_hash).tap(&:run)
|
61
|
+
raise "Error loading database" unless cmd.success?
|
66
62
|
end
|
67
63
|
|
68
64
|
def dump_sql_schema
|
69
|
-
require
|
70
|
-
cmd_str =
|
71
|
-
|
72
|
-
|
65
|
+
require "scmd"
|
66
|
+
cmd_str =
|
67
|
+
"pg_dump -i -s -x -O -f \"#{sql_schema_path}\" #{database}"
|
68
|
+
cmd = Scmd.new(cmd_str, env: env_var_hash).tap(&:run)
|
69
|
+
raise "Error dumping database" unless cmd.success?
|
73
70
|
end
|
74
71
|
|
75
72
|
private
|
76
73
|
|
74
|
+
def validate!
|
75
|
+
if database =~ /\W/
|
76
|
+
raise(
|
77
|
+
Ardb::ConfigurationError,
|
78
|
+
"database value must not contain non-word characters. "\
|
79
|
+
"Given: #{database.inspect}.",
|
80
|
+
)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
77
84
|
def env_var_hash
|
78
85
|
@env_var_hash ||= {
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
86
|
+
"PGHOST" => connect_hash["host"],
|
87
|
+
"PGPORT" => connect_hash["port"],
|
88
|
+
"PGUSER" => connect_hash["username"],
|
89
|
+
"PGPASSWORD" => connect_hash["password"],
|
83
90
|
}
|
84
91
|
end
|
85
|
-
|
86
92
|
end
|
87
|
-
|
88
93
|
end
|
data/lib/ardb/adapter/sqlite.rb
CHANGED
@@ -1,31 +1,27 @@
|
|
1
|
-
|
2
|
-
require 'ardb'
|
3
|
-
require 'ardb/adapter/base'
|
1
|
+
# frozen_string_literal: true
|
4
2
|
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
require "fileutils"
|
4
|
+
require "ardb"
|
5
|
+
require "ardb/adapter/base"
|
8
6
|
|
7
|
+
module Ardb::Adapter
|
8
|
+
class Sqlite < Ardb::Adapter::Base
|
9
9
|
def db_file_path
|
10
|
-
File.expand_path(
|
10
|
+
File.expand_path(database, config.root_path)
|
11
11
|
end
|
12
12
|
|
13
13
|
def validate!
|
14
|
-
if File.exist?(
|
15
|
-
raise RuntimeError, "`#{self.database}` already exists"
|
16
|
-
end
|
14
|
+
raise "`#{database}` already exists" if File.exist?(db_file_path)
|
17
15
|
end
|
18
16
|
|
19
17
|
def create_db
|
20
18
|
validate!
|
21
|
-
FileUtils.mkdir_p File.dirname(
|
22
|
-
ActiveRecord::Base.establish_connection(
|
19
|
+
FileUtils.mkdir_p File.dirname(db_file_path)
|
20
|
+
ActiveRecord::Base.establish_connection(connect_hash)
|
23
21
|
end
|
24
22
|
|
25
23
|
def drop_db
|
26
|
-
FileUtils.rm(
|
24
|
+
FileUtils.rm(db_file_path) if File.exist?(db_file_path)
|
27
25
|
end
|
28
|
-
|
29
26
|
end
|
30
|
-
|
31
27
|
end
|
data/lib/ardb/adapter_spy.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
|
2
|
-
require 'ardb/adapter/base'
|
1
|
+
# frozen_string_literal: true
|
3
2
|
|
4
|
-
|
3
|
+
require "ardb"
|
4
|
+
require "ardb/adapter/base"
|
5
5
|
|
6
|
+
module Ardb
|
6
7
|
class AdapterSpy < Ardb::Adapter::Base
|
7
|
-
|
8
8
|
attr_accessor :drop_tables_called_count
|
9
9
|
attr_accessor :dump_schema_called_count, :load_schema_called_count
|
10
10
|
attr_accessor :drop_db_called_count, :create_db_called_count
|
@@ -22,73 +22,61 @@ module Ardb
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def create_db_called?
|
25
|
-
|
25
|
+
create_db_called_count > 0
|
26
26
|
end
|
27
27
|
|
28
28
|
def drop_db_called?
|
29
|
-
|
29
|
+
drop_db_called_count > 0
|
30
30
|
end
|
31
31
|
|
32
32
|
def drop_tables_called?
|
33
|
-
|
33
|
+
drop_tables_called_count > 0
|
34
34
|
end
|
35
35
|
|
36
36
|
def connect_db_called?
|
37
|
-
|
37
|
+
connect_db_called_count > 0
|
38
38
|
end
|
39
39
|
|
40
40
|
def migrate_db_called?
|
41
|
-
|
41
|
+
migrate_db_called_count > 0
|
42
42
|
end
|
43
43
|
|
44
44
|
def load_schema_called?
|
45
|
-
|
45
|
+
load_schema_called_count > 0
|
46
46
|
end
|
47
47
|
|
48
48
|
def dump_schema_called?
|
49
|
-
|
49
|
+
dump_schema_called_count > 0
|
50
50
|
end
|
51
51
|
|
52
52
|
# Overwritten `Adapter::Base` methods
|
53
53
|
|
54
|
-
def
|
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
|
-
def create_db(*args, &block)
|
54
|
+
def create_db(*_args)
|
65
55
|
self.create_db_called_count += 1
|
66
56
|
end
|
67
57
|
|
68
|
-
def drop_db(*
|
58
|
+
def drop_db(*_args)
|
69
59
|
self.drop_db_called_count += 1
|
70
60
|
end
|
71
61
|
|
72
|
-
def drop_tables(*
|
62
|
+
def drop_tables(*_args)
|
73
63
|
self.drop_tables_called_count += 1
|
74
64
|
end
|
75
65
|
|
76
|
-
def connect_db(*
|
66
|
+
def connect_db(*_args)
|
77
67
|
self.connect_db_called_count += 1
|
78
68
|
end
|
79
69
|
|
80
|
-
def migrate_db(*
|
70
|
+
def migrate_db(*_args)
|
81
71
|
self.migrate_db_called_count += 1
|
82
72
|
end
|
83
73
|
|
84
|
-
def load_schema(*
|
74
|
+
def load_schema(*_args)
|
85
75
|
self.load_schema_called_count += 1
|
86
76
|
end
|
87
77
|
|
88
|
-
def dump_schema(*
|
78
|
+
def dump_schema(*_args)
|
89
79
|
self.dump_schema_called_count += 1
|
90
80
|
end
|
91
|
-
|
92
81
|
end
|
93
|
-
|
94
82
|
end
|
data/lib/ardb/cli/clirb.rb
CHANGED
@@ -1,24 +1,24 @@
|
|
1
1
|
module Ardb; end
|
2
|
-
class Ardb::CLI
|
3
2
|
|
4
|
-
|
3
|
+
class Ardb::CLI
|
4
|
+
class CLIRB # Version 1.2.0, https://github.com/redding/cli.rb
|
5
5
|
Error = Class.new(RuntimeError);
|
6
6
|
HelpExit = Class.new(RuntimeError); VersionExit = Class.new(RuntimeError)
|
7
7
|
attr_reader :argv, :args, :opts, :data
|
8
8
|
|
9
9
|
def initialize(&block)
|
10
10
|
@options = []; instance_eval(&block) if block
|
11
|
-
require
|
11
|
+
require "optparse"
|
12
12
|
@data, @args, @opts = [], [], {}; @parser = OptionParser.new do |p|
|
13
|
-
p.banner =
|
13
|
+
p.banner = ""; @options.each do |o|
|
14
14
|
@opts[o.name] = o.value; p.on(*o.parser_args){ |v| @opts[o.name] = v }
|
15
15
|
end
|
16
|
-
p.on_tail(
|
17
|
-
p.on_tail(
|
16
|
+
p.on_tail("--version", ""){ |v| raise VersionExit, v.to_s }
|
17
|
+
p.on_tail("--help", ""){ |v| raise HelpExit, v.to_s }
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
-
def option(*args); @options << Option.new(*args); end
|
21
|
+
def option(*args, **kargs); @options << Option.new(*args, **kargs); end
|
22
22
|
def parse!(argv)
|
23
23
|
@args = (argv || []).dup.tap do |args_list|
|
24
24
|
begin; @parser.parse!(args_list)
|
@@ -27,33 +27,31 @@ class Ardb::CLI
|
|
27
27
|
end
|
28
28
|
def to_s; @parser.to_s; end
|
29
29
|
def inspect
|
30
|
-
"#<#{self.class}:#{
|
30
|
+
"#<#{self.class}:#{"0x0%x" % (object_id << 1)} @data=#{@data.inspect}>"
|
31
31
|
end
|
32
32
|
|
33
33
|
class Option
|
34
34
|
attr_reader :name, :opt_name, :desc, :abbrev, :value, :klass, :parser_args
|
35
35
|
|
36
|
-
def initialize(name,
|
37
|
-
|
38
|
-
@
|
39
|
-
@value, @klass = gvalinfo(
|
36
|
+
def initialize(name, desc = nil, abbrev: nil, value: nil)
|
37
|
+
@name, @desc = name, desc || ""
|
38
|
+
@opt_name, @abbrev = parse_name_values(name, abbrev)
|
39
|
+
@value, @klass = gvalinfo(value)
|
40
40
|
@parser_args = if [TrueClass, FalseClass, NilClass].include?(@klass)
|
41
41
|
["-#{@abbrev}", "--[no-]#{@opt_name}", @desc]
|
42
42
|
else
|
43
|
-
["-#{@abbrev}", "--#{@opt_name}
|
43
|
+
["-#{@abbrev}", "--#{@opt_name} VALUE", @klass, @desc]
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
47
|
private
|
48
48
|
|
49
49
|
def parse_name_values(name, custom_abbrev)
|
50
|
-
[ (processed_name = name.to_s.strip.downcase)
|
51
|
-
custom_abbrev || processed_name.gsub(/[^a-z]/,
|
50
|
+
[ (processed_name = name.to_s.strip.downcase).gsub("_", "-"),
|
51
|
+
custom_abbrev || processed_name.gsub(/[^a-z]/, "").chars.first || "a"
|
52
52
|
]
|
53
53
|
end
|
54
|
-
def gvalinfo(v); v.kind_of?(Class) ? [nil,
|
55
|
-
def gklass(k); k == Fixnum ? Integer : k; end
|
54
|
+
def gvalinfo(v); v.kind_of?(Class) ? [nil,v] : [v,v.class]; end
|
56
55
|
end
|
57
56
|
end
|
58
|
-
|
59
57
|
end
|