ardb 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/ardb.gemspec +4 -0
- data/bin/ardb +7 -0
- data/lib/ardb.rb +93 -1
- data/lib/ardb/adapter/base.rb +24 -0
- data/lib/ardb/adapter/mysql.rb +22 -0
- data/lib/ardb/adapter/postgresql.rb +49 -0
- data/lib/ardb/adapter/sqlite.rb +36 -0
- data/lib/ardb/cli.rb +113 -0
- data/lib/ardb/migration_helpers.rb +74 -0
- data/lib/ardb/runner.rb +65 -0
- data/lib/ardb/runner/create_command.rb +21 -0
- data/lib/ardb/runner/drop_command.rb +21 -0
- data/lib/ardb/runner/generate_command.rb +64 -0
- data/lib/ardb/runner/migrate_command.rb +48 -0
- data/lib/ardb/test_helpers.rb +24 -0
- data/lib/ardb/version.rb +1 -1
- data/test/helper.rb +17 -1
- data/test/unit/adapter/base_tests.rb +41 -0
- data/test/unit/adapter/mysql_tests.rb +40 -0
- data/test/unit/adapter/postgresql_tests.rb +39 -0
- data/test/unit/adapter/sqlite_tests.rb +39 -0
- data/test/unit/ardb_tests.rb +55 -0
- data/test/unit/config_tests.rb +42 -0
- data/test/unit/migration_helpers_tests.rb +59 -0
- data/test/unit/runner/create_command_tests.rb +18 -0
- data/test/unit/runner/drop_command_tests.rb +17 -0
- data/test/unit/runner/generate_command_tests.rb +46 -0
- data/test/unit/runner/migrate_command_tests.rb +62 -0
- data/test/unit/runner_tests.rb +72 -0
- data/test/unit/test_helpers_tests.rb +14 -0
- metadata +99 -6
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
require 'ardb/runner'
|
3
|
+
|
4
|
+
class Ardb::Runner::CreateCommand
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@adapter = Ardb::Adapter.send(Ardb.config.db.adapter)
|
8
|
+
end
|
9
|
+
|
10
|
+
def run
|
11
|
+
begin
|
12
|
+
@adapter.create_db
|
13
|
+
$stdout.puts "created #{Ardb.config.db.adapter} db `#{Ardb.config.db.database}`"
|
14
|
+
rescue Ardb::Runner::CmdError => e
|
15
|
+
raise e
|
16
|
+
rescue Exception => e
|
17
|
+
raise Ardb::Runner::CmdFail
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
require 'ardb/runner'
|
3
|
+
|
4
|
+
class Ardb::Runner::DropCommand
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@adapter = Ardb::Adapter.send(Ardb.config.db.adapter)
|
8
|
+
end
|
9
|
+
|
10
|
+
def run
|
11
|
+
begin
|
12
|
+
@adapter.drop_db
|
13
|
+
$stdout.puts "dropped #{Ardb.config.db.adapter} db `#{Ardb.config.db.database}`"
|
14
|
+
rescue Ardb::Runner::CmdError => e
|
15
|
+
raise e
|
16
|
+
rescue Exception => e
|
17
|
+
raise Ardb::Runner::CmdFail
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'active_support/core_ext/string'
|
3
|
+
require 'ardb/runner'
|
4
|
+
|
5
|
+
class Ardb::Runner::GenerateCommand
|
6
|
+
|
7
|
+
def initialize(args)
|
8
|
+
@item = args.shift
|
9
|
+
@args = args
|
10
|
+
end
|
11
|
+
|
12
|
+
def run
|
13
|
+
if @item.nil?
|
14
|
+
raise Ardb::Runner::CmdError, "specify an item to generate"
|
15
|
+
end
|
16
|
+
if !self.respond_to?("#{@item}_cmd")
|
17
|
+
raise Ardb::Runner::CmdError, "can't generate #{@item}"
|
18
|
+
end
|
19
|
+
|
20
|
+
begin
|
21
|
+
self.send("#{@item}_cmd")
|
22
|
+
rescue Ardb::Runner::CmdError => e
|
23
|
+
raise e
|
24
|
+
rescue Exception => e
|
25
|
+
$stderr.puts e, *(e.backtrace)
|
26
|
+
$stderr.puts "error generating #{@item}."
|
27
|
+
raise Ardb::Runner::CmdFail
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def migration_cmd
|
32
|
+
MigrationCommand.new(@args.first).run
|
33
|
+
end
|
34
|
+
|
35
|
+
class MigrationCommand
|
36
|
+
attr_reader :identifier, :class_name, :file_name, :template
|
37
|
+
|
38
|
+
def initialize(identifier)
|
39
|
+
if identifier.nil?
|
40
|
+
raise Ardb::Runner::CmdError, "specify a name for the migration"
|
41
|
+
end
|
42
|
+
|
43
|
+
@identifier = identifier
|
44
|
+
@class_name = @identifier.classify.pluralize
|
45
|
+
@file_name = begin
|
46
|
+
"#{Time.now.strftime("%Y%m%d%H%M%S")}_#{@identifier.underscore}"
|
47
|
+
end
|
48
|
+
@template = "require 'ardb/migration_helpers'\n\n"\
|
49
|
+
"class #{@class_name} < ActiveRecord::Migration\n"\
|
50
|
+
" include Ardb::MigrationHelpers\n\n"\
|
51
|
+
" def change\n"\
|
52
|
+
" end\n\n"\
|
53
|
+
"end\n"
|
54
|
+
end
|
55
|
+
|
56
|
+
def run
|
57
|
+
FileUtils.mkdir_p Ardb.config.migrations_path
|
58
|
+
file_path = File.join(Ardb.config.migrations_path, "#{@file_name}.rb")
|
59
|
+
File.open(file_path, "w"){ |f| f.write(@template) }
|
60
|
+
$stdout.puts file_path
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'active_record'
|
3
|
+
require 'ardb/runner'
|
4
|
+
require 'ardb/migration_helpers'
|
5
|
+
|
6
|
+
class Ardb::Runner::MigrateCommand
|
7
|
+
|
8
|
+
attr_reader :migrations_path, :schema_file_path, :version, :verbose
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@migrations_path = Ardb.config.migrations_path
|
12
|
+
@schema_file_path = Ardb.config.schema_path
|
13
|
+
@version = ENV["VERSION"] ? ENV["VERSION"].to_i : nil
|
14
|
+
@verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true
|
15
|
+
end
|
16
|
+
|
17
|
+
def run
|
18
|
+
begin
|
19
|
+
Ardb.init
|
20
|
+
migrate_the_db
|
21
|
+
rescue Ardb::Runner::CmdError => e
|
22
|
+
raise e
|
23
|
+
rescue Exception => e
|
24
|
+
$stderr.puts e, *(e.backtrace)
|
25
|
+
$stderr.puts "error migrating #{Ardb.config.db.database.inspect} database"
|
26
|
+
raise Ardb::Runner::CmdFail
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def migrate_the_db
|
31
|
+
if defined?(ActiveRecord::Migration::CommandRecorder)
|
32
|
+
ActiveRecord::Migration::CommandRecorder.send(:include, Ardb::MigrationHelpers::RecorderMixin)
|
33
|
+
end
|
34
|
+
|
35
|
+
ActiveRecord::Migrator.migrations_path = @migrations_path
|
36
|
+
ActiveRecord::Migration.verbose = @verbose
|
37
|
+
ActiveRecord::Migrator.migrate(@migrations_path, @version) do |migration|
|
38
|
+
ENV["SCOPE"].blank? || (ENV["SCOPE"] == migration.scope)
|
39
|
+
end
|
40
|
+
|
41
|
+
require 'active_record/schema_dumper'
|
42
|
+
FileUtils.mkdir_p File.dirname(@schema_file_path)
|
43
|
+
File.open(@schema_file_path, "w:utf-8") do |file|
|
44
|
+
ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
require 'ardb'
|
3
|
+
|
4
|
+
# Use theses helpers in your test suite. They all generally assume Ardb has
|
5
|
+
# already been initialized by calling `Ardb.init`.
|
6
|
+
|
7
|
+
module Ardb; end
|
8
|
+
module Ardb::TestHelpers
|
9
|
+
module_function
|
10
|
+
|
11
|
+
def drop_tables
|
12
|
+
Ardb.adapter.drop_tables
|
13
|
+
end
|
14
|
+
|
15
|
+
def load_schema
|
16
|
+
# silence STDOUT
|
17
|
+
current_stdout = $stdout.dup
|
18
|
+
$stdout = File.new('/dev/null', 'w')
|
19
|
+
load Ardb.config.schema_path
|
20
|
+
$stdout = current_stdout
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
data/lib/ardb/version.rb
CHANGED
data/test/helper.rb
CHANGED
@@ -2,7 +2,23 @@
|
|
2
2
|
# put any test helpers here
|
3
3
|
|
4
4
|
# add the root dir to the load path
|
5
|
-
|
5
|
+
ROOT_PATH = File.expand_path("../..", __FILE__)
|
6
|
+
$LOAD_PATH.unshift(ROOT_PATH)
|
6
7
|
|
7
8
|
# require pry for debugging (`binding.pry`)
|
8
9
|
require 'pry'
|
10
|
+
|
11
|
+
require 'fileutils'
|
12
|
+
TESTDB_PATH = File.join(ROOT_PATH, 'tmp', 'testdb')
|
13
|
+
FileUtils.mkdir_p TESTDB_PATH
|
14
|
+
|
15
|
+
require 'logger'
|
16
|
+
require 'ardb'
|
17
|
+
Ardb.configure do |c|
|
18
|
+
c.root_path = TESTDB_PATH
|
19
|
+
c.logger = Logger.new($stdout)
|
20
|
+
|
21
|
+
c.db.adapter 'postgresql'
|
22
|
+
c.db.database 'ardbtest'
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'assert'
|
2
|
+
require 'ardb/adapter/base'
|
3
|
+
|
4
|
+
class Ardb::Adapter::Base
|
5
|
+
|
6
|
+
class BaseTests < Assert::Context
|
7
|
+
desc "Ardb::Adapter::Base"
|
8
|
+
setup do
|
9
|
+
@adapter = Ardb::Adapter::Base.new
|
10
|
+
end
|
11
|
+
subject { @adapter }
|
12
|
+
|
13
|
+
should have_reader :config_settings, :database
|
14
|
+
should have_imeths :foreign_key_add_sql, :foreign_key_drop_sql
|
15
|
+
should have_imeths :create_db, :drop_db
|
16
|
+
|
17
|
+
should "use the config's db settings " do
|
18
|
+
assert_equal Ardb.config.db.to_hash, subject.config_settings
|
19
|
+
end
|
20
|
+
|
21
|
+
should "use the config's database" do
|
22
|
+
assert_equal Ardb.config.db.database, subject.database
|
23
|
+
end
|
24
|
+
|
25
|
+
should "not implement the foreign key sql meths" do
|
26
|
+
assert_raises(NotImplementedError) { subject.foreign_key_add_sql }
|
27
|
+
assert_raises(NotImplementedError) { subject.foreign_key_drop_sql }
|
28
|
+
end
|
29
|
+
|
30
|
+
should "not implement the create and drop db methods" do
|
31
|
+
assert_raises(NotImplementedError) { subject.create_db }
|
32
|
+
assert_raises(NotImplementedError) { subject.drop_db }
|
33
|
+
end
|
34
|
+
|
35
|
+
should "not implement the drop table methods" do
|
36
|
+
assert_raises(NotImplementedError) { subject.drop_tables }
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'assert'
|
2
|
+
require 'ardb/adapter/mysql'
|
3
|
+
|
4
|
+
class Ardb::Adapter::Mysql
|
5
|
+
|
6
|
+
class BaseTests < Assert::Context
|
7
|
+
desc "Ardb::Adapter::Mysql"
|
8
|
+
setup do
|
9
|
+
@adapter = Ardb::Adapter::Mysql.new
|
10
|
+
end
|
11
|
+
subject { @adapter }
|
12
|
+
|
13
|
+
should "know its foreign key add sql" do
|
14
|
+
exp_add_sql = "ALTER TABLE :from_table"\
|
15
|
+
" ADD CONSTRAINT :name"\
|
16
|
+
" FOREIGN KEY (:from_column)"\
|
17
|
+
" REFERENCES :to_table (:to_column)"
|
18
|
+
assert_equal exp_add_sql, subject.foreign_key_add_sql
|
19
|
+
end
|
20
|
+
|
21
|
+
should "know its foreign key drop sql" do
|
22
|
+
exp_drop_sql = "ALTER TABLE :from_table"\
|
23
|
+
" DROP FOREIGN KEY :name"
|
24
|
+
assert_equal exp_drop_sql, subject.foreign_key_drop_sql
|
25
|
+
end
|
26
|
+
|
27
|
+
# not currently implemented, see: https://github.com/redding/ardb/issues/13
|
28
|
+
should "not implement the create and drop db methods" do
|
29
|
+
assert_raises(NotImplementedError) { subject.create_db }
|
30
|
+
assert_raises(NotImplementedError) { subject.drop_db }
|
31
|
+
end
|
32
|
+
|
33
|
+
# not currently implemented, see: https://github.com/redding/ardb/issues/28
|
34
|
+
should "not implement the drop tables method" do
|
35
|
+
assert_raises(NotImplementedError) { subject.drop_tables }
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'assert'
|
2
|
+
require 'ardb/adapter/postgresql'
|
3
|
+
|
4
|
+
class Ardb::Adapter::Postgresql
|
5
|
+
|
6
|
+
class BaseTests < Assert::Context
|
7
|
+
desc "Ardb::Adapter::Postgresql"
|
8
|
+
setup do
|
9
|
+
@adapter = Ardb::Adapter::Postgresql.new
|
10
|
+
end
|
11
|
+
subject { @adapter }
|
12
|
+
|
13
|
+
should have_instance_method :public_schema_settings
|
14
|
+
|
15
|
+
should "know it's public schema connection settings" do
|
16
|
+
exp_settings = subject.config_settings.merge({
|
17
|
+
:database => 'postgres',
|
18
|
+
:schema_search_path => 'public'
|
19
|
+
})
|
20
|
+
assert_equal exp_settings, subject.public_schema_settings
|
21
|
+
end
|
22
|
+
|
23
|
+
should "know its foreign key add sql" do
|
24
|
+
exp_add_sql = "ALTER TABLE :from_table"\
|
25
|
+
" ADD CONSTRAINT :name"\
|
26
|
+
" FOREIGN KEY (:from_column)"\
|
27
|
+
" REFERENCES :to_table (:to_column)"
|
28
|
+
assert_equal exp_add_sql, subject.foreign_key_add_sql
|
29
|
+
end
|
30
|
+
|
31
|
+
should "know its foreign key drop sql" do
|
32
|
+
exp_drop_sql = "ALTER TABLE :from_table"\
|
33
|
+
" DROP CONSTRAINT :name"
|
34
|
+
assert_equal exp_drop_sql, subject.foreign_key_drop_sql
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'assert'
|
2
|
+
require 'ardb/adapter/sqlite'
|
3
|
+
|
4
|
+
class Ardb::Adapter::Sqlite
|
5
|
+
|
6
|
+
class BaseTests < Assert::Context
|
7
|
+
desc "Ardb::Adapter::Sqlite"
|
8
|
+
setup do
|
9
|
+
@adapter = Ardb::Adapter::Sqlite.new
|
10
|
+
end
|
11
|
+
subject { @adapter }
|
12
|
+
|
13
|
+
should have_imeths :db_file_path, :validate!
|
14
|
+
|
15
|
+
should "complain if the db file already exists" do
|
16
|
+
FileUtils.mkdir_p(File.dirname(subject.db_file_path))
|
17
|
+
FileUtils.touch(subject.db_file_path)
|
18
|
+
assert_raises(Ardb::Runner::CmdError) { subject.validate! }
|
19
|
+
FileUtils.rm(subject.db_file_path)
|
20
|
+
end
|
21
|
+
|
22
|
+
should "know its db_file_path" do
|
23
|
+
exp_path = Ardb.config.root_path.join(Ardb.config.db.database).to_s
|
24
|
+
assert_equal exp_path, subject.db_file_path
|
25
|
+
end
|
26
|
+
|
27
|
+
should "not implement the foreign key sql meths" do
|
28
|
+
assert_raises(NotImplementedError) { subject.foreign_key_add_sql }
|
29
|
+
assert_raises(NotImplementedError) { subject.foreign_key_drop_sql }
|
30
|
+
end
|
31
|
+
|
32
|
+
# not currently implemented, see: https://github.com/redding/ardb/issues/29
|
33
|
+
should "not implement the drop tables method" do
|
34
|
+
assert_raises(NotImplementedError) { subject.drop_tables }
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'assert'
|
2
|
+
require 'ardb'
|
3
|
+
|
4
|
+
module Ardb
|
5
|
+
|
6
|
+
class BaseTests < Assert::Context
|
7
|
+
desc "Ardb"
|
8
|
+
subject{ Ardb }
|
9
|
+
setup do
|
10
|
+
@orig_ar_logger = ActiveRecord::Base.logger
|
11
|
+
end
|
12
|
+
teardown do
|
13
|
+
Adapter.reset
|
14
|
+
ActiveRecord::Base.logger = @orig_ar_logger
|
15
|
+
end
|
16
|
+
|
17
|
+
should have_imeths :config, :configure, :adapter, :validate!, :init
|
18
|
+
|
19
|
+
should "return its `Config` class with the `config` method" do
|
20
|
+
assert_same Config, subject.config
|
21
|
+
end
|
22
|
+
|
23
|
+
should "complain if init'ing and not all configs are set" do
|
24
|
+
orig_adapter = Ardb.config.db.adapter
|
25
|
+
Ardb.config.db.adapter = nil
|
26
|
+
assert_raises(NotConfiguredError) { subject.init }
|
27
|
+
Ardb.config.db.adapter = orig_adapter
|
28
|
+
end
|
29
|
+
|
30
|
+
should "init the adapter on init" do
|
31
|
+
assert_nil Adapter.current
|
32
|
+
begin
|
33
|
+
subject.init
|
34
|
+
rescue LoadError
|
35
|
+
end
|
36
|
+
|
37
|
+
assert_not_nil Adapter.current
|
38
|
+
exp_adapter = Adapter.send(subject.config.db.adapter)
|
39
|
+
assert_equal exp_adapter, Adapter.current
|
40
|
+
assert_same Adapter.current, subject.adapter
|
41
|
+
end
|
42
|
+
|
43
|
+
should "establish an AR connection on init" do
|
44
|
+
assert_raises(LoadError) do
|
45
|
+
# not going to test this b/c I don't want to bring in all the crap it
|
46
|
+
# takes to actually establish a connection with AR (adapters, etc)
|
47
|
+
# plus, most of this should be handled by AR, ns-options, and the above
|
48
|
+
# tests anyway
|
49
|
+
subject.init
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'assert'
|
2
|
+
require 'ns-options/assert_macros'
|
3
|
+
require 'ardb'
|
4
|
+
|
5
|
+
class Ardb::Config
|
6
|
+
|
7
|
+
class BaseTests < Assert::Context
|
8
|
+
include NsOptions::AssertMacros
|
9
|
+
desc "Ardb::Config"
|
10
|
+
subject{ Ardb::Config }
|
11
|
+
|
12
|
+
should have_namespace :db
|
13
|
+
should have_option :root_path, Pathname, :required => true
|
14
|
+
should have_option :logger, :required => true
|
15
|
+
should have_options :migrations_path, :schema_path
|
16
|
+
|
17
|
+
should "should use `db/migrations` as the default migrations path" do
|
18
|
+
exp_path = Pathname.new(TESTDB_PATH).join("db/migrations").to_s
|
19
|
+
assert_equal exp_path, subject.migrations_path
|
20
|
+
end
|
21
|
+
|
22
|
+
should "should use `db/schema.rb` as the default schema path" do
|
23
|
+
exp_path = Pathname.new(TESTDB_PATH).join("db/schema.rb").to_s
|
24
|
+
assert_equal exp_path, subject.schema_path
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
class DbTests < BaseTests
|
30
|
+
desc "db namespace"
|
31
|
+
subject{ Ardb::Config.db }
|
32
|
+
|
33
|
+
should have_option :adapter, String, :required => true
|
34
|
+
should have_option :database, String, :required => true
|
35
|
+
should have_option :encoding, String, :required => false
|
36
|
+
should have_option :url, String, :required => false
|
37
|
+
should have_option :username, String, :required => false
|
38
|
+
should have_option :password, String, :required => false
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|