cipherstash-pg 1.0.0.beta.1-x86_64-linux → 1.0.0.beta.4-x86_64-linux

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.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/.appveyor.yml +42 -0
  3. data/.gems +6 -0
  4. data/.gemtest +0 -0
  5. data/.github/workflows/binary-gems.yml +117 -0
  6. data/.github/workflows/source-gem.yml +137 -0
  7. data/.gitignore +19 -0
  8. data/.hgsigs +34 -0
  9. data/.hgtags +41 -0
  10. data/.irbrc +23 -0
  11. data/.pryrc +23 -0
  12. data/.tm_properties +21 -0
  13. data/.travis.yml +49 -0
  14. data/Gemfile +3 -3
  15. data/Gemfile.lock +45 -0
  16. data/{History.rdoc → History.md} +168 -153
  17. data/README.ja.md +266 -0
  18. data/README.md +272 -0
  19. data/Rakefile +65 -104
  20. data/Rakefile.cross +298 -0
  21. data/certs/larskanis-2023.pem +24 -0
  22. data/cipherstash-pg.gemspec +0 -0
  23. data/lib/2.7/pg_ext.so +0 -0
  24. data/lib/3.0/pg_ext.so +0 -0
  25. data/lib/3.1/pg_ext.so +0 -0
  26. data/lib/3.2/pg_ext.so +0 -0
  27. data/lib/cipherstash-pg/basic_type_map_based_on_result.rb +11 -0
  28. data/lib/cipherstash-pg/basic_type_map_for_queries.rb +113 -0
  29. data/lib/cipherstash-pg/basic_type_map_for_results.rb +30 -0
  30. data/lib/cipherstash-pg/basic_type_registry.rb +206 -0
  31. data/lib/cipherstash-pg/binary_decoder.rb +21 -0
  32. data/lib/cipherstash-pg/coder.rb +82 -0
  33. data/lib/cipherstash-pg/connection.rb +467 -0
  34. data/lib/cipherstash-pg/constants.rb +3 -0
  35. data/lib/cipherstash-pg/exceptions.rb +19 -0
  36. data/lib/cipherstash-pg/result.rb +22 -0
  37. data/lib/cipherstash-pg/text_decoder.rb +43 -0
  38. data/lib/cipherstash-pg/text_encoder.rb +67 -0
  39. data/lib/cipherstash-pg/tuple.rb +24 -0
  40. data/lib/cipherstash-pg/type_map_by_column.rb +11 -0
  41. data/lib/cipherstash-pg/version.rb +3 -0
  42. data/lib/cipherstash-pg.rb +56 -11
  43. data/lib/libpq.so.5 +0 -0
  44. data/misc/openssl-pg-segfault.rb +15 -25
  45. data/misc/postgres/Rakefile +13 -20
  46. data/misc/postgres/lib/postgres.rb +10 -14
  47. data/misc/ruby-pg/Rakefile +13 -20
  48. data/misc/ruby-pg/lib/ruby/pg.rb +10 -14
  49. data/rakelib/task_extension.rb +17 -31
  50. data/sample/array_insert.rb +7 -20
  51. data/sample/async_api.rb +54 -96
  52. data/sample/async_copyto.rb +20 -35
  53. data/sample/async_mixed.rb +22 -50
  54. data/sample/check_conn.rb +8 -20
  55. data/sample/copydata.rb +18 -68
  56. data/sample/copyfrom.rb +26 -78
  57. data/sample/copyto.rb +10 -16
  58. data/sample/cursor.rb +9 -19
  59. data/sample/disk_usage_report.rb +89 -174
  60. data/sample/issue-119.rb +45 -93
  61. data/sample/losample.rb +48 -66
  62. data/sample/minimal-testcase.rb +6 -17
  63. data/sample/notify_wait.rb +21 -67
  64. data/sample/pg_statistics.rb +100 -281
  65. data/sample/replication_monitor.rb +119 -218
  66. data/sample/test_binary_values.rb +14 -30
  67. data/sample/wal_shipper.rb +199 -431
  68. data/sample/warehouse_partitions.rb +157 -307
  69. data/translation/.po4a-version +7 -0
  70. data/translation/po/all.pot +875 -0
  71. data/translation/po/ja.po +868 -0
  72. data/translation/po4a.cfg +9 -0
  73. metadata +50 -28
  74. data/README.ja.rdoc +0 -13
  75. data/README.rdoc +0 -233
  76. data/lib/pg/basic_type_map_based_on_result.rb +0 -47
  77. data/lib/pg/basic_type_map_for_queries.rb +0 -193
  78. data/lib/pg/basic_type_map_for_results.rb +0 -81
  79. data/lib/pg/basic_type_registry.rb +0 -301
  80. data/lib/pg/binary_decoder.rb +0 -23
  81. data/lib/pg/coder.rb +0 -104
  82. data/lib/pg/connection.rb +0 -878
  83. data/lib/pg/constants.rb +0 -12
  84. data/lib/pg/exceptions.rb +0 -18
  85. data/lib/pg/result.rb +0 -43
  86. data/lib/pg/text_decoder.rb +0 -46
  87. data/lib/pg/text_encoder.rb +0 -59
  88. data/lib/pg/tuple.rb +0 -30
  89. data/lib/pg/type_map_by_column.rb +0 -16
  90. data/lib/pg/version.rb +0 -4
  91. data/lib/pg.rb +0 -55
@@ -0,0 +1,206 @@
1
+ require("cipherstash-pg") unless defined? CipherStashPG
2
+ class CipherStashPG::BasicTypeRegistry
3
+ class CoderMap
4
+ DONT_QUOTE_TYPES = ["int2", "int4", "int8", "float4", "float8", "oid", "bool", "date", "timestamp", "timestamptz"].inject({}) do |h, e|
5
+ h[e] = true
6
+ h
7
+ end
8
+
9
+ def initialize(result, coders_by_name, format, arraycoder)
10
+ coder_map = {}
11
+ arrays, nodes = result.partition { |row| (row["typinput"] == "array_in") }
12
+ nodes.find_all { |row| coders_by_name.key?(row["typname"]) }.each do |row|
13
+ coder = coders_by_name[row["typname"]].dup
14
+ coder.oid = row["oid"].to_i
15
+ coder.name = row["typname"]
16
+ coder.format = format
17
+ coder_map[coder.oid] = coder
18
+ end
19
+ if arraycoder then
20
+ arrays.each do |row|
21
+ elements_coder = coder_map[row["typelem"].to_i]
22
+ next unless elements_coder
23
+ coder = arraycoder.new
24
+ coder.oid = row["oid"].to_i
25
+ coder.name = row["typname"]
26
+ coder.format = format
27
+ coder.elements_type = elements_coder
28
+ coder.needs_quotation = (not DONT_QUOTE_TYPES[elements_coder.name])
29
+ coder_map[coder.oid] = coder
30
+ end
31
+ end
32
+ @coders = coder_map.values
33
+ @coders_by_name = @coders.inject({}) do |h, t|
34
+ h[t.name] = t
35
+ h
36
+ end
37
+ @coders_by_oid = @coders.inject({}) do |h, t|
38
+ h[t.oid] = t
39
+ h
40
+ end
41
+ end
42
+
43
+ attr_reader(:coders)
44
+
45
+ attr_reader(:coders_by_oid)
46
+
47
+ attr_reader(:coders_by_name)
48
+
49
+ def coder_by_name(name)
50
+ @coders_by_name[name]
51
+ end
52
+
53
+ def coder_by_oid(oid)
54
+ @coders_by_oid[oid]
55
+ end
56
+ end
57
+
58
+ class CoderMapsBundle
59
+ attr_reader(:typenames_by_oid)
60
+
61
+ def initialize(connection, registry: nil)
62
+ registry ||= DEFAULT_TYPE_REGISTRY
63
+ result = connection.exec("\t\t\t\tSELECT t.oid, t.typname, t.typelem, t.typdelim, ti.proname AS typinput\n\t\t\t\tFROM pg_type as t\n\t\t\t\tJOIN pg_proc as ti ON ti.oid = t.typinput\n").to_a
64
+ @maps = [[0, :encoder, CipherStashPG::TextEncoder::Array], [0, :decoder, CipherStashPG::TextDecoder::Array], [1, :encoder, nil], [1, :decoder, nil]].inject([]) do |h, (format, direction, arraycoder)|
65
+ coders = (registry.coders_for(format, direction) or {})
66
+ h[format] ||= {}
67
+ h[format][direction] = CoderMap.new(result, coders, format, arraycoder)
68
+ h
69
+ end
70
+ @typenames_by_oid = result.inject({}) do |h, t|
71
+ h[t["oid"].to_i] = t["typname"]
72
+ h
73
+ end
74
+ end
75
+
76
+ def each_format(direction)
77
+ @maps.map { |f| f[direction] }
78
+ end
79
+
80
+ def map_for(format, direction)
81
+ @maps[format][direction]
82
+ end
83
+ end
84
+
85
+ module Checker
86
+ ValidFormats = { 0 => true, 1 => true }
87
+
88
+ ValidDirections = { :encoder => true, :decoder => true }
89
+
90
+ protected(def check_format_and_direction(format, direction)
91
+ unless ValidFormats[format] then
92
+ raise(ArgumentError, ("Invalid format value %p" % format))
93
+ end
94
+ unless ValidDirections[direction] then
95
+ raise(ArgumentError, ("Invalid direction %p" % direction))
96
+ end
97
+ end)
98
+
99
+ protected(def build_coder_maps(conn_or_maps, registry: nil)
100
+ if conn_or_maps.is_a?(CipherStashPG::BasicTypeRegistry::CoderMapsBundle) then
101
+ if registry then
102
+ raise(ArgumentError, "registry argument must be given to CoderMapsBundle")
103
+ end
104
+ conn_or_maps
105
+ else
106
+ CipherStashPG::BasicTypeRegistry::CoderMapsBundle.new(conn_or_maps, :registry => registry)
107
+ end
108
+ end)
109
+ end
110
+
111
+ include(Checker)
112
+
113
+ def initialize
114
+ @coders_by_name = []
115
+ end
116
+
117
+ def coders_for(format, direction)
118
+ check_format_and_direction(format, direction)
119
+ @coders_by_name[format][direction]
120
+ end
121
+
122
+ def register_coder(coder)
123
+ h = @coders_by_name[coder.format] ||= { :encoder => ({}), :decoder => ({}) }
124
+ name = (coder.name or raise(ArgumentError, "name of #{coder.inspect} must be defined"))
125
+ h[:encoder][name] = coder if coder.respond_to?(:encode)
126
+ h[:decoder][name] = coder if coder.respond_to?(:decode)
127
+ self
128
+ end
129
+
130
+ def register_type(format, name, encoder_class, decoder_class)
131
+ if encoder_class then
132
+ register_coder(encoder_class.new(:name => name, :format => format))
133
+ end
134
+ if decoder_class then
135
+ register_coder(decoder_class.new(:name => name, :format => format))
136
+ end
137
+ self
138
+ end
139
+
140
+ def alias_type(format, new, old)
141
+ [:encoder, :decoder].each do |ende|
142
+ enc = @coders_by_name[format][ende][old]
143
+ if enc then
144
+ @coders_by_name[format][ende][new] = enc
145
+ else
146
+ @coders_by_name[format][ende].delete(new)
147
+ end
148
+ end
149
+ self
150
+ end
151
+
152
+ def register_default_types
153
+ register_type(0, "int2", CipherStashPG::TextEncoder::Integer, CipherStashPG::TextDecoder::Integer)
154
+ alias_type(0, "int4", "int2")
155
+ alias_type(0, "int8", "int2")
156
+ alias_type(0, "oid", "int2")
157
+ register_type(0, "numeric", CipherStashPG::TextEncoder::Numeric, CipherStashPG::TextDecoder::Numeric)
158
+ register_type(0, "text", CipherStashPG::TextEncoder::String, CipherStashPG::TextDecoder::String)
159
+ alias_type(0, "varchar", "text")
160
+ alias_type(0, "char", "text")
161
+ alias_type(0, "bpchar", "text")
162
+ alias_type(0, "xml", "text")
163
+ alias_type(0, "name", "text")
164
+ register_type(0, "bytea", nil, CipherStashPG::TextDecoder::Bytea)
165
+ register_type(0, "bool", CipherStashPG::TextEncoder::Boolean, CipherStashPG::TextDecoder::Boolean)
166
+ register_type(0, "float4", CipherStashPG::TextEncoder::Float, CipherStashPG::TextDecoder::Float)
167
+ alias_type(0, "float8", "float4")
168
+ register_type(0, "timestamp", CipherStashPG::TextEncoder::TimestampWithoutTimeZone, CipherStashPG::TextDecoder::TimestampWithoutTimeZone)
169
+ register_type(0, "timestamptz", CipherStashPG::TextEncoder::TimestampWithTimeZone, CipherStashPG::TextDecoder::TimestampWithTimeZone)
170
+ register_type(0, "date", CipherStashPG::TextEncoder::Date, CipherStashPG::TextDecoder::Date)
171
+ register_type(0, "json", CipherStashPG::TextEncoder::JSON, CipherStashPG::TextDecoder::JSON)
172
+ alias_type(0, "jsonb", "json")
173
+ register_type(0, "inet", CipherStashPG::TextEncoder::Inet, CipherStashPG::TextDecoder::Inet)
174
+ alias_type(0, "cidr", "inet")
175
+ register_type(1, "int2", CipherStashPG::BinaryEncoder::Int2, CipherStashPG::BinaryDecoder::Integer)
176
+ register_type(1, "int4", CipherStashPG::BinaryEncoder::Int4, CipherStashPG::BinaryDecoder::Integer)
177
+ register_type(1, "int8", CipherStashPG::BinaryEncoder::Int8, CipherStashPG::BinaryDecoder::Integer)
178
+ alias_type(1, "oid", "int2")
179
+ register_type(1, "text", CipherStashPG::BinaryEncoder::String, CipherStashPG::BinaryDecoder::String)
180
+ alias_type(1, "varchar", "text")
181
+ alias_type(1, "char", "text")
182
+ alias_type(1, "bpchar", "text")
183
+ alias_type(1, "xml", "text")
184
+ alias_type(1, "name", "text")
185
+ register_type(1, "bytea", CipherStashPG::BinaryEncoder::Bytea, CipherStashPG::BinaryDecoder::Bytea)
186
+ register_type(1, "bool", CipherStashPG::BinaryEncoder::Boolean, CipherStashPG::BinaryDecoder::Boolean)
187
+ register_type(1, "float4", nil, CipherStashPG::BinaryDecoder::Float)
188
+ register_type(1, "float8", nil, CipherStashPG::BinaryDecoder::Float)
189
+ register_type(1, "timestamp", nil, CipherStashPG::BinaryDecoder::TimestampUtc)
190
+ register_type(1, "timestamptz", nil, CipherStashPG::BinaryDecoder::TimestampUtcToLocal)
191
+ self
192
+ end
193
+
194
+ alias :define_default_types :register_default_types
195
+
196
+ DEFAULT_TYPE_REGISTRY = CipherStashPG::BasicTypeRegistry.new.register_default_types
197
+
198
+ class << self
199
+ [:register_coder, :register_type, :alias_type].each do |meth|
200
+ define_method(meth) do |*args|
201
+ warn("PG::BasicTypeRegistry.#{meth} is deprecated. Please use your own instance by PG::BasicTypeRegistry.new instead!")
202
+ DEFAULT_TYPE_REGISTRY.send(meth, *args)
203
+ end
204
+ end
205
+ end
206
+ end
@@ -0,0 +1,21 @@
1
+ module CipherStashPG
2
+ module BinaryDecoder
3
+ class TimestampUtc < Timestamp
4
+ def initialize(params = {})
5
+ super(params.merge(:flags => (CipherStashPG::Coder::TIMESTAMP_DB_UTC | CipherStashPG::Coder::TIMESTAMP_APP_UTC)))
6
+ end
7
+ end
8
+
9
+ class TimestampUtcToLocal < Timestamp
10
+ def initialize(params = {})
11
+ super(params.merge(:flags => (CipherStashPG::Coder::TIMESTAMP_DB_UTC | CipherStashPG::Coder::TIMESTAMP_APP_LOCAL)))
12
+ end
13
+ end
14
+
15
+ class TimestampLocal < Timestamp
16
+ def initialize(params = {})
17
+ super(params.merge(:flags => (CipherStashPG::Coder::TIMESTAMP_DB_LOCAL | CipherStashPG::Coder::TIMESTAMP_APP_LOCAL)))
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,82 @@
1
+ module CipherStashPG
2
+ class Coder
3
+ module BinaryFormatting
4
+ Params = { :format => 1 }
5
+
6
+ def initialize(params = {})
7
+ super(Params.merge(params))
8
+ end
9
+ end
10
+
11
+ def initialize(params = {})
12
+ params.each { |key, val| send("#{key}=", val) }
13
+ end
14
+
15
+ def dup
16
+ self.class.new(to_h)
17
+ end
18
+
19
+ def to_h
20
+ { :oid => oid, :format => format, :flags => flags, :name => name }
21
+ end
22
+
23
+ def ==(v)
24
+ (self.class == v.class) and (to_h == v.to_h)
25
+ end
26
+
27
+ def marshal_dump
28
+ Marshal.dump(to_h)
29
+ end
30
+
31
+ def marshal_load(str)
32
+ initialize(Marshal.load(str))
33
+ end
34
+
35
+ def inspect
36
+ str = self.to_s
37
+ oid_str = " oid=#{oid}" unless (oid == 0)
38
+ format_str = " format=#{format}" unless (format == 0)
39
+ name_str = " #{name.inspect}" if name
40
+ str[-1, 0] = "#{name_str} #{oid_str}#{format_str}"
41
+ str
42
+ end
43
+
44
+ def inspect_short
45
+ str = case format
46
+ when 0 then
47
+ "T"
48
+ when 1 then
49
+ "B"
50
+ else
51
+ format.to_s
52
+ end
53
+ str = (str + "E") if respond_to?(:encode)
54
+ str = (str + "D") if respond_to?(:decode)
55
+ "#{(name or self.class.name)}:#{str}"
56
+ end
57
+ end
58
+
59
+ class CompositeCoder < Coder
60
+ def to_h
61
+ super.merge!(:elements_type => elements_type, :needs_quotation => needs_quotation?, :delimiter => delimiter)
62
+ end
63
+
64
+ def inspect
65
+ str = super
66
+ str[-1, 0] = " elements_type=#{elements_type.inspect} #{needs_quotation? ? ("needs") : ("no")} quotation"
67
+ str
68
+ end
69
+ end
70
+
71
+ class CopyCoder < Coder
72
+ def to_h
73
+ super.merge!(:type_map => type_map, :delimiter => delimiter, :null_string => null_string)
74
+ end
75
+ end
76
+
77
+ class RecordCoder < Coder
78
+ def to_h
79
+ super.merge!(:type_map => type_map)
80
+ end
81
+ end
82
+ end