dbsketch 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +674 -0
- data/README.md +1 -0
- data/lib/dbsketch.rb +64 -0
- data/lib/dbsketch/automation/automation_error.rb +15 -0
- data/lib/dbsketch/automation/database_connection_details.rb +32 -0
- data/lib/dbsketch/automation/database_importer.rb +184 -0
- data/lib/dbsketch/automation/database_proxy.rb +78 -0
- data/lib/dbsketch/automation/table_importer.rb +114 -0
- data/lib/dbsketch/comparison/check_constraint_comparator.rb +54 -0
- data/lib/dbsketch/comparison/column_comparator.rb +65 -0
- data/lib/dbsketch/comparison/comparison_error.rb +15 -0
- data/lib/dbsketch/comparison/computed_column_comparator.rb +63 -0
- data/lib/dbsketch/comparison/database_comparator.rb +115 -0
- data/lib/dbsketch/comparison/diff.rb +37 -0
- data/lib/dbsketch/comparison/foreign_key_comparator.rb +56 -0
- data/lib/dbsketch/comparison/function_comparator.rb +56 -0
- data/lib/dbsketch/comparison/index_comparator.rb +65 -0
- data/lib/dbsketch/comparison/primary_key_comparator.rb +61 -0
- data/lib/dbsketch/comparison/procedure_comparator.rb +54 -0
- data/lib/dbsketch/comparison/table_comparator.rb +158 -0
- data/lib/dbsketch/comparison/trigger_comparator.rb +53 -0
- data/lib/dbsketch/comparison/type_comparator.rb +51 -0
- data/lib/dbsketch/comparison/unique_constraint_comparator.rb +58 -0
- data/lib/dbsketch/comparison/view_comparator.rb +54 -0
- data/lib/dbsketch/model/abstract_column.rb +25 -0
- data/lib/dbsketch/model/check_constraint.rb +23 -0
- data/lib/dbsketch/model/column.rb +35 -0
- data/lib/dbsketch/model/computed_column.rb +27 -0
- data/lib/dbsketch/model/custom_code.rb +21 -0
- data/lib/dbsketch/model/database.rb +87 -0
- data/lib/dbsketch/model/database_object.rb +71 -0
- data/lib/dbsketch/model/foreign_key.rb +29 -0
- data/lib/dbsketch/model/function.rb +23 -0
- data/lib/dbsketch/model/index.rb +40 -0
- data/lib/dbsketch/model/model_error.rb +15 -0
- data/lib/dbsketch/model/operation.rb +28 -0
- data/lib/dbsketch/model/primary_key.rb +33 -0
- data/lib/dbsketch/model/procedure.rb +18 -0
- data/lib/dbsketch/model/table.rb +171 -0
- data/lib/dbsketch/model/trigger.rb +32 -0
- data/lib/dbsketch/model/type.rb +92 -0
- data/lib/dbsketch/model/unique_constraint.rb +33 -0
- data/lib/dbsketch/model/view.rb +23 -0
- data/lib/dbsketch/rendering/meta/column_renderer.rb +76 -0
- data/lib/dbsketch/rendering/meta/database_renderer.rb +112 -0
- data/lib/dbsketch/rendering/meta/foreign_key_renderer.rb +31 -0
- data/lib/dbsketch/rendering/meta/index_renderer.rb +30 -0
- data/lib/dbsketch/rendering/meta/operation_renderer.rb +66 -0
- data/lib/dbsketch/rendering/meta/table_renderer.rb +177 -0
- data/lib/dbsketch/rendering/meta/trigger_renderer.rb +31 -0
- data/lib/dbsketch/rendering/meta/type_renderer.rb +37 -0
- data/lib/dbsketch/rendering/meta/view_renderer.rb +32 -0
- data/lib/dbsketch/rendering/sql/column_renderer.rb +75 -0
- data/lib/dbsketch/rendering/sql/database_diff_renderer.rb +94 -0
- data/lib/dbsketch/rendering/sql/database_renderer.rb +139 -0
- data/lib/dbsketch/rendering/sql/foreign_key_renderer.rb +24 -0
- data/lib/dbsketch/rendering/sql/index_renderer.rb +31 -0
- data/lib/dbsketch/rendering/sql/operation_renderer.rb +64 -0
- data/lib/dbsketch/rendering/sql/table_renderer.rb +148 -0
- data/lib/dbsketch/rendering/sql/trigger_renderer.rb +31 -0
- data/lib/dbsketch/rendering/sql/type_renderer.rb +28 -0
- data/lib/dbsketch/rendering/sql/view_renderer.rb +31 -0
- data/lib/dbsketch/version.rb +3 -0
- metadata +134 -0
@@ -0,0 +1,33 @@
|
|
1
|
+
########################################################################################################################
|
2
|
+
# Unique constraint
|
3
|
+
########################################################################################################################
|
4
|
+
|
5
|
+
require_relative 'column'
|
6
|
+
require_relative 'database_object'
|
7
|
+
|
8
|
+
module Dbsketch
|
9
|
+
module Model
|
10
|
+
|
11
|
+
class UniqueConstraint < Database_Object
|
12
|
+
def initialize name, columns, meaning: nil, comment: nil
|
13
|
+
super name, :meaning => meaning, :comment => comment
|
14
|
+
@columns = columns.is_a?(Array) ? columns : [columns]
|
15
|
+
### Preconditions
|
16
|
+
@columns.each_with_index do |column, index|
|
17
|
+
raise ArgumentError, "columns[#{index}] is not a Dbsketch::Model::Column" unless column.is_a? Column
|
18
|
+
end
|
19
|
+
###
|
20
|
+
end
|
21
|
+
|
22
|
+
attr_reader :columns
|
23
|
+
|
24
|
+
def has_column? column_name
|
25
|
+
### Preconditions
|
26
|
+
raise ArgumentError, "column_name is not a String" unless column_name.is_a? String
|
27
|
+
###
|
28
|
+
nil != @columns.find { |c| c.name.downcase == column_name.downcase }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
########################################################################################################################
|
2
|
+
# Defines database view
|
3
|
+
########################################################################################################################
|
4
|
+
|
5
|
+
require_relative 'database_object'
|
6
|
+
|
7
|
+
module Dbsketch
|
8
|
+
module Model
|
9
|
+
|
10
|
+
class View < Database_Object
|
11
|
+
def initialize name, query, meaning: nil, comment: nil, dependencies: []
|
12
|
+
super name, :meaning => meaning, :comment => comment, :dependencies => dependencies
|
13
|
+
### Preconditions
|
14
|
+
raise ArgumentError, "query is not a String" unless query.is_a? String
|
15
|
+
###
|
16
|
+
@query = query
|
17
|
+
end
|
18
|
+
|
19
|
+
attr_reader :query
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
########################################################################################################################
|
2
|
+
# Render a column into SQL
|
3
|
+
########################################################################################################################
|
4
|
+
|
5
|
+
require_relative '../../model/abstract_column'
|
6
|
+
require_relative '../../model/column'
|
7
|
+
require_relative '../../model/computed_column'
|
8
|
+
|
9
|
+
require_relative 'type_renderer'
|
10
|
+
|
11
|
+
module Dbsketch
|
12
|
+
module Rendering
|
13
|
+
module Meta
|
14
|
+
|
15
|
+
class ColumnRenderer
|
16
|
+
def initialize type_renderer: nil, keywords: {}
|
17
|
+
### Preconditions
|
18
|
+
raise ArgumentError, "keywords is not a Hash" unless keywords.is_a? Hash
|
19
|
+
###
|
20
|
+
@keywords = {
|
21
|
+
:column => "Dbsketch::Model::Column.new",
|
22
|
+
:computed_column => "Dbsketch::Model::ComputedColumn.new",
|
23
|
+
:type => "Dbsketch::Model::Type.new"
|
24
|
+
}.merge keywords
|
25
|
+
@type_renderer = (nil == type_renderer ? TypeRenderer.new(:type_keyword => @keywords[:type]) : type_renderer)
|
26
|
+
end
|
27
|
+
|
28
|
+
def create column
|
29
|
+
### Preconditions
|
30
|
+
raise ArgumentError, "column is not a Dbsketch::Model::AbstractColumn" unless column.is_a? Dbsketch::Model::AbstractColumn
|
31
|
+
###
|
32
|
+
if column.is_a? Dbsketch::Model::ComputedColumn
|
33
|
+
create_computed_column column
|
34
|
+
elsif column.is_a? Dbsketch::Model::Column
|
35
|
+
create_column column
|
36
|
+
else
|
37
|
+
raise ArgumentError, "#{column.class} is an unknown subclass of Dbsketch::Model::AbstractColumn"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def get_semantic column
|
44
|
+
str = ""
|
45
|
+
str << ", :meaning => '#{column.meaning}'" if column.meaning
|
46
|
+
str << ", :comment => '#{column.comment}'" if column.comment
|
47
|
+
str
|
48
|
+
end
|
49
|
+
|
50
|
+
def create_column column
|
51
|
+
str = "#{@keywords[:column]}('#{column.name}', #{@type_renderer.create column.type}"
|
52
|
+
str << ", :order => #{column.order}" if nil != column.order
|
53
|
+
str << ", :identity => true" if column.identity
|
54
|
+
str << ", :nullable => false" if not column.nullable
|
55
|
+
if nil != column.default
|
56
|
+
str << ", :default => #{column.default.is_a?(String) ? "'#{column.default}'" : column.default}"
|
57
|
+
end
|
58
|
+
str << get_semantic(column)
|
59
|
+
str << ")"
|
60
|
+
str
|
61
|
+
end
|
62
|
+
|
63
|
+
def create_computed_column column
|
64
|
+
str = "#{@keywords[:computed_column]}('#{column.name}', '#{column.query}'"
|
65
|
+
str << ", :nullable => false" if not column.nullable
|
66
|
+
str << ", :persisted => true" if column.persisted
|
67
|
+
str << get_semantic(column)
|
68
|
+
str << ")"
|
69
|
+
str
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
########################################################################################################################
|
2
|
+
# Render a database into ruby
|
3
|
+
########################################################################################################################
|
4
|
+
|
5
|
+
require_relative '../../comparison/database_comparator'
|
6
|
+
require_relative '../../model/database'
|
7
|
+
|
8
|
+
require_relative 'index_renderer'
|
9
|
+
require_relative 'operation_renderer'
|
10
|
+
require_relative 'table_renderer'
|
11
|
+
require_relative 'trigger_renderer'
|
12
|
+
require_relative 'view_renderer'
|
13
|
+
|
14
|
+
module Dbsketch
|
15
|
+
module Rendering
|
16
|
+
module Meta
|
17
|
+
|
18
|
+
class DatabaseRenderer
|
19
|
+
def initialize index_renderer: nil, operation_renderer: nil, table_renderer: nil, trigger_renderer: nil, view_renderer: nil, options: {}, keywords: {}
|
20
|
+
### Preconditions
|
21
|
+
raise ArgumentError, "index_renderer is not a Dbsketch::Rendering::Meta::IndexRenderer" unless nil == index_renderer or index_renderer.is_a? IndexRenderer
|
22
|
+
raise ArgumentError, "operation_renderer is not a Dbsketch::Rendering::Meta::OperationRenderer" unless nil == operation_renderer or operation_renderer.is_a? OperationRenderer
|
23
|
+
raise ArgumentError, "table_renderer is not a Dbsketch::Rendering::Meta::TableRenderer" unless nil == table_renderer or table_renderer.is_a? TableRenderer
|
24
|
+
raise ArgumentError, "trigger_renderer is not a Dbsketch::Rendering::Meta::TriggerRenderer" unless nil == trigger_renderer or trigger_renderer.is_a? TriggerRenderer
|
25
|
+
raise ArgumentError, "view_renderer is not a Dbsketch::Rendering::Meta::ViewRenderer" unless nil == view_renderer or view_renderer.is_a? ViewRenderer
|
26
|
+
raise ArgumentError, "options is not a Hash" unless options.is_a? Hash
|
27
|
+
raise ArgumentError, "keywords is not a Hash" unless keywords.is_a? Hash
|
28
|
+
###
|
29
|
+
@options = {
|
30
|
+
:order_by_dependencies => true,
|
31
|
+
:pretty => false
|
32
|
+
}.merge options
|
33
|
+
@keywords = keywords
|
34
|
+
@index_renderer = (nil == index_renderer ? IndexRenderer.new : index_renderer)
|
35
|
+
@operation_renderer = (nil == operation_renderer ? OperationRenderer.new : operation_renderer)
|
36
|
+
@table_renderer = (nil == table_renderer ? TableRenderer.new(:options => @options, :keywords => @keywords) : table_renderer)
|
37
|
+
@trigger_renderer = (nil == trigger_renderer ? TriggerRenderer.new : trigger_renderer)
|
38
|
+
@view_renderer = (nil == view_renderer ? ViewRenderer.new : view_renderer)
|
39
|
+
end
|
40
|
+
|
41
|
+
def create database
|
42
|
+
### Preconditions
|
43
|
+
raise ArgumentError, "database is not a Dbsketch::Model::Database" unless database.is_a? Dbsketch::Model::Database
|
44
|
+
###
|
45
|
+
separator = @options[:pretty] ? "\n\n" : "\n"
|
46
|
+
database.order_items! if @options[:order_by_dependencies]
|
47
|
+
database.items.map { |i| create_item i }.flatten.compact.join(separator) + separator
|
48
|
+
end
|
49
|
+
|
50
|
+
def alter database_diff
|
51
|
+
### Preconditions
|
52
|
+
raise ArgumentError, "database_diff is not a Dbsketch::Comparison::DatabaseDiff" unless database_diff.is_a? Dbsketch::Comparison::DatabaseDiff
|
53
|
+
###
|
54
|
+
separator = "\n"
|
55
|
+
|
56
|
+
diffs = database_diff.indexes + database_diff.operations + database_diff.tables + database_diff.triggers + database_diff.views
|
57
|
+
deletions = diffs.select { |d| d.deletion? }.map { |i| drop_item i.old_value }
|
58
|
+
changes = diffs.select { |d| d.change? }.map { |i| alter_item(i) }
|
59
|
+
creations = diffs.select { |d| d.addition? }.map { |i| create_item i.new_value }
|
60
|
+
|
61
|
+
(deletions + changes + creations).flatten.compact.join(separator) + separator
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def create_item item
|
67
|
+
if item.is_a? Dbsketch::Model::Index
|
68
|
+
@index_renderer.create item
|
69
|
+
elsif item.is_a? Dbsketch::Model::Operation
|
70
|
+
@operation_renderer.create item
|
71
|
+
elsif item.is_a? Dbsketch::Model::Table
|
72
|
+
@table_renderer.create item
|
73
|
+
elsif item.is_a? Dbsketch::Model::Trigger
|
74
|
+
@trigger_renderer.create item
|
75
|
+
elsif item.is_a? Dbsketch::Model::View
|
76
|
+
@view_renderer.create item
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def drop_item item
|
81
|
+
if item.is_a? Dbsketch::Model::Index
|
82
|
+
@index_renderer.drop item
|
83
|
+
elsif item.is_a? Dbsketch::Model::Operation
|
84
|
+
@operation_renderer.drop item
|
85
|
+
elsif item.is_a? Dbsketch::Model::Table
|
86
|
+
@table_renderer.drop item
|
87
|
+
elsif item.is_a? Dbsketch::Model::Trigger
|
88
|
+
@trigger_renderer.drop item
|
89
|
+
elsif item.is_a? Dbsketch::Model::View
|
90
|
+
@view_renderer.drop item
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def alter_item item_diff
|
95
|
+
if item_diff.old_value.is_a? Dbsketch::Model::Index
|
96
|
+
"Index.alter #{create_item(item_diff.new_value)}"
|
97
|
+
elsif item_diff.old_value.is_a? Dbsketch::Model::Operation
|
98
|
+
"Operation.alter #{create_item(item_diff.new_value)}"
|
99
|
+
elsif item_diff.old_value.is_a? Dbsketch::Model::Table
|
100
|
+
@table_renderer.alter item_diff
|
101
|
+
elsif item_diff.old_value.is_a? Dbsketch::Model::Trigger
|
102
|
+
"Trigger.alter #{create_item(item_diff.new_value)}"
|
103
|
+
elsif item_diff.old_value.is_a? Dbsketch::Model::View
|
104
|
+
"View.alter #{create_item(item_diff.new_value)}"
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
########################################################################################################################
|
2
|
+
# Render a column into ruby
|
3
|
+
########################################################################################################################
|
4
|
+
|
5
|
+
require_relative '../../model/foreign_key'
|
6
|
+
|
7
|
+
module Dbsketch
|
8
|
+
module Rendering
|
9
|
+
module Meta
|
10
|
+
|
11
|
+
class ForeignKeyRenderer
|
12
|
+
|
13
|
+
def initialize foreign_key_keyword: "Dbsketch::Model::ForeignKey.new"
|
14
|
+
### Preconditions
|
15
|
+
raise ArgumentError, "foreign_key_keyword is not a String" unless foreign_key_keyword.is_a? String
|
16
|
+
###
|
17
|
+
@foreign_key_keyword = foreign_key_keyword
|
18
|
+
end
|
19
|
+
|
20
|
+
def create foreign_key
|
21
|
+
### Preconditions
|
22
|
+
raise ArgumentError, "foreign_key is not a Dbsketch::Model::ForeignKey" unless foreign_key.is_a? Dbsketch::Model::ForeignKey
|
23
|
+
###
|
24
|
+
"#{@foreign_key_keyword}(\"#{foreign_key.name}\", #{foreign_key.constricted_column.name}, #{foreign_key.referenced_table.name}, #{foreign_key.referenced_table.name}['#{foreign_key.referenced_column.name}'])"
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
########################################################################################################################
|
2
|
+
# Render an index into ruby
|
3
|
+
########################################################################################################################
|
4
|
+
|
5
|
+
require_relative '../../model/index'
|
6
|
+
|
7
|
+
module Dbsketch
|
8
|
+
module Rendering
|
9
|
+
module Meta
|
10
|
+
|
11
|
+
class IndexRenderer
|
12
|
+
|
13
|
+
def create index
|
14
|
+
### Preconditions
|
15
|
+
raise ArgumentError, "index is not a Dbsketch::Model::Index" unless index.is_a? Dbsketch::Model::Index
|
16
|
+
###
|
17
|
+
columns = index.columns.map {|c| c.name }
|
18
|
+
columns = columns.count > 1 ? "[#{columns.join(", ")}]" : columns.first
|
19
|
+
"Dbsketch::Model::Index.new(\"#{index.name}\", #{index.target.name}, #{columns})"
|
20
|
+
end
|
21
|
+
|
22
|
+
def drop index
|
23
|
+
"Index.drop #{index.name} from #{index.target.name}"
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
########################################################################################################################
|
2
|
+
# Render a column into ruby
|
3
|
+
########################################################################################################################
|
4
|
+
|
5
|
+
require_relative '../../model/function'
|
6
|
+
require_relative '../../model/procedure'
|
7
|
+
|
8
|
+
module Dbsketch
|
9
|
+
module Rendering
|
10
|
+
module Meta
|
11
|
+
|
12
|
+
class OperationRenderer
|
13
|
+
|
14
|
+
def create operation
|
15
|
+
### Preconditions
|
16
|
+
raise ArgumentError, "operation is not a Dbsketch::Model::Operation" unless operation.is_a? Dbsketch::Model::Operation
|
17
|
+
###
|
18
|
+
if operation.is_a? Dbsketch::Model::Function
|
19
|
+
create_function operation
|
20
|
+
elsif operation.is_a? Dbsketch::Model::Procedure
|
21
|
+
create_procedure operation
|
22
|
+
else
|
23
|
+
raise ArgumentError, "#{operation.class} is an unknown subclass of Dbsketch::Model::Operation"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def drop operation
|
28
|
+
### Preconditions
|
29
|
+
raise ArgumentError, "operation is not a Dbsketch::Model::Operation" unless operation.is_a? Dbsketch::Model::Operation
|
30
|
+
###
|
31
|
+
if operation.is_a? Dbsketch::Model::Function
|
32
|
+
keyword = "Function"
|
33
|
+
elsif operation.is_a? Dbsketch::Model::Procedure
|
34
|
+
keyword = "Procedure"
|
35
|
+
else
|
36
|
+
raise ArgumentError, "#{operation.class} is an unknown subclass of Dbsketch::Model::Operation"
|
37
|
+
end
|
38
|
+
"#{keyword}.drop #{operation.name}"
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def create_function function
|
44
|
+
arguments = function.arguments.map {|a| "\"#{a}\"" }
|
45
|
+
arguments = function.arguments.count > 1 ? "[#{arguments.join(", ")}]" : arguments.first
|
46
|
+
sql = "Dbsketch::Model::Function.new(\"#{function.name}\""
|
47
|
+
sql << ", :arguments => #{arguments}" if nil != arguments
|
48
|
+
sql << ", :returns => \"#{function.returns}\""
|
49
|
+
sql << ", :algo => \"#{function.algo}\")"
|
50
|
+
sql
|
51
|
+
end
|
52
|
+
|
53
|
+
def create_procedure procedure
|
54
|
+
arguments = procedure.arguments.map {|a| "\"#{a}\"" }
|
55
|
+
arguments = procedure.arguments.count > 1 ? "[#{arguments.join(", ")}]" : arguments.first
|
56
|
+
sql = "Dbsketch::Model::Procedure.new(\"#{procedure.name}\""
|
57
|
+
sql << ", :arguments => #{arguments}" if nil != arguments
|
58
|
+
sql << ", :algo => \"#{procedure.algo}\")"
|
59
|
+
sql
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,177 @@
|
|
1
|
+
########################################################################################################################
|
2
|
+
# Render a table into Ruby
|
3
|
+
########################################################################################################################
|
4
|
+
|
5
|
+
require_relative '../../comparison/table_comparator'
|
6
|
+
require_relative '../../model/table'
|
7
|
+
|
8
|
+
require_relative 'column_renderer'
|
9
|
+
require_relative 'foreign_key_renderer'
|
10
|
+
|
11
|
+
module Dbsketch
|
12
|
+
module Rendering
|
13
|
+
module Meta
|
14
|
+
|
15
|
+
class TableRenderer
|
16
|
+
def initialize column_renderer: nil, fk_renderer: nil, options: {}, keywords: {}
|
17
|
+
### Preconditions
|
18
|
+
raise ArgumentError, "options is not a Hash" unless options.is_a? Hash
|
19
|
+
raise ArgumentError, "keywords is not a Hash" unless keywords.is_a? Hash
|
20
|
+
###
|
21
|
+
@options = {
|
22
|
+
:pretty => false,
|
23
|
+
}.merge options
|
24
|
+
@keywords = {
|
25
|
+
:check_constraint => "Dbsketch::Model::CheckConstraint.new",
|
26
|
+
:primary_key => "Dbsketch::Model::PrimaryKey.new",
|
27
|
+
:foreign_key => "Dbsketch::Model::ForeignKey.new",
|
28
|
+
:table => "Dbsketch::Model::Table.new",
|
29
|
+
:unique_constraint => "Dbsketch::Model::UniqueConstraint.new"
|
30
|
+
}.merge keywords
|
31
|
+
@column_renderer = (nil == column_renderer ? ColumnRenderer.new(:keywords => @keywords) : column_renderer)
|
32
|
+
@fk_renderer = (nil == fk_renderer ? ForeignKeyRenderer.new(:foreign_key_keyword => @keywords[:foreign_key] ) : fk_renderer)
|
33
|
+
end
|
34
|
+
|
35
|
+
def create table
|
36
|
+
### Preconditions
|
37
|
+
raise ArgumentError, "table is not a Dbsketch::Model::Table" unless table.is_a? Dbsketch::Model::Table
|
38
|
+
###
|
39
|
+
columns = collect_columns table
|
40
|
+
str = "#{@keywords[:table]}(\"#{table.name}\""
|
41
|
+
str << ", :meaning => \"#{table.meaning}\"" if nil != table.meaning
|
42
|
+
str << ", :comment => \"#{table.comment}\"" if nil != table.comment
|
43
|
+
str << ", #{columns}" if not columns.empty?
|
44
|
+
str << ")"
|
45
|
+
constraints = collect_constraints table
|
46
|
+
str << "\n#{constraints.join("\n")}" if not constraints.empty?
|
47
|
+
str
|
48
|
+
end
|
49
|
+
|
50
|
+
def drop table
|
51
|
+
### Preconditions
|
52
|
+
raise ArgumentError, "table is not a Dbsketch::Model::Table" unless table.is_a? Dbsketch::Model::Table
|
53
|
+
###
|
54
|
+
"Table.drop #{table.name}"
|
55
|
+
end
|
56
|
+
|
57
|
+
def alter table_diff
|
58
|
+
### Preconditions
|
59
|
+
raise ArgumentError, "table_diff is not a Dbsketch::Comparison::TableDiff" unless table_diff.is_a? Dbsketch::Comparison::TableDiff
|
60
|
+
###
|
61
|
+
queries = []
|
62
|
+
|
63
|
+
# Columns
|
64
|
+
deleted_columns = table_diff.columns.select { |d| d.deletion? }
|
65
|
+
if not deleted_columns.empty?
|
66
|
+
queries << "Table.alter #{table_diff.new_table.name} drop column\n\t#{deleted_columns.map { |d| d.old_column.name }.join("\n\t")}"
|
67
|
+
end
|
68
|
+
added_columns = table_diff.columns.select { |d| d.addition? }
|
69
|
+
if not added_columns.empty?
|
70
|
+
queries << "Table.alter #{table_diff.new_table.name} add column\n\t#{added_columns.map { |d| @column_renderer.create d.new_column }.join("\n\t")}"
|
71
|
+
end
|
72
|
+
changed_columns = table_diff.columns.select { |d| d.change? }
|
73
|
+
if not changed_columns.empty?
|
74
|
+
queries << "Table.alter #{table_diff.new_table.name} alter column\n\t#{changed_columns.map { |d| @column_renderer.create d.new_column }.join("\n\t")}"
|
75
|
+
end
|
76
|
+
|
77
|
+
# Primary key
|
78
|
+
if nil != table_diff.primary_key
|
79
|
+
queries << "Table.alter #{table_diff.new_table.name} drop primary key #{table_diff.primary_key.old_key.name}" if table_diff.primary_key.deletion?
|
80
|
+
queries << "Table.alter #{table_diff.new_table.name} alter #{create_primary_key table_diff.new_table, table_diff.primary_key.new_key}" if table_diff.primary_key.change?
|
81
|
+
queries << "Table.alter #{table_diff.new_table.name} add #{create_primary_key table_diff.new_table, table_diff.primary_key.new_key}" if table_diff.primary_key.addition?
|
82
|
+
end
|
83
|
+
|
84
|
+
# Check constraints
|
85
|
+
deleted = table_diff.check_constraints.select { |d| d.deletion? }
|
86
|
+
if not deleted.empty?
|
87
|
+
queries << "Table.alter #{table_diff.new_table.name} drop check constraint\n\t#{deleted.map { |d| d.old_constraint.name }.join("\n\t")}"
|
88
|
+
end
|
89
|
+
added = table_diff.check_constraints.select { |d| d.addition? }
|
90
|
+
if not added.empty?
|
91
|
+
queries << "Table.alter #{table_diff.new_table.name} add\n\t#{added.map { |d| create_check_constraint d.new_constraint }.join("\n\t")}"
|
92
|
+
end
|
93
|
+
changed = table_diff.check_constraints.select { |d| d.change? }
|
94
|
+
if not changed.empty?
|
95
|
+
queries << "Table.alter #{table_diff.new_table.name} alter\n\t#{changed.map { |d| create_check_constraint d.new_constraint }.join("\n\t")}"
|
96
|
+
end
|
97
|
+
queries.flatten.join("\n")
|
98
|
+
|
99
|
+
# Foreign keys
|
100
|
+
deleted = table_diff.foreign_keys.select { |d| d.deletion? }
|
101
|
+
if not deleted.empty?
|
102
|
+
queries << "Table.alter #{table_diff.new_table.name} drop foreign key\n\t#{deleted.map { |d| d.old_key.name }.join("\n\t")}"
|
103
|
+
end
|
104
|
+
added = table_diff.foreign_keys.select { |d| d.addition? }
|
105
|
+
if not added.empty?
|
106
|
+
queries << "Table.alter #{table_diff.new_table.name} add\n\t#{added.map { |d| @fk_renderer.create d.new_key }.join("\n\t")}"
|
107
|
+
end
|
108
|
+
changed = table_diff.foreign_keys.select { |d| d.change? }
|
109
|
+
if not changed.empty?
|
110
|
+
queries << "Table.alter #{table_diff.new_table.name} alter\n\t#{changed.map { |d| @fk_renderer.create d.new_key }.join("\n\t")}"
|
111
|
+
end
|
112
|
+
queries.flatten.join("\n")
|
113
|
+
|
114
|
+
# Unique constraints
|
115
|
+
deleted = table_diff.unique_constraints.select { |d| d.deletion? }
|
116
|
+
if not deleted.empty?
|
117
|
+
queries << "Table.alter #{table_diff.new_table.name} drop unique constraint\n\t#{deleted.map { |d| d.old_constraint.name }.join("\n\t")}"
|
118
|
+
end
|
119
|
+
added = table_diff.unique_constraints.select { |d| d.addition? }
|
120
|
+
if not added.empty?
|
121
|
+
queries << "Table.alter #{table_diff.new_table.name} add\n\t#{added.map { |d| create_unique_constraint d.new_constraint, table_diff.new_table }.join("\n\t")}"
|
122
|
+
end
|
123
|
+
changed = table_diff.unique_constraints.select { |d| d.change? }
|
124
|
+
if not changed.empty?
|
125
|
+
queries << "Table.alter #{table_diff.new_table.name} alter\n\t#{changed.map { |d| create_unique_constraint d.new_constraint, table_diff.new_table }.join("\n\t")}"
|
126
|
+
end
|
127
|
+
queries.flatten.join("\n")
|
128
|
+
end
|
129
|
+
|
130
|
+
private
|
131
|
+
|
132
|
+
def create_primary_key table, primary_key = nil
|
133
|
+
primary_key = table.primary_key if nil == primary_key
|
134
|
+
columns = primary_key.columns.map {|c| "#{table.name.downcase}['#{c.name}']" }
|
135
|
+
columns = columns.count > 1 ? "[#{columns.join(", ")}]" : columns.first
|
136
|
+
"#{@keywords[:primary_key]}(\"#{primary_key.name}\", #{columns})"
|
137
|
+
end
|
138
|
+
|
139
|
+
def create_check_constraint constraint
|
140
|
+
"#{@keywords[:check_constraint]}(\"#{constraint.name}\", \"#{constraint.condition}\")"
|
141
|
+
end
|
142
|
+
|
143
|
+
def create_unique_constraint constraint, table
|
144
|
+
columns = constraint.columns.map {|c| "#{table.name.downcase}['#{c.name}']" }
|
145
|
+
columns = columns.count > 1 ? "[#{columns.join(", ")}]" : columns.first
|
146
|
+
"#{@keywords[:unique_constraint]}(\"#{constraint.name}\", #{columns})"
|
147
|
+
end
|
148
|
+
|
149
|
+
def collect_columns table
|
150
|
+
columns = table.columns.sort { |a,b| a.order <=> b.order }.map { |c| @column_renderer.create c }
|
151
|
+
if columns.count > 1
|
152
|
+
if @options[:pretty]
|
153
|
+
":columns => [\n\t#{columns.join(",\n\t")}\n]"
|
154
|
+
else
|
155
|
+
":columns => [#{columns.join(", ")}]"
|
156
|
+
end
|
157
|
+
elsif columns.count > 0
|
158
|
+
":columns => #{columns.first}"
|
159
|
+
else
|
160
|
+
""
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
def collect_constraints table
|
165
|
+
items = []
|
166
|
+
if nil != table.primary_key then items << "#{table.name.downcase}.add(#{create_primary_key(table)})" end
|
167
|
+
items << table.check_constraints.map { |c| "#{table.name.downcase}.add(#{create_check_constraint c})" }
|
168
|
+
items << table.unique_constraints.map { |c| "#{table.name.downcase}.add(#{create_unique_constraint c, table})" }
|
169
|
+
items << table.foreign_keys.map { |k| "#{table.name.downcase}.add(#{@fk_renderer.create k})" }
|
170
|
+
items.flatten.compact
|
171
|
+
end
|
172
|
+
|
173
|
+
end
|
174
|
+
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|