ardb 0.27.3 → 0.29.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +7 -7
  2. data/Gemfile +4 -5
  3. data/README.md +252 -3
  4. data/ardb.gemspec +8 -8
  5. data/bin/ardb +1 -1
  6. data/lib/ardb.rb +155 -72
  7. data/lib/ardb/adapter/base.rb +67 -47
  8. data/lib/ardb/adapter/mysql.rb +3 -19
  9. data/lib/ardb/adapter/postgresql.rb +33 -37
  10. data/lib/ardb/adapter/sqlite.rb +7 -16
  11. data/lib/ardb/adapter_spy.rb +58 -92
  12. data/lib/ardb/cli.rb +18 -226
  13. data/lib/ardb/{clirb.rb → cli/clirb.rb} +16 -18
  14. data/lib/ardb/cli/commands.rb +365 -0
  15. data/lib/ardb/db_tests.rb +2 -4
  16. data/lib/ardb/default_order_by.rb +3 -13
  17. data/lib/ardb/migration.rb +18 -20
  18. data/lib/ardb/record_spy.rb +7 -26
  19. data/lib/ardb/relation_spy.rb +0 -6
  20. data/lib/ardb/require_autoloaded_active_record_files.rb +103 -58
  21. data/lib/ardb/test_helpers.rb +2 -5
  22. data/lib/ardb/use_db_default.rb +4 -15
  23. data/lib/ardb/version.rb +1 -1
  24. data/script/determine_autoloaded_active_record_files.rb +11 -8
  25. data/test/helper.rb +9 -6
  26. data/test/support/factory.rb +17 -2
  27. data/test/support/fake_schema.rb +5 -0
  28. data/test/support/postgresql/migrations/.keep +0 -0
  29. data/test/support/postgresql/schema.rb +2 -0
  30. data/test/support/postgresql/setup_test_db.rb +51 -0
  31. data/test/support/relative_require_test_db_file.rb +2 -0
  32. data/test/support/require_test_db_file.rb +1 -0
  33. data/test/system/.keep +0 -0
  34. data/test/unit/adapter/base_tests.rb +163 -75
  35. data/test/unit/adapter/mysql_tests.rb +4 -20
  36. data/test/unit/adapter/postgresql_tests.rb +20 -28
  37. data/test/unit/adapter/sqlite_tests.rb +9 -12
  38. data/test/unit/adapter_spy_tests.rb +48 -71
  39. data/test/unit/ardb_tests.rb +338 -38
  40. data/test/unit/cli_tests.rb +334 -225
  41. data/test/unit/db_tests_tests.rb +3 -6
  42. data/test/unit/default_order_by_tests.rb +4 -8
  43. data/test/unit/migration_tests.rb +20 -17
  44. data/test/unit/record_spy_tests.rb +18 -23
  45. data/test/unit/relation_spy_tests.rb +17 -46
  46. data/test/unit/test_helpers_tests.rb +5 -20
  47. data/test/unit/use_db_default_tests.rb +9 -13
  48. metadata +111 -100
  49. data/lib/ardb/has_slug.rb +0 -107
  50. data/lib/ardb/migration_helpers.rb +0 -77
  51. data/lib/ardb/root_path.rb +0 -15
  52. data/test/unit/config_tests.rb +0 -58
  53. data/test/unit/has_slug_tests.rb +0 -341
  54. data/test/unit/migration_helpers_tests.rb +0 -59
@@ -1,18 +1,26 @@
1
- module Ardb; end
2
- class Ardb::Adapter
1
+ require "ardb"
3
2
 
3
+ module Ardb; end
4
+ module Ardb::Adapter
4
5
  class Base
6
+ attr_reader :config
7
+
8
+ def initialize(config)
9
+ @config = config
10
+ validate!
11
+ end
12
+
13
+ def connect_hash; self.config.activerecord_connect_hash; end
14
+ def database; self.config.database; end
15
+ def migrations_path; self.config.migrations_path; end
16
+ def schema_format; self.config.schema_format; end
5
17
 
6
- attr_reader :config_settings, :database
7
- attr_reader :schema_format, :ruby_schema_path, :sql_schema_path
18
+ def ruby_schema_path
19
+ @ruby_schema_path ||= "#{self.config.schema_path}.rb"
20
+ end
8
21
 
9
- def initialize
10
- @config_settings = Ardb.config.db_settings
11
- @database = Ardb.config.db.database
12
- @schema_format = Ardb.config.schema_format
13
- schema_path = Ardb.config.schema_path
14
- @ruby_schema_path = "#{schema_path}.rb"
15
- @sql_schema_path = "#{schema_path}.sql"
22
+ def sql_schema_path
23
+ @sql_schema_path ||= "#{self.config.schema_path}.sql"
16
24
  end
17
25
 
18
26
  def escape_like_pattern(pattern, escape_char = nil)
@@ -21,50 +29,51 @@ class Ardb::Adapter
21
29
  pattern.gsub!(escape_char){ escape_char * 2 }
22
30
  # don't allow custom wildcards
23
31
  pattern.gsub!(/%|_/){ |wildcard_char| "#{escape_char}#{wildcard_char}" }
32
+ pattern
24
33
  end
25
34
 
26
- def foreign_key_add_sql(*args); raise NotImplementedError; end
27
- def foreign_key_drop_sql(*args); raise NotImplementedError; end
28
-
29
35
  def create_db(*args); raise NotImplementedError; end
30
36
  def drop_db(*args); raise NotImplementedError; end
31
37
 
38
+ def drop_tables(*args); raise NotImplementedError; end
39
+
32
40
  def connect_db
33
- ActiveRecord::Base.connection
41
+ ActiveRecord::Base.establish_connection(self.connect_hash)
42
+ # checkout a connection to ensure we can connect to the DB, we don"t do
43
+ # anything with the connection and immediately check it back in
44
+ ActiveRecord::Base.connection_pool.with_connection{ }
34
45
  end
35
46
 
36
47
  def migrate_db
37
- verbose = ENV["MIGRATE_QUIET"].nil?
38
- version = ENV["MIGRATE_VERSION"] ? ENV["MIGRATE_VERSION"].to_i : nil
39
- migrations_path = Ardb.config.migrations_path
40
-
41
- if defined?(ActiveRecord::Migration::CommandRecorder)
42
- require 'ardb/migration_helpers'
43
- ActiveRecord::Migration::CommandRecorder.class_eval do
44
- include Ardb::MigrationHelpers::RecorderMixin
45
- end
46
- end
48
+ migrate_db_up
49
+ end
47
50
 
48
- ActiveRecord::Migrator.migrations_path = migrations_path
49
- ActiveRecord::Migration.verbose = verbose
50
- ActiveRecord::Migrator.migrate(migrations_path, version) do |migration|
51
- ENV["MIGRATE_SCOPE"].blank? || (ENV["MIGRATE_SCOPE"] == migration.scope)
52
- end
51
+ def migrate_db_up(target_version = nil)
52
+ migration_context.up(target_version)
53
53
  end
54
54
 
55
- def drop_tables(*args); raise NotImplementedError; end
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)
65
+ end
56
66
 
57
67
  def load_schema
58
- # silence STDOUT
59
- current_stdout = $stdout.dup
60
- $stdout = File.new('/dev/null', 'w')
61
- load_ruby_schema if @schema_format == :ruby
62
- load_sql_schema if @schema_format == :sql
68
+ current_stdout = $stdout.dup # silence STDOUT
69
+ $stdout = File.new("/dev/null", "w")
70
+ load_ruby_schema if self.schema_format == Ardb::Config::RUBY_SCHEMA_FORMAT
71
+ load_sql_schema if self.schema_format == Ardb::Config::SQL_SCHEMA_FORMAT
63
72
  $stdout = current_stdout
64
73
  end
65
74
 
66
75
  def load_ruby_schema
67
- load @ruby_schema_path
76
+ load self.ruby_schema_path
68
77
  end
69
78
 
70
79
  def load_sql_schema
@@ -72,18 +81,17 @@ class Ardb::Adapter
72
81
  end
73
82
 
74
83
  def dump_schema
75
- # silence STDOUT
76
- current_stdout = $stdout.dup
77
- $stdout = File.new('/dev/null', 'w')
84
+ current_stdout = $stdout.dup # silence STDOUT
85
+ $stdout = File.new("/dev/null", "w")
78
86
  dump_ruby_schema
79
- dump_sql_schema if @schema_format == :sql
87
+ dump_sql_schema if self.schema_format == Ardb::Config::SQL_SCHEMA_FORMAT
80
88
  $stdout = current_stdout
81
89
  end
82
90
 
83
91
  def dump_ruby_schema
84
- require 'active_record/schema_dumper'
85
- FileUtils.mkdir_p File.dirname(@ruby_schema_path)
86
- File.open(@ruby_schema_path, 'w:utf-8') do |file|
92
+ require "active_record/schema_dumper"
93
+ FileUtils.mkdir_p File.dirname(self.ruby_schema_path)
94
+ File.open(self.ruby_schema_path, "w:utf-8") do |file|
87
95
  ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file)
88
96
  end
89
97
  end
@@ -92,10 +100,22 @@ class Ardb::Adapter
92
100
  raise NotImplementedError
93
101
  end
94
102
 
95
- def ==(other_adapter)
96
- self.class == other_adapter.class
103
+ def ==(other)
104
+ if other.kind_of?(self.class)
105
+ self.config == other.config
106
+ else
107
+ super
108
+ end
97
109
  end
98
110
 
99
- end
111
+ private
112
+
113
+ def validate!
114
+ # override as needed
115
+ end
100
116
 
117
+ def migration_context
118
+ ActiveRecord::MigrationContext.new(migrations_path)
119
+ end
120
+ end
101
121
  end
@@ -1,22 +1,6 @@
1
- require 'ardb'
2
- require 'ardb/adapter/base'
3
-
4
- class Ardb::Adapter
5
-
6
- class Mysql < Base
7
-
8
- def foreign_key_add_sql
9
- "ALTER TABLE :from_table"\
10
- " ADD CONSTRAINT :name"\
11
- " FOREIGN KEY (:from_column)"\
12
- " REFERENCES :to_table (:to_column)"
13
- end
14
-
15
- def foreign_key_drop_sql
16
- "ALTER TABLE :from_table"\
17
- " DROP FOREIGN KEY :name"
18
- end
1
+ require "ardb/adapter/base"
19
2
 
3
+ module Ardb::Adapter
4
+ class Mysql < Ardb::Adapter::Base
20
5
  end
21
-
22
6
  end
@@ -1,26 +1,26 @@
1
- require 'ardb'
2
- require 'ardb/adapter/base'
1
+ require "ardb/adapter/base"
3
2
 
4
- class Ardb::Adapter
5
-
6
- class Postgresql < Base
7
-
8
- def public_schema_settings
9
- self.config_settings.merge({
10
- 'database' => 'postgres',
11
- 'schema_search_path' => 'public'
3
+ module Ardb::Adapter
4
+ class Postgresql < Ardb::Adapter::Base
5
+ # the "postgres" db is a "public" (doesn"t typically require auth/grants to
6
+ # connect to) db that typically exists for all postgres installations; the
7
+ # adapter uses it to create/drop other databases
8
+ def public_connect_hash
9
+ @public_connect_hash ||= self.connect_hash.merge({
10
+ "database" => "postgres",
11
+ "schema_search_path" => "public"
12
12
  })
13
13
  end
14
14
 
15
15
  def create_db
16
- ActiveRecord::Base.establish_connection(self.public_schema_settings)
17
- ActiveRecord::Base.connection.create_database(self.database, self.config_settings)
18
- ActiveRecord::Base.establish_connection(self.config_settings)
16
+ ActiveRecord::Base.establish_connection(self.public_connect_hash)
17
+ ActiveRecord::Base.connection.create_database(self.database, self.connect_hash)
18
+ ActiveRecord::Base.establish_connection(self.connect_hash)
19
19
  end
20
20
 
21
21
  def drop_db
22
22
  begin
23
- ActiveRecord::Base.establish_connection(self.public_schema_settings)
23
+ ActiveRecord::Base.establish_connection(self.public_connect_hash)
24
24
  ActiveRecord::Base.connection.tap do |conn|
25
25
  conn.execute "UPDATE pg_catalog.pg_database"\
26
26
  " SET datallowconn=false WHERE datname='#{self.database}'"
@@ -40,47 +40,43 @@ class Ardb::Adapter
40
40
  tables = conn.execute "SELECT table_name"\
41
41
  " FROM information_schema.tables"\
42
42
  " WHERE table_schema = 'public';"
43
- tables.each{ |row| conn.execute "DROP TABLE #{row['table_name']} CASCADE" }
43
+ tables.each{ |row| conn.execute "DROP TABLE #{row["table_name"]} CASCADE" }
44
44
  end
45
45
  end
46
46
 
47
- def foreign_key_add_sql
48
- "ALTER TABLE :from_table"\
49
- " ADD CONSTRAINT :name"\
50
- " FOREIGN KEY (:from_column)"\
51
- " REFERENCES :to_table (:to_column)"
52
- end
53
-
54
- def foreign_key_drop_sql
55
- "ALTER TABLE :from_table"\
56
- " DROP CONSTRAINT :name"
57
- end
58
-
59
47
  def load_sql_schema
60
- require 'scmd'
48
+ require "scmd"
61
49
  cmd_str = "psql -f \"#{self.sql_schema_path}\" #{self.database}"
62
50
  cmd = Scmd.new(cmd_str, :env => env_var_hash).tap(&:run)
63
- raise 'Error loading database' unless cmd.success?
51
+ raise "Error loading database" unless cmd.success?
64
52
  end
65
53
 
66
54
  def dump_sql_schema
67
- require 'scmd'
55
+ require "scmd"
68
56
  cmd_str = "pg_dump -i -s -x -O -f \"#{self.sql_schema_path}\" #{self.database}"
69
57
  cmd = Scmd.new(cmd_str, :env => env_var_hash).tap(&:run)
70
- raise 'Error dumping database' unless cmd.success?
58
+ raise "Error dumping database" unless cmd.success?
71
59
  end
72
60
 
73
61
  private
74
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
+
75
73
  def env_var_hash
76
74
  @env_var_hash ||= {
77
- 'PGHOST' => self.config_settings['host'],
78
- 'PGPORT' => self.config_settings['port'],
79
- 'PGUSER' => self.config_settings['username'],
80
- 'PGPASSWORD' => self.config_settings['password']
75
+ "PGHOST" => self.connect_hash["host"],
76
+ "PGPORT" => self.connect_hash["port"],
77
+ "PGUSER" => self.connect_hash["username"],
78
+ "PGPASSWORD" => self.connect_hash["password"]
81
79
  }
82
80
  end
83
-
84
81
  end
85
-
86
82
  end
@@ -1,18 +1,11 @@
1
- require 'pathname'
2
- require 'fileutils'
3
- require 'ardb'
4
- require 'ardb/adapter/base'
5
-
6
- class Ardb::Adapter
7
-
8
- class Sqlite < Base
1
+ require "fileutils"
2
+ require "ardb"
3
+ require "ardb/adapter/base"
9
4
 
5
+ module Ardb::Adapter
6
+ class Sqlite < Ardb::Adapter::Base
10
7
  def db_file_path
11
- if (path = Pathname.new(self.database)).absolute?
12
- path.to_s
13
- else
14
- Ardb.config.root_path.join(path).to_s
15
- end
8
+ File.expand_path(self.database, self.config.root_path)
16
9
  end
17
10
 
18
11
  def validate!
@@ -24,13 +17,11 @@ class Ardb::Adapter
24
17
  def create_db
25
18
  validate!
26
19
  FileUtils.mkdir_p File.dirname(self.db_file_path)
27
- ActiveRecord::Base.establish_connection(self.config_settings)
20
+ ActiveRecord::Base.establish_connection(self.connect_hash)
28
21
  end
29
22
 
30
23
  def drop_db
31
24
  FileUtils.rm(self.db_file_path) if File.exist?(self.db_file_path)
32
25
  end
33
-
34
26
  end
35
-
36
27
  end
@@ -1,114 +1,80 @@
1
- require 'much-plugin'
1
+ require "ardb"
2
+ require "ardb/adapter/base"
2
3
 
3
4
  module Ardb
4
-
5
- module AdapterSpy
6
- include MuchPlugin
7
-
8
- def self.new(&block)
9
- block ||= proc{ }
10
- record_spy = Class.new{ include Ardb::AdapterSpy }
11
- record_spy.class_eval(&block)
12
- record_spy
5
+ class AdapterSpy < Ardb::Adapter::Base
6
+ attr_accessor :drop_tables_called_count
7
+ attr_accessor :dump_schema_called_count, :load_schema_called_count
8
+ attr_accessor :drop_db_called_count, :create_db_called_count
9
+ attr_accessor :connect_db_called_count, :migrate_db_called_count
10
+
11
+ def initialize(config = nil)
12
+ super(config || Ardb::Config.new)
13
+ @drop_tables_called_count = 0
14
+ @dump_schema_called_count = 0
15
+ @load_schema_called_count = 0
16
+ @drop_db_called_count = 0
17
+ @create_db_called_count = 0
18
+ @connect_db_called_count = 0
19
+ @migrate_db_called_count = 0
13
20
  end
14
21
 
15
- plugin_included do
16
- include InstanceMethods
22
+ def create_db_called?
23
+ self.create_db_called_count > 0
17
24
  end
18
25
 
19
- module InstanceMethods
20
-
21
- attr_accessor :drop_tables_called_count
22
- attr_accessor :dump_schema_called_count, :load_schema_called_count
23
- attr_accessor :drop_db_called_count, :create_db_called_count
24
- attr_accessor :connect_db_called_count, :migrate_db_called_count
25
-
26
- def drop_tables_called_count
27
- @drop_tables_called_count ||= 0
28
- end
29
-
30
- def drop_tables_called?
31
- self.drop_tables_called_count > 0
32
- end
33
-
34
- def drop_tables(*args, &block)
35
- self.drop_tables_called_count += 1
36
- end
37
-
38
- def dump_schema_called_count
39
- @dump_schema_called_count ||= 0
40
- end
41
-
42
- def dump_schema_called?
43
- self.dump_schema_called_count > 0
44
- end
45
-
46
- def dump_schema(*args, &block)
47
- self.dump_schema_called_count += 1
48
- end
49
-
50
- def load_schema_called_count
51
- @load_schema_called_count ||= 0
52
- end
53
-
54
- def load_schema_called?
55
- self.load_schema_called_count > 0
56
- end
57
-
58
- def load_schema(*args, &block)
59
- self.load_schema_called_count += 1
60
- end
61
-
62
- def drop_db_called_count
63
- @drop_db_called_count ||= 0
64
- end
26
+ def drop_db_called?
27
+ self.drop_db_called_count > 0
28
+ end
65
29
 
66
- def drop_db_called?
67
- self.drop_db_called_count > 0
68
- end
30
+ def drop_tables_called?
31
+ self.drop_tables_called_count > 0
32
+ end
69
33
 
70
- def drop_db(*args, &block)
71
- self.drop_db_called_count += 1
72
- end
34
+ def connect_db_called?
35
+ self.connect_db_called_count > 0
36
+ end
73
37
 
74
- def create_db_called_count
75
- @create_db_called_count ||= 0
76
- end
38
+ def migrate_db_called?
39
+ self.migrate_db_called_count > 0
40
+ end
77
41
 
78
- def create_db_called?
79
- self.create_db_called_count > 0
80
- end
42
+ def load_schema_called?
43
+ self.load_schema_called_count > 0
44
+ end
81
45
 
82
- def create_db(*args, &block)
83
- self.create_db_called_count += 1
84
- end
46
+ def dump_schema_called?
47
+ self.dump_schema_called_count > 0
48
+ end
85
49
 
86
- def connect_db_called_count
87
- @connect_db_called_count ||= 0
88
- end
50
+ # Overwritten `Adapter::Base` methods
89
51
 
90
- def connect_db_called?
91
- self.connect_db_called_count > 0
92
- end
52
+ def create_db(*args, &block)
53
+ self.create_db_called_count += 1
54
+ end
93
55
 
94
- def connect_db(*args, &block)
95
- self.connect_db_called_count += 1
96
- end
56
+ def drop_db(*args, &block)
57
+ self.drop_db_called_count += 1
58
+ end
97
59
 
98
- def migrate_db_called_count
99
- @migrate_db_called_count ||= 0
100
- end
60
+ def drop_tables(*args, &block)
61
+ self.drop_tables_called_count += 1
62
+ end
101
63
 
102
- def migrate_db_called?
103
- self.migrate_db_called_count > 0
104
- end
64
+ def connect_db(*args, &block)
65
+ self.connect_db_called_count += 1
66
+ end
105
67
 
106
- def migrate_db(*args, &block)
107
- self.migrate_db_called_count += 1
108
- end
68
+ def migrate_db(*args, &block)
69
+ self.migrate_db_called_count += 1
70
+ end
109
71
 
72
+ def load_schema(*args, &block)
73
+ self.load_schema_called_count += 1
110
74
  end
111
75
 
76
+ def dump_schema(*args, &block)
77
+ self.dump_schema_called_count += 1
78
+ end
112
79
  end
113
-
114
80
  end