dynamic_migrations 2.0.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d576c2761325b577a0e175e24a59833dc595212900f953ee494d71d4a635beef
4
- data.tar.gz: 47911ce666cdd465a8f57a54263155c92ba8d37339cf7bf3c2a6a3fcde549e99
3
+ metadata.gz: b27309525226b33bbcff1b08b3361347e93cff1d182f5620debbe3195b5c1d88
4
+ data.tar.gz: 670213a55b129e2518e793bc5314fe522f72645da50d5b32355cacfec5cff8fb
5
5
  SHA512:
6
- metadata.gz: 6a05c58150c20cdf1a19f14e2d931e7a48e4220531cc5f1f25d9cf0740554fe01a3b3db7e2ea7e12d4d06732c0fa472fdd6652cf27fffdad8a82039f73163eeb
7
- data.tar.gz: 0ae100cf8c850cde3de93c4fd86df3487c1b4f7b7f25de65d9fab6b0dfde020bf4d4f09b802c37c92fe5d26fb0b6b73d12d641cb6f6c0fb3567e8e97f047ce87
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
- :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,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 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.0.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,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dynamic_migrations
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
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-27 00:00:00.000000000 Z
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