activerecord-cipherstash-pg-adapter 0.6.1 → 0.7.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 +4 -4
- 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 +2 -2
- 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: afdad58f343c08018a15ea22511db38a98753bf6c9247fc361599a23277403f8
|
4
|
+
data.tar.gz: 0ad35166f2df40d1ac6f0267ea6d6bb82873558b48c8714cae61e3cb07eb4892
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ec7f1f9f7748f4a4730fa1df4d62199f8ca4b1a62092e19b1318d6d0d8586c4e6e2d7286432c8ccf6f749ffa6bdd595ae5deca17ec80f523e156103703e0b203
|
7
|
+
data.tar.gz: 86187ee7f4cac227c6f68273c72130d022958dd0a2cd3f13201c3f7ae1bc3f1cb5aef368b555247b554e013d44307d0eef96820387e66ce6eb4c5a9d1980a5e4
|
@@ -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.3"
|
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
|
|
@@ -57,7 +57,7 @@ module ActiveRecord
|
|
57
57
|
|
58
58
|
class << self
|
59
59
|
def new_client(conn_params)
|
60
|
-
|
60
|
+
::CipherStashPG.connect(**conn_params)
|
61
61
|
rescue ::PG::Error => error
|
62
62
|
if conn_params && conn_params[:dbname] && error.message.include?(conn_params[:dbname])
|
63
63
|
raise ActiveRecord::NoDatabaseError
|
@@ -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.0
|
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-01 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.3
|
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.3
|
47
47
|
description: CipherStash PostgreSQL adapter for ActiveRecord.
|
48
48
|
email:
|
49
49
|
- robin@cipherstash.com
|