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,23 @@
|
|
1
|
+
########################################################################################################################
|
2
|
+
# Defines database function
|
3
|
+
########################################################################################################################
|
4
|
+
|
5
|
+
require_relative 'operation'
|
6
|
+
|
7
|
+
module Dbsketch
|
8
|
+
module Model
|
9
|
+
|
10
|
+
class Function < Operation
|
11
|
+
def initialize name, meaning: nil, comment: nil, dependencies: [], arguments: [], returns:, algo:
|
12
|
+
super name, :meaning => meaning, :comment => comment, :dependencies => dependencies, :arguments => arguments, :algo => algo
|
13
|
+
### Preconditions
|
14
|
+
raise ArgumentError, "returns is not a String" unless returns.is_a? String
|
15
|
+
###
|
16
|
+
@returns = returns
|
17
|
+
end
|
18
|
+
|
19
|
+
attr_reader :returns
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
########################################################################################################################
|
2
|
+
# Defines database column
|
3
|
+
########################################################################################################################
|
4
|
+
|
5
|
+
require_relative 'abstract_column'
|
6
|
+
require_relative 'computed_column'
|
7
|
+
require_relative 'database_object'
|
8
|
+
require_relative 'table'
|
9
|
+
require_relative 'model_error'
|
10
|
+
require_relative 'view'
|
11
|
+
|
12
|
+
module Dbsketch
|
13
|
+
module Model
|
14
|
+
|
15
|
+
class Index < Database_Object
|
16
|
+
def initialize name, target, columns, meaning: nil, comment: nil, dependencies: []
|
17
|
+
super name, :meaning => meaning, :comment => comment, :dependencies => dependencies
|
18
|
+
@columns = columns.is_a?(Array) ? columns : [columns]
|
19
|
+
### Preconditions
|
20
|
+
raise ArgumentError, "target is not a Dbsketch::Model::Table or a View" unless target.is_a? Table or target.is_a? View
|
21
|
+
@columns.each_with_index do |column, index|
|
22
|
+
raise ArgumentError, "columns[#{index}] is not a Dbsketch::Model::AbstractColumn" unless column.is_a? AbstractColumn
|
23
|
+
raise ModelError, "computed column #{column.name} is not persisted" if column.is_a? ComputedColumn and not column.persisted
|
24
|
+
end
|
25
|
+
###
|
26
|
+
@target = target
|
27
|
+
end
|
28
|
+
|
29
|
+
attr_reader :target, :columns
|
30
|
+
|
31
|
+
def has_column? column_name
|
32
|
+
### Preconditions
|
33
|
+
raise ArgumentError, "column_name is not a String" unless column_name.is_a? String
|
34
|
+
###
|
35
|
+
nil != @columns.find { |c| c.name.downcase == column_name.downcase }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
########################################################################################################################
|
2
|
+
# Represents database model error (for example, two columns with a same name in a table)
|
3
|
+
########################################################################################################################
|
4
|
+
|
5
|
+
module Dbsketch
|
6
|
+
module Model
|
7
|
+
|
8
|
+
class ModelError < StandardError
|
9
|
+
def initialize message
|
10
|
+
super(message)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
########################################################################################################################
|
2
|
+
# Defines database operation (function and procedure common stuff)
|
3
|
+
########################################################################################################################
|
4
|
+
|
5
|
+
require_relative 'database_object'
|
6
|
+
|
7
|
+
module Dbsketch
|
8
|
+
module Model
|
9
|
+
|
10
|
+
class Operation < Database_Object
|
11
|
+
def initialize name, meaning: nil, comment: nil, dependencies: [], arguments: [], algo:
|
12
|
+
super name, :meaning => meaning, :comment => comment, :dependencies => dependencies
|
13
|
+
arguments = arguments.is_a?(Array) ? arguments : [arguments]
|
14
|
+
### Preconditions
|
15
|
+
arguments.each_with_index do |arg, index|
|
16
|
+
raise ArgumentError, "arguments[#{index}] is not a String" unless arg.is_a? String
|
17
|
+
end
|
18
|
+
raise ArgumentError, "algo is not a String" unless algo.is_a? String
|
19
|
+
###
|
20
|
+
@arguments = arguments
|
21
|
+
@algo = algo
|
22
|
+
end
|
23
|
+
|
24
|
+
attr_reader :algo, :arguments
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
########################################################################################################################
|
2
|
+
# Primary Key
|
3
|
+
########################################################################################################################
|
4
|
+
|
5
|
+
require_relative 'column'
|
6
|
+
require_relative 'database_object'
|
7
|
+
|
8
|
+
module Dbsketch
|
9
|
+
module Model
|
10
|
+
|
11
|
+
class PrimaryKey < 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,18 @@
|
|
1
|
+
########################################################################################################################
|
2
|
+
# Defines database stored procedure
|
3
|
+
########################################################################################################################
|
4
|
+
|
5
|
+
require_relative 'operation'
|
6
|
+
|
7
|
+
module Dbsketch
|
8
|
+
module Model
|
9
|
+
|
10
|
+
class Procedure < Operation
|
11
|
+
def initialize name, meaning: nil, comment: nil, dependencies: [], arguments: [], algo:
|
12
|
+
super name, :meaning => meaning, :comment => comment, :dependencies => dependencies, :arguments => arguments, :algo => algo
|
13
|
+
# TODO check arguments are one of [out, output, readonly]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,171 @@
|
|
1
|
+
########################################################################################################################
|
2
|
+
# Defines database table structure
|
3
|
+
########################################################################################################################
|
4
|
+
|
5
|
+
require_relative 'abstract_column'
|
6
|
+
require_relative 'check_constraint'
|
7
|
+
require_relative 'column'
|
8
|
+
require_relative 'database_object'
|
9
|
+
require_relative 'foreign_key'
|
10
|
+
require_relative 'model_error'
|
11
|
+
require_relative 'primary_key'
|
12
|
+
require_relative 'unique_constraint'
|
13
|
+
|
14
|
+
module Dbsketch
|
15
|
+
module Model
|
16
|
+
|
17
|
+
class Table < Database_Object
|
18
|
+
def initialize name, meaning: nil, comment: nil, dependencies: [], columns: [], p_key_columns: []
|
19
|
+
super name, :meaning => meaning, :comment => comment, :dependencies => dependencies
|
20
|
+
columns = columns.is_a?(Array) ? columns.flatten : [columns]
|
21
|
+
p_key_columns = p_key_columns.is_a?(Array) ? p_key_columns : [p_key_columns]
|
22
|
+
### Preconditions
|
23
|
+
columns.each_with_index do |column, index|
|
24
|
+
raise ArgumentError, "columns[#{index}] is not a Dbsketch::Model::AbstractColumn" unless column.is_a? AbstractColumn
|
25
|
+
end
|
26
|
+
p_key_columns.each_with_index do |column, index|
|
27
|
+
raise ArgumentError, "p_key_columns[#{index}] is not a String nor a Dbsketch::Model::AbstractColumn" unless column.is_a? String or column.is_a? AbstractColumn
|
28
|
+
end
|
29
|
+
###
|
30
|
+
@columns = []
|
31
|
+
columns.each { |c| add_column c }
|
32
|
+
@primary_key = nil
|
33
|
+
primary_key_columns = p_key_columns.map { |c| (c.is_a? AbstractColumn) ? c : self[c] }
|
34
|
+
set_primary_key PrimaryKey.new "PK_#{@name}", primary_key_columns if not primary_key_columns.empty?
|
35
|
+
@check_constraints = []
|
36
|
+
@foreign_keys = []
|
37
|
+
@unique_constraints = []
|
38
|
+
end
|
39
|
+
|
40
|
+
attr_reader :columns, :primary_key, :check_constraints, :foreign_keys, :unique_constraints
|
41
|
+
|
42
|
+
def add object
|
43
|
+
objects = object.is_a?(Array) ? object : [object]
|
44
|
+
### Preconditions
|
45
|
+
objects.each_with_index do |o, index|
|
46
|
+
raise ArgumentError, "object n°#{index + 1} is not a valid Dbsketch::Model object" unless o.is_a? AbstractColumn or o.is_a? PrimaryKey or o.is_a? CheckConstraint or o.is_a? ForeignKey or o.is_a? UniqueConstraint
|
47
|
+
end
|
48
|
+
###
|
49
|
+
objects.each do |o|
|
50
|
+
if o.is_a? AbstractColumn
|
51
|
+
add_column o
|
52
|
+
elsif o.is_a? PrimaryKey
|
53
|
+
set_primary_key o
|
54
|
+
elsif o.is_a? CheckConstraint
|
55
|
+
add_check_constraint o
|
56
|
+
elsif o.is_a? ForeignKey
|
57
|
+
add_foreign_key o
|
58
|
+
elsif o.is_a? UniqueConstraint
|
59
|
+
add_unique_constraint o
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def has_column? column_name
|
65
|
+
### Preconditions
|
66
|
+
raise ArgumentError, "column_name is not a String" unless column_name.is_a? String
|
67
|
+
###
|
68
|
+
nil != @columns.find { |c| c.name.downcase == column_name.downcase }
|
69
|
+
end
|
70
|
+
|
71
|
+
def has_check_constraint? constraint_name
|
72
|
+
### Preconditions
|
73
|
+
raise ArgumentError, "constraint_name is not a String" unless constraint_name.is_a? String
|
74
|
+
###
|
75
|
+
nil != @check_constraints.find { |c| c.name.downcase == constraint_name.downcase }
|
76
|
+
end
|
77
|
+
|
78
|
+
def has_foreign_key? key_name
|
79
|
+
### Preconditions
|
80
|
+
raise ArgumentError, "key_name is not a String" unless key_name.is_a? String
|
81
|
+
###
|
82
|
+
nil != @foreign_keys.find { |c| c.name.downcase == key_name.downcase }
|
83
|
+
end
|
84
|
+
|
85
|
+
def has_unique_constraint? constraint_name
|
86
|
+
### Preconditions
|
87
|
+
raise ArgumentError, "constraint_name is not a String" unless constraint_name.is_a? String
|
88
|
+
###
|
89
|
+
nil != @unique_constraints.find { |c| c.name.downcase == constraint_name.downcase }
|
90
|
+
end
|
91
|
+
|
92
|
+
def [] column_name
|
93
|
+
column = @columns.find { |c| c.name.downcase == column_name.downcase }
|
94
|
+
raise ArgumentError, "column #{column_name} not found in table #{@name}" if nil == column
|
95
|
+
column
|
96
|
+
end
|
97
|
+
|
98
|
+
def check_constraint constraint_name
|
99
|
+
constraint = @check_constraints.find { |c| c.name.downcase == constraint_name.downcase }
|
100
|
+
raise ArgumentError, "check constraint #{constraint_name} not found in table #{@name}" if nil == constraint
|
101
|
+
constraint
|
102
|
+
end
|
103
|
+
|
104
|
+
def foreign_key key_name
|
105
|
+
key = @foreign_keys.find { |c| c.name.downcase == key_name.downcase }
|
106
|
+
raise ArgumentError, "foreign key #{key_name} not found in table #{@name}" if nil == key
|
107
|
+
key
|
108
|
+
end
|
109
|
+
|
110
|
+
def unique_constraint constraint_name
|
111
|
+
constraint = @unique_constraints.find { |c| c.name.downcase == constraint_name.downcase }
|
112
|
+
raise ArgumentError, "unique constraint #{constraint_name} not found in table #{@name}" if nil == constraint
|
113
|
+
constraint
|
114
|
+
end
|
115
|
+
|
116
|
+
private
|
117
|
+
|
118
|
+
def add_column column
|
119
|
+
### Preconditions
|
120
|
+
raise ModelError, "column #{column.name} already exists in table #{@name}" if nil != (@columns.find { |c| c.name.downcase == column.name.downcase })
|
121
|
+
raise ModelError, "column #{column.name} has an order but column without order exists in table #{@name}" if nil != column.order and nil != (@columns.find { |c| nil == c.order })
|
122
|
+
raise ModelError, "a column of order #{column.order} already exists in table #{@name}" if nil != (@columns.find { |c| nil != c.order and c.order == column.order })
|
123
|
+
###
|
124
|
+
@columns << column
|
125
|
+
end
|
126
|
+
|
127
|
+
def set_primary_key key
|
128
|
+
### Preconditions
|
129
|
+
raise ModelError, "a primary key already exists in table #{@name}" if nil != @primary_key
|
130
|
+
key.columns.each do |pk_c|
|
131
|
+
raise ModelError, "primary key column #{pk_c.name} does not exists in table #{@name}" if nil == (@columns.find { |c| c.name.downcase == pk_c.name.downcase })
|
132
|
+
end
|
133
|
+
###
|
134
|
+
@primary_key = key
|
135
|
+
end
|
136
|
+
|
137
|
+
def constraint_exist? constraint
|
138
|
+
(nil != (@check_constraints.find { |c| c.name.downcase == constraint.name.downcase }) or
|
139
|
+
nil != (@foreign_keys.find { |k| k.name.downcase == constraint.name.downcase }) or
|
140
|
+
nil != (@unique_constraints.find { |c| c.name.downcase == constraint.name.downcase }))
|
141
|
+
end
|
142
|
+
|
143
|
+
def add_check_constraint constraint
|
144
|
+
### Preconditions
|
145
|
+
raise ModelError, "constraint #{constraint.name} already exists in table #{@name}" if constraint_exist? constraint
|
146
|
+
###
|
147
|
+
@check_constraints << constraint
|
148
|
+
end
|
149
|
+
|
150
|
+
def add_foreign_key constraint
|
151
|
+
### Preconditions
|
152
|
+
raise ModelError, "constraint #{constraint.name} already exists in table #{@name}" if constraint_exist? constraint
|
153
|
+
raise ModelError, "constraint #{constraint.name} column #{constraint.constricted_column.name} does not exists in table #{@name}" if nil == (@columns.find { |c| c.name.downcase == constraint.constricted_column.name.downcase })
|
154
|
+
###
|
155
|
+
@foreign_keys << constraint
|
156
|
+
add_dependencies constraint.referenced_table
|
157
|
+
end
|
158
|
+
|
159
|
+
def add_unique_constraint constraint
|
160
|
+
### Preconditions
|
161
|
+
raise ModelError, "constraint #{constraint.name} already exists in table #{@name}" if constraint_exist? constraint
|
162
|
+
constraint.columns.each do |uc_c|
|
163
|
+
raise ModelError, "constraint column #{uc_c.name} does not exists in table #{@name}" if nil == (@columns.find { |c| c.name.downcase == uc_c.name.downcase })
|
164
|
+
end
|
165
|
+
###
|
166
|
+
@unique_constraints << constraint
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
end
|
171
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
########################################################################################################################
|
2
|
+
# Defines database trigger
|
3
|
+
########################################################################################################################
|
4
|
+
|
5
|
+
require_relative 'database_object'
|
6
|
+
require_relative 'model_error'
|
7
|
+
require_relative 'table'
|
8
|
+
require_relative 'view'
|
9
|
+
|
10
|
+
module Dbsketch
|
11
|
+
module Model
|
12
|
+
|
13
|
+
class Trigger < Database_Object
|
14
|
+
def initialize name, target, activation_time, algo:, meaning: nil, comment: nil, dependencies: []
|
15
|
+
super name, :meaning => meaning, :comment => comment, :dependencies => dependencies
|
16
|
+
### Preconditions
|
17
|
+
raise ArgumentError, "target is not a Dbsketch::Model::Table or View" unless target.is_a? Table or target.is_a? View
|
18
|
+
raise ArgumentError, "activation_time is not a String" unless activation_time.is_a? String
|
19
|
+
raise ModelError, "activation_time does not begins 'for', 'after' or 'instead of' (#{activation_time})" if nil == activation_time.downcase.match(/^(for)|(after)|(instead of)/)
|
20
|
+
raise ArgumentError, "algo is not a String" unless algo.is_a? String
|
21
|
+
###
|
22
|
+
@target = target
|
23
|
+
@activation_time = activation_time
|
24
|
+
@algo = algo
|
25
|
+
add_dependencies target
|
26
|
+
end
|
27
|
+
|
28
|
+
attr_reader :target, :activation_time, :algo
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
########################################################################################################################
|
2
|
+
# Represents database type, allow to check compatibility
|
3
|
+
########################################################################################################################
|
4
|
+
|
5
|
+
module Dbsketch
|
6
|
+
module Model
|
7
|
+
|
8
|
+
class Type
|
9
|
+
def initialize(sql_type, sizes = [])
|
10
|
+
@sizes = sizes.is_a?(Array) ? sizes : [sizes]
|
11
|
+
### Preconditions
|
12
|
+
raise ArgumentError, "sql_type is not a String" unless sql_type.is_a? String
|
13
|
+
@sizes.each do |size|
|
14
|
+
if 'max' == size
|
15
|
+
if not ['varchar', 'nvarchar'].include? sql_type
|
16
|
+
raise ArgumentError, "size 'max' allowed only for [n]varchar"
|
17
|
+
end
|
18
|
+
elsif not size.is_a? Fixnum and not size.is_a? Integer
|
19
|
+
raise ArgumentError, "size #{size} of sql type #{sql_type} is not a number"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
raise ArgumentError, "#{sql_type} do not allow defining sizes" if ['datetime', 'datetime2', 'int'].include? sql_type and @sizes.count > 0
|
23
|
+
raise ArgumentError, "#{sql_type} do not allow more than one size" if sql_type.match(/(n){0,1}(var){0,1}char/) and @sizes.count > 1
|
24
|
+
raise ArgumentError, "#{sql_type} need at least a precision, but no sizes were given" if ['decimal', 'numeric'].include? sql_type and @sizes.count == 0
|
25
|
+
raise ArgumentError, "defining more than 2 sizes for #{sql_type}" if @sizes.count > 2
|
26
|
+
###
|
27
|
+
@sql_type = sql_type
|
28
|
+
end
|
29
|
+
|
30
|
+
attr_reader :sql_type, :sizes
|
31
|
+
|
32
|
+
# Return true if current type can be stored in other_type without error nor information loss
|
33
|
+
def compatible_with? other_type
|
34
|
+
### Preconditions
|
35
|
+
raise ArgumentError, "other_type is not a Dbsketch::Model::Type" unless other_type.is_a? Dbsketch::Model::Type
|
36
|
+
###
|
37
|
+
# TODO enhance this function (numeric and int may be compatible with particular sizes)
|
38
|
+
compatible = false
|
39
|
+
|
40
|
+
if :numeric == get_category(@sql_type)
|
41
|
+
if :numeric == get_category(other_type.sql_type)
|
42
|
+
compatible = size_compatibile_with? other_type.sizes
|
43
|
+
end
|
44
|
+
elsif :datetime == get_category(@sql_type)
|
45
|
+
compatible = (:datetime == get_category(other_type.sql_type))
|
46
|
+
elsif :string == get_category(@sql_type)
|
47
|
+
compatible = false
|
48
|
+
if :string == get_category(other_type.sql_type)
|
49
|
+
if (@sql_type.match(/^(var){0,1}char$/) and other_type.sql_type.match(/^(var){0,1}char$/)) or
|
50
|
+
(@sql_type.match(/^n(var){0,1}char$/) and other_type.sql_type.match(/^n(var){0,1}char$/))
|
51
|
+
compatible = size_compatibile_with? other_type.sizes
|
52
|
+
end
|
53
|
+
end
|
54
|
+
elsif :boolean == get_category(@sql_type)
|
55
|
+
compatible = (:boolean == get_category(other_type.sql_type))
|
56
|
+
end
|
57
|
+
compatible
|
58
|
+
end
|
59
|
+
|
60
|
+
def category
|
61
|
+
get_category(@sql_type)
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def get_category sql_type
|
67
|
+
if ['decimal', 'int', 'numeric'].include? sql_type
|
68
|
+
:numeric
|
69
|
+
elsif ['datetime', 'datetime2'].include? sql_type
|
70
|
+
:datetime
|
71
|
+
elsif sql_type.match(/(n){0,1}(var){0,1}char/)
|
72
|
+
:string
|
73
|
+
elsif 'bit' == sql_type
|
74
|
+
:boolean
|
75
|
+
else
|
76
|
+
:unknown
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def size_compatibile_with? other_sizes
|
81
|
+
compatible = false
|
82
|
+
if @sizes.empty? and other_sizes.empty?
|
83
|
+
compatible = true
|
84
|
+
elsif not @sizes.empty? and not other_sizes.empty?
|
85
|
+
compatible = (@sizes.first <= other_sizes.first)
|
86
|
+
end
|
87
|
+
compatible
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
end
|