dbagile 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENCE.textile +12 -0
- data/README.textile +89 -0
- data/bin/dba +22 -0
- data/lib/dbagile/adapter/sequel/class_methods.rb +18 -0
- data/lib/dbagile/adapter/sequel/connection.rb +38 -0
- data/lib/dbagile/adapter/sequel/data/table_driven.rb +30 -0
- data/lib/dbagile/adapter/sequel/data/transaction_driven.rb +43 -0
- data/lib/dbagile/adapter/sequel/schema/concrete_script.rb +135 -0
- data/lib/dbagile/adapter/sequel/schema/physical_dump.rb +106 -0
- data/lib/dbagile/adapter/sequel/schema/schema2sequel_args.rb +71 -0
- data/lib/dbagile/adapter/sequel/schema/table_driven.rb +52 -0
- data/lib/dbagile/adapter/sequel/schema/transaction_driven.rb +46 -0
- data/lib/dbagile/adapter/sequel/sequel_tracer.rb +144 -0
- data/lib/dbagile/adapter/sequel.rb +46 -0
- data/lib/dbagile/adapter.rb +15 -0
- data/lib/dbagile/command/api.rb +49 -0
- data/lib/dbagile/command/bulk/commons.rb +130 -0
- data/lib/dbagile/command/bulk/export.rb +99 -0
- data/lib/dbagile/command/bulk/import.rb +147 -0
- data/lib/dbagile/command/bulk.rb +3 -0
- data/lib/dbagile/command/class_methods.rb +103 -0
- data/lib/dbagile/command/db/add.rb +94 -0
- data/lib/dbagile/command/db/list.rb +40 -0
- data/lib/dbagile/command/db/ping.rb +49 -0
- data/lib/dbagile/command/db/rm.rb +52 -0
- data/lib/dbagile/command/db/stage.rb +81 -0
- data/lib/dbagile/command/db/use.rb +48 -0
- data/lib/dbagile/command/db.rb +6 -0
- data/lib/dbagile/command/dba.rb +121 -0
- data/lib/dbagile/command/help.rb +50 -0
- data/lib/dbagile/command/repo/create.rb +54 -0
- data/lib/dbagile/command/repo.rb +1 -0
- data/lib/dbagile/command/robust.rb +86 -0
- data/lib/dbagile/command/schema/check.rb +59 -0
- data/lib/dbagile/command/schema/commons.rb +118 -0
- data/lib/dbagile/command/schema/diff.rb +101 -0
- data/lib/dbagile/command/schema/dump.rb +48 -0
- data/lib/dbagile/command/schema/merge.rb +55 -0
- data/lib/dbagile/command/schema/sql_script.rb +124 -0
- data/lib/dbagile/command/schema.rb +6 -0
- data/lib/dbagile/command/sql/drop.rb +40 -0
- data/lib/dbagile/command/sql/heading.rb +34 -0
- data/lib/dbagile/command/sql/send.rb +67 -0
- data/lib/dbagile/command/sql/show.rb +42 -0
- data/lib/dbagile/command/sql.rb +4 -0
- data/lib/dbagile/command/web/tools.rb +23 -0
- data/lib/dbagile/command/web.rb +1 -0
- data/lib/dbagile/command.rb +158 -0
- data/lib/dbagile/contract/connection.rb +66 -0
- data/lib/dbagile/contract/data/dataset.rb +69 -0
- data/lib/dbagile/contract/data/table_driven.rb +49 -0
- data/lib/dbagile/contract/data/transaction_driven.rb +74 -0
- data/lib/dbagile/contract/data.rb +3 -0
- data/lib/dbagile/contract/robust/helpers.rb +19 -0
- data/lib/dbagile/contract/robust/optimistic/data/table_driven.rb +31 -0
- data/lib/dbagile/contract/robust/optimistic/data/transaction_driven.rb +45 -0
- data/lib/dbagile/contract/robust/optimistic/schema/table_driven.rb +53 -0
- data/lib/dbagile/contract/robust/optimistic/schema/transaction_driven.rb +45 -0
- data/lib/dbagile/contract/robust/optimistic.rb +18 -0
- data/lib/dbagile/contract/robust.rb +20 -0
- data/lib/dbagile/contract/schema/table_driven.rb +89 -0
- data/lib/dbagile/contract/schema/transaction_driven.rb +68 -0
- data/lib/dbagile/contract/schema.rb +2 -0
- data/lib/dbagile/contract/utils/delegate.rb +17 -0
- data/lib/dbagile/contract/utils/full.rb +13 -0
- data/lib/dbagile/contract/utils.rb +2 -0
- data/lib/dbagile/contract.rb +5 -0
- data/lib/dbagile/core/chain.rb +92 -0
- data/lib/dbagile/core/connection.rb +51 -0
- data/lib/dbagile/core/database.rb +221 -0
- data/lib/dbagile/core/io/dsl.rb +95 -0
- data/lib/dbagile/core/io/robustness.rb +82 -0
- data/lib/dbagile/core/io.rb +2 -0
- data/lib/dbagile/core/repository/builder.rb +67 -0
- data/lib/dbagile/core/repository/yaml_methods.rb +82 -0
- data/lib/dbagile/core/repository.rb +211 -0
- data/lib/dbagile/core/schema/builder/coercion.rb +210 -0
- data/lib/dbagile/core/schema/builder/concept_factory.rb +61 -0
- data/lib/dbagile/core/schema/builder.rb +187 -0
- data/lib/dbagile/core/schema/composite.rb +239 -0
- data/lib/dbagile/core/schema/computations/filter.rb +40 -0
- data/lib/dbagile/core/schema/computations/merge.rb +55 -0
- data/lib/dbagile/core/schema/computations/minus.rb +44 -0
- data/lib/dbagile/core/schema/computations/split.rb +37 -0
- data/lib/dbagile/core/schema/computations.rb +4 -0
- data/lib/dbagile/core/schema/database_schema.rb +129 -0
- data/lib/dbagile/core/schema/errors.rb +173 -0
- data/lib/dbagile/core/schema/logical/attribute.rb +68 -0
- data/lib/dbagile/core/schema/logical/constraint/candidate_key.rb +70 -0
- data/lib/dbagile/core/schema/logical/constraint/foreign_key.rb +121 -0
- data/lib/dbagile/core/schema/logical/constraint.rb +58 -0
- data/lib/dbagile/core/schema/logical/constraints.rb +28 -0
- data/lib/dbagile/core/schema/logical/heading.rb +47 -0
- data/lib/dbagile/core/schema/logical/relvar.rb +81 -0
- data/lib/dbagile/core/schema/logical.rb +24 -0
- data/lib/dbagile/core/schema/migrate/abstract_script.rb +35 -0
- data/lib/dbagile/core/schema/migrate/collapse_table.rb +15 -0
- data/lib/dbagile/core/schema/migrate/create_table.rb +15 -0
- data/lib/dbagile/core/schema/migrate/drop_table.rb +15 -0
- data/lib/dbagile/core/schema/migrate/expand_table.rb +15 -0
- data/lib/dbagile/core/schema/migrate/operation.rb +141 -0
- data/lib/dbagile/core/schema/migrate/stager.rb +282 -0
- data/lib/dbagile/core/schema/migrate.rb +2 -0
- data/lib/dbagile/core/schema/part.rb +114 -0
- data/lib/dbagile/core/schema/physical/index.rb +64 -0
- data/lib/dbagile/core/schema/physical/indexes.rb +12 -0
- data/lib/dbagile/core/schema/physical.rb +26 -0
- data/lib/dbagile/core/schema/robustness.rb +39 -0
- data/lib/dbagile/core/schema/schema_object.rb +94 -0
- data/lib/dbagile/core/schema.rb +254 -0
- data/lib/dbagile/core/transaction.rb +74 -0
- data/lib/dbagile/core.rb +7 -0
- data/lib/dbagile/environment/buffering.rb +45 -0
- data/lib/dbagile/environment/delegator.rb +59 -0
- data/lib/dbagile/environment/interactions.rb +208 -0
- data/lib/dbagile/environment/on_error.rb +47 -0
- data/lib/dbagile/environment/repository.rb +161 -0
- data/lib/dbagile/environment/robustness.rb +7 -0
- data/lib/dbagile/environment/testing.rb +23 -0
- data/lib/dbagile/environment.rb +122 -0
- data/lib/dbagile/errors.rb +30 -0
- data/lib/dbagile/io/csv.rb +99 -0
- data/lib/dbagile/io/json.rb +41 -0
- data/lib/dbagile/io/pretty_table.rb +128 -0
- data/lib/dbagile/io/ruby.rb +62 -0
- data/lib/dbagile/io/text.rb +18 -0
- data/lib/dbagile/io/type_safe.rb +65 -0
- data/lib/dbagile/io/xml.rb +35 -0
- data/lib/dbagile/io/yaml.rb +30 -0
- data/lib/dbagile/io.rb +94 -0
- data/lib/dbagile/loader.rb +16 -0
- data/lib/dbagile/plugin.rb +29 -0
- data/lib/dbagile/restful/client/delete.rb +22 -0
- data/lib/dbagile/restful/client/get.rb +24 -0
- data/lib/dbagile/restful/client/post.rb +22 -0
- data/lib/dbagile/restful/client/utils.rb +16 -0
- data/lib/dbagile/restful/client.rb +41 -0
- data/lib/dbagile/restful/middleware/delete.rb +22 -0
- data/lib/dbagile/restful/middleware/get.rb +27 -0
- data/lib/dbagile/restful/middleware/one_database.rb +82 -0
- data/lib/dbagile/restful/middleware/post.rb +23 -0
- data/lib/dbagile/restful/middleware/utils.rb +65 -0
- data/lib/dbagile/restful/middleware.rb +54 -0
- data/lib/dbagile/restful/server.rb +65 -0
- data/lib/dbagile/restful.rb +9 -0
- data/lib/dbagile/robustness/dependencies.rb +36 -0
- data/lib/dbagile/robustness/file_system.rb +53 -0
- data/lib/dbagile/robustness.rb +14 -0
- data/lib/dbagile/tools/file_system.rb +24 -0
- data/lib/dbagile/tools/math.rb +11 -0
- data/lib/dbagile/tools/ordered_hash.rb +39 -0
- data/lib/dbagile/tools/ruby.rb +78 -0
- data/lib/dbagile/tools/string.rb +6 -0
- data/lib/dbagile/tools/tuple.rb +49 -0
- data/lib/dbagile/tools.rb +6 -0
- data/lib/dbagile.rb +66 -0
- data/test/assumptions/equality.spec +11 -0
- data/test/assumptions/fixtures.rb +39 -0
- data/test/assumptions/inheritance.spec +17 -0
- data/test/assumptions/sequel/autonumber.spec +19 -0
- data/test/assumptions/sequel/connect.spec +29 -0
- data/test/assumptions/sequel/test.db +0 -0
- data/test/assumptions/stdlib/pathname.spec +13 -0
- data/test/assumptions/yaml/fixtures.rb +25 -0
- data/test/assumptions/yaml/to_yaml.spec +10 -0
- data/test/assumptions.spec +2 -0
- data/test/commands/bulk/export.spec +100 -0
- data/test/commands/bulk/import.spec +49 -0
- data/test/commands/db/add.spec +31 -0
- data/test/commands/db/list.spec +29 -0
- data/test/commands/db/ping.spec +21 -0
- data/test/commands/db/rm.spec +18 -0
- data/test/commands/db/use.spec +18 -0
- data/test/commands/dba.spec +54 -0
- data/test/commands/repo/create.spec +30 -0
- data/test/commands/schema/check.spec +25 -0
- data/test/commands/schema/diff.spec +30 -0
- data/test/commands/schema/dump.spec +23 -0
- data/test/commands/schema/fixtures/add_constraint.yaml +30 -0
- data/test/commands/schema/fixtures/announced.yaml +28 -0
- data/test/commands/schema/fixtures/effective.yaml +20 -0
- data/test/commands/schema/fixtures/invalid.yaml +6 -0
- data/test/commands/schema/sql_script.spec +56 -0
- data/test/commands/sql/drop.spec +25 -0
- data/test/commands/sql/heading.spec +7 -0
- data/test/commands/sql/scripts/delete.sql +1 -0
- data/test/commands/sql/scripts/insert.sql +2 -0
- data/test/commands/sql/send.spec +29 -0
- data/test/commands/sql/show.spec +17 -0
- data/test/commands.spec +138 -0
- data/test/contract/connection/transaction.ex +11 -0
- data/test/contract/connection.spec +9 -0
- data/test/contract/data/dataset/columns.ex +5 -0
- data/test/contract/data/dataset/count.ex +5 -0
- data/test/contract/data/dataset.spec +9 -0
- data/test/contract/data/table_driven/dataset.ex +31 -0
- data/test/contract/data/table_driven/exists_q.ex +27 -0
- data/test/contract/data/table_driven.spec +9 -0
- data/test/contract/data/transaction_driven/delete.ex +29 -0
- data/test/contract/data/transaction_driven/direct_sql.ex +19 -0
- data/test/contract/data/transaction_driven/insert.ex +8 -0
- data/test/contract/data/transaction_driven/update.ex +19 -0
- data/test/contract/data/transaction_driven.spec +18 -0
- data/test/contract/robust/data/table_driven.spec +15 -0
- data/test/contract/robust/data/transaction_driven.spec +21 -0
- data/test/contract/robust/schema/table_driven.spec +21 -0
- data/test/contract/robust/schema/transaction_driven.spec +19 -0
- data/test/contract/schema/table_driven/column_names.ex +5 -0
- data/test/contract/schema/table_driven/has_column_q.ex +13 -0
- data/test/contract/schema/table_driven/has_table_q.ex +11 -0
- data/test/contract/schema/table_driven/heading.ex +5 -0
- data/test/contract/schema/table_driven.spec +9 -0
- data/test/contract/schema/transaction_driven/create_table.ex +10 -0
- data/test/contract/schema/transaction_driven/drop_table.ex +10 -0
- data/test/contract/schema/transaction_driven.spec +18 -0
- data/test/contract.spec +66 -0
- data/test/fixtures/basics/data/basic_values.rb +13 -0
- data/test/fixtures/basics/data/empty_table.rb +3 -0
- data/test/fixtures/basics/data/non_empty_table.rb +4 -0
- data/test/fixtures/basics/data/parts.rb +8 -0
- data/test/fixtures/basics/data/suppliers.rb +7 -0
- data/test/fixtures/basics/data/supplies.rb +14 -0
- data/test/fixtures/basics/dbagile.idx +20 -0
- data/test/fixtures/basics/fixtures.yaml +28 -0
- data/test/fixtures/basics/robust.db +0 -0
- data/test/fixtures/basics/suppliers.yaml +30 -0
- data/test/fixtures/basics/test.db +0 -0
- data/test/fixtures/empty/dbagile.idx +5 -0
- data/test/fixtures.rb +152 -0
- data/test/restful/delete/no_format.ex +32 -0
- data/test/restful/delete.spec +8 -0
- data/test/restful/get/csv_format.ex +12 -0
- data/test/restful/get/json_format.ex +19 -0
- data/test/restful/get/query_string.ex +11 -0
- data/test/restful/get/text_format.ex +12 -0
- data/test/restful/get/yaml_format.ex +14 -0
- data/test/restful/get.spec +5 -0
- data/test/restful/post/no_format.ex +22 -0
- data/test/restful/post.spec +8 -0
- data/test/restful.spec +32 -0
- data/test/run_all_suite.rb +51 -0
- data/test/spec_helper.rb +26 -0
- data/test/support/be_a_valid_json_string.rb +19 -0
- data/test/support/be_a_valid_yaml_string.rb +18 -0
- data/test/unit/adapter/factor.spec +13 -0
- data/test/unit/adapter/sequel/new.spec +19 -0
- data/test/unit/command/api.spec +12 -0
- data/test/unit/command/command_for.spec +36 -0
- data/test/unit/command/command_name_of.spec +21 -0
- data/test/unit/command/ruby_method_for.spec +21 -0
- data/test/unit/command/sanity.spec +34 -0
- data/test/unit/contract/utils/delegate/delegate.spec +23 -0
- data/test/unit/core/chain/chain.spec +57 -0
- data/test/unit/core/chain/connect.spec +22 -0
- data/test/unit/core/chain/delegate_chain.spec +16 -0
- data/test/unit/core/chain/initialize.spec +19 -0
- data/test/unit/core/chain/plug.spec +31 -0
- data/test/unit/core/io/dsl/scope.spec +9 -0
- data/test/unit/core/repository/create_bang.spec +31 -0
- data/test/unit/core/repository/current.spec +31 -0
- data/test/unit/core/repository/database.spec +47 -0
- data/test/unit/core/repository/fixtures/corrupted/dbagile.idx +1 -0
- data/test/unit/core/repository/fixtures/test_and_prod/dbagile.idx +21 -0
- data/test/unit/core/repository/fixtures.rb +25 -0
- data/test/unit/core/repository/has_database_q.spec +16 -0
- data/test/unit/core/repository/load.spec +51 -0
- data/test/unit/core/repository/to_yaml.spec +17 -0
- data/test/unit/core/schema/check.spec +32 -0
- data/test/unit/core/schema/empty_q.spec +18 -0
- data/test/unit/core/schema/filter.spec +42 -0
- data/test/unit/core/schema/fixtures/dbagile.yaml +7 -0
- data/test/unit/core/schema/fixtures/empty.yaml +11 -0
- data/test/unit/core/schema/fixtures/invalid.yaml +54 -0
- data/test/unit/core/schema/fixtures/left.yaml +46 -0
- data/test/unit/core/schema/fixtures/left_minus_right.yaml +31 -0
- data/test/unit/core/schema/fixtures/right.yaml +46 -0
- data/test/unit/core/schema/fixtures/right_minus_left.yaml +31 -0
- data/test/unit/core/schema/fixtures/suppliers_and_parts.yaml +30 -0
- data/test/unit/core/schema/fixtures.rb +32 -0
- data/test/unit/core/schema/merge.spec +72 -0
- data/test/unit/core/schema/minus.spec +26 -0
- data/test/unit/core/schema/sanity.spec +39 -0
- data/test/unit/core/schema/split.spec +58 -0
- data/test/unit/core/schema/stage_script.spec +26 -0
- data/test/unit/core/schema/to_yaml.spec +13 -0
- data/test/unit/core/schema/yaml_display.spec +14 -0
- data/test/unit/core/schema/yaml_load.spec +20 -0
- data/test/unit/core/transaction/transaction.spec +10 -0
- data/test/unit/fixtures.rb +67 -0
- data/test/unit/io/to_xxx.spec +52 -0
- data/test/unit/plugin/options.spec +21 -0
- data/test/unit/plugin/tuple_heading.spec +11 -0
- data/test/unit/plugin/with_options.spec +12 -0
- data/test/unit/tools/ruby/class_unqualified_name.spec +26 -0
- data/test/unit/tools/ruby/extract_file_rdoc.spec +10 -0
- data/test/unit/tools/ruby/fixtures/rdoc.txt +12 -0
- data/test/unit/tools/ruby/fixtures.rb +19 -0
- data/test/unit/tools/ruby/optional_args_block_call.spec +35 -0
- data/test/unit/tools/ruby/parent_module.spec +21 -0
- data/test/unit/tools/ruby/rdoc_file_paragraphs.spec +13 -0
- data/test/unit/tools/tuple/tuple_heading.spec +11 -0
- data/test/unit/tools/tuple/tuple_key.spec +27 -0
- data/test/unit/tools/tuple/tuple_project.spec +23 -0
- data/test/unit.spec +3 -0
- metadata +422 -0
@@ -0,0 +1 @@
|
|
1
|
+
require 'dbagile/command/repo/create.rb'
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module DbAgile
|
2
|
+
class Command
|
3
|
+
module Robust
|
4
|
+
include DbAgile::Core::IO::Robustness
|
5
|
+
|
6
|
+
# Raises an OptionParser::InvalidArgument
|
7
|
+
def bad_argument_list!(rest, expected_name = nil)
|
8
|
+
if rest.empty?
|
9
|
+
raise OptionParser::MissingArgument, "#{expected_name}"
|
10
|
+
else
|
11
|
+
raise OptionParser::InvalidArgument, "#{rest.join(' ')}"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# Raises an OptionParser::AmbiguousArgument
|
16
|
+
def ambigous_argument_list!
|
17
|
+
raise OptionParser::AmbiguousArgument, "Ambiguous options"
|
18
|
+
end
|
19
|
+
|
20
|
+
# Parses pending arguments, assert that it contains exactly
|
21
|
+
# types.size arguments, and convert them to types.
|
22
|
+
def valid_argument_list!(rest, *types)
|
23
|
+
if rest.size == types.size
|
24
|
+
result = rest.zip(types).collect do |arg, type|
|
25
|
+
if String == type
|
26
|
+
arg.to_s
|
27
|
+
elsif Symbol == type
|
28
|
+
arg.to_sym
|
29
|
+
elsif Integer
|
30
|
+
arg.to_i
|
31
|
+
else
|
32
|
+
raise OptionParser::InvalidArgument, arg
|
33
|
+
end
|
34
|
+
end
|
35
|
+
result.size == 1 ? result[0] : result
|
36
|
+
elsif rest.size < types.size
|
37
|
+
raise OptionParser::MissingArgument
|
38
|
+
else
|
39
|
+
raise OptionParser::NeedlessArgument, rest
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Asserts that an argument matches some candidates or
|
44
|
+
# raises a OptionParser::InvalidArgument error.
|
45
|
+
def is_in!(name, value, candidates)
|
46
|
+
value = valid_argument_list!([ value ], candidates.first.class)
|
47
|
+
unless candidates.include?(value)
|
48
|
+
raise OptionParser::InvalidArgument, "Expected one of #{candidates.inspect} for #{name}"
|
49
|
+
end
|
50
|
+
value
|
51
|
+
end
|
52
|
+
|
53
|
+
# Checks that a file exists and can be read or raises an IO error
|
54
|
+
def valid_read_file!(file)
|
55
|
+
raise IOError, "Unable to read #{file}" unless File.file?(file) and File.readable?(file)
|
56
|
+
file
|
57
|
+
end
|
58
|
+
|
59
|
+
#
|
60
|
+
# Asserts that a command exists or raises a NoSuchCommandError.
|
61
|
+
#
|
62
|
+
# @return [DbAgile::Command] the command instance
|
63
|
+
#
|
64
|
+
def has_command!(name, env)
|
65
|
+
cmd = DbAgile::Command.command_for(name, env)
|
66
|
+
if cmd.nil?
|
67
|
+
DbAgile::Command::CATEGORIES.each{|c|
|
68
|
+
cmd = DbAgile::Command.command_for("#{c}:#{name}", env)
|
69
|
+
return cmd if cmd
|
70
|
+
}
|
71
|
+
raise DbAgile::NoSuchCommandError, "No such command #{name.inspect}"
|
72
|
+
else
|
73
|
+
cmd
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
#
|
78
|
+
# Raises a DbAgile::AssumptionFailedError with a specific message
|
79
|
+
#
|
80
|
+
def assumption_error!(msg)
|
81
|
+
raise DbAgile::AssumptionFailedError, msg
|
82
|
+
end
|
83
|
+
|
84
|
+
end # module Robust
|
85
|
+
end # class Command
|
86
|
+
end # module DbAgile
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module DbAgile
|
2
|
+
class Command
|
3
|
+
module Schema
|
4
|
+
#
|
5
|
+
# Check a database schema
|
6
|
+
#
|
7
|
+
# Usage: dba #{command_name} [SCHEMA.yaml|announced|effective|physical]
|
8
|
+
#
|
9
|
+
# This command informs you about bad smells and good practices with relational
|
10
|
+
# schemas (i.e. forgetting to create keys, not providing unique constraint
|
11
|
+
# names, and so on).
|
12
|
+
#
|
13
|
+
# dba #{command_name} SCHEMA.yaml
|
14
|
+
#
|
15
|
+
# Load the schema from file and check it, printing advices and errors on the
|
16
|
+
# message console. The command does not connect any database in this mode.
|
17
|
+
#
|
18
|
+
# dba #{command_name} [announced|effective|physical]
|
19
|
+
#
|
20
|
+
# Checks a schema of the current database. Announced schema is implicit without
|
21
|
+
# any argument. This command uses a fallback chain (announced -> effective ->
|
22
|
+
# physical) and has no side-effect on the database itself (read-only).
|
23
|
+
#
|
24
|
+
class Check < Command
|
25
|
+
include Schema::Commons
|
26
|
+
Command::build_me(self, __FILE__)
|
27
|
+
|
28
|
+
# Returns :single
|
29
|
+
def kind_of_schema_arguments
|
30
|
+
:single
|
31
|
+
end
|
32
|
+
|
33
|
+
# Contribute to options
|
34
|
+
def add_options(opt)
|
35
|
+
self.check_schemas = false
|
36
|
+
end
|
37
|
+
|
38
|
+
# Executes the command
|
39
|
+
def execute_command
|
40
|
+
with_schema do |schema|
|
41
|
+
errors = schema.check!(false)
|
42
|
+
say("\n")
|
43
|
+
if errors.empty?
|
44
|
+
say("Valid schema (#{schema.schema_identifier.inspect})!", :green)
|
45
|
+
say("\n")
|
46
|
+
[ schema, errors ]
|
47
|
+
else
|
48
|
+
say("Invalid schema (#{schema.schema_identifier.inspect}):", :red)
|
49
|
+
errors.error_messages.each{|m| say(" * #{m}")}
|
50
|
+
say("\n")
|
51
|
+
[ schema, errors ]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end # class Check
|
57
|
+
end # module Schema
|
58
|
+
end # class Command
|
59
|
+
end # module DbAgile
|
@@ -0,0 +1,118 @@
|
|
1
|
+
module DbAgile
|
2
|
+
class Command
|
3
|
+
module Schema
|
4
|
+
module Commons
|
5
|
+
|
6
|
+
# Checks schema(s) first?
|
7
|
+
attr_accessor :check_schemas
|
8
|
+
|
9
|
+
# Schema arguments
|
10
|
+
attr_accessor :schema_arguments
|
11
|
+
|
12
|
+
# Adds --[no-]check option
|
13
|
+
def add_check_options(opt)
|
14
|
+
self.check_schemas = true
|
15
|
+
opt.on('--[no-]check', "Perform/Bypass schema checking") do |value|
|
16
|
+
self.check_schemas = value
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Normalizes a schema argument
|
21
|
+
def normalize_schema_argument(argument)
|
22
|
+
if File.exists?(argument) and File.file?(argument)
|
23
|
+
argument
|
24
|
+
else
|
25
|
+
is_in!("schema", argument, [:announced, :effective, :physical])
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Normalizes the pending arguments
|
30
|
+
def normalize_schema_arguments(arguments)
|
31
|
+
@schema_arguments = case kind_of_schema_arguments
|
32
|
+
when :single
|
33
|
+
if arguments.empty?
|
34
|
+
[ :announced ]
|
35
|
+
elsif arguments.size == 1
|
36
|
+
arguments.collect{|arg| normalize_schema_argument(arg) }
|
37
|
+
else
|
38
|
+
bad_argument_list!(arguments)
|
39
|
+
end
|
40
|
+
when :double
|
41
|
+
if arguments.empty?
|
42
|
+
[ :effective, :announced ]
|
43
|
+
elsif arguments.size == 2
|
44
|
+
arguments.collect{|arg| normalize_schema_argument(arg) }
|
45
|
+
else
|
46
|
+
bad_argument_list!(arguments)
|
47
|
+
end
|
48
|
+
when :multiple
|
49
|
+
if arguments.size >= 2
|
50
|
+
arguments.collect{|arg| normalize_schema_argument(arg) }
|
51
|
+
else
|
52
|
+
bad_argument_list!(arguments)
|
53
|
+
end
|
54
|
+
else
|
55
|
+
assumption_error!("Unexpected kind of schema argument #{kind_of_schema_arguments}")
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# Normalizes the pending arguments
|
60
|
+
def normalize_pending_arguments(arguments)
|
61
|
+
normalize_schema_arguments(arguments)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Loads a given schema from a schema argument
|
65
|
+
def load_schema(schema_argument, check = self.check_schemas)
|
66
|
+
schema = case schema_argument
|
67
|
+
when Symbol
|
68
|
+
with_current_database do |database|
|
69
|
+
case schema_argument
|
70
|
+
when :announced
|
71
|
+
database.announced_schema(true)
|
72
|
+
when :effective
|
73
|
+
database.effective_schema(true)
|
74
|
+
when :physical
|
75
|
+
database.physical_schema
|
76
|
+
end
|
77
|
+
end
|
78
|
+
when String
|
79
|
+
s = DbAgile::Core::Schema::yaml_file_load(schema_argument)
|
80
|
+
s.schema_identifier = schema_argument
|
81
|
+
s
|
82
|
+
end
|
83
|
+
|
84
|
+
# A small check, to be sure
|
85
|
+
if schema.nil?
|
86
|
+
assumption_error!("Unexpected schema argument kind #{schema_argument}")
|
87
|
+
end
|
88
|
+
|
89
|
+
# Check schema if requested
|
90
|
+
if check
|
91
|
+
schema.check!
|
92
|
+
end
|
93
|
+
|
94
|
+
# Return schema now
|
95
|
+
schema
|
96
|
+
end
|
97
|
+
|
98
|
+
# Yields the block, passing schemas as an array, according to
|
99
|
+
# kind_of_schema_arguments
|
100
|
+
def with_schemas(check = self.check_schemas)
|
101
|
+
schemas = schema_arguments.collect{|arg| load_schema(arg, check)}
|
102
|
+
case kind_of_schema_arguments
|
103
|
+
when :single
|
104
|
+
yield(schemas.first)
|
105
|
+
when :double
|
106
|
+
yield(schemas[0], schemas[1])
|
107
|
+
when :multiple
|
108
|
+
yield(schemas)
|
109
|
+
else
|
110
|
+
assumption_error!("Unexpected kind of schema argument #{kind_of_schema_arguments}")
|
111
|
+
end
|
112
|
+
end
|
113
|
+
alias :with_schema :with_schemas
|
114
|
+
|
115
|
+
end # module Commons
|
116
|
+
end # module Schema
|
117
|
+
end # class Command
|
118
|
+
end # module DbAgile
|
@@ -0,0 +1,101 @@
|
|
1
|
+
module DbAgile
|
2
|
+
class Command
|
3
|
+
module Schema
|
4
|
+
#
|
5
|
+
# Show differences between database schemas
|
6
|
+
#
|
7
|
+
# Usage: dba #{command_name} [schema1 schema2]
|
8
|
+
#
|
9
|
+
# This command is a diff for database schemas, helping database staging
|
10
|
+
# and migrations by showing objects to create/drop/alter.
|
11
|
+
#
|
12
|
+
# dba #{command_name}
|
13
|
+
#
|
14
|
+
# Shortcut for 'dba schema:diff announced effective'
|
15
|
+
#
|
16
|
+
# dba #{command_name} schema1 schema2
|
17
|
+
#
|
18
|
+
# Show differences between two particular schemas, being either installed
|
19
|
+
# schemas [announced|effective|physical] or schema files. This command
|
20
|
+
# uses a fallback chain (announced -> effective -> physical) and has no
|
21
|
+
# side-effect on the database itself (read-only).
|
22
|
+
#
|
23
|
+
# NOTE: Schema-checking is on by default, which may lead to checking errors,
|
24
|
+
# typically when reverse engineering poorly designed databases. Doing so
|
25
|
+
# immediately informs you about a potential problem.
|
26
|
+
#
|
27
|
+
# Use --no-check to bypass schema checking. See also schema:check.
|
28
|
+
#
|
29
|
+
class Diff < Command
|
30
|
+
include Schema::Commons
|
31
|
+
Command::build_me(self, __FILE__)
|
32
|
+
|
33
|
+
# Output options
|
34
|
+
attr_reader :output_options
|
35
|
+
|
36
|
+
# Sets the default options
|
37
|
+
def set_default_options
|
38
|
+
@output_options = {:skip_unchanged => false}
|
39
|
+
end
|
40
|
+
|
41
|
+
# Contribute to options
|
42
|
+
def add_options(opt)
|
43
|
+
opt.separator nil
|
44
|
+
opt.separator "Options:"
|
45
|
+
add_check_options(opt)
|
46
|
+
opt.on("--[no-]skip-unchanged", "-u",
|
47
|
+
"Don't show objects that did'nt change") do |value|
|
48
|
+
self.output_options[:skip_unchanged] = value
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Returns :single
|
53
|
+
def kind_of_schema_arguments
|
54
|
+
:double
|
55
|
+
end
|
56
|
+
|
57
|
+
# Executes the command
|
58
|
+
def execute_command
|
59
|
+
with_schemas do |left, right|
|
60
|
+
merged = DbAgile::Core::Schema::merge(left, right)
|
61
|
+
show_diff(left, right, merged, environment, output_options)
|
62
|
+
merged
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# Shows difference between left and right
|
67
|
+
def show_diff(left, right, merged, environment, output_options)
|
68
|
+
# Validity
|
69
|
+
if left.looks_valid?
|
70
|
+
lv = environment.color("(valid!)", :green)
|
71
|
+
else
|
72
|
+
lv = environment.color("(INVALID, you'd better run 'dba schema:check --effective')", HighLine::RED + HighLine::BOLD)
|
73
|
+
end
|
74
|
+
if right.looks_valid?
|
75
|
+
rv = environment.color("(valid!)", :green)
|
76
|
+
else
|
77
|
+
rv = environment.color("(INVALID, you'd better run 'dba schema:check')", HighLine::RED + HighLine::BOLD)
|
78
|
+
end
|
79
|
+
|
80
|
+
# Debug
|
81
|
+
ld, rd = left.schema_identifier.inspect, right.schema_identifier.inspect
|
82
|
+
ld, rd = "#{ld} #{lv}", "#{rd} #{rv}"
|
83
|
+
|
84
|
+
# Say
|
85
|
+
environment.say '###'
|
86
|
+
environment.say "### LEFT: #{ld}"
|
87
|
+
environment.say "### RIGHT: #{rd}"
|
88
|
+
environment.say '###'
|
89
|
+
environment.say "### " + environment.color('Objects to add on LEFT', :green)
|
90
|
+
environment.say '### ' + environment.color('Objects to remove on LEFT', :red)
|
91
|
+
environment.say '### ' + environment.color('Objects to alter on LEFT', :cyan)
|
92
|
+
environment.say '###'
|
93
|
+
environment.say "\n"
|
94
|
+
merged.yaml_display(environment, output_options)
|
95
|
+
environment.say "\n"
|
96
|
+
end
|
97
|
+
|
98
|
+
end # class SchemaDump
|
99
|
+
end # module Schema
|
100
|
+
end # class Command
|
101
|
+
end # module DbAgile
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module DbAgile
|
2
|
+
class Command
|
3
|
+
module Schema
|
4
|
+
#
|
5
|
+
# Dump a schema of the current database
|
6
|
+
#
|
7
|
+
# Usage: dba #{command_name} [announced|effective|physical]
|
8
|
+
#
|
9
|
+
# This command dumps the schema of the current database on the output console.
|
10
|
+
# Without argument, the announced schema is implicit. This command uses the
|
11
|
+
# fallback chain (announced -> effective -> physical) and has no side-effect
|
12
|
+
# on the database itself (read-only).
|
13
|
+
#
|
14
|
+
# NOTE: Schema-checking is on by default, which may lead to checking errors,
|
15
|
+
# typically when reverse engineering poorly designed databases. Doing so
|
16
|
+
# immediately informs you about a potential problem.
|
17
|
+
#
|
18
|
+
# Use --no-check to bypass schema checking. See also schema:check.
|
19
|
+
#
|
20
|
+
class Dump < Command
|
21
|
+
include Schema::Commons
|
22
|
+
Command::build_me(self, __FILE__)
|
23
|
+
|
24
|
+
# Contribute to options
|
25
|
+
def add_options(opt)
|
26
|
+
opt.separator nil
|
27
|
+
opt.separator "Options:"
|
28
|
+
add_check_options(opt)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Returns :single
|
32
|
+
def kind_of_schema_arguments
|
33
|
+
:single
|
34
|
+
end
|
35
|
+
|
36
|
+
# Executes the command
|
37
|
+
def execute_command
|
38
|
+
with_schema do |schema|
|
39
|
+
say("# Schema of #{schema.schema_identifier.inspect}", :magenta)
|
40
|
+
flush(schema.to_yaml)
|
41
|
+
schema
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end # class SchemaDump
|
46
|
+
end # module Schema
|
47
|
+
end # class Command
|
48
|
+
end # module DbAgile
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module DbAgile
|
2
|
+
class Command
|
3
|
+
module Schema
|
4
|
+
#
|
5
|
+
# Merge a list of schemas
|
6
|
+
#
|
7
|
+
# Usage: dba #{command_name} SCHEMA_ARG, ...
|
8
|
+
#
|
9
|
+
# This command merges all schema in arguments into a single schema and dumps the
|
10
|
+
# result in YAML on the output console. Schema arguments may be schema files or
|
11
|
+
# schemas installed on the current database [announced|effective|physical]. This
|
12
|
+
# command uses the fallback chain (announced -> effective -> physical) and has no
|
13
|
+
# side-effect on the database itself (read-only).
|
14
|
+
#
|
15
|
+
# NOTE: Schema-checking is on by default and applied on the resulting schema.
|
16
|
+
# This which may lead to checking errors when reverse engineering poorly
|
17
|
+
# designed databases. Doing so immediately informs you about a potential
|
18
|
+
# problem.
|
19
|
+
#
|
20
|
+
# Use --no-check to bypass schema checking. See also schema:check.
|
21
|
+
#
|
22
|
+
class Merge < Command
|
23
|
+
include Schema::Commons
|
24
|
+
Command::build_me(self, __FILE__)
|
25
|
+
|
26
|
+
# Contribute to options
|
27
|
+
def add_options(opt)
|
28
|
+
opt.separator nil
|
29
|
+
opt.separator "Options:"
|
30
|
+
add_check_options(opt)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Returns :single
|
34
|
+
def kind_of_schema_arguments
|
35
|
+
:multiple
|
36
|
+
end
|
37
|
+
|
38
|
+
# Executes the command
|
39
|
+
def execute_command
|
40
|
+
with_schemas(false) do |schemas|
|
41
|
+
empty = DbAgile::Core::Schema::EMPTY_SCHEMA
|
42
|
+
result = schemas.inject(empty){|memo,schema| memo + schema}
|
43
|
+
if self.check_schemas
|
44
|
+
result.check!
|
45
|
+
say("# And the result is valid!", :green)
|
46
|
+
end
|
47
|
+
flush(result.to_yaml)
|
48
|
+
result
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end # class SchemaDump
|
53
|
+
end # module Schema
|
54
|
+
end # class Command
|
55
|
+
end # module DbAgile
|
@@ -0,0 +1,124 @@
|
|
1
|
+
module DbAgile
|
2
|
+
class Command
|
3
|
+
module Schema
|
4
|
+
#
|
5
|
+
# Flush a SQL script for a creating/dropping/staging a schema
|
6
|
+
#
|
7
|
+
# Usage: dba #{command_name} {create, drop, stage} [SCHEMA_ARG, ...]
|
8
|
+
#
|
9
|
+
# dba #{command_name} create [announced|effective|physical|FILE.yaml]
|
10
|
+
#
|
11
|
+
# Flush a SQL script for creating a SQL database from a schema. Announced
|
12
|
+
# schema of the database is the default. This command uses the fallback chain
|
13
|
+
# (announced -> effective -> physical) and has no side-effect on the database
|
14
|
+
# itself (read-only).
|
15
|
+
#
|
16
|
+
# dba #{command_name} drop [announced|effective|physical|FILE.yaml]
|
17
|
+
#
|
18
|
+
# Flush a SQL script for dropping all objects of a SQL database. Announced
|
19
|
+
# schema of the database is the default. This command uses the fallback chain
|
20
|
+
# (announced -> effective -> physical) and has no side-effect on the database
|
21
|
+
# itself (read-only).
|
22
|
+
#
|
23
|
+
# dba #{command_name} stage [schema1 schema2]
|
24
|
+
#
|
25
|
+
# Flush a SQL script for staging a database from schema1 to schema2. Arguments
|
26
|
+
# can be installed schemas of the current database or schema files. Effective
|
27
|
+
# and announced schema of the current database are respectively used by default.
|
28
|
+
# The command uses the fallback chain (announced -> effective -> physical) and
|
29
|
+
# has no side-effect on the current database itself (read-only).
|
30
|
+
#
|
31
|
+
# Schema-checking is on by default, which may lead to checking errors, typically
|
32
|
+
# when reverse engineering poorly designed databases. Doing so immediately informs
|
33
|
+
# you about a potential problem.
|
34
|
+
#
|
35
|
+
# Use --no-check to bypass schema checking. See also schema:check.
|
36
|
+
#
|
37
|
+
class SqlScript < Command
|
38
|
+
include Schema::Commons
|
39
|
+
Command::build_me(self, __FILE__)
|
40
|
+
|
41
|
+
# Kinds of script
|
42
|
+
SCRIPT_KIND = [:create, :drop, :stage]
|
43
|
+
|
44
|
+
# Kind of script [:create, :drop, :stage]
|
45
|
+
attr_accessor :script_kind
|
46
|
+
|
47
|
+
# Contribute to options
|
48
|
+
def add_options(opt)
|
49
|
+
opt.separator nil
|
50
|
+
opt.separator "Options:"
|
51
|
+
add_check_options(opt)
|
52
|
+
end
|
53
|
+
|
54
|
+
# Returns :single
|
55
|
+
def kind_of_schema_arguments
|
56
|
+
if script_kind == :stage
|
57
|
+
:double
|
58
|
+
else
|
59
|
+
:single
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Normalizes the pending arguments
|
64
|
+
def normalize_pending_arguments(arguments)
|
65
|
+
case arguments.size
|
66
|
+
when 0
|
67
|
+
bad_argument_list!(arguments, "script kind")
|
68
|
+
else
|
69
|
+
self.script_kind = is_in!("script kind", arguments.shift, SCRIPT_KIND)
|
70
|
+
normalize_schema_arguments(arguments)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# Executes the command
|
75
|
+
def execute_command
|
76
|
+
case kind_of_schema_arguments
|
77
|
+
when :single
|
78
|
+
execute_single_command
|
79
|
+
when :double
|
80
|
+
execute_double_command
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# Execution for :create and :drop
|
85
|
+
def execute_single_command
|
86
|
+
script = with_schema{|schema|
|
87
|
+
case self.script_kind
|
88
|
+
when :create
|
89
|
+
DbAgile::Core::Schema::create_script(schema)
|
90
|
+
when :drop
|
91
|
+
DbAgile::Core::Schema::drop_script(schema)
|
92
|
+
else
|
93
|
+
raise DbAgile::AssumptionFailedError, "Unknown script kind #{self.script_kind}"
|
94
|
+
end
|
95
|
+
}
|
96
|
+
with_current_connection{|conn|
|
97
|
+
conn.script2sql(script, environment.output_buffer)
|
98
|
+
}
|
99
|
+
end
|
100
|
+
|
101
|
+
# Execution for :stage
|
102
|
+
def execute_double_command
|
103
|
+
script = with_schemas{|left, right|
|
104
|
+
case self.script_kind
|
105
|
+
when :stage
|
106
|
+
merged = left + right
|
107
|
+
script = DbAgile::Core::Schema::stage_script(merged)
|
108
|
+
if merged.status == DbAgile::Core::Schema::NO_CHANGE
|
109
|
+
say("Nothing to stage", :magenta)
|
110
|
+
end
|
111
|
+
script
|
112
|
+
else
|
113
|
+
raise DbAgile::AssumptionFailedError, "Unknown script kind #{self.script_kind}"
|
114
|
+
end
|
115
|
+
}
|
116
|
+
with_current_connection{|conn|
|
117
|
+
conn.script2sql(script, environment.output_buffer)
|
118
|
+
}
|
119
|
+
end
|
120
|
+
|
121
|
+
end # class CreateScript
|
122
|
+
end # module Schema
|
123
|
+
end # class Command
|
124
|
+
end # module DbAgile
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module DbAgile
|
2
|
+
class Command
|
3
|
+
module SQL
|
4
|
+
#
|
5
|
+
# Drop a table from a SQL database
|
6
|
+
#
|
7
|
+
# Usage: dba #{command_name} TABLE
|
8
|
+
#
|
9
|
+
# This command issues a "DROP TABLE ..." in the DbAgile's command chain, therefore
|
10
|
+
# targetting the schema of the physical SQL database and bypassing other schemas if
|
11
|
+
# present (announced and effectice schemas in particular).
|
12
|
+
#
|
13
|
+
# As it may lead to divergences between schemas, and between effective and physical
|
14
|
+
# schemas in particular, you should consider using schema:* commands instead, when
|
15
|
+
# possible.
|
16
|
+
#
|
17
|
+
class Drop < Command
|
18
|
+
Command::build_me(self, __FILE__)
|
19
|
+
|
20
|
+
# Table which must be dropped
|
21
|
+
attr_accessor :table
|
22
|
+
|
23
|
+
# Normalizes the pending arguments
|
24
|
+
def normalize_pending_arguments(arguments)
|
25
|
+
self.table = valid_argument_list!(arguments, Symbol)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Executes the command
|
29
|
+
def execute_command
|
30
|
+
with_current_connection do |connection|
|
31
|
+
connection.transaction do |t|
|
32
|
+
t.drop_table(self.table)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end # class Drop
|
38
|
+
end # module SQL
|
39
|
+
end # class Command
|
40
|
+
end # module DbAgile
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module DbAgile
|
2
|
+
class Command
|
3
|
+
module SQL
|
4
|
+
#
|
5
|
+
# Show the heading of a table
|
6
|
+
#
|
7
|
+
# Usage: dba #{command_name} TABLE
|
8
|
+
#
|
9
|
+
# This commands shows a list with columns names and types for a given table
|
10
|
+
# of the current SQL database.
|
11
|
+
#
|
12
|
+
class Heading < Command
|
13
|
+
Command::build_me(self, __FILE__)
|
14
|
+
|
15
|
+
# Table whose heading must be displayed
|
16
|
+
attr_accessor :dataset
|
17
|
+
|
18
|
+
# Normalizes the pending arguments
|
19
|
+
def normalize_pending_arguments(arguments)
|
20
|
+
self.dataset = valid_argument_list!(arguments, Symbol)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Executes the command
|
24
|
+
def execute_command
|
25
|
+
with_current_connection do |connection|
|
26
|
+
heading = connection.heading(self.dataset)
|
27
|
+
flush("{\n" + heading.collect{|pair| " #{pair[0]}: #{pair[1]}"}.join(",\n") + "\n}\n")
|
28
|
+
heading
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end # class Heading
|
32
|
+
end # # module SQL
|
33
|
+
end # class Command
|
34
|
+
end # module DbAgile
|