dynamic_migrations 2.0.0 → 2.2.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 +14 -0
- data/lib/dynamic_migrations/postgres/server/database/differences.rb +1 -10
- data/lib/dynamic_migrations/postgres/server/database/loaded_schemas_builder.rb +1 -18
- data/lib/dynamic_migrations/postgres/server/database/schema/table/column.rb +2 -33
- data/lib/dynamic_migrations/postgres/server/database/structure_loader.rb +16 -106
- data/lib/dynamic_migrations/version.rb +1 -1
- data/lib/dynamic_migrations.rb +0 -1
- metadata +2 -3
- data/lib/dynamic_migrations/postgres/data_types.rb +0 -273
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b27309525226b33bbcff1b08b3361347e93cff1d182f5620debbe3195b5c1d88
|
4
|
+
data.tar.gz: 670213a55b129e2518e793bc5314fe522f72645da50d5b32355cacfec5cff8fb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4227acc9480ac7c9022a0e1f9473627d3b7ab11611d164582b9edf9049928a4a36c1292ce5f43f9f627f9c2c4968e6b8bb4da1ed0dde11b41cd431d6d61022a6
|
7
|
+
data.tar.gz: ef666cf1f797e262469fc080524726d3e70e1f1a52a4dfdb08bc9b9fbc5925671b25cead8013555618ade984bf603e86812ea8689cba2e59a5dd1a8d411664dc
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,19 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [2.2.0](https://github.com/craigulliott/dynamic_migrations/compare/v2.1.0...v2.2.0) (2023-07-31)
|
4
|
+
|
5
|
+
|
6
|
+
### Features
|
7
|
+
|
8
|
+
* using postgres shorthand names such as `numeric(12,2)` for types, and removing the additional column metadata ([86d0113](https://github.com/craigulliott/dynamic_migrations/commit/86d0113aabd4350f278164d18e3c0a611fcf5595))
|
9
|
+
|
10
|
+
## [2.1.0](https://github.com/craigulliott/dynamic_migrations/compare/v2.0.0...v2.1.0) (2023-07-31)
|
11
|
+
|
12
|
+
|
13
|
+
### Features
|
14
|
+
|
15
|
+
* apply default column values to column data types ([6911c5f](https://github.com/craigulliott/dynamic_migrations/commit/6911c5f2026b47ef2e9f7bc529f7ff0d8f098700))
|
16
|
+
|
3
17
|
## [2.0.0](https://github.com/craigulliott/dynamic_migrations/compare/v1.1.1...v2.0.0) (2023-07-27)
|
4
18
|
|
5
19
|
|
@@ -130,16 +130,7 @@ module DynamicMigrations
|
|
130
130
|
:null,
|
131
131
|
:default,
|
132
132
|
:description,
|
133
|
-
:
|
134
|
-
:character_octet_length,
|
135
|
-
:numeric_precision,
|
136
|
-
:numeric_precision_radix,
|
137
|
-
:numeric_scale,
|
138
|
-
:datetime_precision,
|
139
|
-
:interval_type,
|
140
|
-
:udt_schema,
|
141
|
-
:udt_name,
|
142
|
-
:updatable
|
133
|
+
:interval_type
|
143
134
|
]
|
144
135
|
end
|
145
136
|
# look for any columns in the comparison list which were not in the base list
|
@@ -22,28 +22,11 @@ module DynamicMigrations
|
|
22
22
|
|
23
23
|
# add each table column
|
24
24
|
table_definition[:columns].each do |column_name, column_definition|
|
25
|
-
# we only need these for arrays and user-defined types
|
26
|
-
# (user-defined is usually ENUMS)
|
27
|
-
if [:ARRAY, :"USER-DEFINED"].include? column_definition[:data_type]
|
28
|
-
udt_schema = column_definition[:udt_schema]
|
29
|
-
udt_name = column_definition[:udt_name]
|
30
|
-
else
|
31
|
-
udt_schema = nil
|
32
|
-
udt_name = nil
|
33
|
-
end
|
34
|
-
|
35
25
|
table.add_column column_name, column_definition[:data_type],
|
36
26
|
null: column_definition[:null],
|
37
27
|
default: column_definition[:default],
|
38
28
|
description: column_definition[:description],
|
39
|
-
|
40
|
-
character_octet_length: column_definition[:character_octet_length],
|
41
|
-
numeric_precision: column_definition[:numeric_precision],
|
42
|
-
numeric_precision_radix: column_definition[:numeric_precision_radix],
|
43
|
-
numeric_scale: column_definition[:numeric_scale],
|
44
|
-
datetime_precision: column_definition[:datetime_precision],
|
45
|
-
udt_schema: udt_schema,
|
46
|
-
udt_name: udt_name
|
29
|
+
interval_type: column_definition[:interval_type]
|
47
30
|
end
|
48
31
|
|
49
32
|
# add any validations
|
@@ -13,23 +13,14 @@ module DynamicMigrations
|
|
13
13
|
|
14
14
|
attr_reader :table
|
15
15
|
attr_reader :name
|
16
|
+
attr_reader :data_type
|
16
17
|
attr_reader :description
|
17
18
|
attr_reader :null
|
18
19
|
attr_reader :default
|
19
|
-
attr_reader :data_type
|
20
|
-
attr_reader :character_maximum_length
|
21
|
-
attr_reader :character_octet_length
|
22
|
-
attr_reader :numeric_precision
|
23
|
-
attr_reader :numeric_precision_radix
|
24
|
-
attr_reader :numeric_scale
|
25
|
-
attr_reader :datetime_precision
|
26
20
|
attr_reader :interval_type
|
27
|
-
attr_reader :udt_schema
|
28
|
-
attr_reader :udt_name
|
29
|
-
attr_reader :updatable
|
30
21
|
|
31
22
|
# initialize a new object to represent a column in a postgres table
|
32
|
-
def initialize source, table, name, data_type, null: true, default: nil, description: nil,
|
23
|
+
def initialize source, table, name, data_type, null: true, default: nil, description: nil, interval_type: nil
|
33
24
|
super source
|
34
25
|
raise ExpectedTableError, table unless table.is_a? Table
|
35
26
|
@table = table
|
@@ -38,9 +29,7 @@ module DynamicMigrations
|
|
38
29
|
@name = name
|
39
30
|
|
40
31
|
@data_type = data_type
|
41
|
-
|
42
32
|
@null = null
|
43
|
-
|
44
33
|
@default = default
|
45
34
|
|
46
35
|
unless description.nil?
|
@@ -48,27 +37,7 @@ module DynamicMigrations
|
|
48
37
|
@description = description
|
49
38
|
end
|
50
39
|
|
51
|
-
DataTypes.validate_column_properties!(data_type,
|
52
|
-
character_maximum_length: character_maximum_length,
|
53
|
-
character_octet_length: character_octet_length,
|
54
|
-
numeric_precision: numeric_precision,
|
55
|
-
numeric_precision_radix: numeric_precision_radix,
|
56
|
-
numeric_scale: numeric_scale,
|
57
|
-
datetime_precision: datetime_precision,
|
58
|
-
interval_type: interval_type,
|
59
|
-
udt_schema: udt_schema,
|
60
|
-
udt_name: udt_name)
|
61
|
-
|
62
|
-
@character_maximum_length = character_maximum_length
|
63
|
-
@character_octet_length = character_octet_length
|
64
|
-
@numeric_precision = numeric_precision
|
65
|
-
@numeric_precision_radix = numeric_precision_radix
|
66
|
-
@numeric_scale = numeric_scale
|
67
|
-
@datetime_precision = datetime_precision
|
68
40
|
@interval_type = interval_type
|
69
|
-
@udt_schema = udt_schema
|
70
|
-
@udt_name = udt_name
|
71
|
-
@updatable = updatable
|
72
41
|
end
|
73
42
|
|
74
43
|
# return true if this column has a description, otherwise false
|
@@ -7,88 +7,41 @@ module DynamicMigrations
|
|
7
7
|
module StructureLoader
|
8
8
|
def create_database_structure_cache
|
9
9
|
connection.exec(<<~SQL)
|
10
|
-
CREATE MATERIALIZED VIEW public.dynamic_migrations_structure_cache
|
10
|
+
CREATE MATERIALIZED VIEW public.dynamic_migrations_structure_cache AS
|
11
11
|
SELECT
|
12
12
|
-- Name of the schema containing the table
|
13
13
|
schemata.schema_name,
|
14
14
|
-- Name of the table
|
15
15
|
tables.table_name,
|
16
16
|
-- The comment which has been added to the table (if any)
|
17
|
-
table_description.description
|
17
|
+
table_description.description AS table_description,
|
18
18
|
-- Name of the column
|
19
19
|
columns.column_name,
|
20
20
|
-- The comment which has been added to the column (if any)
|
21
|
-
column_description.description
|
21
|
+
column_description.description AS column_description,
|
22
22
|
-- Default expression of the column
|
23
23
|
columns.column_default,
|
24
24
|
-- YES if the column is possibly nullable, NO if
|
25
25
|
-- it is known not nullable
|
26
26
|
columns.is_nullable,
|
27
|
-
--
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
-- If data_type identifies a character or bit string type,
|
37
|
-
-- the declared maximum length; null for all other data
|
38
|
-
-- types or if no maximum length was declared.
|
39
|
-
columns.character_maximum_length,
|
40
|
-
-- If data_type identifies a character type, the maximum
|
41
|
-
-- possible length in octets (bytes) of a datum; null for
|
42
|
-
-- all other data types. The maximum octet length depends
|
43
|
-
-- on the declared character maximum length (see above)
|
44
|
-
-- and the server encoding.
|
45
|
-
columns.character_octet_length,
|
46
|
-
-- If data_type identifies a numeric type, this column
|
47
|
-
-- contains the (declared or implicit) precision of the type
|
48
|
-
-- for this column. The precision indicates the number of
|
49
|
-
-- significant digits. It can be expressed in decimal (base 10)
|
50
|
-
-- or binary (base 2) terms, as specified in the column
|
51
|
-
-- numeric_precision_radix. For all other data types, this
|
52
|
-
-- column is null.
|
53
|
-
columns.numeric_precision,
|
54
|
-
-- If data_type identifies a numeric type, this column indicates
|
55
|
-
-- in which base the values in the columns numeric_precision and
|
56
|
-
-- numeric_scale are expressed. The value is either 2 or 10. For
|
57
|
-
-- all other data types, this column is null.
|
58
|
-
columns.numeric_precision_radix,
|
59
|
-
-- If data_type identifies an exact numeric type, this column
|
60
|
-
-- contains the (declared or implicit) scale of the type for this
|
61
|
-
-- column. The scale indicates the number of significant digits to
|
62
|
-
-- the right of the decimal point. It can be expressed in decimal
|
63
|
-
-- (base 10) or binary (base 2) terms, as specified in the column
|
64
|
-
-- numeric_precision_radix. For all other data types, this column
|
65
|
-
-- is null.
|
66
|
-
columns.numeric_scale,
|
67
|
-
-- If data_type identifies a date, time, timestamp, or interval
|
68
|
-
-- type, this column contains the (declared or implicit) fractional
|
69
|
-
-- seconds precision of the type for this column, that is, the
|
70
|
-
-- number of decimal digits maintained following the decimal point
|
71
|
-
-- in the seconds value. For all other data types, this column is
|
72
|
-
-- null.
|
73
|
-
columns.datetime_precision,
|
27
|
+
-- The formatted data type (such as integer, char(5) or numeric(12,2)[])
|
28
|
+
CASE
|
29
|
+
WHEN tables.table_name IS NOT NULL THEN
|
30
|
+
(
|
31
|
+
SELECT format_type(atttypid,atttypmod) FROM pg_attribute a
|
32
|
+
WHERE a.attrelid = concat('"', schemata.schema_name, '"', '.', '"', tables.table_name, '"')::regclass
|
33
|
+
AND attnum = columns.ordinal_position
|
34
|
+
)
|
35
|
+
END AS data_type,
|
74
36
|
-- If data_type identifies an interval type, this column contains
|
75
37
|
-- the specification which fields the intervals include for this
|
76
38
|
-- column, e.g., YEAR TO MONTH, DAY TO SECOND, etc. If no field
|
77
39
|
-- restrictions were specified (that is, the interval accepts all
|
78
|
-
|
79
|
-
columns.interval_type
|
80
|
-
-- Name of the schema that the column data type (the underlying
|
81
|
-
--type of the domain, if applicable) is defined in
|
82
|
-
columns.udt_schema,
|
83
|
-
-- Name of the column data type (the underlying type of the domain,
|
84
|
-
-- if applicable)
|
85
|
-
columns.udt_name,
|
86
|
-
-- YES if the column is updatable, NO if not (Columns in base tables
|
87
|
-
-- are always updatable, columns in views not necessarily)
|
88
|
-
columns.is_updatable
|
40
|
+
-- fields), and for all other data types, this field is null.
|
41
|
+
columns.interval_type
|
89
42
|
FROM information_schema.schemata
|
90
43
|
LEFT JOIN information_schema.tables ON schemata.schema_name = tables.table_schema AND left(tables.table_name, 3) != 'pg_'
|
91
|
-
LEFT JOIN information_schema.columns ON tables.table_name = columns.table_name
|
44
|
+
LEFT JOIN information_schema.columns ON tables.table_name = columns.table_name AND schemata.schema_name = columns.table_schema
|
92
45
|
-- required for the column and table description/comment joins
|
93
46
|
LEFT JOIN pg_catalog.pg_statio_all_tables ON pg_statio_all_tables.schemaname = schemata.schema_name AND pg_statio_all_tables.relname = tables.table_name
|
94
47
|
-- required for the table description/comment
|
@@ -142,16 +95,7 @@ module DynamicMigrations
|
|
142
95
|
column[:null] = row["is_nullable"] == "YES"
|
143
96
|
column[:default] = row["column_default"]
|
144
97
|
column[:description] = row["column_description"]
|
145
|
-
column[:character_maximum_length] = row["character_maximum_length"].nil? ? nil : row["character_maximum_length"].to_i
|
146
|
-
column[:character_octet_length] = row["character_octet_length"].nil? ? nil : row["character_octet_length"].to_i
|
147
|
-
column[:numeric_precision] = row["numeric_precision"].nil? ? nil : row["numeric_precision"].to_i
|
148
|
-
column[:numeric_precision_radix] = row["numeric_precision_radix"].nil? ? nil : row["numeric_precision_radix"].to_i
|
149
|
-
column[:numeric_scale] = row["numeric_scale"].nil? ? nil : row["numeric_scale"].to_i
|
150
|
-
column[:datetime_precision] = row["datetime_precision"].nil? ? nil : row["datetime_precision"].to_i
|
151
98
|
column[:interval_type] = row["interval_type"].nil? ? nil : row["interval_type"].to_sym
|
152
|
-
column[:udt_schema] = row["udt_schema"].to_sym
|
153
|
-
column[:udt_name] = row["udt_name"].to_sym
|
154
|
-
column[:updatable] = row["is_updatable"] == "YES"
|
155
99
|
end
|
156
100
|
end
|
157
101
|
end
|
@@ -168,29 +112,11 @@ module DynamicMigrations
|
|
168
112
|
table = schema.add_table table_name, table_definition[:description]
|
169
113
|
|
170
114
|
table_definition[:columns].each do |column_name, column_definition|
|
171
|
-
# we only need these for arrays and user-defined types
|
172
|
-
# (user-defined is usually ENUMS)
|
173
|
-
if [:ARRAY, :"USER-DEFINED"].include? column_definition[:data_type]
|
174
|
-
udt_schema = column_definition[:udt_schema]
|
175
|
-
udt_name = column_definition[:udt_name]
|
176
|
-
else
|
177
|
-
udt_schema = nil
|
178
|
-
udt_name = nil
|
179
|
-
end
|
180
|
-
|
181
115
|
table.add_column column_name, column_definition[:data_type],
|
182
116
|
null: column_definition[:null],
|
183
117
|
default: column_definition[:default],
|
184
118
|
description: column_definition[:description],
|
185
|
-
|
186
|
-
character_octet_length: column_definition[:character_octet_length],
|
187
|
-
numeric_precision: column_definition[:numeric_precision],
|
188
|
-
numeric_precision_radix: column_definition[:numeric_precision_radix],
|
189
|
-
numeric_scale: column_definition[:numeric_scale],
|
190
|
-
datetime_precision: column_definition[:datetime_precision],
|
191
|
-
udt_schema: udt_schema,
|
192
|
-
udt_name: udt_name,
|
193
|
-
updatable: column_definition[:updatable]
|
119
|
+
interval_type: column_definition[:interval_type]
|
194
120
|
end
|
195
121
|
end
|
196
122
|
end
|
@@ -219,22 +145,6 @@ module DynamicMigrations
|
|
219
145
|
table_names.reject! { |table_name| table_name.start_with? "pg_" }
|
220
146
|
table_names.sort
|
221
147
|
end
|
222
|
-
|
223
|
-
# returns a list of columns definitions for the provided table
|
224
|
-
def fetch_columns schema_name, table_name
|
225
|
-
rows = connection.exec_params(<<-SQL, [schema_name.to_s, table_name.to_s])
|
226
|
-
SELECT column_name, is_nullable, data_type, character_octet_length, column_default, numeric_precision, numeric_precision_radix, numeric_scale, udt_schema, udt_name
|
227
|
-
FROM information_schema.columns
|
228
|
-
WHERE table_schema = $1
|
229
|
-
AND table_name = $2;
|
230
|
-
SQL
|
231
|
-
rows.map do |row|
|
232
|
-
{
|
233
|
-
column_name: row["column_name"].to_sym,
|
234
|
-
type: row["data_type"].to_sym
|
235
|
-
}
|
236
|
-
end
|
237
|
-
end
|
238
148
|
end
|
239
149
|
end
|
240
150
|
end
|
data/lib/dynamic_migrations.rb
CHANGED
@@ -36,7 +36,6 @@ require "dynamic_migrations/postgres/server/database/schema/table/unique_constra
|
|
36
36
|
|
37
37
|
require "dynamic_migrations/postgres/server"
|
38
38
|
require "dynamic_migrations/postgres/connections"
|
39
|
-
require "dynamic_migrations/postgres/data_types"
|
40
39
|
|
41
40
|
module DynamicMigrations
|
42
41
|
class Error < StandardError
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dynamic_migrations
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Craig Ulliott
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-07-
|
11
|
+
date: 2023-07-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pg
|
@@ -73,7 +73,6 @@ files:
|
|
73
73
|
- lib/dynamic_migrations/module_included_into_unexpected_target_error.rb
|
74
74
|
- lib/dynamic_migrations/postgres.rb
|
75
75
|
- lib/dynamic_migrations/postgres/connections.rb
|
76
|
-
- lib/dynamic_migrations/postgres/data_types.rb
|
77
76
|
- lib/dynamic_migrations/postgres/server.rb
|
78
77
|
- lib/dynamic_migrations/postgres/server/database.rb
|
79
78
|
- lib/dynamic_migrations/postgres/server/database/configured_schemas.rb
|
@@ -1,273 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module DynamicMigrations
|
4
|
-
module Postgres
|
5
|
-
module DataTypes
|
6
|
-
class MissingRequiredAttributeError < StandardError
|
7
|
-
def initialize data_type, attribute
|
8
|
-
super "Missing required attribute `#{attribute}` for data_type `#{data_type}`"
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
class UnexpectedPropertyError < StandardError
|
13
|
-
def initialize data_type, attribute, value
|
14
|
-
super "Unexpected property `#{attribute}` with value `#{value}` for data_type `#{data_type}`"
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
class UnsupportedTypeError < StandardError
|
19
|
-
def initialize data_type
|
20
|
-
super "Unsupported type `#{data_type}`"
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
DATA_TYPES = {
|
25
|
-
ARRAY: {
|
26
|
-
description: "binary data (“byte array”)",
|
27
|
-
required: [
|
28
|
-
:udt_schema,
|
29
|
-
:udt_name
|
30
|
-
]
|
31
|
-
},
|
32
|
-
"USER-DEFINED": {
|
33
|
-
description: "binary data (“byte array”)",
|
34
|
-
required: [
|
35
|
-
:udt_schema,
|
36
|
-
:udt_name
|
37
|
-
]
|
38
|
-
},
|
39
|
-
bigint: {
|
40
|
-
description: "signed eight-byte integer",
|
41
|
-
required: [
|
42
|
-
:numeric_precision,
|
43
|
-
:numeric_precision_radix,
|
44
|
-
:numeric_scale
|
45
|
-
]
|
46
|
-
},
|
47
|
-
# skipping this, in my tests it automatically turned into a bigint
|
48
|
-
# bigserial: {
|
49
|
-
# description: "autoincrementing eight-byte integer"
|
50
|
-
# },
|
51
|
-
bit: {
|
52
|
-
description: "fixed-length bit string",
|
53
|
-
args: "[ (n) ]",
|
54
|
-
required: [
|
55
|
-
:character_maximum_length
|
56
|
-
]
|
57
|
-
},
|
58
|
-
"bit varying": {
|
59
|
-
description: "variable-length bit string",
|
60
|
-
args: "[ (n) ]"
|
61
|
-
},
|
62
|
-
boolean: {
|
63
|
-
description: "logical Boolean (true/false)",
|
64
|
-
required: []
|
65
|
-
},
|
66
|
-
box: {
|
67
|
-
description: "rectangular box on a plane"
|
68
|
-
},
|
69
|
-
bytea: {
|
70
|
-
description: "binary data (“byte array”)"
|
71
|
-
},
|
72
|
-
character: {
|
73
|
-
description: "fixed-length character string",
|
74
|
-
args: "[ (n) ]",
|
75
|
-
required: [
|
76
|
-
:character_maximum_length,
|
77
|
-
:character_octet_length
|
78
|
-
]
|
79
|
-
},
|
80
|
-
"character varying": {
|
81
|
-
description: "variable-length character string",
|
82
|
-
args: "[ (n) ]",
|
83
|
-
required: [
|
84
|
-
:character_octet_length
|
85
|
-
]
|
86
|
-
},
|
87
|
-
cidr: {
|
88
|
-
description: "IPv4 or IPv6 network address"
|
89
|
-
},
|
90
|
-
circle: {
|
91
|
-
description: "circle on a plane"
|
92
|
-
},
|
93
|
-
date: {
|
94
|
-
description: "calendar date (year, month, day)",
|
95
|
-
required: [
|
96
|
-
:datetime_precision
|
97
|
-
]
|
98
|
-
},
|
99
|
-
"double precision": {
|
100
|
-
description: "double precision floating-point number (8 bytes)",
|
101
|
-
required: [
|
102
|
-
:numeric_precision,
|
103
|
-
:numeric_precision_radix
|
104
|
-
]
|
105
|
-
},
|
106
|
-
inet: {
|
107
|
-
description: "IPv4 or IPv6 host address"
|
108
|
-
},
|
109
|
-
integer: {
|
110
|
-
description: "signed four-byte integer",
|
111
|
-
required: [
|
112
|
-
:numeric_precision,
|
113
|
-
:numeric_precision_radix,
|
114
|
-
:numeric_scale
|
115
|
-
]
|
116
|
-
},
|
117
|
-
interval: {
|
118
|
-
description: "time span",
|
119
|
-
args: "[ fields ] [ (p) ]",
|
120
|
-
required: [
|
121
|
-
:datetime_precision
|
122
|
-
]
|
123
|
-
},
|
124
|
-
json: {
|
125
|
-
description: "textual JSON data"
|
126
|
-
},
|
127
|
-
jsonb: {
|
128
|
-
description: "binary JSON data, decomposed"
|
129
|
-
},
|
130
|
-
line: {
|
131
|
-
description: "infinite line on a plane"
|
132
|
-
},
|
133
|
-
lseg: {
|
134
|
-
description: "line segment on a plane"
|
135
|
-
},
|
136
|
-
macaddr: {
|
137
|
-
description: "MAC (Media Access Control) address"
|
138
|
-
},
|
139
|
-
macaddr8: {
|
140
|
-
description: "MAC (Media Access Control) address (EUI-64 format)"
|
141
|
-
},
|
142
|
-
money: {
|
143
|
-
description: "currency amount"
|
144
|
-
},
|
145
|
-
numeric: {
|
146
|
-
description: "exact numeric of selectable precision",
|
147
|
-
args: "[ (p, s) ]",
|
148
|
-
required: [
|
149
|
-
:numeric_precision_radix
|
150
|
-
],
|
151
|
-
optional: [
|
152
|
-
:numeric_precision,
|
153
|
-
:numeric_scale
|
154
|
-
]
|
155
|
-
},
|
156
|
-
path: {
|
157
|
-
description: "geometric path on a plane"
|
158
|
-
},
|
159
|
-
pg_lsn: {
|
160
|
-
description: "PostgreSQL Log Sequence Number"
|
161
|
-
},
|
162
|
-
pg_snapshot: {
|
163
|
-
description: "user-level transaction ID snapshot"
|
164
|
-
},
|
165
|
-
point: {
|
166
|
-
description: "geometric point on a plane"
|
167
|
-
},
|
168
|
-
polygon: {
|
169
|
-
description: "closed geometric path on a plane"
|
170
|
-
},
|
171
|
-
real: {
|
172
|
-
description: "single precision floating-point number (4 bytes)",
|
173
|
-
required: [
|
174
|
-
:numeric_precision,
|
175
|
-
:numeric_precision_radix
|
176
|
-
]
|
177
|
-
},
|
178
|
-
smallint: {
|
179
|
-
description: "signed two-byte",
|
180
|
-
required: [
|
181
|
-
:numeric_precision,
|
182
|
-
:numeric_precision_radix,
|
183
|
-
:numeric_scale
|
184
|
-
]
|
185
|
-
},
|
186
|
-
smallserial: {
|
187
|
-
description: "autoincrementing two-byte"
|
188
|
-
},
|
189
|
-
serial: {
|
190
|
-
description: "autoincrementing four-byte"
|
191
|
-
},
|
192
|
-
text: {
|
193
|
-
description: "variable-length character string",
|
194
|
-
required: [
|
195
|
-
:character_octet_length
|
196
|
-
]
|
197
|
-
},
|
198
|
-
"time without time zone": {
|
199
|
-
description: "time of day (no time zone)",
|
200
|
-
args: "[ (p) ]",
|
201
|
-
required: [
|
202
|
-
:datetime_precision
|
203
|
-
]
|
204
|
-
},
|
205
|
-
"time with time zone": {
|
206
|
-
description: "time of day, including time zone",
|
207
|
-
args: "[ (p) ]",
|
208
|
-
required: [
|
209
|
-
:datetime_precision
|
210
|
-
]
|
211
|
-
},
|
212
|
-
"timestamp without time zone": {
|
213
|
-
description: "date and time (no time zone)",
|
214
|
-
args: "[ (p) ]",
|
215
|
-
required: [
|
216
|
-
:datetime_precision
|
217
|
-
]
|
218
|
-
},
|
219
|
-
"timestamp with time zone": {
|
220
|
-
description: "date and time, including time zone",
|
221
|
-
args: "[ (p) ]",
|
222
|
-
required: [
|
223
|
-
:datetime_precision
|
224
|
-
]
|
225
|
-
},
|
226
|
-
tsquery: {
|
227
|
-
description: "text search query"
|
228
|
-
},
|
229
|
-
tsvector: {
|
230
|
-
description: "text search document"
|
231
|
-
},
|
232
|
-
txid_snapshot: {
|
233
|
-
description: "user-level transaction ID snapshot (deprecated; see pg_snapshot)"
|
234
|
-
},
|
235
|
-
uuid: {
|
236
|
-
description: "universally unique identifier"
|
237
|
-
},
|
238
|
-
xml: {
|
239
|
-
description: "XML data"
|
240
|
-
}
|
241
|
-
}
|
242
|
-
|
243
|
-
def self.validate_type_exists! data_type
|
244
|
-
raise ExpectedSymbolError, data_type unless data_type.is_a? Symbol
|
245
|
-
raise UnsupportedTypeError, data_type unless DATA_TYPES.key? data_type
|
246
|
-
true
|
247
|
-
end
|
248
|
-
|
249
|
-
def self.validate_column_properties! data_type, **column_options
|
250
|
-
validate_type_exists! data_type
|
251
|
-
|
252
|
-
required_attributes = DATA_TYPES[data_type][:required] || []
|
253
|
-
optional_attributes = DATA_TYPES[data_type][:optional] || []
|
254
|
-
possible_attributes = required_attributes + optional_attributes
|
255
|
-
|
256
|
-
# assert all required attributes are present
|
257
|
-
required_attributes.each do |attribute|
|
258
|
-
unless column_options.key?(attribute) && !column_options[attribute].nil?
|
259
|
-
raise MissingRequiredAttributeError.new data_type, attribute
|
260
|
-
end
|
261
|
-
end
|
262
|
-
|
263
|
-
# assert no unexpected attributes are present
|
264
|
-
column_options.each do |key, value|
|
265
|
-
unless value.nil? || possible_attributes.include?(key)
|
266
|
-
raise UnexpectedPropertyError.new data_type, key, value
|
267
|
-
end
|
268
|
-
end
|
269
|
-
true
|
270
|
-
end
|
271
|
-
end
|
272
|
-
end
|
273
|
-
end
|