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,144 @@
|
|
1
|
+
module DbAgile
|
2
|
+
class SequelAdapter
|
3
|
+
class SequelTracer
|
4
|
+
include DbAgile::Contract::Utils::Delegate
|
5
|
+
|
6
|
+
### INIT AND OPTIONS #########################################################
|
7
|
+
|
8
|
+
# Default options of this adapter
|
9
|
+
DEFAULT_OPTIONS = {
|
10
|
+
:trace_sql => false,
|
11
|
+
:trace_only => false,
|
12
|
+
:trace_buffer => STDERR
|
13
|
+
}
|
14
|
+
|
15
|
+
# Adapter delegate
|
16
|
+
attr_reader :delegate
|
17
|
+
|
18
|
+
# Creates a tracer instance
|
19
|
+
def initialize(delegate, options)
|
20
|
+
raise ArgumentError, "Connection options should be a Hash" unless options.kind_of?(Hash)
|
21
|
+
@delegate = delegate
|
22
|
+
@options = DEFAULT_OPTIONS.merge(options)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Tracing is on?
|
26
|
+
def trace?
|
27
|
+
@trace ||= (@options[:trace_sql] && !trace_buffer.nil?)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Only traces, forget about delegation?
|
31
|
+
def trace_only?
|
32
|
+
@trace_only ||= @options[:trace_only]
|
33
|
+
end
|
34
|
+
|
35
|
+
# Returns the tracing buffer
|
36
|
+
def trace_buffer
|
37
|
+
@buffer ||= @options[:trace_buffer]
|
38
|
+
end
|
39
|
+
|
40
|
+
### UTILS ####################################################################
|
41
|
+
|
42
|
+
# Returns SQL statement for a given alter table block
|
43
|
+
def alter_table_sql(table_name, &block)
|
44
|
+
generator = ::Sequel::Schema::AlterTableGenerator.new(self, &block)
|
45
|
+
sqls = delegate.db.send(:alter_table_sql_list, table_name, generator.operations).flatten
|
46
|
+
sqls.join("\n")
|
47
|
+
end
|
48
|
+
|
49
|
+
### SCHEMA UPDATES ###########################################################
|
50
|
+
|
51
|
+
# Creates a table with some columns.
|
52
|
+
def create_table(transaction, table_name, columns)
|
53
|
+
if trace?
|
54
|
+
gen = ::Sequel::Schema::Generator.new(self){
|
55
|
+
columns.each_pair{|name, type| column(name, type)}
|
56
|
+
}
|
57
|
+
sql = delegate.db.send(:create_table_sql, table_name, gen, {})
|
58
|
+
trace(sql)
|
59
|
+
end
|
60
|
+
return super unless trace_only?
|
61
|
+
nil
|
62
|
+
end
|
63
|
+
|
64
|
+
# Adds some columns to a table
|
65
|
+
def add_columns(transaction, table_name, columns)
|
66
|
+
if trace?
|
67
|
+
trace(alter_table_sql(table_name){
|
68
|
+
columns.each_pair{|name, type| add_column(name, type)}
|
69
|
+
})
|
70
|
+
end
|
71
|
+
return super unless trace_only?
|
72
|
+
nil
|
73
|
+
end
|
74
|
+
|
75
|
+
# Make columns be a candidate key for the table.
|
76
|
+
def key!(transaction, table_name, columns)
|
77
|
+
if trace?
|
78
|
+
trace(alter_table_sql(table_name){
|
79
|
+
add_index(columns, :unique => true)
|
80
|
+
})
|
81
|
+
end
|
82
|
+
return super unless trace_only?
|
83
|
+
nil
|
84
|
+
end
|
85
|
+
|
86
|
+
### DATA UPDATES #############################################################
|
87
|
+
|
88
|
+
# Inserts a tuple inside a given table
|
89
|
+
def insert(transaction, table_name, record)
|
90
|
+
if trace?
|
91
|
+
trace(delegate.db[table_name].insert_sql(record))
|
92
|
+
end
|
93
|
+
return super unless trace_only?
|
94
|
+
record
|
95
|
+
end
|
96
|
+
|
97
|
+
# Updates a project of a given table
|
98
|
+
def update(transaction, table_name, proj, update)
|
99
|
+
if trace?
|
100
|
+
trace(delegate.db[table_name].where(proj).update_sql(update))
|
101
|
+
end
|
102
|
+
return super unless trace_only?
|
103
|
+
true
|
104
|
+
end
|
105
|
+
|
106
|
+
# Deletes a projection from a given table
|
107
|
+
def delete(transaction, table_name, proj = {})
|
108
|
+
if trace?
|
109
|
+
if proj.empty?
|
110
|
+
trace(delegate.db[table_name].delete_sql)
|
111
|
+
else
|
112
|
+
trace(delegate.db[table_name].where(proj).delete_sql)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
return super unless trace_only?
|
116
|
+
true
|
117
|
+
end
|
118
|
+
|
119
|
+
# Sends SQL directly to the database SQL server.
|
120
|
+
def direct_sql(transaction, sql)
|
121
|
+
if trace?
|
122
|
+
trace(sql)
|
123
|
+
end
|
124
|
+
return super unless trace_only?
|
125
|
+
nil
|
126
|
+
end
|
127
|
+
|
128
|
+
### ABOUT TRACING ############################################################
|
129
|
+
|
130
|
+
# Traces a SQL statement. Returns true if trace_only, false
|
131
|
+
# otherwise
|
132
|
+
def trace(sql)
|
133
|
+
case out = trace_buffer
|
134
|
+
when Logger
|
135
|
+
out.info(sql)
|
136
|
+
else
|
137
|
+
out << "#{sql}\n"
|
138
|
+
end
|
139
|
+
sql
|
140
|
+
end
|
141
|
+
|
142
|
+
end # class SequelTracer
|
143
|
+
end # class SequelAdapter
|
144
|
+
end # module DbAgile
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'dbagile/adapter/sequel/class_methods'
|
2
|
+
require 'dbagile/adapter/sequel/connection'
|
3
|
+
|
4
|
+
require 'dbagile/adapter/sequel/data/table_driven'
|
5
|
+
require 'dbagile/adapter/sequel/data/transaction_driven'
|
6
|
+
|
7
|
+
require 'dbagile/adapter/sequel/schema/physical_dump'
|
8
|
+
require 'dbagile/adapter/sequel/schema/schema2sequel_args'
|
9
|
+
require 'dbagile/adapter/sequel/schema/concrete_script'
|
10
|
+
require 'dbagile/adapter/sequel/schema/table_driven'
|
11
|
+
require 'dbagile/adapter/sequel/schema/transaction_driven'
|
12
|
+
module DbAgile
|
13
|
+
#
|
14
|
+
# Implements the Adapter contract using Sequel.
|
15
|
+
#
|
16
|
+
class SequelAdapter < Adapter
|
17
|
+
extend SequelAdapter::ClassMethods
|
18
|
+
include SequelAdapter::Connection
|
19
|
+
include SequelAdapter::Data::TableDriven
|
20
|
+
include SequelAdapter::Data::TransactionDriven
|
21
|
+
include SequelAdapter::Schema::TableDriven
|
22
|
+
include SequelAdapter::Schema::TransactionDriven
|
23
|
+
|
24
|
+
# Underlying database URI
|
25
|
+
attr_reader :uri
|
26
|
+
|
27
|
+
# Connection options
|
28
|
+
attr_reader :options
|
29
|
+
|
30
|
+
# Creates an adapter with a given uri
|
31
|
+
def initialize(uri, options = {})
|
32
|
+
@uri, @options = uri, options
|
33
|
+
end
|
34
|
+
|
35
|
+
# Returns the underlying Sequel::Database instance
|
36
|
+
def db
|
37
|
+
unless @db
|
38
|
+
@db = ::Sequel.connect(uri)
|
39
|
+
@db.logger = @options[:sequel_logger]
|
40
|
+
end
|
41
|
+
@db
|
42
|
+
end
|
43
|
+
|
44
|
+
end # class SequelAdapter
|
45
|
+
end # module DbAgile
|
46
|
+
require 'dbagile/adapter/sequel/sequel_tracer'
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module DbAgile
|
2
|
+
class Adapter
|
3
|
+
include DbAgile::Contract::Robust::Helpers
|
4
|
+
include DbAgile::Contract::Utils::Full
|
5
|
+
|
6
|
+
# Builds an adapter instance from an URI
|
7
|
+
def self.factor(uri, options = {})
|
8
|
+
return uri if uri.kind_of?(Adapter)
|
9
|
+
DbAgile::SequelAdapter.new(uri, options)
|
10
|
+
end
|
11
|
+
def self.[](*args) factor(*args) end
|
12
|
+
|
13
|
+
end # class Adapter
|
14
|
+
end # module DbAgile
|
15
|
+
require 'dbagile/adapter/sequel'
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module DbAgile
|
2
|
+
class Command
|
3
|
+
class API
|
4
|
+
include DbAgile::Environment::Delegator
|
5
|
+
|
6
|
+
# Underlying environment
|
7
|
+
attr_reader :environment
|
8
|
+
|
9
|
+
# Creates an API instance for a given environment
|
10
|
+
def initialize(environment)
|
11
|
+
@environment = environment
|
12
|
+
end
|
13
|
+
|
14
|
+
##############################################################################
|
15
|
+
# Ruby commands
|
16
|
+
##############################################################################
|
17
|
+
|
18
|
+
# Returns a dataset instance
|
19
|
+
def dataset(name)
|
20
|
+
environment.with_current_connection{|c|
|
21
|
+
c.dataset(name)
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
##############################################################################
|
26
|
+
# Console subcommands mimics
|
27
|
+
##############################################################################
|
28
|
+
|
29
|
+
# Add API methods to Command class
|
30
|
+
DbAgile::Command::each_subclass do |subclass|
|
31
|
+
method_name = DbAgile::Command::ruby_method_for(subclass)
|
32
|
+
module_eval <<-EOF
|
33
|
+
def #{method_name}(*options)
|
34
|
+
options = options.flatten
|
35
|
+
command = DbAgile::Command::command_for(#{subclass.name}, environment)
|
36
|
+
options = DbAgile::Command::build_command_options(options)
|
37
|
+
command.unsecure_run(__FILE__, options)
|
38
|
+
end
|
39
|
+
EOF
|
40
|
+
end
|
41
|
+
|
42
|
+
# Delegates this api on a environment duplication
|
43
|
+
def dup
|
44
|
+
API.new(environment.dup)
|
45
|
+
end
|
46
|
+
|
47
|
+
end # class API
|
48
|
+
end # class Command
|
49
|
+
end # module DbAgile
|
@@ -0,0 +1,130 @@
|
|
1
|
+
module DbAgile
|
2
|
+
class Command
|
3
|
+
module Bulk
|
4
|
+
module Commons
|
5
|
+
|
6
|
+
# Output/input format [ruby, csv, json]
|
7
|
+
attr_accessor :format
|
8
|
+
|
9
|
+
# Connection options
|
10
|
+
attr_accessor :conn_options
|
11
|
+
|
12
|
+
# Input/output options
|
13
|
+
attr_accessor :io_options
|
14
|
+
|
15
|
+
# Type system to use
|
16
|
+
attr_accessor :type_system
|
17
|
+
|
18
|
+
# Dataset whose contents must be shown
|
19
|
+
attr_accessor :dataset
|
20
|
+
|
21
|
+
# Columns to select
|
22
|
+
attr_accessor :select
|
23
|
+
|
24
|
+
# Columns to allbut
|
25
|
+
attr_accessor :allbut
|
26
|
+
|
27
|
+
# Builds default io options
|
28
|
+
def set_default_options
|
29
|
+
self.format = :csv
|
30
|
+
self.type_system = nil
|
31
|
+
self.conn_options = {}
|
32
|
+
self.io_options = Hash.new{|h,k| h[k] = {}}
|
33
|
+
end
|
34
|
+
|
35
|
+
# Adds the select/allbut options
|
36
|
+
def add_select_options(opt)
|
37
|
+
opt.on('--select x,y,z', Array,
|
38
|
+
"Select x, y, z columns only") do |value|
|
39
|
+
self.select = value.collect{|c| c.to_sym}
|
40
|
+
end
|
41
|
+
opt.on('--allbut x,y,z', Array,
|
42
|
+
"Select all but x, y, z columns") do |value|
|
43
|
+
self.allbut = value.collect{|c| c.to_sym}
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def add_typesafe_options(opt)
|
48
|
+
opt.on("--type-safe=[X]", [:ruby],
|
49
|
+
"Read/Write type-safe values for (ruby)") do |value|
|
50
|
+
case value
|
51
|
+
when :ruby, NilClass
|
52
|
+
require 'sbyc/type_system/ruby'
|
53
|
+
self.type_system = SByC::TypeSystem::Ruby
|
54
|
+
else
|
55
|
+
raise ArgumentError, "Unknown type system #{value}"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Adds the format options for output
|
61
|
+
def add_output_format_options(opt)
|
62
|
+
opt.on('--format=X', [:csv, :text, :json, :yaml, :ruby, :xml],
|
63
|
+
"Export dataset in (csv, text, json, yaml, ruby, xml)") do |value|
|
64
|
+
self.format = value
|
65
|
+
end
|
66
|
+
opt.on("--csv", "Export dataset in csv (default)"){ self.format = :csv }
|
67
|
+
opt.on("--text", "Export dataset as a plain text table"){ self.format = :text }
|
68
|
+
opt.on("--json", "Export dataset in json"){ self.format = :json }
|
69
|
+
opt.on("--yaml", "Export dataset in yaml"){ self.format = :yaml }
|
70
|
+
opt.on("--xml", "Export dataset in xml"){ self.format = :xml }
|
71
|
+
opt.on("--ruby", "Export dataset as ruby code"){ self.format = :ruby }
|
72
|
+
end
|
73
|
+
|
74
|
+
# Adds the format options for input
|
75
|
+
def add_input_format_options(opt)
|
76
|
+
opt.on('--format=X', [:csv, :json, :yaml, :ruby],
|
77
|
+
"Import dataset from (csv, json, yaml, ruby)") do |value|
|
78
|
+
self.format = value
|
79
|
+
end
|
80
|
+
opt.on("--csv", "Import dataset from csv (default)"){ self.format = :csv }
|
81
|
+
opt.on("--json", "Import dataset from json"){ self.format = :json }
|
82
|
+
opt.on("--ruby", "Import dataset from ruby code"){ self.format = :ruby }
|
83
|
+
opt.on("--yaml", "Import dataset from yaml"){ self.format = :yaml }
|
84
|
+
end
|
85
|
+
|
86
|
+
# Adds the CSV options
|
87
|
+
def add_csv_options(opt)
|
88
|
+
opt.on("--headers", "-h", "Read/Write column names on first line") do
|
89
|
+
io_options[:csv][:headers] = true
|
90
|
+
end
|
91
|
+
opt.on("--separator=C", "Use C as column separator character") do |value|
|
92
|
+
io_options[:csv][:col_sep] = value
|
93
|
+
end
|
94
|
+
opt.on("--quote=C", "Use C as quoting character") do |value|
|
95
|
+
io_options[:csv][:quote_char] = value
|
96
|
+
end
|
97
|
+
opt.on("--force-quotes", "Force quoting?") do
|
98
|
+
io_options[:csv][:force_quotes] = true
|
99
|
+
end
|
100
|
+
opt.on("--skip-blanks", "Skip blank lines?") do
|
101
|
+
io_options[:csv][:skip_blanks] = true
|
102
|
+
end
|
103
|
+
end
|
104
|
+
alias :add_csv_input_options :add_csv_options
|
105
|
+
alias :add_csv_output_options :add_csv_options
|
106
|
+
|
107
|
+
# Adds output JSON options
|
108
|
+
def add_json_output_options(opt)
|
109
|
+
opt.on("--[no-]pretty", "Generate a pretty JSON document") do |value|
|
110
|
+
io_options[:json][:pretty] = value
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
# Adds output TEXT options
|
115
|
+
def add_text_output_options(opt)
|
116
|
+
opt.on("--wrap-at=X", Integer,
|
117
|
+
"Wraps table after X's character (no wrap by default)") do |x|
|
118
|
+
io_options[:text][:wrap_at] = x
|
119
|
+
end
|
120
|
+
opt.on("--truncate-at=X", Integer,
|
121
|
+
"Truncate row lines at X character") do |x|
|
122
|
+
io_options[:text][:truncate_at] = x
|
123
|
+
io_options[:text][:append_with] = '...'
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
end # module Commons
|
128
|
+
end # module Bulk
|
129
|
+
end # class Command
|
130
|
+
end # module DbAgile
|
@@ -0,0 +1,99 @@
|
|
1
|
+
module DbAgile
|
2
|
+
class Command
|
3
|
+
module Bulk
|
4
|
+
#
|
5
|
+
# Export a table/view/query to (csv, json, yaml, ruby, xml)
|
6
|
+
#
|
7
|
+
# Usage: dba #{command_name} [OPTIONS] DATASET [FILE]
|
8
|
+
#
|
9
|
+
# This command helps exporting data in a SQL database to common transfer
|
10
|
+
# formats.
|
11
|
+
#
|
12
|
+
class Export < Command
|
13
|
+
include Bulk::Commons
|
14
|
+
Command::build_me(self, __FILE__)
|
15
|
+
|
16
|
+
# Output file to use
|
17
|
+
attr_accessor :output_file
|
18
|
+
|
19
|
+
# Contribute to options
|
20
|
+
def add_options(opt)
|
21
|
+
# Main output options
|
22
|
+
opt.separator "\nOutput options:"
|
23
|
+
opt.on("--output=FILE", "-o", "Flush output in FILE (stdout by default)") do |value|
|
24
|
+
self.output_file = value
|
25
|
+
end
|
26
|
+
|
27
|
+
opt.separator "\nRelational options:"
|
28
|
+
add_select_options(opt)
|
29
|
+
|
30
|
+
opt.separator "\nRecognized format options:"
|
31
|
+
add_output_format_options(opt)
|
32
|
+
add_typesafe_options(opt)
|
33
|
+
|
34
|
+
# CSV output options
|
35
|
+
opt.separator "\nCSV options:"
|
36
|
+
add_csv_output_options(opt)
|
37
|
+
|
38
|
+
# CSV output options
|
39
|
+
opt.separator "\nTEXT options:"
|
40
|
+
add_text_output_options(opt)
|
41
|
+
|
42
|
+
# JSON output options
|
43
|
+
opt.separator "\nJSON options:"
|
44
|
+
add_json_output_options(opt)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Normalizes the pending arguments
|
48
|
+
def normalize_pending_arguments(arguments)
|
49
|
+
case arguments.size
|
50
|
+
when 1
|
51
|
+
self.dataset = valid_argument_list!(arguments, String)
|
52
|
+
when 2
|
53
|
+
raise OptionParser::AmbiguousArgument, '--output-file=#{self.output_file}' if self.output_file
|
54
|
+
self.dataset, self.output_file = valid_argument_list!(arguments, String, String)
|
55
|
+
else
|
56
|
+
bad_argument_list!(arguments)
|
57
|
+
end
|
58
|
+
unless /select|SELECT/ =~ self.dataset
|
59
|
+
self.dataset = self.dataset.to_sym
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Yields the block with the IO object to use for output
|
64
|
+
def with_io(&block)
|
65
|
+
if self.output_file
|
66
|
+
require 'fileutils'
|
67
|
+
FileUtils.mkdir_p(File.dirname(self.output_file))
|
68
|
+
File.open(self.output_file, "w", &block)
|
69
|
+
else
|
70
|
+
block.call(environment.output_buffer)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# Executes the command
|
75
|
+
def execute_command
|
76
|
+
with_current_connection do |connection|
|
77
|
+
# Prepare the dataset
|
78
|
+
ds = connection.dataset(self.dataset)
|
79
|
+
if self.select
|
80
|
+
ds = ds.select(*self.select)
|
81
|
+
elsif self.allbut
|
82
|
+
ds = ds.allbut(*self.allbut)
|
83
|
+
end
|
84
|
+
|
85
|
+
# Export it
|
86
|
+
with_io{|io|
|
87
|
+
method = "to_#{self.format}".to_sym
|
88
|
+
io = environment.output_buffer
|
89
|
+
options = io_options[self.format]
|
90
|
+
options[:type_system] = self.type_system if self.type_system
|
91
|
+
ds.send(method, io, options)
|
92
|
+
}
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
end # class Export
|
97
|
+
end # module Bulk
|
98
|
+
end # class Command
|
99
|
+
end # module DbAgile
|
@@ -0,0 +1,147 @@
|
|
1
|
+
module DbAgile
|
2
|
+
class Command
|
3
|
+
module Bulk
|
4
|
+
#
|
5
|
+
# Import a table from (csv, json, yaml, ruby)
|
6
|
+
#
|
7
|
+
# Usage: dba #{command_name} [OPTIONS] TABLE [FILE]
|
8
|
+
#
|
9
|
+
class Import < Command
|
10
|
+
include Bulk::Commons
|
11
|
+
include ::DbAgile::Tools::Tuple
|
12
|
+
Command::build_me(self, __FILE__)
|
13
|
+
|
14
|
+
# Input file to use
|
15
|
+
attr_accessor :input_file
|
16
|
+
|
17
|
+
# Drop table?
|
18
|
+
attr_accessor :drop_table
|
19
|
+
|
20
|
+
# Create table?
|
21
|
+
attr_accessor :create_table
|
22
|
+
|
23
|
+
# Truncate table?
|
24
|
+
attr_accessor :truncate_table
|
25
|
+
|
26
|
+
# Contribute to options
|
27
|
+
def add_options(opt)
|
28
|
+
# Main output options
|
29
|
+
opt.separator "\nInput options:"
|
30
|
+
opt.on("--input=FILE", "-i", "Read input from FILE (stdin by default)") do |value|
|
31
|
+
self.input_file = value
|
32
|
+
end
|
33
|
+
|
34
|
+
opt.separator "\nSQL options:"
|
35
|
+
opt.on("--create-table", "-c", "Create table before inserting values") do |value|
|
36
|
+
self.drop_table = true
|
37
|
+
self.create_table = true
|
38
|
+
self.truncate_table = false
|
39
|
+
end
|
40
|
+
opt.on("--drop-table", "-d", "Drop table before inserting values") do |value|
|
41
|
+
self.drop_table = true
|
42
|
+
self.create_table = true
|
43
|
+
self.truncate_table = false
|
44
|
+
end
|
45
|
+
opt.on("--truncate", "-t", "Truncate table before inserting values") do |value|
|
46
|
+
self.truncate_table = true
|
47
|
+
end
|
48
|
+
opt.on('--trace-sql', "Trace SQL statements on STDOUT (but executes them)") do |value|
|
49
|
+
self.conn_options[:trace_sql] = true
|
50
|
+
end
|
51
|
+
opt.on('--dry-run', "Trace SQL statements on STDOUT only, do nothing on the database") do |value|
|
52
|
+
self.conn_options[:trace_sql] = true
|
53
|
+
self.conn_options[:trace_only] = true
|
54
|
+
end
|
55
|
+
|
56
|
+
opt.separator "\nRecognized format options:"
|
57
|
+
add_input_format_options(opt)
|
58
|
+
add_typesafe_options(opt)
|
59
|
+
|
60
|
+
# CSV output options
|
61
|
+
opt.separator "\nCSV options:"
|
62
|
+
add_csv_input_options(opt)
|
63
|
+
end
|
64
|
+
|
65
|
+
# Normalizes the pending arguments
|
66
|
+
def normalize_pending_arguments(arguments)
|
67
|
+
case arguments.size
|
68
|
+
when 1
|
69
|
+
self.dataset = valid_argument_list!(arguments, Symbol)
|
70
|
+
when 2
|
71
|
+
raise OptionParser::AmbiguousArgument, '--input-file=#{self.input_file}' if self.input_file
|
72
|
+
self.dataset, self.input_file = valid_argument_list!(arguments, Symbol, String)
|
73
|
+
else
|
74
|
+
bad_argument_list!(arguments)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# Yields the block with the IO object to use for input
|
79
|
+
def with_io(&block)
|
80
|
+
if self.input_file
|
81
|
+
File.open(self.input_file, "r", &block)
|
82
|
+
else
|
83
|
+
block.call(environment.input_buffer)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# Yields the block with each emitted tuple
|
88
|
+
def with_emitter(&block)
|
89
|
+
with_io{|io|
|
90
|
+
options = io_options[self.format]
|
91
|
+
options[:type_system] = self.type_system if self.type_system
|
92
|
+
options[:input_file] = self.input_file
|
93
|
+
case self.format
|
94
|
+
when :csv
|
95
|
+
DbAgile::IO::CSV::from_csv(io, options, &block)
|
96
|
+
when :json
|
97
|
+
DbAgile::IO::JSON::from_json(io, options, &block)
|
98
|
+
when :yaml
|
99
|
+
DbAgile::IO::YAML::from_yaml(io, options, &block)
|
100
|
+
when :ruby
|
101
|
+
DbAgile::IO::Ruby::from_ruby(io, options, &block)
|
102
|
+
end
|
103
|
+
}
|
104
|
+
end
|
105
|
+
|
106
|
+
# Executes the command
|
107
|
+
def execute_command
|
108
|
+
with_current_connection(conn_options) do |connection|
|
109
|
+
|
110
|
+
# Make the job now
|
111
|
+
connection.transaction do |t|
|
112
|
+
first = true
|
113
|
+
with_emitter do |tuple|
|
114
|
+
make_the_job(t, tuple, first)
|
115
|
+
first = false
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
# Makes the insert job
|
123
|
+
def make_the_job(t, tuple, first = true)
|
124
|
+
handle_schema_modification(t, tuple) if first
|
125
|
+
t.insert(self.dataset, tuple)
|
126
|
+
end
|
127
|
+
|
128
|
+
# Handles the schema modifications
|
129
|
+
def handle_schema_modification(t, tuple)
|
130
|
+
# Handle table creation/deletion/truncation
|
131
|
+
if drop_table
|
132
|
+
t.drop_table(self.dataset) if t.has_table?(self.dataset)
|
133
|
+
end
|
134
|
+
if create_table
|
135
|
+
heading = tuple_heading(tuple)
|
136
|
+
heading = check_tuple_heading(heading, environment)
|
137
|
+
t.create_table(self.dataset, heading)
|
138
|
+
end
|
139
|
+
if truncate_table
|
140
|
+
t.delete(self.dataset, {})
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
end # class Import
|
145
|
+
end # module Bulk
|
146
|
+
end # class Command
|
147
|
+
end # module DbAgile
|