dynamic_migrations 2.2.0 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +28 -4
- data/lib/dynamic_migrations/active_record/migrators/column.rb +21 -0
- data/lib/dynamic_migrations/active_record/migrators/foreign_key_constraint.rb +112 -0
- data/lib/dynamic_migrations/active_record/migrators/function.rb +108 -0
- data/lib/dynamic_migrations/active_record/migrators/index.rb +27 -0
- data/lib/dynamic_migrations/active_record/migrators/schema.rb +21 -0
- data/lib/dynamic_migrations/active_record/migrators/table.rb +21 -0
- data/lib/dynamic_migrations/active_record/migrators/trigger.rb +109 -0
- data/lib/dynamic_migrations/active_record/migrators/unique_constraint.rb +63 -0
- data/lib/dynamic_migrations/active_record/migrators/validation.rb +67 -0
- data/lib/dynamic_migrations/active_record/migrators.rb +64 -0
- data/lib/dynamic_migrations/name_helper.rb +13 -0
- data/lib/dynamic_migrations/postgres/generator/column.rb +92 -0
- data/lib/dynamic_migrations/postgres/generator/foreign_key_constraint.rb +84 -0
- data/lib/dynamic_migrations/postgres/generator/fragment.rb +30 -0
- data/lib/dynamic_migrations/postgres/generator/function.rb +77 -0
- data/lib/dynamic_migrations/postgres/generator/index.rb +101 -0
- data/lib/dynamic_migrations/postgres/generator/primary_key.rb +55 -0
- data/lib/dynamic_migrations/postgres/generator/schema.rb +19 -0
- data/lib/dynamic_migrations/postgres/generator/schema_migrations/section.rb +37 -0
- data/lib/dynamic_migrations/postgres/generator/schema_migrations.rb +92 -0
- data/lib/dynamic_migrations/postgres/generator/table.rb +122 -0
- data/lib/dynamic_migrations/postgres/generator/trigger.rb +101 -0
- data/lib/dynamic_migrations/postgres/generator/unique_constraint.rb +79 -0
- data/lib/dynamic_migrations/postgres/generator/validation.rb +87 -0
- data/lib/dynamic_migrations/postgres/generator.rb +359 -0
- data/lib/dynamic_migrations/postgres/server/database/differences/to_migrations/schemas/functions.rb +68 -0
- data/lib/dynamic_migrations/postgres/server/database/differences/to_migrations/schemas/tables/columns.rb +72 -0
- data/lib/dynamic_migrations/postgres/server/database/differences/to_migrations/schemas/tables/foreign_key_constraints.rb +73 -0
- data/lib/dynamic_migrations/postgres/server/database/differences/to_migrations/schemas/tables/indexes.rb +73 -0
- data/lib/dynamic_migrations/postgres/server/database/differences/to_migrations/schemas/tables/primary_key.rb +49 -0
- data/lib/dynamic_migrations/postgres/server/database/differences/to_migrations/schemas/tables/triggers.rb +73 -0
- data/lib/dynamic_migrations/postgres/server/database/differences/to_migrations/schemas/tables/unique_constraints.rb +73 -0
- data/lib/dynamic_migrations/postgres/server/database/differences/to_migrations/schemas/tables/validations.rb +73 -0
- data/lib/dynamic_migrations/postgres/server/database/differences/to_migrations/schemas/tables.rb +80 -0
- data/lib/dynamic_migrations/postgres/server/database/differences/to_migrations/schemas.rb +48 -0
- data/lib/dynamic_migrations/postgres/server/database/differences/to_migrations.rb +59 -0
- data/lib/dynamic_migrations/postgres/server/database/differences.rb +81 -6
- data/lib/dynamic_migrations/postgres/server/database/keys_and_unique_constraints_loader.rb +35 -9
- data/lib/dynamic_migrations/postgres/server/database/loaded_schemas_builder.rb +49 -8
- data/lib/dynamic_migrations/postgres/server/database/schema/function.rb +69 -0
- data/lib/dynamic_migrations/postgres/server/database/schema/functions.rb +63 -0
- data/lib/dynamic_migrations/postgres/server/database/schema/table/column.rb +4 -0
- data/lib/dynamic_migrations/postgres/server/database/schema/table/columns.rb +1 -1
- data/lib/dynamic_migrations/postgres/server/database/schema/table/foreign_key_constraint.rb +40 -5
- data/lib/dynamic_migrations/postgres/server/database/schema/table/index.rb +23 -9
- data/lib/dynamic_migrations/postgres/server/database/schema/table/primary_key.rb +21 -6
- data/lib/dynamic_migrations/postgres/server/database/schema/table/trigger.rb +151 -0
- data/lib/dynamic_migrations/postgres/server/database/schema/table/triggers.rb +66 -0
- data/lib/dynamic_migrations/postgres/server/database/schema/table/unique_constraint.rb +19 -9
- data/lib/dynamic_migrations/postgres/server/database/schema/table/validation.rb +20 -1
- data/lib/dynamic_migrations/postgres/server/database/schema/table.rb +15 -5
- data/lib/dynamic_migrations/postgres/server/database/schema/tables.rb +63 -0
- data/lib/dynamic_migrations/postgres/server/database/schema.rb +3 -49
- data/lib/dynamic_migrations/postgres/server/database/source.rb +21 -0
- data/lib/dynamic_migrations/postgres/server/database/structure_loader.rb +6 -6
- data/lib/dynamic_migrations/postgres/server/database/triggers_and_functions_loader.rb +131 -0
- data/lib/dynamic_migrations/postgres/server/database/validations_loader.rb +10 -4
- data/lib/dynamic_migrations/postgres/server/database.rb +2 -1
- data/lib/dynamic_migrations/postgres/server.rb +6 -0
- data/lib/dynamic_migrations/postgres.rb +1 -1
- data/lib/dynamic_migrations/version.rb +1 -1
- data/lib/dynamic_migrations.rb +47 -3
- metadata +44 -2
@@ -10,11 +10,12 @@ module DynamicMigrations
|
|
10
10
|
CREATE MATERIALIZED VIEW public.dynamic_migrations_keys_and_unique_constraints_cache as
|
11
11
|
SELECT
|
12
12
|
c.conname AS constraint_name,
|
13
|
+
pg_get_constraintdef(c.oid, true) as constraint_definition,
|
13
14
|
CASE c.contype
|
14
|
-
WHEN 'f'::"char" THEN '
|
15
|
-
WHEN 'p'::"char" THEN '
|
16
|
-
WHEN 'u'::"char" THEN '
|
17
|
-
END
|
15
|
+
WHEN 'f'::"char" THEN 'foreign_key'::text
|
16
|
+
WHEN 'p'::"char" THEN 'primary_key'::text
|
17
|
+
WHEN 'u'::"char" THEN 'unique'::text
|
18
|
+
END AS constraint_type,
|
18
19
|
sch.nspname AS schema_name,
|
19
20
|
tbl.relname AS table_name,
|
20
21
|
ARRAY_AGG(col.attname ORDER BY u.attposition) AS column_names,
|
@@ -24,7 +25,23 @@ module DynamicMigrations
|
|
24
25
|
NULLIF(ARRAY_AGG(f_col.attname ORDER BY f_u.attposition), ARRAY[null]::name[]) AS foreign_column_names,
|
25
26
|
c.condeferrable as deferrable,
|
26
27
|
c.condeferred as initially_deferred,
|
28
|
+
CASE c.confupdtype
|
29
|
+
WHEN 'a'::"char" THEN 'no_action'::text
|
30
|
+
WHEN 'r'::"char" THEN 'restrict'::text
|
31
|
+
WHEN 'c'::"char" THEN 'cascade'::text
|
32
|
+
WHEN 'n'::"char" THEN 'set_null'::text
|
33
|
+
WHEN 'd'::"char" THEN 'set_default'::text
|
34
|
+
END AS on_update,
|
35
|
+
CASE c.confdeltype
|
36
|
+
WHEN 'a'::"char" THEN 'no_action'::text
|
37
|
+
WHEN 'r'::"char" THEN 'restrict'::text
|
38
|
+
WHEN 'c'::"char" THEN 'cascade'::text
|
39
|
+
WHEN 'n'::"char" THEN 'set_null'::text
|
40
|
+
WHEN 'd'::"char" THEN 'set_default'::text
|
41
|
+
END AS on_delete,
|
27
42
|
am.amname as index_type,
|
43
|
+
obj_description(c.oid, 'pg_constraint') as description,
|
44
|
+
-- in case we need to update this query in a later version of DynamicMigrations
|
28
45
|
1 as table_version
|
29
46
|
FROM pg_constraint c
|
30
47
|
LEFT JOIN LATERAL UNNEST(c.conkey)
|
@@ -68,10 +85,10 @@ module DynamicMigrations
|
|
68
85
|
LEFT JOIN pg_am am ON am.oid=index_cls.relam
|
69
86
|
|
70
87
|
WHERE
|
71
|
-
-- only
|
88
|
+
-- only foreign_key, unique or primary_key
|
72
89
|
c.contype in ('f', 'u', 'p')
|
73
90
|
|
74
|
-
GROUP BY constraint_name, constraint_type, condeferrable, condeferred, schema_name, table_name, foreign_schema_name, foreign_table_name, am.amname
|
91
|
+
GROUP BY c.oid, constraint_name, constraint_type, condeferrable, condeferred, schema_name, table_name, foreign_schema_name, foreign_table_name, am.amname
|
75
92
|
ORDER BY schema_name, table_name;
|
76
93
|
SQL
|
77
94
|
connection.exec(<<~SQL)
|
@@ -86,12 +103,12 @@ module DynamicMigrations
|
|
86
103
|
# useful hash representing the keys and indexes of your database
|
87
104
|
def fetch_keys_and_unique_constraints
|
88
105
|
begin
|
89
|
-
rows = connection.
|
106
|
+
rows = connection.exec(<<~SQL)
|
90
107
|
SELECT * FROM public.dynamic_migrations_keys_and_unique_constraints_cache
|
91
108
|
SQL
|
92
109
|
rescue PG::UndefinedTable
|
93
110
|
create_database_keys_and_unique_constraints_cache
|
94
|
-
rows = connection.
|
111
|
+
rows = connection.exec(<<~SQL)
|
95
112
|
SELECT * FROM public.dynamic_migrations_keys_and_unique_constraints_cache
|
96
113
|
SQL
|
97
114
|
end
|
@@ -111,14 +128,20 @@ module DynamicMigrations
|
|
111
128
|
|
112
129
|
column_names = row["column_names"].gsub(/\A\{/, "").gsub(/\}\Z/, "").split(",").map { |column_name| column_name.to_sym }
|
113
130
|
|
114
|
-
|
131
|
+
description = (row["description"] == "") ? nil : row["description"]
|
132
|
+
|
133
|
+
if constraint_type == :foreign_key
|
115
134
|
foreign_schema_name = row["foreign_schema_name"].to_sym
|
116
135
|
foreign_table_name = row["foreign_table_name"].to_sym
|
117
136
|
foreign_column_names = row["foreign_column_names"].gsub(/\A\{/, "").gsub(/\}\Z/, "").split(",").map { |column_name| column_name.to_sym }
|
137
|
+
on_update = row["on_update"].to_sym
|
138
|
+
on_delete = row["on_delete"].to_sym
|
118
139
|
else
|
119
140
|
foreign_schema_name = nil
|
120
141
|
foreign_table_name = nil
|
121
142
|
foreign_column_names = nil
|
143
|
+
on_update = nil
|
144
|
+
on_delete = nil
|
122
145
|
end
|
123
146
|
|
124
147
|
deferrable = row["deferrable"] == "TRUE"
|
@@ -137,6 +160,9 @@ module DynamicMigrations
|
|
137
160
|
foreign_column_names: foreign_column_names,
|
138
161
|
deferrable: deferrable,
|
139
162
|
initially_deferred: initially_deferred,
|
163
|
+
on_update: on_update,
|
164
|
+
on_delete: on_delete,
|
165
|
+
description: description,
|
140
166
|
index_type: index_type
|
141
167
|
}
|
142
168
|
end
|
@@ -8,6 +8,9 @@ module DynamicMigrations
|
|
8
8
|
class UnexpectedConstrintTypeError < StandardError
|
9
9
|
end
|
10
10
|
|
11
|
+
class UnexpectedTriggerSchema < StandardError
|
12
|
+
end
|
13
|
+
|
11
14
|
# recursively process the database and build all the schemas,
|
12
15
|
# tables and columns
|
13
16
|
def recursively_build_schemas_from_database
|
@@ -17,7 +20,7 @@ module DynamicMigrations
|
|
17
20
|
schema_validations = validations[schema_name]
|
18
21
|
|
19
22
|
schema_definition[:tables].each do |table_name, table_definition|
|
20
|
-
table = schema.add_table table_name, table_definition[:description]
|
23
|
+
table = schema.add_table table_name, description: table_definition[:description]
|
21
24
|
table_validations = schema_validations && schema_validations[table_name]
|
22
25
|
|
23
26
|
# add each table column
|
@@ -31,7 +34,7 @@ module DynamicMigrations
|
|
31
34
|
|
32
35
|
# add any validations
|
33
36
|
table_validations&.each do |validation_name, validation_definition|
|
34
|
-
table.add_validation validation_name, validation_definition[:columns], validation_definition[:check_clause]
|
37
|
+
table.add_validation validation_name, validation_definition[:columns], validation_definition[:check_clause], description: validation_definition[:description], deferrable: validation_definition[:deferrable], initially_deferred: validation_definition[:initially_deferred]
|
35
38
|
end
|
36
39
|
end
|
37
40
|
end
|
@@ -45,14 +48,14 @@ module DynamicMigrations
|
|
45
48
|
keys_and_unique_constraints.each do |constraint_type, constraint_definitions|
|
46
49
|
constraint_definitions.each do |constraint_name, constraint_definition|
|
47
50
|
case constraint_type
|
48
|
-
when :
|
49
|
-
table.add_primary_key constraint_name, constraint_definition[:column_names],
|
51
|
+
when :primary_key
|
52
|
+
table.add_primary_key constraint_name, constraint_definition[:column_names], description: constraint_definition[:description]
|
50
53
|
|
51
|
-
when :
|
52
|
-
table.add_foreign_key_constraint constraint_name, constraint_definition[:column_names], constraint_definition[:foreign_schema_name], constraint_definition[:foreign_table_name], constraint_definition[:foreign_column_names], deferrable: constraint_definition[:deferrable], initially_deferred: constraint_definition[:initially_deferred]
|
54
|
+
when :foreign_key
|
55
|
+
table.add_foreign_key_constraint constraint_name, constraint_definition[:column_names], constraint_definition[:foreign_schema_name], constraint_definition[:foreign_table_name], constraint_definition[:foreign_column_names], description: constraint_definition[:description], deferrable: constraint_definition[:deferrable], initially_deferred: constraint_definition[:initially_deferred], on_delete: constraint_definition[:on_delete], on_update: constraint_definition[:on_update]
|
53
56
|
|
54
|
-
when :
|
55
|
-
table.add_unique_constraint constraint_name, constraint_definition[:column_names],
|
57
|
+
when :unique
|
58
|
+
table.add_unique_constraint constraint_name, constraint_definition[:column_names], description: constraint_definition[:description], deferrable: constraint_definition[:deferrable], initially_deferred: constraint_definition[:initially_deferred]
|
56
59
|
|
57
60
|
else
|
58
61
|
raise UnexpectedConstrintTypeError, constraint_type
|
@@ -61,6 +64,44 @@ module DynamicMigrations
|
|
61
64
|
end
|
62
65
|
end
|
63
66
|
end
|
67
|
+
|
68
|
+
# add all functions and triggers (functions first, because the triggers are dependent on them)
|
69
|
+
fetch_triggers_and_functions.each do |schema_name, schema_definition|
|
70
|
+
schema_definition.each do |table_name, triggers|
|
71
|
+
# the table that this trigger works on
|
72
|
+
table = loaded_schema(schema_name).table(table_name)
|
73
|
+
# all the triggers for this table
|
74
|
+
triggers.each do |trigger_name, trigger_definition|
|
75
|
+
# the trigger and function can be in different schemas
|
76
|
+
function_schema = loaded_schema(trigger_definition[:function_schema])
|
77
|
+
trigger_schema = loaded_schema(trigger_definition[:trigger_schema])
|
78
|
+
|
79
|
+
if trigger_schema != table.schema
|
80
|
+
raise UnexpectedTriggerSchema, "Trigger schema `#{trigger_schema.name}` does not match table schema `#{table.schema.name}`"
|
81
|
+
end
|
82
|
+
|
83
|
+
# if this function does not exist locally, then add it
|
84
|
+
unless function_schema.has_function?(trigger_definition[:function_name])
|
85
|
+
function_schema.add_function trigger_definition[:function_name], trigger_definition[:function_definition], description: trigger_definition[:function_description]
|
86
|
+
end
|
87
|
+
|
88
|
+
# get the function
|
89
|
+
function = function_schema.function(trigger_definition[:function_name])
|
90
|
+
|
91
|
+
# create the trigger
|
92
|
+
table.add_trigger trigger_name, action_timing: trigger_definition[:action_timing],
|
93
|
+
event_manipulation: trigger_definition[:event_manipulation],
|
94
|
+
action_order: trigger_definition[:action_order],
|
95
|
+
action_statement: trigger_definition[:action_statement],
|
96
|
+
action_orientation: trigger_definition[:action_orientation],
|
97
|
+
function: function,
|
98
|
+
action_condition: trigger_definition[:action_condition],
|
99
|
+
action_reference_old_table: trigger_definition[:action_reference_old_table],
|
100
|
+
action_reference_new_table: trigger_definition[:action_reference_new_table],
|
101
|
+
description: trigger_definition[:description]
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
64
105
|
end
|
65
106
|
end
|
66
107
|
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DynamicMigrations
|
4
|
+
module Postgres
|
5
|
+
class Server
|
6
|
+
class Database
|
7
|
+
class Schema
|
8
|
+
# This class represents a postgres function.
|
9
|
+
class Function < Source
|
10
|
+
class ExpectedSchemaError < StandardError
|
11
|
+
end
|
12
|
+
|
13
|
+
class ExpectedDefinitionError < StandardError
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_reader :schema
|
17
|
+
attr_reader :name
|
18
|
+
attr_reader :definition
|
19
|
+
attr_reader :description
|
20
|
+
attr_reader :triggers
|
21
|
+
|
22
|
+
# initialize a new object to represent a postgres function
|
23
|
+
def initialize source, schema, name, definition, description: nil
|
24
|
+
super source
|
25
|
+
|
26
|
+
@triggers ||= []
|
27
|
+
|
28
|
+
raise ExpectedSchemaError, schema unless schema.is_a? Schema
|
29
|
+
@schema = schema
|
30
|
+
|
31
|
+
raise ExpectedSymbolError, name unless name.is_a? Symbol
|
32
|
+
@name = name
|
33
|
+
|
34
|
+
unless definition.is_a?(String) && definition.strip != ""
|
35
|
+
raise ExpectedDefinitionError, definition
|
36
|
+
end
|
37
|
+
@definition = definition
|
38
|
+
|
39
|
+
unless description.nil?
|
40
|
+
raise ExpectedStringError, description unless description.is_a? String
|
41
|
+
@description = description
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# returns true if this function has a description, otehrwise false
|
46
|
+
def has_description?
|
47
|
+
!@description.nil?
|
48
|
+
end
|
49
|
+
|
50
|
+
# returns all the triggers which are associated with this function
|
51
|
+
def add_trigger trigger
|
52
|
+
# this should never happen, but adding it just in case
|
53
|
+
unless trigger.source == source
|
54
|
+
raise "Internal error - trigger source `#{trigger.source}` does not match function source `#{source}`"
|
55
|
+
end
|
56
|
+
@triggers << trigger
|
57
|
+
end
|
58
|
+
|
59
|
+
def differences_descriptions other_function
|
60
|
+
method_differences_descriptions other_function, [
|
61
|
+
:definition
|
62
|
+
]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DynamicMigrations
|
4
|
+
module Postgres
|
5
|
+
class Server
|
6
|
+
class Database
|
7
|
+
class Schema < Source
|
8
|
+
module Functions
|
9
|
+
class FunctionAlreadyExistsError < StandardError
|
10
|
+
end
|
11
|
+
|
12
|
+
class FunctionDoesNotExistError < StandardError
|
13
|
+
end
|
14
|
+
|
15
|
+
# create and add a new function from a provided function name
|
16
|
+
def add_function function_name, definition, description: nil
|
17
|
+
raise ExpectedSymbolError, function_name unless function_name.is_a? Symbol
|
18
|
+
if has_function? function_name
|
19
|
+
raise(FunctionAlreadyExistsError, "Function #{function_name} already exists")
|
20
|
+
end
|
21
|
+
included_target = self
|
22
|
+
if included_target.is_a? Schema
|
23
|
+
new_function = @functions[function_name] = Function.new source, included_target, function_name, definition, description: description
|
24
|
+
else
|
25
|
+
raise ModuleIncludedIntoUnexpectedTargetError, included_target
|
26
|
+
end
|
27
|
+
# sort the hash so that the functions are in alphabetical order by name
|
28
|
+
sorted_functions = {}
|
29
|
+
@functions.keys.sort.each do |function_name|
|
30
|
+
sorted_functions[function_name] = @functions[function_name]
|
31
|
+
end
|
32
|
+
@functions = sorted_functions
|
33
|
+
# return the new function
|
34
|
+
new_function
|
35
|
+
end
|
36
|
+
|
37
|
+
# return a function by its name, raises an error if the function does not exist
|
38
|
+
def function function_name
|
39
|
+
raise ExpectedSymbolError, function_name unless function_name.is_a? Symbol
|
40
|
+
raise FunctionDoesNotExistError unless has_function? function_name
|
41
|
+
@functions[function_name]
|
42
|
+
end
|
43
|
+
|
44
|
+
# returns true/false representing if a function with the provided name exists
|
45
|
+
def has_function? function_name
|
46
|
+
raise ExpectedSymbolError, function_name unless function_name.is_a? Symbol
|
47
|
+
@functions.key? function_name
|
48
|
+
end
|
49
|
+
|
50
|
+
# returns an array of all functions in the schema
|
51
|
+
def functions
|
52
|
+
@functions.values
|
53
|
+
end
|
54
|
+
|
55
|
+
def functions_hash
|
56
|
+
@functions
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -18,7 +18,7 @@ module DynamicMigrations
|
|
18
18
|
# error if the column does not exist
|
19
19
|
def column name
|
20
20
|
raise ExpectedSymbolError, name unless name.is_a? Symbol
|
21
|
-
raise ColumnDoesNotExistError unless has_column? name
|
21
|
+
raise ColumnDoesNotExistError, name unless has_column? name
|
22
22
|
@columns[name]
|
23
23
|
end
|
24
24
|
|
@@ -20,14 +20,20 @@ module DynamicMigrations
|
|
20
20
|
class DuplicateColumnError < StandardError
|
21
21
|
end
|
22
22
|
|
23
|
+
class UnexpectedReferentialActionError < StandardError
|
24
|
+
end
|
25
|
+
|
23
26
|
attr_reader :table
|
24
27
|
attr_reader :foreign_table
|
25
28
|
attr_reader :name
|
26
29
|
attr_reader :deferrable
|
27
30
|
attr_reader :initially_deferred
|
31
|
+
attr_reader :on_delete
|
32
|
+
attr_reader :on_update
|
33
|
+
attr_reader :description
|
28
34
|
|
29
35
|
# initialize a new object to represent a foreign_key_constraint in a postgres table
|
30
|
-
def initialize source, table, columns, foreign_table, foreign_columns, name, deferrable: false, initially_deferred: false
|
36
|
+
def initialize source, table, columns, foreign_table, foreign_columns, name, description: nil, deferrable: false, initially_deferred: false, on_delete: :no_action, on_update: :no_action
|
31
37
|
super source
|
32
38
|
|
33
39
|
raise ExpectedTableError, table unless table.is_a? Table
|
@@ -64,11 +70,27 @@ module DynamicMigrations
|
|
64
70
|
raise ExpectedSymbolError, name unless name.is_a? Symbol
|
65
71
|
@name = name
|
66
72
|
|
73
|
+
unless description.nil?
|
74
|
+
raise ExpectedStringError, description unless description.is_a? String
|
75
|
+
@description = description
|
76
|
+
end
|
77
|
+
|
67
78
|
raise ExpectedBooleanError, deferrable unless [true, false].include?(deferrable)
|
68
79
|
@deferrable = deferrable
|
69
80
|
|
70
81
|
raise ExpectedBooleanError, initially_deferred unless [true, false].include?(initially_deferred)
|
71
82
|
@initially_deferred = initially_deferred
|
83
|
+
|
84
|
+
raise UnexpectedReferentialActionError, on_delete unless [:no_action, :restrict, :cascade, :set_null, :set_default].include?(on_delete)
|
85
|
+
@on_delete = on_delete
|
86
|
+
|
87
|
+
raise UnexpectedReferentialActionError, on_update unless [:no_action, :restrict, :cascade, :set_null, :set_default].include?(on_update)
|
88
|
+
@on_update = on_update
|
89
|
+
end
|
90
|
+
|
91
|
+
# return true if this has a description, otherwise false
|
92
|
+
def has_description?
|
93
|
+
!@description.nil?
|
72
94
|
end
|
73
95
|
|
74
96
|
def columns
|
@@ -83,10 +105,6 @@ module DynamicMigrations
|
|
83
105
|
@foreign_columns.values
|
84
106
|
end
|
85
107
|
|
86
|
-
def foreign_column_names
|
87
|
-
@foreign_columns.keys
|
88
|
-
end
|
89
|
-
|
90
108
|
def foreign_schema_name
|
91
109
|
@foreign_table.schema.name
|
92
110
|
end
|
@@ -95,6 +113,23 @@ module DynamicMigrations
|
|
95
113
|
@foreign_table.name
|
96
114
|
end
|
97
115
|
|
116
|
+
def foreign_column_names
|
117
|
+
@foreign_columns.keys
|
118
|
+
end
|
119
|
+
|
120
|
+
def differences_descriptions other_foreign_key_constraint
|
121
|
+
method_differences_descriptions other_foreign_key_constraint, [
|
122
|
+
:column_names,
|
123
|
+
:foreign_schema_name,
|
124
|
+
:foreign_table_name,
|
125
|
+
:foreign_column_names,
|
126
|
+
:deferrable,
|
127
|
+
:initially_deferred,
|
128
|
+
:on_delete,
|
129
|
+
:on_update
|
130
|
+
]
|
131
|
+
end
|
132
|
+
|
98
133
|
private
|
99
134
|
|
100
135
|
# used internally to set the columns from this objects initialize method
|
@@ -35,13 +35,12 @@ module DynamicMigrations
|
|
35
35
|
attr_reader :unique
|
36
36
|
attr_reader :where
|
37
37
|
attr_reader :type
|
38
|
-
attr_reader :deferrable
|
39
|
-
attr_reader :initially_deferred
|
40
38
|
attr_reader :order
|
41
39
|
attr_reader :nulls_position
|
40
|
+
attr_reader :description
|
42
41
|
|
43
42
|
# initialize a new object to represent a index in a postgres table
|
44
|
-
def initialize source, table, columns, name, unique: false, where: nil, type: :btree,
|
43
|
+
def initialize source, table, columns, name, description: nil, unique: false, where: nil, type: :btree, include_columns: [], order: :asc, nulls_position: :last
|
45
44
|
super source
|
46
45
|
raise ExpectedTableError, table unless table.is_a? Table
|
47
46
|
@table = table
|
@@ -60,6 +59,11 @@ module DynamicMigrations
|
|
60
59
|
raise ExpectedSymbolError, name unless name.is_a? Symbol
|
61
60
|
@name = name
|
62
61
|
|
62
|
+
unless description.nil?
|
63
|
+
raise ExpectedStringError, description unless description.is_a? String
|
64
|
+
@description = description
|
65
|
+
end
|
66
|
+
|
63
67
|
raise ExpectedBooleanError, unique unless [true, false].include?(unique)
|
64
68
|
@unique = unique
|
65
69
|
|
@@ -71,12 +75,6 @@ module DynamicMigrations
|
|
71
75
|
raise UnexpectedIndexTypeError, type unless INDEX_TYPES.include?(type)
|
72
76
|
@type = type
|
73
77
|
|
74
|
-
raise ExpectedBooleanError, deferrable unless [true, false].include?(deferrable)
|
75
|
-
@deferrable = deferrable
|
76
|
-
|
77
|
-
raise ExpectedBooleanError, initially_deferred unless [true, false].include?(initially_deferred)
|
78
|
-
@initially_deferred = initially_deferred
|
79
|
-
|
80
78
|
# assert that the include_columns is an array (it's optional, so can be an empty array)
|
81
79
|
unless include_columns.is_a?(Array)
|
82
80
|
raise ExpectedArrayOfColumnsError
|
@@ -93,6 +91,11 @@ module DynamicMigrations
|
|
93
91
|
@nulls_position = nulls_position
|
94
92
|
end
|
95
93
|
|
94
|
+
# return true if this has a description, otherwise false
|
95
|
+
def has_description?
|
96
|
+
!@description.nil?
|
97
|
+
end
|
98
|
+
|
96
99
|
# return an array of this indexes columns
|
97
100
|
def columns
|
98
101
|
@columns.values
|
@@ -111,6 +114,17 @@ module DynamicMigrations
|
|
111
114
|
@include_columns.keys
|
112
115
|
end
|
113
116
|
|
117
|
+
def differences_descriptions other_index
|
118
|
+
method_differences_descriptions other_index, [
|
119
|
+
:column_names,
|
120
|
+
:unique,
|
121
|
+
:where,
|
122
|
+
:type,
|
123
|
+
:order,
|
124
|
+
:nulls_position
|
125
|
+
]
|
126
|
+
end
|
127
|
+
|
114
128
|
private
|
115
129
|
|
116
130
|
# used internally to set the columns from this objects initialize method
|
@@ -8,8 +8,6 @@ module DynamicMigrations
|
|
8
8
|
class Table
|
9
9
|
# This class represents a postgres table primary_key
|
10
10
|
class PrimaryKey < Source
|
11
|
-
INDEX_TYPES = [:btree, :gin]
|
12
|
-
|
13
11
|
class ExpectedTableError < StandardError
|
14
12
|
end
|
15
13
|
|
@@ -24,10 +22,10 @@ module DynamicMigrations
|
|
24
22
|
|
25
23
|
attr_reader :table
|
26
24
|
attr_reader :name
|
27
|
-
attr_reader :
|
25
|
+
attr_reader :description
|
28
26
|
|
29
27
|
# initialize a new object to represent a primary_key in a postgres table
|
30
|
-
def initialize source, table, columns, name,
|
28
|
+
def initialize source, table, columns, name, description: nil
|
31
29
|
super source
|
32
30
|
raise ExpectedTableError, table unless table.is_a? Table
|
33
31
|
@table = table
|
@@ -45,8 +43,15 @@ module DynamicMigrations
|
|
45
43
|
raise ExpectedSymbolError, name unless name.is_a? Symbol
|
46
44
|
@name = name
|
47
45
|
|
48
|
-
|
49
|
-
|
46
|
+
unless description.nil?
|
47
|
+
raise ExpectedStringError, description unless description.is_a? String
|
48
|
+
@description = description
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# return true if this has a description, otherwise false
|
53
|
+
def has_description?
|
54
|
+
!@description.nil?
|
50
55
|
end
|
51
56
|
|
52
57
|
# return an array of this primary keys columns
|
@@ -54,6 +59,16 @@ module DynamicMigrations
|
|
54
59
|
@columns.values
|
55
60
|
end
|
56
61
|
|
62
|
+
def column_names
|
63
|
+
@columns.keys
|
64
|
+
end
|
65
|
+
|
66
|
+
def differences_descriptions other_primary_key
|
67
|
+
method_differences_descriptions other_primary_key, [
|
68
|
+
:column_names
|
69
|
+
]
|
70
|
+
end
|
71
|
+
|
57
72
|
private
|
58
73
|
|
59
74
|
# used internally to set the columns from this objects initialize method
|