ardb 0.26.0 → 0.27.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.
- data/ardb.gemspec +1 -0
- data/bin/ardb +1 -1
- data/lib/ardb.rb +1 -1
- data/lib/ardb/adapter/base.rb +73 -66
- data/lib/ardb/adapter/sqlite.rb +1 -1
- data/lib/ardb/adapter_spy.rb +18 -5
- data/lib/ardb/cli.rb +239 -76
- data/lib/ardb/clirb.rb +58 -0
- data/lib/ardb/default_order_by.rb +59 -0
- data/lib/ardb/has_slug.rb +7 -6
- data/lib/ardb/migration.rb +42 -0
- data/lib/ardb/migration_helpers.rb +56 -53
- data/lib/ardb/record_spy.rb +5 -5
- data/lib/ardb/relation_spy.rb +13 -2
- data/lib/ardb/root_path.rb +7 -4
- data/lib/ardb/test_helpers.rb +56 -42
- data/lib/ardb/use_db_default.rb +8 -7
- data/lib/ardb/version.rb +1 -1
- data/test/support/factory.rb +5 -0
- data/test/unit/adapter/base_tests.rb +22 -5
- data/test/unit/adapter/mysql_tests.rb +1 -1
- data/test/unit/adapter/sqlite_tests.rb +2 -2
- data/test/unit/adapter_spy_tests.rb +19 -6
- data/test/unit/cli_tests.rb +610 -0
- data/test/unit/default_order_by_tests.rb +122 -0
- data/test/unit/has_slug_tests.rb +5 -0
- data/test/unit/migration_tests.rb +88 -0
- data/test/unit/record_spy_tests.rb +6 -0
- data/test/unit/test_helpers_tests.rb +26 -3
- data/test/unit/use_db_default_tests.rb +5 -0
- metadata +31 -25
- data/lib/ardb/runner.rb +0 -50
- data/lib/ardb/runner/connect_command.rb +0 -20
- data/lib/ardb/runner/create_command.rb +0 -25
- data/lib/ardb/runner/drop_command.rb +0 -25
- data/lib/ardb/runner/generate_command.rb +0 -64
- data/lib/ardb/runner/migrate_command.rb +0 -28
- data/test/unit/runner/connect_command_tests.rb +0 -17
- data/test/unit/runner/create_command_tests.rb +0 -67
- data/test/unit/runner/drop_command_tests.rb +0 -68
- data/test/unit/runner/generate_command_tests.rb +0 -46
- data/test/unit/runner/migrate_command_tests.rb +0 -96
- data/test/unit/runner_tests.rb +0 -69
data/lib/ardb/clirb.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
module Ardb
|
2
|
+
|
3
|
+
class CLIRB # Version 1.0.0, https://github.com/redding/cli.rb
|
4
|
+
Error = Class.new(RuntimeError);
|
5
|
+
HelpExit = Class.new(RuntimeError); VersionExit = Class.new(RuntimeError)
|
6
|
+
attr_reader :argv, :args, :opts, :data
|
7
|
+
|
8
|
+
def initialize(&block)
|
9
|
+
@options = []; instance_eval(&block) if block
|
10
|
+
require 'optparse'
|
11
|
+
@data, @args, @opts = [], [], {}; @parser = OptionParser.new do |p|
|
12
|
+
p.banner = ''; @options.each do |o|
|
13
|
+
@opts[o.name] = o.value; p.on(*o.parser_args){ |v| @opts[o.name] = v }
|
14
|
+
end
|
15
|
+
p.on_tail('--version', ''){ |v| raise VersionExit, v.to_s }
|
16
|
+
p.on_tail('--help', ''){ |v| raise HelpExit, v.to_s }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def option(*args); @options << Option.new(*args); end
|
21
|
+
def parse!(argv)
|
22
|
+
@args = (argv || []).dup.tap do |args_list|
|
23
|
+
begin; @parser.parse!(args_list)
|
24
|
+
rescue OptionParser::ParseError => err; raise Error, err.message; end
|
25
|
+
end; @data = @args + [@opts]
|
26
|
+
end
|
27
|
+
def to_s; @parser.to_s; end
|
28
|
+
def inspect
|
29
|
+
"#<#{self.class}:#{'0x0%x' % (object_id << 1)} @data=#{@data.inspect}>"
|
30
|
+
end
|
31
|
+
|
32
|
+
class Option
|
33
|
+
attr_reader :name, :opt_name, :desc, :abbrev, :value, :klass, :parser_args
|
34
|
+
|
35
|
+
def initialize(name, *args)
|
36
|
+
settings, @desc = args.last.kind_of?(::Hash) ? args.pop : {}, args.pop || ''
|
37
|
+
@name, @opt_name, @abbrev = parse_name_values(name, settings[:abbrev])
|
38
|
+
@value, @klass = gvalinfo(settings[:value])
|
39
|
+
@parser_args = if [TrueClass, FalseClass, NilClass].include?(@klass)
|
40
|
+
["-#{@abbrev}", "--[no-]#{@opt_name}", @desc]
|
41
|
+
else
|
42
|
+
["-#{@abbrev}", "--#{@opt_name} #{@opt_name.upcase}", @klass, @desc]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def parse_name_values(name, custom_abbrev)
|
49
|
+
[ (processed_name = name.to_s.strip.downcase), processed_name.gsub('_', '-'),
|
50
|
+
custom_abbrev || processed_name.gsub(/[^a-z]/, '').chars.first || 'a'
|
51
|
+
]
|
52
|
+
end
|
53
|
+
def gvalinfo(v); v.kind_of?(Class) ? [nil,gklass(v)] : [v,gklass(v.class)]; end
|
54
|
+
def gklass(k); k == Fixnum ? Integer : k; end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'much-plugin'
|
2
|
+
|
3
|
+
module Ardb
|
4
|
+
|
5
|
+
module DefaultOrderBy
|
6
|
+
include MuchPlugin
|
7
|
+
|
8
|
+
DEFAULT_ATTRIBUTE = :order_by
|
9
|
+
DEFAULT_SCOPE_PROC = proc{ self.class.scoped }
|
10
|
+
|
11
|
+
plugin_included do
|
12
|
+
extend ClassMethods
|
13
|
+
include InstanceMethods
|
14
|
+
|
15
|
+
@ardb_default_order_by_config = {}
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
module ClassMethods
|
20
|
+
|
21
|
+
def default_order_by(options = nil)
|
22
|
+
options ||= {}
|
23
|
+
|
24
|
+
@ardb_default_order_by_config.merge!({
|
25
|
+
:attribute => options[:attribute] || DEFAULT_ATTRIBUTE,
|
26
|
+
:scope_proc => options[:scope] || DEFAULT_SCOPE_PROC
|
27
|
+
})
|
28
|
+
|
29
|
+
before_validation :ardb_default_order_by, :on => :create
|
30
|
+
end
|
31
|
+
|
32
|
+
def ardb_default_order_by_config
|
33
|
+
@ardb_default_order_by_config
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
module InstanceMethods
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def reset_order_by
|
43
|
+
attr_name = self.class.ardb_default_order_by_config[:attribute]
|
44
|
+
scope_proc = self.class.ardb_default_order_by_config[:scope_proc]
|
45
|
+
|
46
|
+
current_max = self.instance_eval(&scope_proc).maximum(attr_name) || 0
|
47
|
+
self.send("#{attr_name}=", current_max + 1)
|
48
|
+
end
|
49
|
+
|
50
|
+
def ardb_default_order_by
|
51
|
+
attr_name = self.class.ardb_default_order_by_config[:attribute]
|
52
|
+
reset_order_by if self.send(attr_name).to_s.empty?
|
53
|
+
true
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
data/lib/ardb/has_slug.rb
CHANGED
@@ -1,19 +1,20 @@
|
|
1
|
+
require 'much-plugin'
|
2
|
+
|
1
3
|
module Ardb
|
2
4
|
|
3
5
|
module HasSlug
|
6
|
+
include MuchPlugin
|
4
7
|
|
5
8
|
DEFAULT_ATTRIBUTE = :slug
|
6
9
|
DEFAULT_PREPROCESSOR = :downcase
|
7
10
|
DEFAULT_SEPARATOR = '-'.freeze
|
8
11
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
include InstanceMethods
|
12
|
+
plugin_included do
|
13
|
+
extend ClassMethods
|
14
|
+
include InstanceMethods
|
13
15
|
|
14
|
-
|
16
|
+
@ardb_has_slug_config = {}
|
15
17
|
|
16
|
-
end
|
17
18
|
end
|
18
19
|
|
19
20
|
module ClassMethods
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module Ardb
|
4
|
+
|
5
|
+
class Migration
|
6
|
+
|
7
|
+
attr_reader :identifier, :class_name, :file_name, :file_path
|
8
|
+
attr_reader :source
|
9
|
+
|
10
|
+
def initialize(identifier)
|
11
|
+
raise NoIdentifierError if identifier.to_s.empty?
|
12
|
+
|
13
|
+
@identifier = identifier
|
14
|
+
@class_name = @identifier.classify.pluralize
|
15
|
+
@file_name = get_file_name(@identifier)
|
16
|
+
@file_path = File.join(Ardb.config.migrations_path, "#{@file_name}.rb")
|
17
|
+
|
18
|
+
@source = "require 'ardb/migration_helpers'\n\n" \
|
19
|
+
"class #{@class_name} < ActiveRecord::Migration\n" \
|
20
|
+
" include Ardb::MigrationHelpers\n\n" \
|
21
|
+
" def change\n" \
|
22
|
+
" end\n\n" \
|
23
|
+
"end\n"
|
24
|
+
end
|
25
|
+
|
26
|
+
def save!
|
27
|
+
FileUtils.mkdir_p Ardb.config.migrations_path
|
28
|
+
File.open(self.file_path, 'w'){ |f| f.write(self.source) }
|
29
|
+
self
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def get_file_name(identifier)
|
35
|
+
"#{Time.now.strftime("%Y%m%d%H%M%S")}_#{identifier.underscore}"
|
36
|
+
end
|
37
|
+
|
38
|
+
NoIdentifierError = Class.new(ArgumentError)
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
@@ -1,72 +1,75 @@
|
|
1
1
|
require 'ardb'
|
2
2
|
|
3
|
-
module Ardb
|
4
|
-
module Ardb::MigrationHelpers
|
5
|
-
module_function
|
3
|
+
module Ardb
|
6
4
|
|
7
|
-
|
8
|
-
|
9
|
-
execute(fk.add_sql)
|
10
|
-
end
|
11
|
-
|
12
|
-
def drop_foreign_key(*args)
|
13
|
-
from_table, from_column = args[0..1]
|
14
|
-
options = args.last.kind_of?(Hash) ? args.last : {}
|
15
|
-
fk = ForeignKey.new(from_table, from_column, nil, options)
|
16
|
-
execute(fk.drop_sql)
|
17
|
-
end
|
18
|
-
|
19
|
-
def remove_column_with_fk(table, column)
|
20
|
-
drop_foreign_key(table, column)
|
21
|
-
remove_column(table, column)
|
22
|
-
end
|
5
|
+
module MigrationHelpers
|
6
|
+
module_function
|
23
7
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
def initialize(from_table, from_column, to_table, options=nil)
|
28
|
-
options ||= {}
|
29
|
-
@from_table = from_table.to_s
|
30
|
-
@from_column = from_column.to_s
|
31
|
-
@to_table = to_table.to_s
|
32
|
-
@to_column = (options[:to_column] || 'id').to_s
|
33
|
-
@name = (options[:name] || "fk_#{@from_table}_#{@from_column}").to_s
|
34
|
-
@adapter = Ardb::Adapter.send(Ardb.config.db.adapter)
|
8
|
+
def foreign_key(from_table, from_column, to_table, options={})
|
9
|
+
fk = ForeignKey.new(from_table, from_column, to_table, options)
|
10
|
+
execute(fk.add_sql)
|
35
11
|
end
|
36
12
|
|
37
|
-
def
|
38
|
-
|
13
|
+
def drop_foreign_key(*args)
|
14
|
+
from_table, from_column = args[0..1]
|
15
|
+
options = args.last.kind_of?(Hash) ? args.last : {}
|
16
|
+
fk = ForeignKey.new(from_table, from_column, nil, options)
|
17
|
+
execute(fk.drop_sql)
|
39
18
|
end
|
40
19
|
|
41
|
-
def
|
42
|
-
|
20
|
+
def remove_column_with_fk(table, column)
|
21
|
+
drop_foreign_key(table, column)
|
22
|
+
remove_column(table, column)
|
43
23
|
end
|
44
24
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
25
|
+
class ForeignKey
|
26
|
+
attr_reader :from_table, :from_column, :to_table, :to_column, :name, :adapter
|
27
|
+
|
28
|
+
def initialize(from_table, from_column, to_table, options=nil)
|
29
|
+
options ||= {}
|
30
|
+
@from_table = from_table.to_s
|
31
|
+
@from_column = from_column.to_s
|
32
|
+
@to_table = to_table.to_s
|
33
|
+
@to_column = (options[:to_column] || 'id').to_s
|
34
|
+
@name = (options[:name] || "fk_#{@from_table}_#{@from_column}").to_s
|
35
|
+
@adapter = Ardb::Adapter.send(Ardb.config.db.adapter)
|
36
|
+
end
|
37
|
+
|
38
|
+
def add_sql
|
39
|
+
apply_data(@adapter.foreign_key_add_sql)
|
40
|
+
end
|
41
|
+
|
42
|
+
def drop_sql
|
43
|
+
apply_data(@adapter.foreign_key_drop_sql)
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def apply_data(template_sql)
|
49
|
+
template_sql.
|
50
|
+
gsub(':from_table', @from_table).
|
51
|
+
gsub(':from_column', @from_column).
|
52
|
+
gsub(':to_table', @to_table).
|
53
|
+
gsub(':to_column', @to_column).
|
54
|
+
gsub(':name', @name)
|
55
|
+
end
|
54
56
|
end
|
55
|
-
end
|
56
57
|
|
57
|
-
|
58
|
-
|
58
|
+
# This file will setup the AR migration command recorder for being able to
|
59
|
+
# change our stuff, require it in an initializer
|
59
60
|
|
60
|
-
|
61
|
+
module RecorderMixin
|
61
62
|
|
62
|
-
|
63
|
-
|
64
|
-
|
63
|
+
def foreign_key(*args)
|
64
|
+
record(:foreign_key, args)
|
65
|
+
end
|
66
|
+
|
67
|
+
protected
|
65
68
|
|
66
|
-
|
69
|
+
def invert_foreign_key(args)
|
70
|
+
[ :drop_foreign_key, args ]
|
71
|
+
end
|
67
72
|
|
68
|
-
def invert_foreign_key(args)
|
69
|
-
[ :drop_foreign_key, args ]
|
70
73
|
end
|
71
74
|
|
72
75
|
end
|
data/lib/ardb/record_spy.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
require 'arel'
|
2
|
+
require 'much-plugin'
|
2
3
|
require 'ardb/relation_spy'
|
3
4
|
|
4
5
|
module Ardb
|
5
6
|
|
6
7
|
module RecordSpy
|
8
|
+
include MuchPlugin
|
7
9
|
|
8
10
|
def self.new(&block)
|
9
11
|
block ||= proc{ }
|
@@ -12,11 +14,9 @@ module Ardb
|
|
12
14
|
record_spy
|
13
15
|
end
|
14
16
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
include InstanceMethods
|
19
|
-
end
|
17
|
+
plugin_included do
|
18
|
+
extend ClassMethods
|
19
|
+
include InstanceMethods
|
20
20
|
end
|
21
21
|
|
22
22
|
module ClassMethods
|
data/lib/ardb/relation_spy.rb
CHANGED
@@ -4,13 +4,16 @@ module Ardb
|
|
4
4
|
|
5
5
|
attr_reader :applied
|
6
6
|
attr_accessor :limit_value, :offset_value
|
7
|
-
attr_accessor :pluck_values
|
7
|
+
attr_accessor :pluck_values, :maximum_values, :minimum_values
|
8
8
|
attr_accessor :results
|
9
9
|
|
10
10
|
def initialize
|
11
11
|
@applied, @results = [], []
|
12
12
|
@offset_value, @limit_value = nil, nil
|
13
|
-
|
13
|
+
|
14
|
+
@pluck_values = {}
|
15
|
+
@maximum_values = {}
|
16
|
+
@minimum_values = {}
|
14
17
|
end
|
15
18
|
|
16
19
|
def initialize_copy(copied_from)
|
@@ -134,6 +137,14 @@ module Ardb
|
|
134
137
|
[@pluck_values[column_name]] * @results.size
|
135
138
|
end
|
136
139
|
|
140
|
+
def maximum(column_name)
|
141
|
+
@maximum_values[column_name]
|
142
|
+
end
|
143
|
+
|
144
|
+
def minimum(column_name)
|
145
|
+
@minimum_values[column_name]
|
146
|
+
end
|
147
|
+
|
137
148
|
class AppliedExpression < Struct.new(:type, :args)
|
138
149
|
def to_sql
|
139
150
|
"#{self.type}: #{self.args.inspect}"
|
data/lib/ardb/root_path.rb
CHANGED
@@ -2,11 +2,14 @@
|
|
2
2
|
# to the full qualifed root path. The goal here is to specify path options
|
3
3
|
# with root-relative path strings.
|
4
4
|
|
5
|
-
module Ardb
|
6
|
-
|
5
|
+
module Ardb
|
6
|
+
|
7
|
+
class RootPath < String
|
8
|
+
|
9
|
+
def initialize(path_string)
|
10
|
+
super(Ardb.config.root_path.join(path_string).to_s)
|
11
|
+
end
|
7
12
|
|
8
|
-
def initialize(path_string)
|
9
|
-
super(Ardb.config.root_path.join(path_string).to_s)
|
10
13
|
end
|
11
14
|
|
12
15
|
end
|
data/lib/ardb/test_helpers.rb
CHANGED
@@ -4,62 +4,76 @@ require 'ardb'
|
|
4
4
|
# Use theses helpers in your test suite. They all generally assume Ardb has
|
5
5
|
# already been initialized by calling `Ardb.init`.
|
6
6
|
|
7
|
-
module Ardb
|
8
|
-
module Ardb::TestHelpers
|
9
|
-
module_function
|
7
|
+
module Ardb
|
10
8
|
|
11
|
-
|
12
|
-
|
13
|
-
end
|
9
|
+
module TestHelpers
|
10
|
+
module_function
|
14
11
|
|
15
|
-
|
16
|
-
|
17
|
-
|
12
|
+
def drop_tables
|
13
|
+
Ardb.adapter.drop_tables
|
14
|
+
end
|
18
15
|
|
19
|
-
|
20
|
-
|
21
|
-
|
16
|
+
def load_schema
|
17
|
+
Ardb.adapter.load_schema
|
18
|
+
end
|
22
19
|
|
23
|
-
|
24
|
-
|
25
|
-
self.create_db!
|
26
|
-
true
|
20
|
+
def create_db!
|
21
|
+
Ardb.adapter.create_db
|
27
22
|
end
|
28
|
-
end
|
29
23
|
|
30
|
-
|
31
|
-
|
32
|
-
|
24
|
+
def create_db
|
25
|
+
@create_db ||= begin
|
26
|
+
self.create_db!
|
27
|
+
true
|
28
|
+
end
|
29
|
+
end
|
33
30
|
|
34
|
-
|
35
|
-
|
36
|
-
self.drop_db!
|
37
|
-
true
|
31
|
+
def drop_db!
|
32
|
+
Ardb.adapter.drop_db
|
38
33
|
end
|
39
|
-
end
|
40
34
|
|
41
|
-
|
42
|
-
|
43
|
-
|
35
|
+
def drop_db
|
36
|
+
@drop_db ||= begin
|
37
|
+
self.drop_db!
|
38
|
+
true
|
39
|
+
end
|
40
|
+
end
|
44
41
|
|
45
|
-
|
46
|
-
|
47
|
-
self.migrate_db!
|
48
|
-
true
|
42
|
+
def connect_db!
|
43
|
+
Ardb.adapter.connect_db
|
49
44
|
end
|
50
|
-
end
|
51
45
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
46
|
+
def connect_db
|
47
|
+
@connect_db ||= begin
|
48
|
+
self.connect_db!
|
49
|
+
true
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def migrate_db!
|
54
|
+
Ardb.adapter.migrate_db
|
55
|
+
end
|
56
|
+
|
57
|
+
def migrate_db
|
58
|
+
@migrate_db ||= begin
|
59
|
+
self.migrate_db!
|
60
|
+
true
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def reset_db!
|
65
|
+
self.drop_db!
|
66
|
+
self.create_db!
|
67
|
+
self.load_schema
|
68
|
+
end
|
57
69
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
70
|
+
def reset_db
|
71
|
+
@reset_db ||= begin
|
72
|
+
self.reset_db!
|
73
|
+
true
|
74
|
+
end
|
62
75
|
end
|
76
|
+
|
63
77
|
end
|
64
78
|
|
65
79
|
end
|