ardb 0.27.3 → 0.28.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 +4 -4
- data/Gemfile +5 -1
- data/ardb.gemspec +3 -4
- data/lib/ardb.rb +135 -68
- data/lib/ardb/adapter/base.rb +39 -24
- data/lib/ardb/adapter/mysql.rb +1 -2
- data/lib/ardb/adapter/postgresql.rb +14 -12
- data/lib/ardb/adapter/sqlite.rb +3 -8
- data/lib/ardb/adapter_spy.rb +67 -87
- data/lib/ardb/cli.rb +11 -219
- data/lib/ardb/{clirb.rb → cli/clirb.rb} +2 -1
- data/lib/ardb/cli/commands.rb +275 -0
- data/lib/ardb/migration.rb +8 -6
- data/lib/ardb/migration_helpers.rb +1 -1
- data/lib/ardb/pg_json.rb +90 -0
- data/lib/ardb/version.rb +1 -1
- data/test/helper.rb +15 -3
- data/test/support/factory.rb +15 -0
- data/test/support/fake_schema.rb +5 -0
- data/test/support/postgresql/migrations/.gitkeep +0 -0
- data/test/support/postgresql/pg_json_migrations/20160519133432_create_pg_json_migrate_test.rb +13 -0
- data/test/support/postgresql/schema.rb +3 -0
- data/test/support/postgresql/setup_test_db.rb +51 -0
- data/test/support/relative_require_test_db_file.rb +2 -0
- data/test/support/require_test_db_file.rb +1 -0
- data/test/system/pg_json_tests.rb +85 -0
- data/test/unit/adapter/base_tests.rb +104 -39
- data/test/unit/adapter/mysql_tests.rb +2 -1
- data/test/unit/adapter/postgresql_tests.rb +10 -9
- data/test/unit/adapter/sqlite_tests.rb +8 -3
- data/test/unit/adapter_spy_tests.rb +57 -66
- data/test/unit/ardb_tests.rb +323 -36
- data/test/unit/cli_tests.rb +193 -146
- data/test/unit/has_slug_tests.rb +9 -9
- data/test/unit/migration_helpers_tests.rb +18 -12
- data/test/unit/migration_tests.rb +18 -11
- data/test/unit/pg_json_tests.rb +39 -0
- data/test/unit/record_spy_tests.rb +1 -1
- data/test/unit/test_helpers_tests.rb +2 -6
- data/test/unit/use_db_default_tests.rb +2 -2
- metadata +29 -34
- data/lib/ardb/root_path.rb +0 -15
- data/test/unit/config_tests.rb +0 -58
@@ -0,0 +1,275 @@
|
|
1
|
+
require 'ardb'
|
2
|
+
require 'ardb/cli/clirb'
|
3
|
+
require 'much-plugin'
|
4
|
+
|
5
|
+
module Ardb; end
|
6
|
+
class Ardb::CLI
|
7
|
+
|
8
|
+
InvalidCommandError = Class.new(ArgumentError)
|
9
|
+
CommandExitError = Class.new(RuntimeError)
|
10
|
+
|
11
|
+
class InvalidCommand
|
12
|
+
|
13
|
+
attr_reader :name, :clirb
|
14
|
+
|
15
|
+
def initialize(name)
|
16
|
+
@name = name
|
17
|
+
@clirb = CLIRB.new
|
18
|
+
end
|
19
|
+
|
20
|
+
def new; self; end
|
21
|
+
|
22
|
+
def run(argv)
|
23
|
+
@clirb.parse!([@name, argv].flatten.compact)
|
24
|
+
raise CLIRB::HelpExit if @name.to_s.empty?
|
25
|
+
raise InvalidCommandError, "'#{self.name}' is not a command."
|
26
|
+
end
|
27
|
+
|
28
|
+
def help
|
29
|
+
"Usage: ardb [COMMAND] [options]\n\n" \
|
30
|
+
"Options: #{@clirb}\n" \
|
31
|
+
"Commands:\n" \
|
32
|
+
"#{COMMANDS.to_s.split("\n").map{ |l| " #{l}" }.join("\n")}\n"
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
module ValidCommand
|
38
|
+
include MuchPlugin
|
39
|
+
|
40
|
+
plugin_included do
|
41
|
+
include InstanceMethods
|
42
|
+
end
|
43
|
+
|
44
|
+
module InstanceMethods
|
45
|
+
|
46
|
+
def initialize(&clirb_build)
|
47
|
+
@clirb = CLIRB.new(&clirb_build)
|
48
|
+
end
|
49
|
+
|
50
|
+
def clirb; @clirb; end
|
51
|
+
|
52
|
+
def run(argv, stdout = nil, stderr = nil)
|
53
|
+
@clirb.parse!(argv)
|
54
|
+
@stdout = stdout || $stdout
|
55
|
+
@stderr = stderr || $stderr
|
56
|
+
end
|
57
|
+
|
58
|
+
def summary
|
59
|
+
''
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
class ConnectCommand
|
67
|
+
include ValidCommand
|
68
|
+
|
69
|
+
def run(argv, *args)
|
70
|
+
super
|
71
|
+
|
72
|
+
Ardb.init(false)
|
73
|
+
begin
|
74
|
+
Ardb.adapter.connect_db
|
75
|
+
@stdout.puts "connected to #{Ardb.config.adapter} db `#{Ardb.config.database}`"
|
76
|
+
rescue StandardError => e
|
77
|
+
@stderr.puts e
|
78
|
+
@stderr.puts e.backtrace.join("\n")
|
79
|
+
@stderr.puts "error connecting to #{Ardb.config.database.inspect} database " \
|
80
|
+
"with #{Ardb.config.activerecord_connect_hash.inspect}"
|
81
|
+
raise CommandExitError
|
82
|
+
end
|
83
|
+
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
|
+
end
|
97
|
+
|
98
|
+
class CreateCommand
|
99
|
+
include ValidCommand
|
100
|
+
|
101
|
+
def run(argv, *args)
|
102
|
+
super
|
103
|
+
|
104
|
+
Ardb.init(false)
|
105
|
+
begin
|
106
|
+
Ardb.adapter.create_db
|
107
|
+
@stdout.puts "created #{Ardb.config.adapter} db `#{Ardb.config.database}`"
|
108
|
+
rescue StandardError => e
|
109
|
+
@stderr.puts e
|
110
|
+
@stderr.puts "error creating #{Ardb.config.database.inspect} database"
|
111
|
+
raise CommandExitError
|
112
|
+
end
|
113
|
+
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
|
+
end
|
127
|
+
|
128
|
+
class DropCommand
|
129
|
+
include ValidCommand
|
130
|
+
|
131
|
+
def run(argv, *args)
|
132
|
+
super
|
133
|
+
|
134
|
+
Ardb.init(true)
|
135
|
+
begin
|
136
|
+
Ardb.adapter.drop_db
|
137
|
+
@stdout.puts "dropped #{Ardb.config.adapter} db `#{Ardb.config.database}`"
|
138
|
+
rescue StandardError => e
|
139
|
+
@stderr.puts e
|
140
|
+
@stderr.puts "error dropping #{Ardb.config.database.inspect} database"
|
141
|
+
raise CommandExitError
|
142
|
+
end
|
143
|
+
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
|
+
end
|
157
|
+
|
158
|
+
class MigrateCommand
|
159
|
+
include ValidCommand
|
160
|
+
|
161
|
+
def run(argv, *args)
|
162
|
+
super
|
163
|
+
|
164
|
+
Ardb.init(true)
|
165
|
+
begin
|
166
|
+
Ardb.adapter.migrate_db
|
167
|
+
Ardb.adapter.dump_schema unless ENV['ARDB_MIGRATE_NO_SCHEMA']
|
168
|
+
rescue StandardError => e
|
169
|
+
@stderr.puts e
|
170
|
+
@stderr.puts e.backtrace.join("\n")
|
171
|
+
@stderr.puts "error migrating #{Ardb.config.database.inspect} database"
|
172
|
+
raise CommandExitError
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
def summary
|
177
|
+
"Migrate the configured DB"
|
178
|
+
end
|
179
|
+
|
180
|
+
def help
|
181
|
+
"Usage: ardb migrate [options]\n\n" \
|
182
|
+
"Options: #{@clirb}\n" \
|
183
|
+
"Description:\n" \
|
184
|
+
" #{self.summary}"
|
185
|
+
end
|
186
|
+
|
187
|
+
end
|
188
|
+
|
189
|
+
class GenerateMigrationCommand
|
190
|
+
include ValidCommand
|
191
|
+
|
192
|
+
def run(argv, *args)
|
193
|
+
super
|
194
|
+
|
195
|
+
Ardb.init(false)
|
196
|
+
begin
|
197
|
+
require 'ardb/migration'
|
198
|
+
migration = Ardb::Migration.new(Ardb.config, @clirb.args.first)
|
199
|
+
migration.save!
|
200
|
+
@stdout.puts "generated #{migration.file_path}"
|
201
|
+
rescue Ardb::Migration::NoIdentifierError => exception
|
202
|
+
error = ArgumentError.new("MIGRATION-NAME must be provided")
|
203
|
+
error.set_backtrace(exception.backtrace)
|
204
|
+
raise error
|
205
|
+
rescue StandardError => e
|
206
|
+
@stderr.puts e
|
207
|
+
@stderr.puts e.backtrace.join("\n")
|
208
|
+
@stderr.puts "error generating migration"
|
209
|
+
raise CommandExitError
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
def summary
|
214
|
+
"Generate a migration file given a MIGRATION-NAME"
|
215
|
+
end
|
216
|
+
|
217
|
+
def help
|
218
|
+
"Usage: ardb generate-migration [options] MIGRATION-NAME\n\n" \
|
219
|
+
"Options: #{@clirb}\n" \
|
220
|
+
"Description:\n" \
|
221
|
+
" #{self.summary}"
|
222
|
+
end
|
223
|
+
|
224
|
+
end
|
225
|
+
|
226
|
+
class CommandSet
|
227
|
+
|
228
|
+
def initialize(&unknown_cmd_block)
|
229
|
+
@lookup = Hash.new{ |h,k| unknown_cmd_block.call(k) }
|
230
|
+
@names = []
|
231
|
+
@aliases = {}
|
232
|
+
@summaries = {}
|
233
|
+
end
|
234
|
+
|
235
|
+
def add(klass, name, *aliases)
|
236
|
+
begin
|
237
|
+
cmd = klass.new
|
238
|
+
rescue StandardError => err
|
239
|
+
# don't add any commands you can't init
|
240
|
+
else
|
241
|
+
([name] + aliases).each{ |n| @lookup[n] = cmd }
|
242
|
+
@to_s = nil
|
243
|
+
@names << name
|
244
|
+
@aliases[name] = aliases.empty? ? '' : "(#{aliases.join(', ')})"
|
245
|
+
@summaries[name] = cmd.summary.to_s.empty? ? '' : "# #{cmd.summary}"
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
def remove(name)
|
250
|
+
@lookup.delete(name)
|
251
|
+
@names.delete(name)
|
252
|
+
@aliases.delete(name)
|
253
|
+
@to_s = nil
|
254
|
+
end
|
255
|
+
|
256
|
+
def [](name)
|
257
|
+
@lookup[name]
|
258
|
+
end
|
259
|
+
|
260
|
+
def size
|
261
|
+
@names.size
|
262
|
+
end
|
263
|
+
|
264
|
+
def to_s
|
265
|
+
max_name_size = @names.map{ |n| n.size }.max || 0
|
266
|
+
max_alias_size = @aliases.values.map{ |v| v.size }.max || 0
|
267
|
+
|
268
|
+
@to_s ||= @names.map do |n|
|
269
|
+
"#{n.ljust(max_name_size)} #{@aliases[n].ljust(max_alias_size)} #{@summaries[n]}"
|
270
|
+
end.join("\n")
|
271
|
+
end
|
272
|
+
|
273
|
+
end
|
274
|
+
|
275
|
+
end
|
data/lib/ardb/migration.rb
CHANGED
@@ -4,16 +4,18 @@ module Ardb
|
|
4
4
|
|
5
5
|
class Migration
|
6
6
|
|
7
|
-
attr_reader :
|
8
|
-
attr_reader :source
|
7
|
+
attr_reader :migrations_path, :identifier
|
8
|
+
attr_reader :class_name, :file_name, :file_path, :source
|
9
9
|
|
10
|
-
def initialize(identifier)
|
10
|
+
def initialize(ardb_config, identifier)
|
11
11
|
raise NoIdentifierError if identifier.to_s.empty?
|
12
12
|
|
13
|
-
@
|
13
|
+
@migrations_path = ardb_config.migrations_path
|
14
|
+
@identifier = identifier
|
15
|
+
|
14
16
|
@class_name = @identifier.classify.pluralize
|
15
17
|
@file_name = get_file_name(@identifier)
|
16
|
-
@file_path = File.join(
|
18
|
+
@file_path = File.join(self.migrations_path, "#{@file_name}.rb")
|
17
19
|
|
18
20
|
@source = "require 'ardb/migration_helpers'\n\n" \
|
19
21
|
"class #{@class_name} < ActiveRecord::Migration\n" \
|
@@ -24,7 +26,7 @@ module Ardb
|
|
24
26
|
end
|
25
27
|
|
26
28
|
def save!
|
27
|
-
FileUtils.mkdir_p
|
29
|
+
FileUtils.mkdir_p self.migrations_path
|
28
30
|
File.open(self.file_path, 'w'){ |f| f.write(self.source) }
|
29
31
|
self
|
30
32
|
end
|
@@ -32,7 +32,7 @@ module Ardb
|
|
32
32
|
@to_table = to_table.to_s
|
33
33
|
@to_column = (options[:to_column] || 'id').to_s
|
34
34
|
@name = (options[:name] || "fk_#{@from_table}_#{@from_column}").to_s
|
35
|
-
@adapter = Ardb::Adapter.
|
35
|
+
@adapter = Ardb::Adapter.new(Ardb.config)
|
36
36
|
end
|
37
37
|
|
38
38
|
def add_sql
|
data/lib/ardb/pg_json.rb
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
require 'active_support'
|
3
|
+
|
4
|
+
# Allow ActiveRecord to work with PostgreSQL json/jsonb fields, which aren't
|
5
|
+
# supported with ActiveRecord 3.2
|
6
|
+
# https://github.com/romanbsd/activerecord-postgres-json/blob/master/lib/activerecord-postgres-json/activerecord.rb
|
7
|
+
require 'active_record/connection_adapters/postgresql_adapter'
|
8
|
+
|
9
|
+
module ActiveRecord
|
10
|
+
module ConnectionAdapters
|
11
|
+
PostgreSQLAdapter::NATIVE_DATABASE_TYPES[:json] = { :name => 'json' }
|
12
|
+
PostgreSQLAdapter::NATIVE_DATABASE_TYPES[:jsonb] = { :name => 'jsonb' }
|
13
|
+
|
14
|
+
class PostgreSQLColumn < Column
|
15
|
+
# Adds the json type for the column.
|
16
|
+
def simplified_type_with_json(field_type)
|
17
|
+
case field_type
|
18
|
+
when 'json'
|
19
|
+
:json
|
20
|
+
when 'jsonb'
|
21
|
+
:jsonb
|
22
|
+
else
|
23
|
+
simplified_type_without_json(field_type)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
alias_method_chain :simplified_type, :json
|
28
|
+
|
29
|
+
class << self
|
30
|
+
def extract_value_from_default_with_json(default)
|
31
|
+
case default
|
32
|
+
when "'{}'::json", "'{}'::jsonb"
|
33
|
+
'{}'
|
34
|
+
when "'[]'::json", "'[]'::jsonb"
|
35
|
+
'[]'
|
36
|
+
else
|
37
|
+
extract_value_from_default_without_json(default)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
alias_method_chain :extract_value_from_default, :json
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
class TableDefinition
|
47
|
+
# Adds json type for migrations. So you can add columns to a table like:
|
48
|
+
# create_table :people do |t|
|
49
|
+
# ...
|
50
|
+
# t.json :info
|
51
|
+
# ...
|
52
|
+
# end
|
53
|
+
def json(*args)
|
54
|
+
options = args.extract_options!
|
55
|
+
column_names = args
|
56
|
+
column_names.each { |name| column(name, 'json', options) }
|
57
|
+
end
|
58
|
+
|
59
|
+
def jsonb(*args)
|
60
|
+
options = args.extract_options!
|
61
|
+
column_names = args
|
62
|
+
column_names.each { |name| column(name, 'jsonb', options) }
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
class Table
|
68
|
+
# Adds json type for migrations. So you can add columns to a table like:
|
69
|
+
# change_table :people do |t|
|
70
|
+
# ...
|
71
|
+
# t.json :info
|
72
|
+
# ...
|
73
|
+
# end
|
74
|
+
def json(*args)
|
75
|
+
options = args.extract_options!
|
76
|
+
column_names = args
|
77
|
+
column_names.each { |name| column(name, 'json', options) }
|
78
|
+
end
|
79
|
+
|
80
|
+
def jsonb(*args)
|
81
|
+
options = args.extract_options!
|
82
|
+
column_names = args
|
83
|
+
column_names.each { |name| column(name, 'jsonb', options) }
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
data/lib/ardb/version.rb
CHANGED
data/test/helper.rb
CHANGED
@@ -4,10 +4,22 @@
|
|
4
4
|
# add the root dir to the load path
|
5
5
|
$LOAD_PATH.unshift(File.expand_path("../..", __FILE__))
|
6
6
|
|
7
|
+
TEST_SUPPORT_PATH = File.expand_path("../support", __FILE__)
|
8
|
+
TMP_PATH = File.expand_path("../../tmp", __FILE__)
|
9
|
+
|
10
|
+
require 'logger'
|
11
|
+
log_path = File.expand_path("../../log/test.log", __FILE__)
|
12
|
+
TEST_LOGGER = Logger.new(File.open(log_path, 'w'))
|
13
|
+
|
7
14
|
# require pry for debugging (`binding.pry`)
|
8
15
|
require 'pry'
|
9
16
|
require 'test/support/factory'
|
10
17
|
|
11
|
-
|
12
|
-
|
13
|
-
|
18
|
+
# 1.8.7 backfills
|
19
|
+
|
20
|
+
# Array#sample
|
21
|
+
if !(a = Array.new).respond_to?(:sample) && a.respond_to?(:choice)
|
22
|
+
class Array
|
23
|
+
alias_method :sample, :choice
|
24
|
+
end
|
25
|
+
end
|
data/test/support/factory.rb
CHANGED
@@ -8,4 +8,19 @@ module Factory
|
|
8
8
|
"#{Factory.string}_things"
|
9
9
|
end
|
10
10
|
|
11
|
+
def self.ardb_config
|
12
|
+
Ardb::Config.new.tap do |c|
|
13
|
+
c.adapter = Factory.string
|
14
|
+
c.database = Factory.string
|
15
|
+
c.encoding = Factory.string
|
16
|
+
c.host = Factory.string
|
17
|
+
c.port = Factory.integer
|
18
|
+
c.username = Factory.string
|
19
|
+
c.password = Factory.string
|
20
|
+
c.pool = Factory.integer
|
21
|
+
c.checkout_timeout = Factory.integer
|
22
|
+
c.min_messages = Factory.string
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
11
26
|
end
|