activerecord7-redshift-adapter-pennylane 1.0.3 → 1.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. checksums.yaml +4 -4
  2. data/lib/active_record/connection_adapters/redshift_7_0/oid/decimal.rb +1 -1
  3. data/lib/active_record/connection_adapters/redshift_7_0/schema_statements.rb +3 -3
  4. data/lib/active_record/connection_adapters/redshift_7_0_adapter.rb +0 -2
  5. data/lib/active_record/connection_adapters/redshift_7_1/oid/decimal.rb +1 -1
  6. data/lib/active_record/connection_adapters/redshift_7_1/quoting.rb +1 -1
  7. data/lib/active_record/connection_adapters/redshift_7_1/schema_statements.rb +3 -3
  8. data/lib/active_record/connection_adapters/redshift_7_1_adapter.rb +0 -1
  9. data/lib/active_record/connection_adapters/redshift_7_2/array_parser.rb +92 -0
  10. data/lib/active_record/connection_adapters/redshift_7_2/column.rb +17 -0
  11. data/lib/active_record/connection_adapters/redshift_7_2/database_statements.rb +180 -0
  12. data/lib/active_record/connection_adapters/redshift_7_2/oid/date_time.rb +36 -0
  13. data/lib/active_record/connection_adapters/redshift_7_2/oid/decimal.rb +15 -0
  14. data/lib/active_record/connection_adapters/redshift_7_2/oid/json.rb +41 -0
  15. data/lib/active_record/connection_adapters/redshift_7_2/oid/jsonb.rb +25 -0
  16. data/lib/active_record/connection_adapters/redshift_7_2/oid/type_map_initializer.rb +62 -0
  17. data/lib/active_record/connection_adapters/redshift_7_2/oid.rb +17 -0
  18. data/lib/active_record/connection_adapters/redshift_7_2/quoting.rb +164 -0
  19. data/lib/active_record/connection_adapters/redshift_7_2/referential_integrity.rb +17 -0
  20. data/lib/active_record/connection_adapters/redshift_7_2/schema_definitions.rb +70 -0
  21. data/lib/active_record/connection_adapters/redshift_7_2/schema_dumper.rb +17 -0
  22. data/lib/active_record/connection_adapters/redshift_7_2/schema_statements.rb +422 -0
  23. data/lib/active_record/connection_adapters/redshift_7_2/type_metadata.rb +43 -0
  24. data/lib/active_record/connection_adapters/redshift_7_2/utils.rb +81 -0
  25. data/lib/active_record/connection_adapters/redshift_7_2_adapter.rb +847 -0
  26. data/lib/active_record/connection_adapters/redshift_adapter.rb +8 -2
  27. data/lib/active_record/tasks/redshift_7_0_tasks.rb +148 -0
  28. data/lib/active_record/tasks/redshift_7_1_tasks.rb +151 -0
  29. data/lib/active_record/tasks/redshift_7_2_tasks.rb +151 -0
  30. data/lib/active_record/tasks/redshift_tasks.rb +11 -0
  31. data/lib/activerecord7-redshift-adapter-pennylane.rb +13 -0
  32. metadata +25 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e8108a9c785d7604af14ffbaca6265c6350c119406c09951c0a73a2aba888471
4
- data.tar.gz: a71d3843e77264799115393dd6ba8bb50717722c292aab9e3e73b0d0463d634e
3
+ metadata.gz: 26e7edd35acf5f404cb34a387350b1f0a10460b70d6cdffa78e146ff2e5e9bae
4
+ data.tar.gz: c6b7aa54b4e1d7487e40f048b035e90189e6ac3aed91ffddbcd706297b12de27
5
5
  SHA512:
6
- metadata.gz: e4fd3c18f5255e06b5e0cb855c516b538304e00de9293108fde3eeb2fa7a90df2539824259af6201b4b14cd3c2d0b148c7357e29bdf00559cfcf1e700cb23ea5
7
- data.tar.gz: 96c5852565ca6416135a7a19b49fc384007fbfb7a2bed043dd3d4804caaa765c5ba8fde811e5dc298531bc971d291acdf513b4708276fcddb76f2de489060dbe
6
+ metadata.gz: f2a95375595b29b82be85c059d2ae82cfd67269ddb603531e700fe45e35ce3750fd10f913afff46138284673a652e8af01a32b223f7de1ad830287820bcda4bc
7
+ data.tar.gz: 96a9934cc31208484b910adbe2cb22db6872ab16dbb2b011ce1d88a80785fffcf1bdecfeb6a0b065b34cea7a1b38241c1eca425606d2863092af4d2d9189bab6
@@ -5,7 +5,7 @@ module ActiveRecord
5
5
  module Redshift
6
6
  module OID # :nodoc:
7
7
  class Decimal < Type::Decimal # :nodoc:
8
- def infinity(**options)
8
+ def infinity(options = {})
9
9
  BigDecimal('Infinity') * (options[:negative] ? -1 : 1)
10
10
  end
11
11
  end
@@ -24,7 +24,7 @@ module ActiveRecord
24
24
  module SchemaStatements
25
25
  # Drops the database specified on the +name+ attribute
26
26
  # and creates it again using the provided +options+.
27
- def recreate_database(name, **options) # :nodoc:
27
+ def recreate_database(name, options = {}) # :nodoc:
28
28
  drop_database(name)
29
29
  create_database(name, options)
30
30
  end
@@ -37,7 +37,7 @@ module ActiveRecord
37
37
  # Example:
38
38
  # create_database config[:database], config
39
39
  # create_database 'foo_development', encoding: 'unicode'
40
- def create_database(name, **options)
40
+ def create_database(name, options = {})
41
41
  options = { encoding: 'utf8' }.merge!(options.symbolize_keys)
42
42
 
43
43
  option_string = options.inject('') do |memo, (key, value)|
@@ -129,7 +129,7 @@ module ActiveRecord
129
129
  end
130
130
 
131
131
  def drop_table(table_name, **options)
132
- execute "DROP TABLE #{quote_table_name(table_name)}#{' CASCADE' if options[:force] == :cascade}"
132
+ execute "DROP TABLE#{' IF EXISTS' if options[:if_exists]} #{quote_table_name(table_name)}#{' CASCADE' if options[:force] == :cascade}"
133
133
  end
134
134
 
135
135
  # Returns true if schema exists.
@@ -20,8 +20,6 @@ require 'pg'
20
20
 
21
21
  require 'ipaddr'
22
22
 
23
- ActiveRecord::Tasks::DatabaseTasks.register_task(/redshift/, 'ActiveRecord::Tasks::PostgreSQLDatabaseTasks')
24
-
25
23
  module ActiveRecord
26
24
  module ConnectionHandling # :nodoc:
27
25
  RS_VALID_CONN_PARAMS = %i[host hostaddr port dbname user password connect_timeout
@@ -5,7 +5,7 @@ module ActiveRecord
5
5
  module Redshift
6
6
  module OID # :nodoc:
7
7
  class Decimal < Type::Decimal # :nodoc:
8
- def infinity(**options)
8
+ def infinity(options = {})
9
9
  BigDecimal('Infinity') * (options[:negative] ? -1 : 1)
10
10
  end
11
11
  end
@@ -44,7 +44,7 @@ module ActiveRecord
44
44
 
45
45
  # Quotes column names for use in SQL queries.
46
46
  def quote_column_name(name) # :nodoc:
47
- QUOTED_COLUMN_NAMES[name] ||= PG::Connection.quote_ident(super).freeze
47
+ QUOTED_COLUMN_NAMES[name] ||= PG::Connection.quote_ident(name.to_s).freeze
48
48
  end
49
49
 
50
50
  # Quotes schema names for use in SQL queries.
@@ -24,7 +24,7 @@ module ActiveRecord
24
24
  module SchemaStatements
25
25
  # Drops the database specified on the +name+ attribute
26
26
  # and creates it again using the provided +options+.
27
- def recreate_database(name, **options) # :nodoc:
27
+ def recreate_database(name, options = {}) # :nodoc:
28
28
  drop_database(name)
29
29
  create_database(name, options)
30
30
  end
@@ -37,7 +37,7 @@ module ActiveRecord
37
37
  # Example:
38
38
  # create_database config[:database], config
39
39
  # create_database 'foo_development', encoding: 'unicode'
40
- def create_database(name, **options)
40
+ def create_database(name, options = {})
41
41
  options = { encoding: 'utf8' }.merge!(options.symbolize_keys)
42
42
 
43
43
  option_string = options.inject('') do |memo, (key, value)|
@@ -129,7 +129,7 @@ module ActiveRecord
129
129
  end
130
130
 
131
131
  def drop_table(table_name, **options)
132
- execute "DROP TABLE #{quote_table_name(table_name)}#{' CASCADE' if options[:force] == :cascade}"
132
+ execute "DROP TABLE#{' IF EXISTS' if options[:if_exists]} #{quote_table_name(table_name)}#{' CASCADE' if options[:force] == :cascade}"
133
133
  end
134
134
 
135
135
  # Returns true if schema exists.
@@ -20,7 +20,6 @@ require 'pg'
20
20
 
21
21
  require 'ipaddr'
22
22
 
23
- ActiveRecord::Tasks::DatabaseTasks.register_task(/redshift/, 'ActiveRecord::Tasks::PostgreSQLDatabaseTasks')
24
23
  module ActiveRecord
25
24
  module ConnectionHandling # :nodoc:
26
25
 
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module ConnectionAdapters
5
+ module Redshift
6
+ module ArrayParser # :nodoc:
7
+ DOUBLE_QUOTE = '"'
8
+ BACKSLASH = '\\'
9
+ COMMA = ','
10
+ BRACKET_OPEN = '{'
11
+ BRACKET_CLOSE = '}'
12
+
13
+ def parse_pg_array(string) # :nodoc:
14
+ local_index = 0
15
+ array = []
16
+ while local_index < string.length
17
+ case string[local_index]
18
+ when BRACKET_OPEN
19
+ local_index, array = parse_array_contents(array, string, local_index + 1)
20
+ when BRACKET_CLOSE
21
+ return array
22
+ end
23
+ local_index += 1
24
+ end
25
+
26
+ array
27
+ end
28
+
29
+ private
30
+
31
+ def parse_array_contents(array, string, index)
32
+ is_escaping = false
33
+ is_quoted = false
34
+ was_quoted = false
35
+ current_item = ''
36
+
37
+ local_index = index
38
+ while local_index
39
+ token = string[local_index]
40
+ if is_escaping
41
+ current_item << token
42
+ is_escaping = false
43
+ elsif is_quoted
44
+ case token
45
+ when DOUBLE_QUOTE
46
+ is_quoted = false
47
+ was_quoted = true
48
+ when BACKSLASH
49
+ is_escaping = true
50
+ else
51
+ current_item << token
52
+ end
53
+ else
54
+ case token
55
+ when BACKSLASH
56
+ is_escaping = true
57
+ when COMMA
58
+ add_item_to_array(array, current_item, was_quoted)
59
+ current_item = ''
60
+ was_quoted = false
61
+ when DOUBLE_QUOTE
62
+ is_quoted = true
63
+ when BRACKET_OPEN
64
+ internal_items = []
65
+ local_index, internal_items = parse_array_contents(internal_items, string, local_index + 1)
66
+ array.push(internal_items)
67
+ when BRACKET_CLOSE
68
+ add_item_to_array(array, current_item, was_quoted)
69
+ return local_index, array
70
+ else
71
+ current_item << token
72
+ end
73
+ end
74
+
75
+ local_index += 1
76
+ end
77
+ [local_index, array]
78
+ end
79
+
80
+ def add_item_to_array(array, current_item, quoted)
81
+ return if !quoted && current_item.empty?
82
+
83
+ if !quoted && current_item == 'NULL'
84
+ array.push nil
85
+ else
86
+ array.push current_item
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module ConnectionAdapters
5
+ class RedshiftColumn < Column # :nodoc:
6
+ delegate :oid, :fmod, to: :sql_type_metadata
7
+
8
+ # Required for Rails 6.1, see https://github.com/rails/rails/pull/41756
9
+ mattr_reader :array, default: false
10
+ alias array? array
11
+
12
+ def initialize(name, default, sql_type_metadata, null = true, default_function = nil, **)
13
+ super name, default, sql_type_metadata, null, default_function
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,180 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module ConnectionAdapters
5
+ module Redshift
6
+ module DatabaseStatements
7
+ def explain(arel, binds = [], options = [])
8
+ sql = build_explain_clause(options) + " " + to_sql(arel, binds)
9
+ result = internal_exec_query(sql, "EXPLAIN", binds)
10
+ PostgreSQL::ExplainPrettyPrinter.new.pp(result)
11
+ end
12
+
13
+ # Queries the database and returns the results in an Array-like object
14
+ def query(sql, name = nil) # :nodoc:
15
+ mark_transaction_written_if_write(sql)
16
+
17
+ log(sql, name) do
18
+ with_raw_connection do |conn|
19
+ result = conn.async_exec(sql).map_types!(@type_map_for_results).values
20
+ verified!
21
+ result
22
+ end
23
+ end
24
+ end
25
+
26
+ READ_QUERY = ActiveRecord::ConnectionAdapters::AbstractAdapter.build_read_query_regexp(
27
+ :close, :declare, :fetch, :move, :set, :show
28
+ ) # :nodoc:
29
+ private_constant :READ_QUERY
30
+
31
+ def write_query?(sql) # :nodoc:
32
+ !READ_QUERY.match?(sql)
33
+ rescue ArgumentError # Invalid encoding
34
+ !READ_QUERY.match?(sql.b)
35
+ end
36
+
37
+ # Executes an SQL statement, returning a PG::Result object on success
38
+ # or raising a PG::Error exception otherwise.
39
+ #
40
+ # Setting +allow_retry+ to true causes the db to reconnect and retry
41
+ # executing the SQL statement in case of a connection-related exception.
42
+ # This option should only be enabled for known idempotent queries.
43
+ #
44
+ # Note: the PG::Result object is manually memory managed; if you don't
45
+ # need it specifically, you may want consider the <tt>exec_query</tt> wrapper.
46
+ def execute(...) # :nodoc:
47
+ super
48
+ ensure
49
+ @notice_receiver_sql_warnings = []
50
+ end
51
+
52
+ def raw_execute(sql, name, async: false, allow_retry: false, materialize_transactions: true)
53
+ log(sql, name, async: async) do
54
+ with_raw_connection(allow_retry: allow_retry, materialize_transactions: materialize_transactions) do |conn|
55
+ result = conn.async_exec(sql)
56
+ verified!
57
+ handle_warnings(result)
58
+ result
59
+ end
60
+ end
61
+ end
62
+
63
+ def internal_exec_query(sql, name = "SQL", binds = [], prepare: false, async: false, allow_retry: false, materialize_transactions: true) # :nodoc:
64
+ execute_and_clear(sql, name, binds, prepare: prepare, async: async, allow_retry: allow_retry, materialize_transactions: materialize_transactions) do |result|
65
+ types = {}
66
+ fields = result.fields
67
+ fields.each_with_index do |fname, i|
68
+ ftype = result.ftype i
69
+ fmod = result.fmod i
70
+ types[fname] = types[i] = get_oid_type(ftype, fmod, fname)
71
+ end
72
+ build_result(columns: fields, rows: result.values, column_types: types)
73
+ end
74
+ end
75
+
76
+ def exec_delete(sql, name = nil, binds = []) # :nodoc:
77
+ execute_and_clear(sql, name, binds) { |result| result.cmd_tuples }
78
+ end
79
+ alias :exec_update :exec_delete
80
+
81
+ def exec_insert(sql, name = nil, binds = [], pk = nil, sequence_name = nil, returning: nil) # :nodoc:
82
+ if use_insert_returning? || pk == false
83
+ super
84
+ else
85
+ result = internal_exec_query(sql, name, binds)
86
+ unless sequence_name
87
+ table_ref = extract_table_ref_from_insert_sql(sql)
88
+ if table_ref
89
+ pk = primary_key(table_ref) if pk.nil?
90
+ pk = suppress_composite_primary_key(pk)
91
+ sequence_name = default_sequence_name(table_ref, pk)
92
+ end
93
+ return result unless sequence_name
94
+ end
95
+ last_insert_id_result(sequence_name)
96
+ end
97
+ end
98
+
99
+ # Begins a transaction.
100
+ def begin_db_transaction
101
+ internal_execute('BEGIN', allow_retry: true, materialize_transactions: false)
102
+ end
103
+
104
+ def begin_isolated_db_transaction(isolation)
105
+ begin_db_transaction
106
+ internal_execute("SET TRANSACTION ISOLATION LEVEL #{transaction_isolation_levels.fetch(isolation)}", allow_retry: true, materialize_transactions: false)
107
+ end
108
+
109
+ # Commits a transaction.
110
+ def commit_db_transaction
111
+ internal_execute('COMMIT', allow_retry: false, materialize_transactions: true)
112
+ end
113
+
114
+ # Aborts a transaction.
115
+ def exec_rollback_db_transaction
116
+ internal_execute('ROLLBACK', allow_retry: false, materialize_transactions: true)
117
+ end
118
+
119
+ def exec_restart_db_transaction # :nodoc:
120
+ cancel_any_running_query
121
+ exec_rollback_db_transaction
122
+ begin_db_transaction
123
+ end
124
+
125
+ # From https://www.postgresql.org/docs/current/functions-datetime.html#FUNCTIONS-DATETIME-CURRENT
126
+ HIGH_PRECISION_CURRENT_TIMESTAMP = Arel.sql("CURRENT_TIMESTAMP").freeze # :nodoc:
127
+ private_constant :HIGH_PRECISION_CURRENT_TIMESTAMP
128
+
129
+ def high_precision_current_timestamp
130
+ HIGH_PRECISION_CURRENT_TIMESTAMP
131
+ end
132
+
133
+ def build_explain_clause(options = [])
134
+ return "EXPLAIN" if options.empty?
135
+
136
+ "EXPLAIN (#{options.join(", ").upcase})"
137
+ end
138
+
139
+ private
140
+
141
+ IDLE_TRANSACTION_STATUSES = [PG::PQTRANS_IDLE, PG::PQTRANS_INTRANS, PG::PQTRANS_INERROR]
142
+ private_constant :IDLE_TRANSACTION_STATUSES
143
+
144
+ def cancel_any_running_query
145
+ return if @raw_connection.nil? || IDLE_TRANSACTION_STATUSES.include?(@raw_connection.transaction_status)
146
+
147
+ @raw_connection.cancel
148
+ @raw_connection.block
149
+ rescue PG::Error
150
+ end
151
+
152
+ # Returns the current ID of a table's sequence.
153
+ def last_insert_id_result(sequence_name)
154
+ internal_exec_query("SELECT currval(#{quote(sequence_name)})", "SQL")
155
+ end
156
+
157
+ def returning_column_values(result)
158
+ result.rows.first
159
+ end
160
+
161
+ def suppress_composite_primary_key(pk)
162
+ pk unless pk.is_a?(Array)
163
+ end
164
+
165
+ def handle_warnings(sql)
166
+ @notice_receiver_sql_warnings.each do |warning|
167
+ next if warning_ignored?(warning)
168
+
169
+ warning.sql = sql
170
+ ActiveRecord.db_warnings_action.call(warning)
171
+ end
172
+ end
173
+
174
+ def warning_ignored?(warning)
175
+ ["WARNING", "ERROR", "FATAL", "PANIC"].exclude?(warning.level) || super
176
+ end
177
+ end
178
+ end
179
+ end
180
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module ConnectionAdapters
5
+ module Redshift
6
+ module OID # :nodoc:
7
+ class DateTime < Type::DateTime # :nodoc:
8
+ def type_cast_for_database(value)
9
+ if has_precision? && value.acts_like?(:time) && value.year <= 0
10
+ bce_year = format('%04d', -value.year + 1)
11
+ "#{super.sub(/^-?\d+/, bce_year)} BC"
12
+ else
13
+ super
14
+ end
15
+ end
16
+
17
+ def cast_value(value)
18
+ if value.is_a?(::String)
19
+ case value
20
+ when 'infinity' then ::Float::INFINITY
21
+ when '-infinity' then -::Float::INFINITY
22
+ when / BC$/
23
+ astronomical_year = format('%04d', -value[/^\d+/].to_i + 1)
24
+ super(value.sub(/ BC$/, '').sub(/^\d+/, astronomical_year))
25
+ else
26
+ super
27
+ end
28
+ else
29
+ value
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module ConnectionAdapters
5
+ module Redshift
6
+ module OID # :nodoc:
7
+ class Decimal < Type::Decimal # :nodoc:
8
+ def infinity(options = {})
9
+ BigDecimal('Infinity') * (options[:negative] ? -1 : 1)
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module ConnectionAdapters
5
+ module Redshift
6
+ module OID # :nodoc:
7
+ class Json < Type::Value # :nodoc:
8
+ include ActiveModel::Type::Helpers::Mutable
9
+
10
+ def type
11
+ :json
12
+ end
13
+
14
+ def type_cast_from_database(value)
15
+ if value.is_a?(::String)
16
+ begin
17
+ ::ActiveSupport::JSON.decode(value)
18
+ rescue StandardError
19
+ nil
20
+ end
21
+ else
22
+ super
23
+ end
24
+ end
25
+
26
+ def type_cast_for_database(value)
27
+ if value.is_a?(::Array) || value.is_a?(::Hash)
28
+ ::ActiveSupport::JSON.encode(value)
29
+ else
30
+ super
31
+ end
32
+ end
33
+
34
+ def accessor
35
+ ActiveRecord::Store::StringKeyedHashAccessor
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module ConnectionAdapters
5
+ module Redshift
6
+ module OID # :nodoc:
7
+ class Jsonb < Json # :nodoc:
8
+ def type
9
+ :jsonb
10
+ end
11
+
12
+ def changed_in_place?(raw_old_value, new_value)
13
+ # Postgres does not preserve insignificant whitespaces when
14
+ # roundtripping jsonb columns. This causes some false positives for
15
+ # the comparison here. Therefore, we need to parse and re-dump the
16
+ # raw value here to ensure the insignificant whitespaces are
17
+ # consistent with our encoder's output.
18
+ raw_old_value = type_cast_for_database(type_cast_from_database(raw_old_value))
19
+ super(raw_old_value, new_value)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module ConnectionAdapters
5
+ module Redshift
6
+ module OID # :nodoc:
7
+ # This class uses the data from PostgreSQL pg_type table to build
8
+ # the OID -> Type mapping.
9
+ # - OID is an integer representing the type.
10
+ # - Type is an OID::Type object.
11
+ # This class has side effects on the +store+ passed during initialization.
12
+ class TypeMapInitializer # :nodoc:
13
+ def initialize(store, run_complex_types = true)
14
+ @store = store
15
+ @run_complex_types = run_complex_types
16
+ end
17
+
18
+ def run(records)
19
+ records
20
+ .reject { |row| @store.key? row['oid'].to_i }
21
+ .select { |row| @store.key? row['typname'] }
22
+ .each { |row| register_mapped_type(row) }
23
+ end
24
+
25
+ private
26
+
27
+ def register_mapped_type(row)
28
+ alias_type row['oid'], row['typname']
29
+ end
30
+
31
+ def register(oid, oid_type = nil, &block)
32
+ oid = assert_valid_registration(oid, oid_type || block)
33
+ if block_given?
34
+ @store.register_type(oid, &block)
35
+ else
36
+ @store.register_type(oid, oid_type)
37
+ end
38
+ end
39
+
40
+ def alias_type(oid, target)
41
+ oid = assert_valid_registration(oid, target)
42
+ @store.alias_type(oid, target)
43
+ end
44
+
45
+ def register_with_subtype(oid, target_oid)
46
+ return unless @store.key?(target_oid)
47
+
48
+ register(oid) do |_, *args|
49
+ yield @store.lookup(target_oid, *args)
50
+ end
51
+ end
52
+
53
+ def assert_valid_registration(oid, oid_type)
54
+ raise ArgumentError, "can't register nil type for OID #{oid}" if oid_type.nil?
55
+
56
+ oid.to_i
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'oid/date_time'
4
+ require_relative 'oid/decimal'
5
+ require_relative 'oid/json'
6
+ require_relative 'oid/jsonb'
7
+
8
+ require_relative 'oid/type_map_initializer'
9
+
10
+ module ActiveRecord
11
+ module ConnectionAdapters
12
+ module Redshift
13
+ module OID # :nodoc:
14
+ end
15
+ end
16
+ end
17
+ end