dynamic_migrations 2.1.0 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6bbdbe66b5d24e600037fcaf794929bca95cb55b6a2bd45de324934ab1ab22b2
4
- data.tar.gz: 06dd757a70e427b753e6f5b3f1bdbf970c749947d13ba7771449f595a2968743
3
+ metadata.gz: b27309525226b33bbcff1b08b3361347e93cff1d182f5620debbe3195b5c1d88
4
+ data.tar.gz: 670213a55b129e2518e793bc5314fe522f72645da50d5b32355cacfec5cff8fb
5
5
  SHA512:
6
- metadata.gz: c1f8deb5208188c16ff9b6b0071b9fea82111626336cd73d77e519ce93bb1af4df74090c3e34de49d007d1709f7b7041f95cbfca97dc4676e91e74b19b5ee556
7
- data.tar.gz: bfced908cb97de19a678043f6e6fff00faeb11d4dc1ac8b3b15b3e8611f21c121b5ad9a04dae54a8cbf118f9efee9b9462a1b6dcf12904c511d23c15d079ea93
6
+ metadata.gz: 4227acc9480ac7c9022a0e1f9473627d3b7ab11611d164582b9edf9049928a4a36c1292ce5f43f9f627f9c2c4968e6b8bb4da1ed0dde11b41cd431d6d61022a6
7
+ data.tar.gz: ef666cf1f797e262469fc080524726d3e70e1f1a52a4dfdb08bc9b9fbc5925671b25cead8013555618ade984bf603e86812ea8689cba2e59a5dd1a8d411664dc
data/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
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
+
3
10
  ## [2.1.0](https://github.com/craigulliott/dynamic_migrations/compare/v2.0.0...v2.1.0) (2023-07-31)
4
11
 
5
12
 
@@ -130,16 +130,7 @@ module DynamicMigrations
130
130
  :null,
131
131
  :default,
132
132
  :description,
133
- :character_maximum_length,
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
- character_maximum_length: column_definition[:character_maximum_length],
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, character_maximum_length: nil, character_octet_length: nil, numeric_precision: nil, numeric_precision_radix: nil, numeric_scale: nil, datetime_precision: nil, interval_type: nil, udt_schema: nil, udt_name: nil, updatable: true
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,38 +37,7 @@ module DynamicMigrations
48
37
  @description = description
49
38
  end
50
39
 
51
- # apply any defaults for this data type
52
- character_maximum_length = character_maximum_length.nil? ? DataTypes.default_for(data_type, :character_maximum_length) : character_maximum_length
53
- character_octet_length = character_octet_length.nil? ? DataTypes.default_for(data_type, :character_octet_length) : character_octet_length
54
- numeric_precision = numeric_precision.nil? ? DataTypes.default_for(data_type, :numeric_precision) : numeric_precision
55
- numeric_precision_radix = numeric_precision_radix.nil? ? DataTypes.default_for(data_type, :numeric_precision_radix) : numeric_precision_radix
56
- numeric_scale = numeric_scale.nil? ? DataTypes.default_for(data_type, :numeric_scale) : numeric_scale
57
- datetime_precision = datetime_precision.nil? ? DataTypes.default_for(data_type, :datetime_precision) : datetime_precision
58
- interval_type = interval_type.nil? ? DataTypes.default_for(data_type, :interval_type) : interval_type
59
- udt_schema = udt_schema.nil? ? DataTypes.default_for(data_type, :udt_schema) : udt_schema
60
- udt_name = udt_name.nil? ? DataTypes.default_for(data_type, :udt_name) : udt_name
61
-
62
- DataTypes.validate_column_properties!(data_type,
63
- character_maximum_length: character_maximum_length,
64
- character_octet_length: character_octet_length,
65
- numeric_precision: numeric_precision,
66
- numeric_precision_radix: numeric_precision_radix,
67
- numeric_scale: numeric_scale,
68
- datetime_precision: datetime_precision,
69
- interval_type: interval_type,
70
- udt_schema: udt_schema,
71
- udt_name: udt_name)
72
-
73
- @character_maximum_length = character_maximum_length
74
- @character_octet_length = character_octet_length
75
- @numeric_precision = numeric_precision
76
- @numeric_precision_radix = numeric_precision_radix
77
- @numeric_scale = numeric_scale
78
- @datetime_precision = datetime_precision
79
40
  @interval_type = interval_type
80
- @udt_schema = udt_schema
81
- @udt_name = udt_name
82
- @updatable = updatable
83
41
  end
84
42
 
85
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 as
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 as table_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 as column_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
- -- Data type of the column, if it is a built-in type,
28
- -- or ARRAY if it is some array (in that case, see the
29
- -- view element_types), else USER-DEFINED (in that case,
30
- -- the type is identified in udt_name and associated
31
- -- columns). If the column is based on a domain, this
32
- -- column refers to the type underlying the domain (and
33
- -- the domain is identified in domain_name and associated
34
- -- columns).
35
- columns.data_type,
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
- -- fields), and for all other data types, this field is null.
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
- character_maximum_length: column_definition[:character_maximum_length],
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DynamicMigrations
4
- VERSION = "2.1.0"
4
+ VERSION = "2.2.0"
5
5
  end
@@ -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,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dynamic_migrations
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Craig Ulliott
@@ -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,320 +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 UnexpectedPropertyNameError < StandardError
13
- def initialize attribute
14
- super "Unexpected property `#{attribute}`"
15
- end
16
- end
17
-
18
- class UnexpectedPropertyError < StandardError
19
- def initialize data_type, attribute, value
20
- super "Unexpected property `#{attribute}` with value `#{value}` for data_type `#{data_type}`"
21
- end
22
- end
23
-
24
- class UnsupportedTypeError < StandardError
25
- def initialize data_type
26
- super "Unsupported type `#{data_type}`"
27
- end
28
- end
29
-
30
- ATTRIBUTE_NAMES = [
31
- :character_maximum_length,
32
- :character_octet_length,
33
- :numeric_precision,
34
- :numeric_precision_radix,
35
- :numeric_scale,
36
- :datetime_precision,
37
- :interval_type,
38
- :udt_schema,
39
- :udt_name
40
- ].freeze
41
-
42
- DATA_TYPES = {
43
- ARRAY: {
44
- description: "binary data (“byte array”)",
45
- required: [
46
- :udt_schema,
47
- :udt_name
48
- ]
49
- },
50
- "USER-DEFINED": {
51
- description: "binary data (“byte array”)",
52
- required: [
53
- :udt_schema,
54
- :udt_name
55
- ]
56
- },
57
- bigint: {
58
- description: "signed eight-byte integer",
59
- required: [
60
- :numeric_precision,
61
- :numeric_precision_radix,
62
- :numeric_scale
63
- ],
64
- defaults: {
65
- numeric_precision: 64,
66
- numeric_precision_radix: 2,
67
- numeric_scale: 0
68
- }
69
- },
70
- # skipping this, in my tests it automatically turned into a bigint
71
- # bigserial: {
72
- # description: "autoincrementing eight-byte integer"
73
- # },
74
- bit: {
75
- description: "fixed-length bit string",
76
- args: "[ (n) ]",
77
- required: [
78
- :character_maximum_length
79
- ]
80
- },
81
- "bit varying": {
82
- description: "variable-length bit string",
83
- args: "[ (n) ]"
84
- },
85
- boolean: {
86
- description: "logical Boolean (true/false)",
87
- required: []
88
- },
89
- box: {
90
- description: "rectangular box on a plane"
91
- },
92
- bytea: {
93
- description: "binary data (“byte array”)"
94
- },
95
- character: {
96
- description: "fixed-length character string",
97
- args: "[ (n) ]",
98
- required: [
99
- :character_maximum_length,
100
- :character_octet_length
101
- ]
102
- },
103
- "character varying": {
104
- description: "variable-length character string",
105
- args: "[ (n) ]",
106
- required: [
107
- :character_octet_length
108
- ],
109
- defaults: {
110
- character_octet_length: 1073741824
111
- }
112
- },
113
- cidr: {
114
- description: "IPv4 or IPv6 network address"
115
- },
116
- circle: {
117
- description: "circle on a plane"
118
- },
119
- date: {
120
- description: "calendar date (year, month, day)",
121
- required: [
122
- :datetime_precision
123
- ]
124
- },
125
- "double precision": {
126
- description: "double precision floating-point number (8 bytes)",
127
- required: [
128
- :numeric_precision,
129
- :numeric_precision_radix
130
- ]
131
- },
132
- inet: {
133
- description: "IPv4 or IPv6 host address"
134
- },
135
- integer: {
136
- description: "signed four-byte integer",
137
- required: [
138
- :numeric_precision,
139
- :numeric_precision_radix,
140
- :numeric_scale
141
- ],
142
- defaults: {
143
- numeric_precision: 32,
144
- numeric_precision_radix: 2,
145
- numeric_scale: 0
146
- }
147
- },
148
- interval: {
149
- description: "time span",
150
- args: "[ fields ] [ (p) ]",
151
- required: [
152
- :datetime_precision
153
- ]
154
- },
155
- json: {
156
- description: "textual JSON data"
157
- },
158
- jsonb: {
159
- description: "binary JSON data, decomposed"
160
- },
161
- line: {
162
- description: "infinite line on a plane"
163
- },
164
- lseg: {
165
- description: "line segment on a plane"
166
- },
167
- macaddr: {
168
- description: "MAC (Media Access Control) address"
169
- },
170
- macaddr8: {
171
- description: "MAC (Media Access Control) address (EUI-64 format)"
172
- },
173
- money: {
174
- description: "currency amount"
175
- },
176
- numeric: {
177
- description: "exact numeric of selectable precision",
178
- args: "[ (p, s) ]",
179
- required: [
180
- :numeric_precision_radix
181
- ],
182
- optional: [
183
- :numeric_precision,
184
- :numeric_scale
185
- ]
186
- },
187
- path: {
188
- description: "geometric path on a plane"
189
- },
190
- pg_lsn: {
191
- description: "PostgreSQL Log Sequence Number"
192
- },
193
- pg_snapshot: {
194
- description: "user-level transaction ID snapshot"
195
- },
196
- point: {
197
- description: "geometric point on a plane"
198
- },
199
- polygon: {
200
- description: "closed geometric path on a plane"
201
- },
202
- real: {
203
- description: "single precision floating-point number (4 bytes)",
204
- required: [
205
- :numeric_precision,
206
- :numeric_precision_radix
207
- ]
208
- },
209
- smallint: {
210
- description: "signed two-byte",
211
- required: [
212
- :numeric_precision,
213
- :numeric_precision_radix,
214
- :numeric_scale
215
- ]
216
- },
217
- smallserial: {
218
- description: "autoincrementing two-byte"
219
- },
220
- serial: {
221
- description: "autoincrementing four-byte"
222
- },
223
- text: {
224
- description: "variable-length character string",
225
- required: [
226
- :character_octet_length
227
- ],
228
- defaults: {
229
- character_octet_length: 1073741824
230
- }
231
- },
232
- "time without time zone": {
233
- description: "time of day (no time zone)",
234
- args: "[ (p) ]",
235
- required: [
236
- :datetime_precision
237
- ]
238
- },
239
- "time with time zone": {
240
- description: "time of day, including time zone",
241
- args: "[ (p) ]",
242
- required: [
243
- :datetime_precision
244
- ]
245
- },
246
- "timestamp without time zone": {
247
- description: "date and time (no time zone)",
248
- args: "[ (p) ]",
249
- required: [
250
- :datetime_precision
251
- ]
252
- },
253
- "timestamp with time zone": {
254
- description: "date and time, including time zone",
255
- args: "[ (p) ]",
256
- required: [
257
- :datetime_precision
258
- ]
259
- },
260
- tsquery: {
261
- description: "text search query"
262
- },
263
- tsvector: {
264
- description: "text search document"
265
- },
266
- txid_snapshot: {
267
- description: "user-level transaction ID snapshot (deprecated; see pg_snapshot)"
268
- },
269
- uuid: {
270
- description: "universally unique identifier"
271
- },
272
- xml: {
273
- description: "XML data"
274
- }
275
- }.freeze
276
-
277
- def self.default_for data_type, attribute
278
- raise ExpectedSymbolError, data_type unless data_type.is_a? Symbol
279
- raise ExpectedSymbolError, attribute unless attribute.is_a? Symbol
280
- raise UnsupportedTypeError, data_type unless DATA_TYPES.key? data_type
281
-
282
- unless ATTRIBUTE_NAMES.include? attribute
283
- raise UnexpectedPropertyNameError.new attribute
284
- end
285
-
286
- defaults = DATA_TYPES[data_type][:defaults]
287
- defaults && defaults[attribute] || nil
288
- end
289
-
290
- def self.validate_type_exists! data_type
291
- raise ExpectedSymbolError, data_type unless data_type.is_a? Symbol
292
- raise UnsupportedTypeError, data_type unless DATA_TYPES.key? data_type
293
- true
294
- end
295
-
296
- def self.validate_column_properties! data_type, **column_options
297
- validate_type_exists! data_type
298
-
299
- required_attributes = DATA_TYPES[data_type][:required] || []
300
- optional_attributes = DATA_TYPES[data_type][:optional] || []
301
- possible_attributes = required_attributes + optional_attributes
302
-
303
- # assert all required attributes are present
304
- required_attributes.each do |attribute|
305
- unless column_options.key?(attribute) && !column_options[attribute].nil?
306
- raise MissingRequiredAttributeError.new data_type, attribute
307
- end
308
- end
309
-
310
- # assert no unexpected attributes are present
311
- column_options.each do |key, value|
312
- unless value.nil? || possible_attributes.include?(key)
313
- raise UnexpectedPropertyError.new data_type, key, value
314
- end
315
- end
316
- true
317
- end
318
- end
319
- end
320
- end