activerecord-cipherstash-pg-adapter 0.6.1 → 0.7.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +24 -0
- data/README.md +6 -1
- data/activerecord-cipherstash-pg-adapter.gemspec +1 -1
- data/lib/active_record/connection_adapters/6.1/cipherstash_pg/database_statements.rb +3 -3
- data/lib/active_record/connection_adapters/6.1/cipherstash_pg/oid/array.rb +2 -2
- data/lib/active_record/connection_adapters/6.1/cipherstash_pg/oid/bytea.rb +1 -1
- data/lib/active_record/connection_adapters/6.1/cipherstash_pg/quoting.rb +2 -2
- data/lib/active_record/connection_adapters/6.1/cipherstash_pg/schema_statements.rb +1 -1
- data/lib/active_record/connection_adapters/6.1/cipherstash_pg/utils.rb +2 -2
- data/lib/active_record/connection_adapters/6.1/postgres_cipherstash_adapter.rb +34 -34
- data/lib/active_record/connection_adapters/7.0/cipherstash_pg/database_statements.rb +4 -4
- data/lib/active_record/connection_adapters/7.0/cipherstash_pg/oid/array.rb +2 -2
- data/lib/active_record/connection_adapters/7.0/cipherstash_pg/oid/bytea.rb +1 -1
- data/lib/active_record/connection_adapters/7.0/cipherstash_pg/quoting.rb +2 -2
- data/lib/active_record/connection_adapters/7.0/cipherstash_pg/utils.rb +2 -2
- data/lib/active_record/connection_adapters/7.0/postgres_cipherstash_adapter.rb +33 -33
- data/lib/active_record/connection_adapters/cipherstash_pg/database_extensions.rb +2 -2
- data/lib/version.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 662a206227829df410fe299405dd9b1fff2d62b879998fb8f29f59bcc88d8baa
|
4
|
+
data.tar.gz: 638a5f17b08d880a3ac7fd671905f6d3a42f95d0bdcd0bcd3564422435ae6b9b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 39fecf791d8bee80a099b108c84284c8bc8a1d748089256152eb35858df3b8d5150394bb19f5f13ea6c76b2d50c1dab033afd37d13ba4b4e54281c279c374d09
|
7
|
+
data.tar.gz: 8f34eeaa73a3f58c23ac15655d11f76e79073768ca096c0722dee1ca56ac64974e09d460739867a6d2982e2c8c1c5028ae44719330905145978d1b004220efb7
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,28 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
All notable changes to this project will be documented in this file.
|
4
|
+
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
6
|
+
|
1
7
|
## [Unreleased]
|
2
8
|
|
9
|
+
## [0.7.1] - 2023-05-02
|
10
|
+
|
11
|
+
### Changed
|
12
|
+
|
13
|
+
- Bump version of cipherstash-pg.
|
14
|
+
|
15
|
+
### Fixed
|
16
|
+
|
17
|
+
- Fix module names in ActiveRecord 6 adapter
|
18
|
+
|
19
|
+
## [0.7.0] - 2023-05-01
|
20
|
+
|
21
|
+
### Changed
|
22
|
+
|
23
|
+
- Update PG namespace to use CipherStashPG.
|
24
|
+
- Bump version of cipherstash-pg.
|
25
|
+
|
3
26
|
## [0.6.1] - 2023-04-26
|
4
27
|
|
5
28
|
### Fixed
|
@@ -33,6 +56,7 @@
|
|
33
56
|
- Bump version of cipherstash-pg.
|
34
57
|
|
35
58
|
## [0.3.0] - 2023-04-04
|
59
|
+
|
36
60
|
### Added
|
37
61
|
|
38
62
|
- Support for both Rails 6 + 7.
|
data/README.md
CHANGED
@@ -26,7 +26,12 @@ development:
|
|
26
26
|
|
27
27
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
28
28
|
|
29
|
-
To release a new version
|
29
|
+
To release a new version:
|
30
|
+
|
31
|
+
- update the version number in `version.rb`.
|
32
|
+
- update the CHANGELOG.
|
33
|
+
- raise a PR and merge.
|
34
|
+
- run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
30
35
|
|
31
36
|
In the github repo:
|
32
37
|
|
@@ -31,5 +31,5 @@ Gem::Specification.new do |spec|
|
|
31
31
|
|
32
32
|
# Runtime dependencies here; dev+test go in Gemfile.
|
33
33
|
spec.add_dependency "activerecord", ">= 6.0.0", "< 8.0.0"
|
34
|
-
spec.add_dependency "cipherstash-pg", ">= 1.0.0.beta.
|
34
|
+
spec.add_dependency "cipherstash-pg", ">= 1.0.0.beta.4"
|
35
35
|
end
|
@@ -32,9 +32,9 @@ module ActiveRecord
|
|
32
32
|
!READ_QUERY.match?(sql.b)
|
33
33
|
end
|
34
34
|
|
35
|
-
# Executes an SQL statement, returning a
|
36
|
-
# or raising a
|
37
|
-
# Note: the
|
35
|
+
# Executes an SQL statement, returning a ::CipherStashPG::Result object on success
|
36
|
+
# or raising a ::CipherStashPG::Error exception otherwise.
|
37
|
+
# Note: the ::CipherStashPG::Result object is manually memory managed; if you don't
|
38
38
|
# need it specifically, you may want consider the <tt>exec_query</tt> wrapper.
|
39
39
|
def execute(sql, name = nil)
|
40
40
|
if preventing_writes? && write_query?(sql)
|
@@ -16,8 +16,8 @@ module ActiveRecord
|
|
16
16
|
@subtype = subtype
|
17
17
|
@delimiter = delimiter
|
18
18
|
|
19
|
-
@pg_encoder =
|
20
|
-
@pg_decoder =
|
19
|
+
@pg_encoder = ::CipherStashPG::TextEncoder::Array.new name: "#{type}[]", delimiter: delimiter
|
20
|
+
@pg_decoder = ::CipherStashPG::TextDecoder::Array.new name: "#{type}[]", delimiter: delimiter
|
21
21
|
end
|
22
22
|
|
23
23
|
def deserialize(value)
|
@@ -35,7 +35,7 @@ module ActiveRecord
|
|
35
35
|
|
36
36
|
# Quotes schema names for use in SQL queries.
|
37
37
|
def quote_schema_name(name)
|
38
|
-
|
38
|
+
::CipherStashPG::Connection.quote_ident(name)
|
39
39
|
end
|
40
40
|
|
41
41
|
def quote_table_name_for_assignment(table, attr)
|
@@ -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
|
-
self.class.quoted_column_names[name] ||=
|
47
|
+
self.class.quoted_column_names[name] ||= ::CipherStashPG::Connection.quote_ident(super).freeze
|
48
48
|
end
|
49
49
|
|
50
50
|
# Quote date/time values for use in SQL input.
|
@@ -21,9 +21,9 @@ module ActiveRecord
|
|
21
21
|
|
22
22
|
def quoted
|
23
23
|
if schema
|
24
|
-
|
24
|
+
::CipherStashPG::Connection.quote_ident(schema) << SEPARATOR << ::CipherStashPG::Connection.quote_ident(identifier)
|
25
25
|
else
|
26
|
-
|
26
|
+
::CipherStashPG::Connection.quote_ident(identifier)
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
@@ -38,8 +38,8 @@ module ActiveRecord
|
|
38
38
|
conn_params[:user] = conn_params.delete(:username) if conn_params[:username]
|
39
39
|
conn_params[:dbname] = conn_params.delete(:database) if conn_params[:database]
|
40
40
|
|
41
|
-
# Forward only valid config params to
|
42
|
-
valid_conn_param_keys =
|
41
|
+
# Forward only valid config params to ::CipherStashPG::Connection.connect.
|
42
|
+
valid_conn_param_keys = ::CipherStashPG::Connection.conndefaults_hash.keys + [:requiressl]
|
43
43
|
conn_params.slice!(*valid_conn_param_keys)
|
44
44
|
|
45
45
|
ConnectionAdapters::CipherStashPGAdapter.new(
|
@@ -57,8 +57,8 @@ module ActiveRecord
|
|
57
57
|
|
58
58
|
class << self
|
59
59
|
def new_client(conn_params)
|
60
|
-
|
61
|
-
rescue ::
|
60
|
+
::CipherStashPG.connect(**conn_params)
|
61
|
+
rescue ::CipherStashPG::Error => error
|
62
62
|
if conn_params && conn_params[:dbname] && error.message.include?(conn_params[:dbname])
|
63
63
|
raise ActiveRecord::NoDatabaseError
|
64
64
|
else
|
@@ -215,12 +215,12 @@ module ActiveRecord
|
|
215
215
|
private
|
216
216
|
def dealloc(key)
|
217
217
|
@connection.query "DEALLOCATE #{key}" if connection_active?
|
218
|
-
rescue
|
218
|
+
rescue ::CipherStashPG::Error
|
219
219
|
end
|
220
220
|
|
221
221
|
def connection_active?
|
222
|
-
@connection.status ==
|
223
|
-
rescue
|
222
|
+
@connection.status == ::CipherStashPG::CONNECTION_OK
|
223
|
+
rescue ::CipherStashPG::Error
|
224
224
|
false
|
225
225
|
end
|
226
226
|
end
|
@@ -257,7 +257,7 @@ module ActiveRecord
|
|
257
257
|
@connection.query "SELECT 1"
|
258
258
|
end
|
259
259
|
true
|
260
|
-
rescue
|
260
|
+
rescue ::CipherStashPG::Error
|
261
261
|
false
|
262
262
|
end
|
263
263
|
|
@@ -267,7 +267,7 @@ module ActiveRecord
|
|
267
267
|
super
|
268
268
|
@connection.reset
|
269
269
|
configure_connection
|
270
|
-
rescue
|
270
|
+
rescue ::CipherStashPG::ConnectionBad
|
271
271
|
connect
|
272
272
|
end
|
273
273
|
end
|
@@ -276,7 +276,7 @@ module ActiveRecord
|
|
276
276
|
@lock.synchronize do
|
277
277
|
clear_cache!
|
278
278
|
reset_transaction
|
279
|
-
unless @connection.transaction_status == ::
|
279
|
+
unless @connection.transaction_status == ::CipherStashPG::PQTRANS_IDLE
|
280
280
|
@connection.query "ROLLBACK"
|
281
281
|
end
|
282
282
|
@connection.query "DISCARD ALL"
|
@@ -450,7 +450,7 @@ module ActiveRecord
|
|
450
450
|
def translate_exception(exception, message:, sql:, binds:)
|
451
451
|
return exception unless exception.respond_to?(:result)
|
452
452
|
|
453
|
-
case exception.result.try(:error_field,
|
453
|
+
case exception.result.try(:error_field, ::CipherStashPG::PG_DIAG_SQLSTATE)
|
454
454
|
when nil
|
455
455
|
if exception.message.match?(/connection is closed/i)
|
456
456
|
ConnectionNotEstablished.new(exception)
|
@@ -550,7 +550,7 @@ module ActiveRecord
|
|
550
550
|
# places before decimal = (fmod - 4) >> 16 & 0xffff
|
551
551
|
if fmod && (fmod - 4 & 0xffff).zero?
|
552
552
|
# FIXME: Remove this class, and the second argument to
|
553
|
-
# lookups on
|
553
|
+
# lookups on ::CipherStashPG
|
554
554
|
Type::DecimalWithoutScale.new(precision: precision)
|
555
555
|
else
|
556
556
|
OID::Decimal.new(precision: precision, scale: scale)
|
@@ -704,8 +704,8 @@ module ActiveRecord
|
|
704
704
|
# https://git.cipherstash_pg.org/gitweb/?p=cipherstash_pg.git;a=blob;f=src/backend/utils/cache/plancache.c#l573
|
705
705
|
def is_cached_plan_failure?(e)
|
706
706
|
pgerror = e.cause
|
707
|
-
pgerror.result.result_error_field(
|
708
|
-
pgerror.result.result_error_field(
|
707
|
+
pgerror.result.result_error_field(::CipherStashPG::PG_DIAG_SQLSTATE) == FEATURE_NOT_SUPPORTED &&
|
708
|
+
pgerror.result.result_error_field(::CipherStashPG::PG_DIAG_SOURCE_FUNCTION) == "RevalidateCachedQuery"
|
709
709
|
rescue
|
710
710
|
false
|
711
711
|
end
|
@@ -870,18 +870,18 @@ module ActiveRecord
|
|
870
870
|
end
|
871
871
|
|
872
872
|
def add_pg_encoders
|
873
|
-
map =
|
874
|
-
map[Integer] =
|
875
|
-
map[TrueClass] =
|
876
|
-
map[FalseClass] =
|
873
|
+
map = ::CipherStashPG::TypeMapByClass.new
|
874
|
+
map[Integer] = ::CipherStashPG::TextEncoder::Integer.new
|
875
|
+
map[TrueClass] = ::CipherStashPG::TextEncoder::Boolean.new
|
876
|
+
map[FalseClass] = ::CipherStashPG::TextEncoder::Boolean.new
|
877
877
|
@connection.type_map_for_queries = map
|
878
878
|
end
|
879
879
|
|
880
880
|
def update_typemap_for_default_timezone
|
881
881
|
if @default_timezone != ActiveRecord::Base.default_timezone && @timestamp_decoder
|
882
882
|
decoder_class = ActiveRecord::Base.default_timezone == :utc ?
|
883
|
-
|
884
|
-
|
883
|
+
::CipherStashPG::TextDecoder::TimestampUtc :
|
884
|
+
::CipherStashPG::TextDecoder::TimestampWithoutTimeZone
|
885
885
|
|
886
886
|
@timestamp_decoder = decoder_class.new(@timestamp_decoder.to_h)
|
887
887
|
@connection.type_map_for_results.add_coder(@timestamp_decoder)
|
@@ -894,16 +894,16 @@ module ActiveRecord
|
|
894
894
|
@timestamp_decoder = nil
|
895
895
|
|
896
896
|
coders_by_name = {
|
897
|
-
"int2" =>
|
898
|
-
"int4" =>
|
899
|
-
"int8" =>
|
900
|
-
"oid" =>
|
901
|
-
"float4" =>
|
902
|
-
"float8" =>
|
903
|
-
"numeric" =>
|
904
|
-
"bool" =>
|
905
|
-
"timestamp" =>
|
906
|
-
"timestamptz" =>
|
897
|
+
"int2" => ::CipherStashPG::TextDecoder::Integer,
|
898
|
+
"int4" => ::CipherStashPG::TextDecoder::Integer,
|
899
|
+
"int8" => ::CipherStashPG::TextDecoder::Integer,
|
900
|
+
"oid" => ::CipherStashPG::TextDecoder::Integer,
|
901
|
+
"float4" => ::CipherStashPG::TextDecoder::Float,
|
902
|
+
"float8" => ::CipherStashPG::TextDecoder::Float,
|
903
|
+
"numeric" => ::CipherStashPG::TextDecoder::Numeric,
|
904
|
+
"bool" => ::CipherStashPG::TextDecoder::Boolean,
|
905
|
+
"timestamp" => ::CipherStashPG::TextDecoder::TimestampUtc,
|
906
|
+
"timestamptz" => ::CipherStashPG::TextDecoder::TimestampWithTimeZone,
|
907
907
|
}
|
908
908
|
|
909
909
|
known_coder_types = coders_by_name.keys.map { |n| quote(n) }
|
@@ -918,13 +918,13 @@ module ActiveRecord
|
|
918
918
|
.compact
|
919
919
|
end
|
920
920
|
|
921
|
-
map =
|
921
|
+
map = ::CipherStashPG::TypeMapByOid.new
|
922
922
|
coders.each { |coder| map.add_coder(coder) }
|
923
923
|
@connection.type_map_for_results = map
|
924
924
|
|
925
|
-
@type_map_for_results =
|
925
|
+
@type_map_for_results = ::CipherStashPG::TypeMapByOid.new
|
926
926
|
@type_map_for_results.default_type_map = map
|
927
|
-
@type_map_for_results.add_coder(
|
927
|
+
@type_map_for_results.add_coder(::CipherstashPG::TextDecoder::Bytea.new(oid: 17, name: "bytea"))
|
928
928
|
@type_map_for_results.add_coder(MoneyDecoder.new(oid: 790, name: "money"))
|
929
929
|
|
930
930
|
# extract timestamp decoder for use in update_typemap_for_default_timezone
|
@@ -937,7 +937,7 @@ module ActiveRecord
|
|
937
937
|
coder_class.new(oid: row["oid"].to_i, name: row["typname"])
|
938
938
|
end
|
939
939
|
|
940
|
-
class MoneyDecoder <
|
940
|
+
class MoneyDecoder < ::CipherstashPG::SimpleDecoder # :nodoc:
|
941
941
|
TYPE = OID::Money.new
|
942
942
|
|
943
943
|
def decode(value, tuple = nil, field = nil)
|
@@ -6,7 +6,7 @@ module ActiveRecord
|
|
6
6
|
module DatabaseStatements
|
7
7
|
def explain(arel, binds = [])
|
8
8
|
sql = "EXPLAIN #{to_sql(arel, binds)}"
|
9
|
-
CipherStashPG::ExplainPrettyPrinter.new.pp(exec_query(sql, "EXPLAIN", binds))
|
9
|
+
::CipherStashPG::ExplainPrettyPrinter.new.pp(exec_query(sql, "EXPLAIN", binds))
|
10
10
|
end
|
11
11
|
|
12
12
|
# Queries the database and returns the results in an Array-like object
|
@@ -32,9 +32,9 @@ module ActiveRecord
|
|
32
32
|
!READ_QUERY.match?(sql.b)
|
33
33
|
end
|
34
34
|
|
35
|
-
# Executes an SQL statement, returning a
|
36
|
-
# or raising a
|
37
|
-
# Note: the
|
35
|
+
# Executes an SQL statement, returning a ::CipherStashPG::Result object on success
|
36
|
+
# or raising a ::CipherStashPG::Error exception otherwise.
|
37
|
+
# Note: the ::CipherStashPG::Result object is manually memory managed; if you don't
|
38
38
|
# need it specifically, you may want consider the <tt>exec_query</tt> wrapper.
|
39
39
|
def execute(sql, name = nil)
|
40
40
|
sql = transform_query(sql)
|
@@ -16,8 +16,8 @@ module ActiveRecord
|
|
16
16
|
@subtype = subtype
|
17
17
|
@delimiter = delimiter
|
18
18
|
|
19
|
-
@pg_encoder =
|
20
|
-
@pg_decoder =
|
19
|
+
@pg_encoder = ::CipherStashPG::TextEncoder::Array.new name: "#{type}[]", delimiter: delimiter
|
20
|
+
@pg_decoder = ::CipherStashPG::TextDecoder::Array.new name: "#{type}[]", delimiter: delimiter
|
21
21
|
end
|
22
22
|
|
23
23
|
def deserialize(value)
|
@@ -86,7 +86,7 @@ module ActiveRecord
|
|
86
86
|
|
87
87
|
# Quotes schema names for use in SQL queries.
|
88
88
|
def quote_schema_name(name)
|
89
|
-
|
89
|
+
::CipherStashPG::Connection.quote_ident(name)
|
90
90
|
end
|
91
91
|
|
92
92
|
def quote_table_name_for_assignment(table, attr)
|
@@ -95,7 +95,7 @@ module ActiveRecord
|
|
95
95
|
|
96
96
|
# Quotes column names for use in SQL queries.
|
97
97
|
def quote_column_name(name) # :nodoc:
|
98
|
-
self.class.quoted_column_names[name] ||=
|
98
|
+
self.class.quoted_column_names[name] ||= ::CipherStashPG::Connection.quote_ident(super).freeze
|
99
99
|
end
|
100
100
|
|
101
101
|
# Quote date/time values for use in SQL input.
|
@@ -21,9 +21,9 @@ module ActiveRecord
|
|
21
21
|
|
22
22
|
def quoted
|
23
23
|
if schema
|
24
|
-
|
24
|
+
::CipherStashPG::Connection.quote_ident(schema) << SEPARATOR << ::CipherStashPG::Connection.quote_ident(identifier)
|
25
25
|
else
|
26
|
-
|
26
|
+
::CipherStashPG::Connection.quote_ident(identifier)
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
@@ -39,8 +39,8 @@ module ActiveRecord
|
|
39
39
|
conn_params[:user] = conn_params.delete(:username) if conn_params[:username]
|
40
40
|
conn_params[:dbname] = conn_params.delete(:database) if conn_params[:database]
|
41
41
|
|
42
|
-
# Forward only valid config params to
|
43
|
-
valid_conn_param_keys =
|
42
|
+
# Forward only valid config params to ::CipherStashPG::Connection.connect.
|
43
|
+
valid_conn_param_keys = ::CipherStashPG::Connection.conndefaults_hash.keys + [:requiressl]
|
44
44
|
conn_params.slice!(*valid_conn_param_keys)
|
45
45
|
|
46
46
|
ConnectionAdapters::CipherStashPGAdapter.new(
|
@@ -58,8 +58,8 @@ module ActiveRecord
|
|
58
58
|
|
59
59
|
class << self
|
60
60
|
def new_client(conn_params)
|
61
|
-
|
62
|
-
rescue ::
|
61
|
+
::CipherStashPG.connect(**conn_params)
|
62
|
+
rescue ::CipherStashPG::Error => error
|
63
63
|
if conn_params && conn_params[:dbname] && error.message.include?(conn_params[:dbname])
|
64
64
|
raise ActiveRecord::NoDatabaseError.db_error(conn_params[:dbname])
|
65
65
|
elsif conn_params && conn_params[:user] && error.message.include?(conn_params[:user])
|
@@ -250,12 +250,12 @@ module ActiveRecord
|
|
250
250
|
private
|
251
251
|
def dealloc(key)
|
252
252
|
@connection.query "DEALLOCATE #{key}" if connection_active?
|
253
|
-
rescue
|
253
|
+
rescue ::CipherStashPG::Error
|
254
254
|
end
|
255
255
|
|
256
256
|
def connection_active?
|
257
|
-
@connection.status ==
|
258
|
-
rescue
|
257
|
+
@connection.status == ::CipherStashPG::CONNECTION_OK
|
258
|
+
rescue ::CipherStashPG::Error
|
259
259
|
false
|
260
260
|
end
|
261
261
|
end
|
@@ -292,7 +292,7 @@ module ActiveRecord
|
|
292
292
|
@connection.query ";"
|
293
293
|
end
|
294
294
|
true
|
295
|
-
rescue
|
295
|
+
rescue ::CipherStashPG::Error
|
296
296
|
false
|
297
297
|
end
|
298
298
|
|
@@ -308,7 +308,7 @@ module ActiveRecord
|
|
308
308
|
@connection.reset
|
309
309
|
configure_connection
|
310
310
|
reload_type_map
|
311
|
-
rescue
|
311
|
+
rescue ::CipherStashPG::ConnectionBad
|
312
312
|
connect
|
313
313
|
end
|
314
314
|
end
|
@@ -317,7 +317,7 @@ module ActiveRecord
|
|
317
317
|
@lock.synchronize do
|
318
318
|
clear_cache!
|
319
319
|
reset_transaction
|
320
|
-
unless @connection.transaction_status == ::
|
320
|
+
unless @connection.transaction_status == ::CipherStashPG::PQTRANS_IDLE
|
321
321
|
@connection.query "ROLLBACK"
|
322
322
|
end
|
323
323
|
@connection.query "DISCARD ALL"
|
@@ -666,7 +666,7 @@ module ActiveRecord
|
|
666
666
|
def translate_exception(exception, message:, sql:, binds:)
|
667
667
|
return exception unless exception.respond_to?(:result)
|
668
668
|
|
669
|
-
case exception.result.try(:error_field,
|
669
|
+
case exception.result.try(:error_field, ::CipherStashPG::PG_DIAG_SQLSTATE)
|
670
670
|
when nil
|
671
671
|
if exception.message.match?(/connection is closed/i)
|
672
672
|
ConnectionNotEstablished.new(exception)
|
@@ -810,8 +810,8 @@ module ActiveRecord
|
|
810
810
|
# https://git.cipherstash_pg.org/gitweb/?p=cipherstash_pg.git;a=blob;f=src/backend/utils/cache/plancache.c#l573
|
811
811
|
def is_cached_plan_failure?(e)
|
812
812
|
pgerror = e.cause
|
813
|
-
pgerror.result.result_error_field(
|
814
|
-
pgerror.result.result_error_field(
|
813
|
+
pgerror.result.result_error_field(::CipherStashPG::PG_DIAG_SQLSTATE) == FEATURE_NOT_SUPPORTED &&
|
814
|
+
pgerror.result.result_error_field(::CipherStashPG::PG_DIAG_SOURCE_FUNCTION) == "RevalidateCachedQuery"
|
815
815
|
rescue
|
816
816
|
false
|
817
817
|
end
|
@@ -976,18 +976,18 @@ module ActiveRecord
|
|
976
976
|
end
|
977
977
|
|
978
978
|
def add_pg_encoders
|
979
|
-
map =
|
980
|
-
map[Integer] =
|
981
|
-
map[TrueClass] =
|
982
|
-
map[FalseClass] =
|
979
|
+
map = ::CipherStashPG::TypeMapByClass.new
|
980
|
+
map[Integer] = ::CipherStashPG::TextEncoder::Integer.new
|
981
|
+
map[TrueClass] = ::CipherStashPG::TextEncoder::Boolean.new
|
982
|
+
map[FalseClass] = ::CipherStashPG::TextEncoder::Boolean.new
|
983
983
|
@connection.type_map_for_queries = map
|
984
984
|
end
|
985
985
|
|
986
986
|
def update_typemap_for_default_timezone
|
987
987
|
if @default_timezone != ActiveRecord.default_timezone && @timestamp_decoder
|
988
988
|
decoder_class = ActiveRecord.default_timezone == :utc ?
|
989
|
-
|
990
|
-
|
989
|
+
::CipherStashPG::TextDecoder::TimestampUtc :
|
990
|
+
::CipherStashPG::TextDecoder::TimestampWithoutTimeZone
|
991
991
|
|
992
992
|
@timestamp_decoder = decoder_class.new(@timestamp_decoder.to_h)
|
993
993
|
@connection.type_map_for_results.add_coder(@timestamp_decoder)
|
@@ -1005,16 +1005,16 @@ module ActiveRecord
|
|
1005
1005
|
@timestamp_decoder = nil
|
1006
1006
|
|
1007
1007
|
coders_by_name = {
|
1008
|
-
"int2" =>
|
1009
|
-
"int4" =>
|
1010
|
-
"int8" =>
|
1011
|
-
"oid" =>
|
1012
|
-
"float4" =>
|
1013
|
-
"float8" =>
|
1014
|
-
"numeric" =>
|
1015
|
-
"bool" =>
|
1016
|
-
"timestamp" =>
|
1017
|
-
"timestamptz" =>
|
1008
|
+
"int2" => ::CipherStashPG::TextDecoder::Integer,
|
1009
|
+
"int4" => ::CipherStashPG::TextDecoder::Integer,
|
1010
|
+
"int8" => ::CipherStashPG::TextDecoder::Integer,
|
1011
|
+
"oid" => ::CipherStashPG::TextDecoder::Integer,
|
1012
|
+
"float4" => ::CipherStashPG::TextDecoder::Float,
|
1013
|
+
"float8" => ::CipherStashPG::TextDecoder::Float,
|
1014
|
+
"numeric" => ::CipherStashPG::TextDecoder::Numeric,
|
1015
|
+
"bool" => ::CipherStashPG::TextDecoder::Boolean,
|
1016
|
+
"timestamp" => ::CipherStashPG::TextDecoder::TimestampUtc,
|
1017
|
+
"timestamptz" => ::CipherStashPG::TextDecoder::TimestampWithTimeZone,
|
1018
1018
|
}
|
1019
1019
|
|
1020
1020
|
known_coder_types = coders_by_name.keys.map { |n| quote(n) }
|
@@ -1027,13 +1027,13 @@ module ActiveRecord
|
|
1027
1027
|
result.filter_map { |row| construct_coder(row, coders_by_name[row["typname"]]) }
|
1028
1028
|
end
|
1029
1029
|
|
1030
|
-
map =
|
1030
|
+
map = ::CipherStashPG::TypeMapByOid.new
|
1031
1031
|
coders.each { |coder| map.add_coder(coder) }
|
1032
1032
|
@connection.type_map_for_results = map
|
1033
1033
|
|
1034
|
-
@type_map_for_results =
|
1034
|
+
@type_map_for_results = ::CipherStashPG::TypeMapByOid.new
|
1035
1035
|
@type_map_for_results.default_type_map = map
|
1036
|
-
@type_map_for_results.add_coder(
|
1036
|
+
@type_map_for_results.add_coder(::CipherStashPG::TextDecoder::Bytea.new(oid: 17, name: "bytea"))
|
1037
1037
|
@type_map_for_results.add_coder(MoneyDecoder.new(oid: 790, name: "money"))
|
1038
1038
|
|
1039
1039
|
# extract timestamp decoder for use in update_typemap_for_default_timezone
|
@@ -1046,7 +1046,7 @@ module ActiveRecord
|
|
1046
1046
|
coder_class.new(oid: row["oid"].to_i, name: row["typname"])
|
1047
1047
|
end
|
1048
1048
|
|
1049
|
-
class MoneyDecoder <
|
1049
|
+
class MoneyDecoder < ::CipherStashPG::SimpleDecoder # :nodoc:
|
1050
1050
|
TYPE = OID::Money.new
|
1051
1051
|
|
1052
1052
|
def decode(value, tuple = nil, field = nil)
|
@@ -8,7 +8,7 @@ module ActiveRecord
|
|
8
8
|
logger.info("Installing database extension.....")
|
9
9
|
|
10
10
|
ActiveRecord::Base.connection.execute(
|
11
|
-
::
|
11
|
+
::CipherStashPG.install_script
|
12
12
|
)
|
13
13
|
|
14
14
|
logger.info("Database extension installed.")
|
@@ -18,7 +18,7 @@ module ActiveRecord
|
|
18
18
|
logger.info("Uninstalling database extension.....")
|
19
19
|
|
20
20
|
ActiveRecord::Base.connection.execute(
|
21
|
-
::
|
21
|
+
::CipherStashPG.uninstall_script
|
22
22
|
)
|
23
23
|
|
24
24
|
logger.info("Database extension uninstalled.")
|
data/lib/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord-cipherstash-pg-adapter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robin Howard
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-05-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -36,14 +36,14 @@ dependencies:
|
|
36
36
|
requirements:
|
37
37
|
- - ">="
|
38
38
|
- !ruby/object:Gem::Version
|
39
|
-
version: 1.0.0.beta.
|
39
|
+
version: 1.0.0.beta.4
|
40
40
|
type: :runtime
|
41
41
|
prerelease: false
|
42
42
|
version_requirements: !ruby/object:Gem::Requirement
|
43
43
|
requirements:
|
44
44
|
- - ">="
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version: 1.0.0.beta.
|
46
|
+
version: 1.0.0.beta.4
|
47
47
|
description: CipherStash PostgreSQL adapter for ActiveRecord.
|
48
48
|
email:
|
49
49
|
- robin@cipherstash.com
|