dbsketch 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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