dbsketch 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +674 -0
  3. data/README.md +1 -0
  4. data/lib/dbsketch.rb +64 -0
  5. data/lib/dbsketch/automation/automation_error.rb +15 -0
  6. data/lib/dbsketch/automation/database_connection_details.rb +32 -0
  7. data/lib/dbsketch/automation/database_importer.rb +184 -0
  8. data/lib/dbsketch/automation/database_proxy.rb +78 -0
  9. data/lib/dbsketch/automation/table_importer.rb +114 -0
  10. data/lib/dbsketch/comparison/check_constraint_comparator.rb +54 -0
  11. data/lib/dbsketch/comparison/column_comparator.rb +65 -0
  12. data/lib/dbsketch/comparison/comparison_error.rb +15 -0
  13. data/lib/dbsketch/comparison/computed_column_comparator.rb +63 -0
  14. data/lib/dbsketch/comparison/database_comparator.rb +115 -0
  15. data/lib/dbsketch/comparison/diff.rb +37 -0
  16. data/lib/dbsketch/comparison/foreign_key_comparator.rb +56 -0
  17. data/lib/dbsketch/comparison/function_comparator.rb +56 -0
  18. data/lib/dbsketch/comparison/index_comparator.rb +65 -0
  19. data/lib/dbsketch/comparison/primary_key_comparator.rb +61 -0
  20. data/lib/dbsketch/comparison/procedure_comparator.rb +54 -0
  21. data/lib/dbsketch/comparison/table_comparator.rb +158 -0
  22. data/lib/dbsketch/comparison/trigger_comparator.rb +53 -0
  23. data/lib/dbsketch/comparison/type_comparator.rb +51 -0
  24. data/lib/dbsketch/comparison/unique_constraint_comparator.rb +58 -0
  25. data/lib/dbsketch/comparison/view_comparator.rb +54 -0
  26. data/lib/dbsketch/model/abstract_column.rb +25 -0
  27. data/lib/dbsketch/model/check_constraint.rb +23 -0
  28. data/lib/dbsketch/model/column.rb +35 -0
  29. data/lib/dbsketch/model/computed_column.rb +27 -0
  30. data/lib/dbsketch/model/custom_code.rb +21 -0
  31. data/lib/dbsketch/model/database.rb +87 -0
  32. data/lib/dbsketch/model/database_object.rb +71 -0
  33. data/lib/dbsketch/model/foreign_key.rb +29 -0
  34. data/lib/dbsketch/model/function.rb +23 -0
  35. data/lib/dbsketch/model/index.rb +40 -0
  36. data/lib/dbsketch/model/model_error.rb +15 -0
  37. data/lib/dbsketch/model/operation.rb +28 -0
  38. data/lib/dbsketch/model/primary_key.rb +33 -0
  39. data/lib/dbsketch/model/procedure.rb +18 -0
  40. data/lib/dbsketch/model/table.rb +171 -0
  41. data/lib/dbsketch/model/trigger.rb +32 -0
  42. data/lib/dbsketch/model/type.rb +92 -0
  43. data/lib/dbsketch/model/unique_constraint.rb +33 -0
  44. data/lib/dbsketch/model/view.rb +23 -0
  45. data/lib/dbsketch/rendering/meta/column_renderer.rb +76 -0
  46. data/lib/dbsketch/rendering/meta/database_renderer.rb +112 -0
  47. data/lib/dbsketch/rendering/meta/foreign_key_renderer.rb +31 -0
  48. data/lib/dbsketch/rendering/meta/index_renderer.rb +30 -0
  49. data/lib/dbsketch/rendering/meta/operation_renderer.rb +66 -0
  50. data/lib/dbsketch/rendering/meta/table_renderer.rb +177 -0
  51. data/lib/dbsketch/rendering/meta/trigger_renderer.rb +31 -0
  52. data/lib/dbsketch/rendering/meta/type_renderer.rb +37 -0
  53. data/lib/dbsketch/rendering/meta/view_renderer.rb +32 -0
  54. data/lib/dbsketch/rendering/sql/column_renderer.rb +75 -0
  55. data/lib/dbsketch/rendering/sql/database_diff_renderer.rb +94 -0
  56. data/lib/dbsketch/rendering/sql/database_renderer.rb +139 -0
  57. data/lib/dbsketch/rendering/sql/foreign_key_renderer.rb +24 -0
  58. data/lib/dbsketch/rendering/sql/index_renderer.rb +31 -0
  59. data/lib/dbsketch/rendering/sql/operation_renderer.rb +64 -0
  60. data/lib/dbsketch/rendering/sql/table_renderer.rb +148 -0
  61. data/lib/dbsketch/rendering/sql/trigger_renderer.rb +31 -0
  62. data/lib/dbsketch/rendering/sql/type_renderer.rb +28 -0
  63. data/lib/dbsketch/rendering/sql/view_renderer.rb +31 -0
  64. data/lib/dbsketch/version.rb +3 -0
  65. metadata +134 -0
@@ -0,0 +1,54 @@
1
+ ########################################################################################################################
2
+ # Compute differences between two existing check constraint
3
+ ########################################################################################################################
4
+
5
+ require_relative '../model/check_constraint'
6
+ require_relative 'comparison_error'
7
+ require_relative 'diff'
8
+
9
+ module Dbsketch
10
+ module Comparison
11
+
12
+ class CheckConstraintDiff < Diff
13
+ def initialize old_constraint, new_constraint
14
+ super old_constraint, new_constraint
15
+ end
16
+ alias :old_constraint :old_value
17
+ alias :new_constraint :new_value
18
+
19
+ def condition
20
+ ### Preconditions
21
+ raise ComparisonError, "no change found" if not change?
22
+ ###
23
+ Diff.new old_constraint.condition, new_constraint.condition
24
+ end
25
+ end
26
+
27
+ end
28
+ end
29
+
30
+ module Dbsketch
31
+ module Comparison
32
+
33
+ class CheckConstraintComparator
34
+
35
+ def are_equivalent? old_constraint, new_constraint
36
+ ### Preconditions
37
+ raise ArgumentError, "old_constraint is not a Dbsketch::Model::CheckConstraint" unless nil == old_constraint or old_constraint.is_a? Dbsketch::Model::CheckConstraint
38
+ raise ArgumentError, "new_constraint is not a Dbsketch::Model::CheckConstraint" unless nil == new_constraint or new_constraint.is_a? Dbsketch::Model::CheckConstraint
39
+ ###
40
+ (nil != old_constraint and nil != new_constraint) and (old_constraint.condition == new_constraint.condition)
41
+ end
42
+
43
+ def compare old_constraint, new_constraint
44
+ ### Preconditions
45
+ raise ArgumentError, "old_constraint is not a Dbsketch::Model::CheckConstraint" unless nil == old_constraint or old_constraint.is_a? Dbsketch::Model::CheckConstraint
46
+ raise ArgumentError, "new_constraint is not a Dbsketch::Model::CheckConstraint" unless nil == new_constraint or new_constraint.is_a? Dbsketch::Model::CheckConstraint
47
+ ###
48
+ CheckConstraintDiff.new(old_constraint, new_constraint) if not are_equivalent? old_constraint, new_constraint
49
+ end
50
+
51
+ end
52
+
53
+ end
54
+ end
@@ -0,0 +1,65 @@
1
+ ########################################################################################################################
2
+ # Compute differences between two existing columns
3
+ ########################################################################################################################
4
+
5
+ require_relative '../model/column'
6
+ require_relative 'diff'
7
+ require_relative 'type_comparator'
8
+
9
+ module Dbsketch
10
+ module Comparison
11
+
12
+ class ColumnDiff < Diff
13
+ def initialize old_column, new_column, type_comparator, options
14
+ super old_column, new_column
15
+ if change?
16
+ @type = type_comparator.compare(old_column.type, new_column.type)
17
+ @identity = Diff.new(old_column.identity, new_column.identity) if old_column.identity != new_column.identity
18
+ @default = Diff.new(old_column.default, new_column.default) if old_column.default != new_column.default
19
+ @nullable = Diff.new(old_column.nullable, new_column.nullable) if old_column.nullable != new_column.nullable
20
+ @order = Diff.new(old_column.order, new_column.order) if options[:compare_order] and old_column.order != new_column.order
21
+ end
22
+ end
23
+
24
+ attr_reader :type, :identity, :default, :nullable, :order
25
+ alias :old_column :old_value
26
+ alias :new_column :new_value
27
+ end
28
+
29
+ end
30
+ end
31
+
32
+ module Dbsketch
33
+ module Comparison
34
+
35
+ class ColumnComparator
36
+ def initialize options: {}
37
+ @options = { :compare_order => true }.merge options
38
+ @type_comparator = TypeComparator.new
39
+ end
40
+
41
+ def are_equivalent? old_column, new_column
42
+ ### Preconditions
43
+ raise ArgumentError, "old_column is not a Dbsketch::Model::Column" unless nil == old_column or old_column.is_a? Dbsketch::Model::Column
44
+ raise ArgumentError, "new_column is not a Dbsketch::Model::Column" unless nil == new_column or new_column.is_a? Dbsketch::Model::Column
45
+ ###
46
+ (nil != old_column and nil != new_column) and
47
+ @type_comparator.are_equivalent?(old_column.type, new_column.type) and
48
+ old_column.identity == new_column.identity and
49
+ old_column.default == new_column.default and
50
+ old_column.nullable == new_column.nullable and
51
+ (not @options[:compare_order] or old_column.order == new_column.order)
52
+ end
53
+
54
+ def compare old_column, new_column
55
+ ### Preconditions
56
+ raise ArgumentError, "old_column is not a Dbsketch::Model::Column" unless nil == old_column or old_column.is_a? Dbsketch::Model::Column
57
+ raise ArgumentError, "new_column is not a Dbsketch::Model::Column" unless nil == new_column or new_column.is_a? Dbsketch::Model::Column
58
+ ###
59
+ ColumnDiff.new(old_column, new_column, @type_comparator, @options) if not are_equivalent? old_column, new_column
60
+ end
61
+
62
+ end
63
+
64
+ end
65
+ end
@@ -0,0 +1,15 @@
1
+ ########################################################################################################################
2
+ # Represents database comparison error
3
+ ########################################################################################################################
4
+
5
+ module Dbsketch
6
+ module Comparison
7
+
8
+ class ComparisonError < StandardError
9
+ def initialize message
10
+ super(message)
11
+ end
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,63 @@
1
+ ########################################################################################################################
2
+ # Compute differences between two existing computed columns
3
+ ########################################################################################################################
4
+
5
+ require_relative '../model/computed_column'
6
+ require_relative 'diff'
7
+ require_relative 'type_comparator'
8
+
9
+ module Dbsketch
10
+ module Comparison
11
+
12
+ class ComputedColumnDiff < Diff
13
+ def initialize old_column, new_column, options
14
+ super old_column, new_column
15
+ if change?
16
+ @query = Diff.new(old_column.query, new_column.query) if old_column.query != new_column.query
17
+ @nullable = Diff.new(old_column.nullable, new_column.nullable) if old_column.nullable != new_column.nullable
18
+ @order = Diff.new(old_column.order, new_column.order) if options[:compare_order] and old_column.order != new_column.order
19
+ @persisted = Diff.new(old_column.persisted, new_column.persisted) if old_column.persisted != new_column.persisted
20
+ end
21
+ end
22
+
23
+ attr_reader :query, :nullable, :order, :persisted
24
+ alias :old_column :old_value
25
+ alias :new_column :new_value
26
+ end
27
+
28
+ end
29
+ end
30
+
31
+ module Dbsketch
32
+ module Comparison
33
+
34
+ class ComputedColumnComparator
35
+
36
+ def initialize options: {}
37
+ @options = { :compare_order => true }.merge options
38
+ end
39
+
40
+ def are_equivalent? old_column, new_column
41
+ ### Preconditions
42
+ raise ArgumentError, "old_column is not a Dbsketch::Model::ComputedColumn" unless nil == old_column or old_column.is_a? Dbsketch::Model::ComputedColumn
43
+ raise ArgumentError, "new_column is not a Dbsketch::Model::ComputedColumn" unless nil == new_column or new_column.is_a? Dbsketch::Model::ComputedColumn
44
+ ###
45
+ (nil != old_column and nil != new_column) and
46
+ old_column.query == new_column.query and
47
+ old_column.nullable == new_column.nullable and
48
+ old_column.persisted == new_column.persisted and
49
+ (not @options[:compare_order] or old_column.order == new_column.order)
50
+ end
51
+
52
+ def compare old_column, new_column
53
+ ### Preconditions
54
+ raise ArgumentError, "old_column is not a Dbsketch::Model::ComputedColumn" unless nil == old_column or old_column.is_a? Dbsketch::Model::ComputedColumn
55
+ raise ArgumentError, "new_column is not a Dbsketch::Model::ComputedColumn" unless nil == new_column or new_column.is_a? Dbsketch::Model::ComputedColumn
56
+ ###
57
+ ComputedColumnDiff.new(old_column, new_column, @options) if not are_equivalent? old_column, new_column
58
+ end
59
+
60
+ end
61
+
62
+ end
63
+ end
@@ -0,0 +1,115 @@
1
+ ########################################################################################################################
2
+ # Database differences between two databases
3
+ ########################################################################################################################
4
+
5
+ require_relative '../model/database'
6
+ require_relative 'diff'
7
+ require_relative 'index_comparator'
8
+ require_relative 'table_comparator'
9
+ require_relative 'trigger_comparator'
10
+ require_relative 'view_comparator'
11
+
12
+ module Dbsketch
13
+ module Comparison
14
+
15
+ class DatabaseDiff < Diff
16
+ def initialize(old_database, new_database, indexes, operations, tables, triggers, views)
17
+ super old_database, new_database
18
+ ### Preconditions
19
+ raise ArgumentError, "old_database is not a Dbsketch::Model::Database" unless old_database.is_a? Dbsketch::Model::Database
20
+ raise ArgumentError, "new_database is not a Dbsketch::Model::Database" unless new_database.is_a? Dbsketch::Model::Database
21
+ ###
22
+ @indexes = indexes
23
+ @operations = operations
24
+ @tables = tables
25
+ @triggers = triggers
26
+ @views = views
27
+ end
28
+ attr_reader :indexes, :operations, :tables, :triggers, :views
29
+ end
30
+
31
+ class DatabaseComparator
32
+ def initialize options: {}
33
+ @index_comparator = IndexComparator.new
34
+ @function_comparator = FunctionComparator.new
35
+ @procedure_comparator = ProcedureComparator.new
36
+ @table_comparator = TableComparator.new :options => options
37
+ @trigger_comparator = TriggerComparator.new
38
+ @view_comparator = ViewComparator.new
39
+ end
40
+
41
+ def are_equivalent? old_database, new_database
42
+ ### Preconditions
43
+ raise ArgumentError, "old_database is not a Dbsketch::Model::Database" unless old_database.is_a? Dbsketch::Model::Database
44
+ raise ArgumentError, "new_database is not a Dbsketch::Model::Database" unless new_database.is_a? Dbsketch::Model::Database
45
+ ###
46
+ indexes(old_database, new_database).empty? and operations(old_database, new_database).empty? and tables(old_database, new_database).empty? and triggers(old_database, new_database).empty? and views(old_database, new_database).empty?
47
+ end
48
+
49
+ # Returns a DatabaseDiff if tables are different, nil otherwise
50
+ def compare old_database, new_database
51
+ ### Preconditions
52
+ raise ArgumentError, "old_database is not a Dbsketch::Model::Database" unless old_database.is_a? Dbsketch::Model::Database
53
+ raise ArgumentError, "new_database is not a Dbsketch::Model::Database" unless new_database.is_a? Dbsketch::Model::Database
54
+ ###
55
+ DatabaseDiff.new(
56
+ old_database, new_database, indexes(old_database, new_database), operations(old_database, new_database), tables(old_database, new_database), triggers(old_database, new_database), views(old_database, new_database)
57
+ ) if not are_equivalent? old_database, new_database
58
+ end
59
+
60
+ private
61
+
62
+ def find_diffs old_database, new_database, comparator, collection
63
+ ### Preconditions
64
+ raise ArgumentError, "collection is not a Symbol" unless collection.is_a? Symbol
65
+ raise ArgumentError, "collection is not a method of Dbsketch::Model::Database" unless old_database.respond_to? collection
66
+ ###
67
+ diffs = old_database.method(collection).call.select { |old_item| not new_database.has_item? old_item.name }.map do |old_item|
68
+ comparator.compare(old_item, nil)
69
+ end
70
+ diffs << new_database.method(collection).call.select { |new_item| not old_database.has_item? new_item.name }.map do |new_item|
71
+ comparator.compare(nil, new_item)
72
+ end
73
+ diffs << old_database.method(collection).call.select { |old_item| new_database.has_item? old_item.name }.map do |old_item|
74
+ comparator.compare(old_item, new_database[old_item.name])
75
+ end
76
+ diffs.flatten.compact
77
+ end
78
+
79
+ def indexes old_database, new_database
80
+ find_diffs old_database, new_database, @index_comparator, :indexes
81
+ end
82
+
83
+ def operations old_database, new_database
84
+ diffs = old_database.operations.select { |old_op| not new_database.has_item? old_op.name }.map do |old_op|
85
+ (old_op.is_a? Dbsketch::Model::Function) ? @function_comparator.compare(old_op, nil) : @procedure_comparator.compare(old_op, nil)
86
+ end
87
+ diffs << new_database.operations.select { |new_op| not old_database.has_item? new_op.name }.map do |new_op|
88
+ (new_op.is_a? Dbsketch::Model::Function) ? @function_comparator.compare(nil, new_op) : @procedure_comparator.compare(nil, new_op)
89
+ end
90
+ diffs << old_database.operations.select { |old_op| new_database.has_item? old_op.name }.map do |old_op|
91
+ if old_op.class == new_database[old_op.name].class
92
+ (old_op.is_a? Dbsketch::Model::Function) ? @function_comparator.compare(old_op, new_database[old_op.name]) : @procedure_comparator.compare(old_op, new_database[old_op.name])
93
+ else
94
+ Diff.new old_op, new_database[old_op.name]
95
+ end
96
+ end
97
+ diffs.flatten.compact
98
+ end
99
+
100
+ def tables old_database, new_database
101
+ find_diffs old_database, new_database, @table_comparator, :tables
102
+ end
103
+
104
+ def triggers old_database, new_database
105
+ find_diffs old_database, new_database, @trigger_comparator, :triggers
106
+ end
107
+
108
+ def views old_database, new_database
109
+ find_diffs old_database, new_database, @view_comparator, :views
110
+ end
111
+
112
+ end
113
+
114
+ end
115
+ end
@@ -0,0 +1,37 @@
1
+ ########################################################################################################################
2
+ # Defines difference between two values
3
+ ########################################################################################################################
4
+
5
+ module Dbsketch
6
+ module Comparison
7
+
8
+ class Diff
9
+ def initialize old_value, new_value
10
+ ### Preconditions
11
+ raise ArgumentError, "new_value is not different from old_value" unless new_value != old_value
12
+ ###
13
+ @old_value = old_value
14
+ @new_value = new_value
15
+ end
16
+
17
+ attr_reader :old_value, :new_value
18
+
19
+ # Returns true if the diff represents the deletion of an old value
20
+ def deletion?
21
+ nil != @old_value and nil == @new_value
22
+ end
23
+
24
+ # Returns true if the diff represents a change
25
+ def change?
26
+ nil != @old_value and nil != @new_value
27
+ end
28
+
29
+ # Returns true if the diff represents the addition of a new value
30
+ def addition?
31
+ nil == @old_value and nil != @new_value
32
+ end
33
+
34
+ end
35
+
36
+ end
37
+ end
@@ -0,0 +1,56 @@
1
+ ########################################################################################################################
2
+ # Compute differences between two existing foreign keys
3
+ ########################################################################################################################
4
+
5
+ require_relative '../model/foreign_key'
6
+ require_relative 'diff'
7
+
8
+ module Dbsketch
9
+ module Comparison
10
+
11
+ class ForeignKeyDiff < Diff
12
+ def initialize old_key, new_key
13
+ super old_key, new_key
14
+ if change?
15
+ @constricted_column = Diff.new(old_key.constricted_column.name, new_key.constricted_column.name) if old_key.constricted_column.name != new_key.constricted_column.name
16
+ @referenced_table = Diff.new(old_key.referenced_table.name, new_key.referenced_table.name) if old_key.referenced_table.name != new_key.referenced_table.name
17
+ @referenced_column = Diff.new(old_key.referenced_column.name, new_key.referenced_column.name) if old_key.referenced_column.name != new_key.referenced_column.name
18
+ end
19
+ end
20
+
21
+ attr_reader :constricted_column, :referenced_table, :referenced_column
22
+ alias :old_key :old_value
23
+ alias :new_key :new_value
24
+ end
25
+
26
+ end
27
+ end
28
+
29
+ module Dbsketch
30
+ module Comparison
31
+
32
+ class ForeignKeyComparator
33
+
34
+ def are_equivalent? old_key, new_key
35
+ ### Preconditions
36
+ raise ArgumentError, "old_key is not a Dbsketch::Model::ForeignKey" unless nil == old_key or old_key.is_a? Dbsketch::Model::ForeignKey
37
+ raise ArgumentError, "new_key is not a Dbsketch::Model::ForeignKey" unless nil == new_key or new_key.is_a? Dbsketch::Model::ForeignKey
38
+ ###
39
+ (nil != old_key and nil != new_key) and
40
+ old_key.constricted_column.name == new_key.constricted_column.name and
41
+ old_key.referenced_table.name == new_key.referenced_table.name and
42
+ old_key.referenced_column.name == new_key.referenced_column.name
43
+ end
44
+
45
+ def compare old_key, new_key
46
+ ### Preconditions
47
+ raise ArgumentError, "old_key is not a Dbsketch::Model::ForeignKey" unless nil == old_key or old_key.is_a? Dbsketch::Model::ForeignKey
48
+ raise ArgumentError, "new_key is not a Dbsketch::Model::ForeignKey" unless nil == new_key or new_key.is_a? Dbsketch::Model::ForeignKey
49
+ ###
50
+ ForeignKeyDiff.new(old_key, new_key) if not are_equivalent? old_key, new_key
51
+ end
52
+
53
+ end
54
+
55
+ end
56
+ end
@@ -0,0 +1,56 @@
1
+ ########################################################################################################################
2
+ # Compute differences between two functions
3
+ ########################################################################################################################
4
+
5
+ require_relative '../model/function'
6
+ require_relative 'diff'
7
+
8
+ module Dbsketch
9
+ module Comparison
10
+
11
+ class FunctionDiff < Diff
12
+ def initialize old_function, new_function
13
+ super old_function, new_function
14
+ if change?
15
+ @arguments = Diff.new(old_function.arguments, new_function.arguments) if old_function.arguments != new_function.arguments
16
+ @returns = Diff.new(old_function.returns, new_function.returns) if old_function.returns != new_function.returns
17
+ @algo = Diff.new(old_function.algo, new_function.algo) if old_function.algo != new_function.algo
18
+ end
19
+ end
20
+
21
+ attr_reader :arguments, :returns, :algo
22
+ alias :old_function :old_value
23
+ alias :new_function :new_value
24
+ end
25
+
26
+ end
27
+ end
28
+
29
+ module Dbsketch
30
+ module Comparison
31
+
32
+ class FunctionComparator
33
+
34
+ def are_equivalent? old_function, new_function
35
+ ### Preconditions
36
+ raise ArgumentError, "old_function is not a Dbsketch::Model::Function" unless nil == old_function or old_function.is_a? Dbsketch::Model::Function
37
+ raise ArgumentError, "new_function is not a Dbsketch::Model::Function" unless nil == new_function or new_function.is_a? Dbsketch::Model::Function
38
+ ###
39
+ (nil != old_function and nil != new_function) and
40
+ old_function.arguments == new_function.arguments and
41
+ old_function.returns == new_function.returns and
42
+ old_function.algo == new_function.algo
43
+ end
44
+
45
+ def compare old_function, new_function
46
+ ### Preconditions
47
+ raise ArgumentError, "old_function is not a Dbsketch::Model::Function" unless nil == old_function or old_function.is_a? Dbsketch::Model::Function
48
+ raise ArgumentError, "new_function is not a Dbsketch::Model::Function" unless nil == new_function or new_function.is_a? Dbsketch::Model::Function
49
+ ###
50
+ FunctionDiff.new(old_function, new_function) if not are_equivalent? old_function, new_function
51
+ end
52
+
53
+ end
54
+
55
+ end
56
+ end