pg 1.6.0.rc1-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 (118) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +4 -0
  3. data/BSDL +22 -0
  4. data/Contributors.rdoc +46 -0
  5. data/Gemfile +23 -0
  6. data/History.md +958 -0
  7. data/LICENSE +56 -0
  8. data/Manifest.txt +72 -0
  9. data/POSTGRES +23 -0
  10. data/README-OS_X.rdoc +68 -0
  11. data/README-Windows.rdoc +56 -0
  12. data/README.ja.md +300 -0
  13. data/README.md +286 -0
  14. data/Rakefile +161 -0
  15. data/certs/ged.pem +24 -0
  16. data/certs/kanis@comcard.de.pem +20 -0
  17. data/certs/larskanis-2022.pem +26 -0
  18. data/certs/larskanis-2023.pem +24 -0
  19. data/certs/larskanis-2024.pem +24 -0
  20. data/ext/errorcodes.def +1043 -0
  21. data/ext/errorcodes.rb +45 -0
  22. data/ext/errorcodes.txt +494 -0
  23. data/ext/extconf.rb +282 -0
  24. data/ext/gvl_wrappers.c +32 -0
  25. data/ext/gvl_wrappers.h +297 -0
  26. data/ext/pg.c +703 -0
  27. data/ext/pg.h +390 -0
  28. data/ext/pg_binary_decoder.c +460 -0
  29. data/ext/pg_binary_encoder.c +583 -0
  30. data/ext/pg_cancel_connection.c +360 -0
  31. data/ext/pg_coder.c +622 -0
  32. data/ext/pg_connection.c +4869 -0
  33. data/ext/pg_copy_coder.c +921 -0
  34. data/ext/pg_errors.c +95 -0
  35. data/ext/pg_record_coder.c +522 -0
  36. data/ext/pg_result.c +1764 -0
  37. data/ext/pg_text_decoder.c +1008 -0
  38. data/ext/pg_text_encoder.c +833 -0
  39. data/ext/pg_tuple.c +572 -0
  40. data/ext/pg_type_map.c +200 -0
  41. data/ext/pg_type_map_all_strings.c +130 -0
  42. data/ext/pg_type_map_by_class.c +271 -0
  43. data/ext/pg_type_map_by_column.c +355 -0
  44. data/ext/pg_type_map_by_mri_type.c +313 -0
  45. data/ext/pg_type_map_by_oid.c +388 -0
  46. data/ext/pg_type_map_in_ruby.c +333 -0
  47. data/ext/pg_util.c +149 -0
  48. data/ext/pg_util.h +65 -0
  49. data/ext/vc/pg.sln +26 -0
  50. data/ext/vc/pg_18/pg.vcproj +216 -0
  51. data/ext/vc/pg_19/pg_19.vcproj +209 -0
  52. data/lib/2.7/pg_ext.so +0 -0
  53. data/lib/3.0/pg_ext.so +0 -0
  54. data/lib/3.1/pg_ext.so +0 -0
  55. data/lib/3.2/pg_ext.so +0 -0
  56. data/lib/3.3/pg_ext.so +0 -0
  57. data/lib/pg/basic_type_map_based_on_result.rb +67 -0
  58. data/lib/pg/basic_type_map_for_queries.rb +202 -0
  59. data/lib/pg/basic_type_map_for_results.rb +104 -0
  60. data/lib/pg/basic_type_registry.rb +311 -0
  61. data/lib/pg/binary_decoder/date.rb +9 -0
  62. data/lib/pg/binary_decoder/timestamp.rb +26 -0
  63. data/lib/pg/binary_encoder/timestamp.rb +20 -0
  64. data/lib/pg/cancel_connection.rb +30 -0
  65. data/lib/pg/coder.rb +106 -0
  66. data/lib/pg/connection.rb +1027 -0
  67. data/lib/pg/exceptions.rb +31 -0
  68. data/lib/pg/result.rb +43 -0
  69. data/lib/pg/text_decoder/date.rb +21 -0
  70. data/lib/pg/text_decoder/inet.rb +9 -0
  71. data/lib/pg/text_decoder/json.rb +17 -0
  72. data/lib/pg/text_decoder/numeric.rb +9 -0
  73. data/lib/pg/text_decoder/timestamp.rb +30 -0
  74. data/lib/pg/text_encoder/date.rb +13 -0
  75. data/lib/pg/text_encoder/inet.rb +31 -0
  76. data/lib/pg/text_encoder/json.rb +17 -0
  77. data/lib/pg/text_encoder/numeric.rb +9 -0
  78. data/lib/pg/text_encoder/timestamp.rb +24 -0
  79. data/lib/pg/tuple.rb +30 -0
  80. data/lib/pg/type_map_by_column.rb +16 -0
  81. data/lib/pg/version.rb +4 -0
  82. data/lib/pg.rb +144 -0
  83. data/misc/openssl-pg-segfault.rb +31 -0
  84. data/misc/postgres/History.txt +9 -0
  85. data/misc/postgres/Manifest.txt +5 -0
  86. data/misc/postgres/README.txt +21 -0
  87. data/misc/postgres/Rakefile +21 -0
  88. data/misc/postgres/lib/postgres.rb +16 -0
  89. data/misc/ruby-pg/History.txt +9 -0
  90. data/misc/ruby-pg/Manifest.txt +5 -0
  91. data/misc/ruby-pg/README.txt +21 -0
  92. data/misc/ruby-pg/Rakefile +21 -0
  93. data/misc/ruby-pg/lib/ruby/pg.rb +16 -0
  94. data/pg.gemspec +36 -0
  95. data/ports/x86_64-linux/lib/libpq-ruby-pg.so.1 +0 -0
  96. data/rakelib/task_extension.rb +46 -0
  97. data/sample/array_insert.rb +20 -0
  98. data/sample/async_api.rb +102 -0
  99. data/sample/async_copyto.rb +39 -0
  100. data/sample/async_mixed.rb +56 -0
  101. data/sample/check_conn.rb +21 -0
  102. data/sample/copydata.rb +71 -0
  103. data/sample/copyfrom.rb +81 -0
  104. data/sample/copyto.rb +19 -0
  105. data/sample/cursor.rb +21 -0
  106. data/sample/disk_usage_report.rb +177 -0
  107. data/sample/issue-119.rb +94 -0
  108. data/sample/losample.rb +69 -0
  109. data/sample/minimal-testcase.rb +17 -0
  110. data/sample/notify_wait.rb +72 -0
  111. data/sample/pg_statistics.rb +285 -0
  112. data/sample/replication_monitor.rb +222 -0
  113. data/sample/test_binary_values.rb +33 -0
  114. data/sample/wal_shipper.rb +434 -0
  115. data/sample/warehouse_partitions.rb +311 -0
  116. data.tar.gz.sig +0 -0
  117. metadata +252 -0
  118. metadata.gz.sig +0 -0
data/README.md ADDED
@@ -0,0 +1,286 @@
1
+ # pg
2
+
3
+ * home :: https://github.com/ged/ruby-pg
4
+ * docs :: http://deveiate.org/code/pg (English) ,
5
+ https://deveiate.org/code/pg/README_ja_md.html (Japanese)
6
+ * clog :: link:/History.md
7
+
8
+ [![Join the chat at https://gitter.im/ged/ruby-pg](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/ged/ruby-pg?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
9
+
10
+
11
+ ## Description
12
+
13
+ Pg is the Ruby interface to the [PostgreSQL RDBMS](http://www.postgresql.org/).
14
+ It works with [PostgreSQL 10 and later](http://www.postgresql.org/support/versioning/).
15
+
16
+ A small example usage:
17
+ ```ruby
18
+ #!/usr/bin/env ruby
19
+
20
+ require 'pg'
21
+
22
+ # Output a table of current connections to the DB
23
+ conn = PG.connect( dbname: 'sales' )
24
+ conn.exec( "SELECT * FROM pg_stat_activity" ) do |result|
25
+ puts " PID | User | Query"
26
+ result.each do |row|
27
+ puts " %7d | %-16s | %s " %
28
+ row.values_at('pid', 'usename', 'query')
29
+ end
30
+ end
31
+ ```
32
+
33
+ ## Build Status
34
+
35
+ [![Build Status Github Actions](https://github.com/ged/ruby-pg/actions/workflows/source-gem.yml/badge.svg?branch=master)](https://github.com/ged/ruby-pg/actions/workflows/source-gem.yml)
36
+ [![Binary gems](https://github.com/ged/ruby-pg/actions/workflows/binary-gems.yml/badge.svg?branch=master)](https://github.com/ged/ruby-pg/actions/workflows/binary-gems.yml)
37
+ [![Build Status Appveyor](https://ci.appveyor.com/api/projects/status/gjx5axouf3b1wicp?svg=true)](https://ci.appveyor.com/project/ged/ruby-pg-9j8l3)
38
+
39
+
40
+ ## Requirements
41
+
42
+ * Ruby 2.7 or newer
43
+ * PostgreSQL 10.x or later (with headers, -dev packages, etc).
44
+
45
+ It usually works with earlier versions of Ruby/PostgreSQL as well, but those are
46
+ not regularly tested.
47
+
48
+
49
+ ## Versioning
50
+
51
+ We tag and release gems according to the [Semantic Versioning](http://semver.org/) principle.
52
+
53
+ As a result of this policy, you can (and should) specify a dependency on this gem using the [Pessimistic Version Constraint](http://guides.rubygems.org/patterns/#pessimistic-version-constraint) with two digits of precision.
54
+
55
+ For example:
56
+
57
+ ```ruby
58
+ spec.add_dependency 'pg', '~> 1.0'
59
+ ```
60
+
61
+ ## How To Install
62
+
63
+ Install via RubyGems:
64
+
65
+ gem install pg
66
+
67
+ You may need to specify the path to the 'pg_config' program installed with
68
+ Postgres:
69
+
70
+ gem install pg -- --with-pg-config=<path to pg_config>
71
+
72
+ If you're installing via Bundler, you can provide compile hints like so:
73
+
74
+ bundle config build.pg --with-pg-config=<path to pg_config>
75
+
76
+ See README-OS_X.rdoc for more information about installing under MacOS X, and
77
+ README-Windows.rdoc for Windows build/installation instructions.
78
+
79
+ There's also [a Google+ group](http://goo.gl/TFy1U) and a
80
+ [mailing list](http://groups.google.com/group/ruby-pg) if you get stuck, or just
81
+ want to chat about something.
82
+
83
+ If you want to install as a signed gem, the public certs of the gem signers
84
+ can be found in [the `certs` directory](https://github.com/ged/ruby-pg/tree/master/certs)
85
+ of the repository.
86
+
87
+
88
+ ## Type Casts
89
+
90
+ Pg can optionally type cast result values and query parameters in Ruby or
91
+ native C code. This can speed up data transfers to and from the database,
92
+ because String allocations are reduced and conversions in (slower) Ruby code
93
+ can be omitted.
94
+
95
+ Very basic type casting can be enabled by:
96
+ ```ruby
97
+ conn.type_map_for_results = PG::BasicTypeMapForResults.new conn
98
+ # ... this works for result value mapping:
99
+ conn.exec("select 1, now(), '{2,3}'::int[]").values
100
+ # => [[1, 2014-09-21 20:51:56 +0200, [2, 3]]]
101
+
102
+ conn.type_map_for_queries = PG::BasicTypeMapForQueries.new conn
103
+ # ... and this for param value mapping:
104
+ conn.exec_params("SELECT $1::text, $2::text, $3::text", [1, 1.23, [2,3]]).values
105
+ # => [["1", "1.2300000000000000E+00", "{2,3}"]]
106
+ ```
107
+
108
+ But Pg's type casting is highly customizable. That's why it's divided into
109
+ 2 layers:
110
+
111
+ ### Encoders / Decoders (ext/pg_*coder.c, lib/pg/*coder.rb)
112
+
113
+ This is the lower layer, containing encoding classes that convert Ruby
114
+ objects for transmission to the DBMS and decoding classes to convert
115
+ received data back to Ruby objects. The classes are namespaced according
116
+ to their format and direction in PG::TextEncoder, PG::TextDecoder,
117
+ PG::BinaryEncoder and PG::BinaryDecoder.
118
+
119
+ It is possible to assign a type OID, format code (text or binary) and
120
+ optionally a name to an encoder or decoder object. It's also possible
121
+ to build composite types by assigning an element encoder/decoder.
122
+ PG::Coder objects can be used to set up a PG::TypeMap or alternatively
123
+ to convert single values to/from their string representation.
124
+
125
+ The following PostgreSQL column types are supported by ruby-pg (TE = Text Encoder, TD = Text Decoder, BE = Binary Encoder, BD = Binary Decoder):
126
+
127
+ * Integer: [TE](rdoc-ref:PG::TextEncoder::Integer), [TD](rdoc-ref:PG::TextDecoder::Integer), [BD](rdoc-ref:PG::BinaryDecoder::Integer) 💡 No links? Switch to [here](https://deveiate.org/code/pg/README_md.html#label-Type+Casts) 💡
128
+ * BE: [Int2](rdoc-ref:PG::BinaryEncoder::Int2), [Int4](rdoc-ref:PG::BinaryEncoder::Int4), [Int8](rdoc-ref:PG::BinaryEncoder::Int8)
129
+ * Float: [TE](rdoc-ref:PG::TextEncoder::Float), [TD](rdoc-ref:PG::TextDecoder::Float), [BD](rdoc-ref:PG::BinaryDecoder::Float)
130
+ * BE: [Float4](rdoc-ref:PG::BinaryEncoder::Float4), [Float8](rdoc-ref:PG::BinaryEncoder::Float8)
131
+ * Numeric: [TE](rdoc-ref:PG::TextEncoder::Numeric), [TD](rdoc-ref:PG::TextDecoder::Numeric)
132
+ * Boolean: [TE](rdoc-ref:PG::TextEncoder::Boolean), [TD](rdoc-ref:PG::TextDecoder::Boolean), [BE](rdoc-ref:PG::BinaryEncoder::Boolean), [BD](rdoc-ref:PG::BinaryDecoder::Boolean)
133
+ * String: [TE](rdoc-ref:PG::TextEncoder::String), [TD](rdoc-ref:PG::TextDecoder::String), [BE](rdoc-ref:PG::BinaryEncoder::String), [BD](rdoc-ref:PG::BinaryDecoder::String)
134
+ * Bytea: [TE](rdoc-ref:PG::TextEncoder::Bytea), [TD](rdoc-ref:PG::TextDecoder::Bytea), [BE](rdoc-ref:PG::BinaryEncoder::Bytea), [BD](rdoc-ref:PG::BinaryDecoder::Bytea)
135
+ * Base64: [TE](rdoc-ref:PG::TextEncoder::ToBase64), [TD](rdoc-ref:PG::TextDecoder::FromBase64), [BE](rdoc-ref:PG::BinaryEncoder::FromBase64), [BD](rdoc-ref:PG::BinaryDecoder::ToBase64)
136
+ * Timestamp:
137
+ * TE: [local](rdoc-ref:PG::TextEncoder::TimestampWithoutTimeZone), [UTC](rdoc-ref:PG::TextEncoder::TimestampUtc), [with-TZ](rdoc-ref:PG::TextEncoder::TimestampWithTimeZone)
138
+ * TD: [local](rdoc-ref:PG::TextDecoder::TimestampLocal), [UTC](rdoc-ref:PG::TextDecoder::TimestampUtc), [UTC-to-local](rdoc-ref:PG::TextDecoder::TimestampUtcToLocal)
139
+ * BE: [local](rdoc-ref:PG::BinaryEncoder::TimestampLocal), [UTC](rdoc-ref:PG::BinaryEncoder::TimestampUtc)
140
+ * BD: [local](rdoc-ref:PG::BinaryDecoder::TimestampLocal), [UTC](rdoc-ref:PG::BinaryDecoder::TimestampUtc), [UTC-to-local](rdoc-ref:PG::BinaryDecoder::TimestampUtcToLocal)
141
+ * Date: [TE](rdoc-ref:PG::TextEncoder::Date), [TD](rdoc-ref:PG::TextDecoder::Date), [BE](rdoc-ref:PG::BinaryEncoder::Date), [BD](rdoc-ref:PG::BinaryDecoder::Date)
142
+ * JSON and JSONB: [TE](rdoc-ref:PG::TextEncoder::JSON), [TD](rdoc-ref:PG::TextDecoder::JSON)
143
+ * Inet: [TE](rdoc-ref:PG::TextEncoder::Inet), [TD](rdoc-ref:PG::TextDecoder::Inet)
144
+ * Array: [TE](rdoc-ref:PG::TextEncoder::Array), [TD](rdoc-ref:PG::TextDecoder::Array), [BE](rdoc-ref:PG::BinaryEncoder::Array), [BD](rdoc-ref:PG::BinaryDecoder::Array)
145
+ * Composite Type (also called "Row" or "Record"): [TE](rdoc-ref:PG::TextEncoder::Record), [TD](rdoc-ref:PG::TextDecoder::Record)
146
+
147
+ The following text and binary formats can also be encoded although they are not used as column type:
148
+
149
+ * COPY input and output data: [TE](rdoc-ref:PG::TextEncoder::CopyRow), [TD](rdoc-ref:PG::TextDecoder::CopyRow), [BE](rdoc-ref:PG::BinaryEncoder::CopyRow), [BD](rdoc-ref:PG::BinaryDecoder::CopyRow)
150
+ * Literal for insertion into SQL string: [TE](rdoc-ref:PG::TextEncoder::QuotedLiteral)
151
+ * SQL-Identifier: [TE](rdoc-ref:PG::TextEncoder::Identifier), [TD](rdoc-ref:PG::TextDecoder::Identifier)
152
+
153
+ ### PG::TypeMap and derivations (ext/pg_type_map*.c, lib/pg/type_map*.rb)
154
+
155
+ A TypeMap defines which value will be converted by which encoder/decoder.
156
+ There are different type map strategies, implemented by several derivations
157
+ of this class. They can be chosen and configured according to the particular
158
+ needs for type casting. The default type map is PG::TypeMapAllStrings.
159
+
160
+ A type map can be assigned per connection or per query respectively per
161
+ result set. Type maps can also be used for COPY in and out data streaming.
162
+ See PG::Connection#copy_data .
163
+
164
+ The following base type maps are available:
165
+
166
+ * PG::TypeMapAllStrings - encodes and decodes all values to and from strings (default)
167
+ * PG::TypeMapByClass - selects encoder based on the class of the value to be sent
168
+ * PG::TypeMapByColumn - selects encoder and decoder by column order
169
+ * PG::TypeMapByOid - selects decoder by PostgreSQL type OID
170
+ * PG::TypeMapInRuby - define a custom type map in ruby
171
+
172
+ The following type maps are prefilled with type mappings from the PG::BasicTypeRegistry :
173
+
174
+ * PG::BasicTypeMapForResults - a PG::TypeMapByOid prefilled with decoders for common PostgreSQL column types
175
+ * PG::BasicTypeMapBasedOnResult - a PG::TypeMapByOid prefilled with encoders for common PostgreSQL column types
176
+ * PG::BasicTypeMapForQueries - a PG::TypeMapByClass prefilled with encoders for common Ruby value classes
177
+
178
+
179
+ ## Thread support
180
+
181
+ PG is thread safe in such a way that different threads can use different PG::Connection objects concurrently.
182
+ However it is not safe to access any Pg objects simultaneously from more than one thread.
183
+ So make sure to open a new database server connection for every new thread or use a wrapper library like ActiveRecord that manages connections in a thread safe way.
184
+
185
+ If messages like the following are printed to stderr, you're probably using one connection from several threads:
186
+
187
+ message type 0x31 arrived from server while idle
188
+ message type 0x32 arrived from server while idle
189
+ message type 0x54 arrived from server while idle
190
+ message type 0x43 arrived from server while idle
191
+ message type 0x5a arrived from server while idle
192
+
193
+
194
+ ## Fiber IO scheduler support
195
+
196
+ Pg is fully compatible with `Fiber.scheduler` introduced in Ruby-3.0 since pg-1.3.0.
197
+ On Windows support for `Fiber.scheduler` is available on Ruby-3.1 or newer.
198
+ All possibly blocking IO operations are routed through the `Fiber.scheduler` if one is registered for the running thread.
199
+ That is why pg internally uses the asynchronous libpq interface even for synchronous/blocking method calls.
200
+ It also uses Ruby's DNS resolution instead of libpq's builtin functions.
201
+
202
+ Internally Pg always uses the nonblocking connection mode of libpq.
203
+ It then behaves like running in blocking mode but ensures, that all blocking IO is handled in Ruby through a possibly registered `Fiber.scheduler`.
204
+ When `PG::Connection.setnonblocking(true)` is called then the nonblocking state stays enabled, but the additional handling of blocking states is disabled, so that the calling program has to handle blocking states on its own.
205
+
206
+ An exception to this rule are the methods for large objects like `PG::Connection#lo_create` and authentication methods using external libraries (like GSSAPI authentication).
207
+ They are not compatible with `Fiber.scheduler`, so that blocking states are not passed to the registered IO scheduler.
208
+ That means the operation will work properly, but IO waiting states can not be used to switch to another Fiber doing IO.
209
+
210
+
211
+ ## Ractor support
212
+
213
+ Pg is fully compatible with Ractor introduced in Ruby-3.0 since pg-1.5.0.
214
+ All type en/decoders and type maps are shareable between ractors if they are made frozen by `Ractor.make_shareable`.
215
+ Also frozen PG::Result and PG::Tuple objects can be shared.
216
+ All frozen objects (except PG::Connection) can still be used to do communication with the PostgreSQL server or to read retrieved data.
217
+
218
+ PG::Connection is not shareable and must be created within each Ractor to establish a dedicated connection.
219
+
220
+
221
+ ## Contributing
222
+
223
+ To report bugs, suggest features, or check out the source with Git,
224
+ [check out the project page](https://github.com/ged/ruby-pg).
225
+
226
+ After checking out the source, install all dependencies:
227
+
228
+ $ bundle install
229
+
230
+ Cleanup extension files, packaging files, test databases.
231
+ Run this to change between PostgreSQL versions:
232
+
233
+ $ rake clean
234
+
235
+ Compile extension:
236
+
237
+ $ rake compile
238
+
239
+ Run tests/specs on the PostgreSQL version that `pg_config --bindir` points to:
240
+
241
+ $ rake test
242
+
243
+ Or run a specific test per file and line number on a specific PostgreSQL version:
244
+
245
+ $ PATH=/usr/lib/postgresql/14/bin:$PATH rspec -Ilib -fd spec/pg/connection_spec.rb:455
246
+
247
+ Generate the API documentation:
248
+
249
+ $ rake docs
250
+
251
+ Make sure, that all bugs and new features are verified by tests.
252
+
253
+ The current maintainers are Michael Granger <ged@FaerieMUD.org> and
254
+ Lars Kanis <lars@greiz-reinsdorf.de>.
255
+
256
+
257
+ ## Copying
258
+
259
+ Copyright (c) 1997-2022 by the authors.
260
+
261
+ * Jeff Davis <ruby-pg@j-davis.com>
262
+ * Guy Decoux (ts) <decoux@moulon.inra.fr>
263
+ * Michael Granger <ged@FaerieMUD.org>
264
+ * Lars Kanis <lars@greiz-reinsdorf.de>
265
+ * Dave Lee
266
+ * Eiji Matsumoto <usagi@ruby.club.or.jp>
267
+ * Yukihiro Matsumoto <matz@ruby-lang.org>
268
+ * Noboru Saitou <noborus@netlab.jp>
269
+
270
+ You may redistribute this software under the same terms as Ruby itself; see
271
+ https://www.ruby-lang.org/en/about/license.txt or the BSDL file in the source
272
+ for details.
273
+
274
+ Portions of the code are from the PostgreSQL project, and are distributed
275
+ under the terms of the PostgreSQL license, included in the file POSTGRES.
276
+
277
+ Portions copyright LAIKA, Inc.
278
+
279
+
280
+ ## Acknowledgments
281
+
282
+ See Contributors.rdoc for the many additional fine people that have contributed
283
+ to this library over the years.
284
+
285
+ We are thankful to the people at the ruby-list and ruby-dev mailing lists.
286
+ And to the people who developed PostgreSQL.
data/Rakefile ADDED
@@ -0,0 +1,161 @@
1
+ # -*- rake -*-
2
+
3
+ # Enable english error messages, as some specs depend on them
4
+ ENV["LANG"] = "C"
5
+
6
+ require 'rbconfig'
7
+ require 'pathname'
8
+ require 'tmpdir'
9
+ require 'rake/extensiontask'
10
+ require 'rake/clean'
11
+ require 'rspec/core/rake_task'
12
+ require 'bundler'
13
+ require 'bundler/gem_helper'
14
+
15
+ # Build directory constants
16
+ BASEDIR = Pathname( __FILE__ ).dirname
17
+ SPECDIR = BASEDIR + 'spec'
18
+ LIBDIR = BASEDIR + 'lib'
19
+ EXTDIR = BASEDIR + 'ext'
20
+ PKGDIR = BASEDIR + 'pkg'
21
+ TMPDIR = BASEDIR + 'tmp'
22
+ TESTDIR = BASEDIR + "tmp_test_*"
23
+
24
+ DLEXT = RbConfig::CONFIG['DLEXT']
25
+ EXT = LIBDIR + "pg_ext.#{DLEXT}"
26
+
27
+ GEMSPEC = 'pg.gemspec'
28
+
29
+ CLEAN.include( TESTDIR.to_s )
30
+ CLEAN.include( PKGDIR.to_s, TMPDIR.to_s )
31
+ CLEAN.include "lib/*/libpq.dll"
32
+ CLEAN.include "lib/pg_ext.*"
33
+ CLEAN.include "lib/pg/postgresql_lib_path.rb"
34
+ CLEAN.include "ports/*.installed"
35
+ CLEAN.include "ports/*mingw*", "ports/*linux*"
36
+
37
+ Bundler::GemHelper.install_tasks
38
+ $gem_spec = Bundler.load_gemspec(GEMSPEC)
39
+
40
+ desc "Turn on warnings and debugging in the build."
41
+ task :maint do
42
+ ENV['MAINTAINER_MODE'] = 'yes'
43
+ end
44
+
45
+ CrossLibrary = Struct.new :platform, :openssl_config, :toolchain
46
+ CrossLibraries = [
47
+ ['x64-mingw-ucrt', 'mingw64', 'x86_64-w64-mingw32'],
48
+ ['x86-mingw32', 'mingw', 'i686-w64-mingw32'],
49
+ ['x64-mingw32', 'mingw64', 'x86_64-w64-mingw32'],
50
+ ['x86_64-linux', 'linux-x86_64', 'x86_64-redhat-linux-gnu'],
51
+ ].map do |platform, openssl_config, toolchain|
52
+ CrossLibrary.new platform, openssl_config, toolchain
53
+ end
54
+
55
+ # Rake-compiler task
56
+ Rake::ExtensionTask.new do |ext|
57
+ ext.name = 'pg_ext'
58
+ ext.gem_spec = $gem_spec
59
+ ext.ext_dir = 'ext'
60
+ ext.lib_dir = 'lib'
61
+ ext.source_pattern = "*.{c,h}"
62
+ ext.cross_compile = true
63
+ ext.cross_platform = CrossLibraries.map(&:platform)
64
+
65
+ ext.cross_config_options += CrossLibraries.map do |xlib|
66
+ {
67
+ xlib.platform => [
68
+ "--with-cross-build=#{xlib.platform}",
69
+ "--with-openssl-platform=#{xlib.openssl_config}",
70
+ "--with-toolchain=#{xlib.toolchain}",
71
+ ]
72
+ }
73
+ end
74
+
75
+ # Add libpq.dll/.so to fat binary gemspecs
76
+ ext.cross_compiling do |spec|
77
+ spec.files << "ports/#{spec.platform.to_s}/lib/libpq-ruby-pg.so.1" if spec.platform.to_s =~ /linux/
78
+ spec.files << "ports/#{spec.platform.to_s}/lib/libpq.dll" if spec.platform.to_s =~ /mingw|mswin/
79
+ end
80
+ end
81
+
82
+ task 'gem:native:prepare' do
83
+ require 'io/console'
84
+ require 'rake_compiler_dock'
85
+
86
+ # Copy gem signing key and certs to be accessible from the docker container
87
+ mkdir_p 'build/gem'
88
+ sh "cp ~/.gem/gem-*.pem build/gem/ || true"
89
+ sh "bundle package"
90
+ begin
91
+ OpenSSL::PKey.read(File.read(File.expand_path("~/.gem/gem-private_key.pem")), ENV["GEM_PRIVATE_KEY_PASSPHRASE"] || "")
92
+ rescue OpenSSL::PKey::PKeyError
93
+ ENV["GEM_PRIVATE_KEY_PASSPHRASE"] = STDIN.getpass("Enter passphrase of gem signature key: ")
94
+ retry
95
+ end
96
+ end
97
+
98
+ CrossLibraries.each do |xlib|
99
+ platform = xlib.platform
100
+ desc "Build fat binary gem for platform #{platform}"
101
+ task "gem:native:#{platform}" => ['gem:native:prepare'] do
102
+ RakeCompilerDock.sh <<-EOT, platform: platform
103
+ #{ "sudo yum install -y perl-IPC-Cmd bison flex &&" if platform =~ /linux/ }
104
+ #{ # remove nm on Linux to suppress PostgreSQL's check for exit which raises thread_exit as a false positive:
105
+ "sudo mv `which nm` `which nm`.bak && sudo mv `which nm` `which nm`.bak &&" if platform =~ /linux/ }
106
+ #{ "sudo apt-get update && sudo apt-get install -y bison flex &&" if platform =~ /mingw/ }
107
+ (cp build/gem/gem-*.pem ~/.gem/ || true) &&
108
+ bundle install --local &&
109
+ rake native:#{platform} pkg/#{$gem_spec.full_name}-#{platform}.gem MAKEOPTS=-j`nproc` RUBY_CC_VERSION=3.3.0:3.2.0:3.1.0:3.0.0:2.7.0
110
+ EOT
111
+ end
112
+ desc "Build the native binary gems"
113
+ multitask 'gem:native' => "gem:native:#{platform}"
114
+ end
115
+
116
+ RSpec::Core::RakeTask.new(:spec).rspec_opts = "--profile -cfdoc"
117
+ task :test => :spec
118
+
119
+ # Use the fivefish formatter for docs generated from development checkout
120
+ require 'rdoc/task'
121
+
122
+ RDoc::Task.new( 'docs' ) do |rdoc|
123
+ rdoc.options = $gem_spec.rdoc_options
124
+ rdoc.rdoc_files = $gem_spec.extra_rdoc_files
125
+ rdoc.generator = :fivefish
126
+ rdoc.rdoc_dir = 'doc'
127
+ end
128
+
129
+ desc "Build the source gem #{$gem_spec.full_name}.gem into the pkg directory"
130
+ task :gem => :build
131
+
132
+ task :clobber do
133
+ puts "Stop any Postmaster instances that remain after testing."
134
+ require_relative 'spec/helpers'
135
+ PG::TestingHelpers.stop_existing_postmasters()
136
+ end
137
+
138
+ desc "Update list of server error codes"
139
+ task :update_error_codes do
140
+ URL_ERRORCODES_TXT = "http://git.postgresql.org/gitweb/?p=postgresql.git;a=blob_plain;f=src/backend/utils/errcodes.txt;hb=refs/tags/REL_17_0"
141
+
142
+ ERRORCODES_TXT = "ext/errorcodes.txt"
143
+ sh "wget #{URL_ERRORCODES_TXT.inspect} -O #{ERRORCODES_TXT.inspect} || curl #{URL_ERRORCODES_TXT.inspect} -o #{ERRORCODES_TXT.inspect}"
144
+
145
+ ruby 'ext/errorcodes.rb', 'ext/errorcodes.txt', 'ext/errorcodes.def'
146
+ end
147
+
148
+ file 'ext/pg_errors.c' => ['ext/errorcodes.def'] do
149
+ # trigger compilation of changed errorcodes.def
150
+ touch 'ext/pg_errors.c'
151
+ end
152
+
153
+ desc "Translate readme"
154
+ task :translate do
155
+ cd "translation" do
156
+ # po4a's lexer might change, so record its version for reference
157
+ sh "LANG=C po4a --version > .po4a-version"
158
+
159
+ sh "po4a po4a.cfg"
160
+ end
161
+ end
data/certs/ged.pem ADDED
@@ -0,0 +1,24 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIID+DCCAmCgAwIBAgIBBDANBgkqhkiG9w0BAQsFADAiMSAwHgYDVQQDDBdnZWQv
3
+ REM9RmFlcmllTVVEL0RDPW9yZzAeFw0yMjAxMDcyMzU4MTRaFw0yMzAxMDcyMzU4
4
+ MTRaMCIxIDAeBgNVBAMMF2dlZC9EQz1GYWVyaWVNVUQvREM9b3JnMIIBojANBgkq
5
+ hkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAvyVhkRzvlEs0fe7145BYLfN6njX9ih5H
6
+ L60U0p0euIurpv84op9CNKF9tx+1WKwyQvQP7qFGuZxkSUuWcP/sFhDXL1lWUuIl
7
+ M4uHbGCRmOshDrF4dgnBeOvkHr1fIhPlJm5FO+Vew8tSQmlDsosxLUx+VB7DrVFO
8
+ 5PU2AEbf04GGSrmqADGWXeaslaoRdb1fu/0M5qfPTRn5V39sWD9umuDAF9qqil/x
9
+ Sl6phTvgBrG8GExHbNZpLARd3xrBYLEFsX7RvBn2UPfgsrtvpdXjsHGfpT3IPN+B
10
+ vQ66lts4alKC69TE5cuKasWBm+16A4aEe3XdZBRNmtOu/g81gvwA7fkJHKllJuaI
11
+ dXzdHqq+zbGZVSQ7pRYHYomD0IiDe1DbIouFnPWmagaBnGHwXkDT2bKKP+s2v21m
12
+ ozilJg4aar2okb/RA6VS87o+d7g6LpDDMMQjH4G9OPnJENLdhu8KnPw/ivSVvQw7
13
+ N2I4L/ZOIe2DIVuYH7aLHfjZDQv/mNgpAgMBAAGjOTA3MAkGA1UdEwQCMAAwCwYD
14
+ VR0PBAQDAgSwMB0GA1UdDgQWBBRyjf55EbrHagiRLqt5YAd3yb8k4DANBgkqhkiG
15
+ 9w0BAQsFAAOCAYEASrm1AbEoxACZ9WXJH3R5axV3U0CA4xaETlL2YT+2nOfVBMQ9
16
+ 0ZlkPx6j4ghKJgAIi1TMfDM2JyPJsppQh8tiNccDjWc62UZRY/dq26cMqf/lcI+a
17
+ 6YBuEYvzZfearwVs8tHnXtwYV3WSCoCOQaB+nq2lA1O+nkKNl41WOsVbNama5jx3
18
+ 8cQtVSEEmZy6jIDJ8c5TmBJ7BQUDEUEWA/A3V42Xyctoj7DvUXWE0lP+X6ypAVSr
19
+ lFh3TS64D7NTvxkmg7natUoCvobl6kGl4yMaqE4YRTlfuzhpf91TSOntClqrAOsS
20
+ K1s56WndQj3IoBocdY9mQhDZLtLHofSkymoP8btBlj5SsN24TiF0VMSZlctSCYZg
21
+ GKyHim/MMlIfGOWsgfioq5jzwmql7W4CDubbb8Lkg70v+hN2E/MnNVAcNE3gyaGc
22
+ P5YP5BAbNW+gvd3QHRiWTTuhgHrdDnGdXg93N2M5KHn1ug8BtPLQwlcFwEpKnlLn
23
+ btEP+7EplFuoiMfd
24
+ -----END CERTIFICATE-----
@@ -0,0 +1,20 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDLjCCAhagAwIBAgIBCzANBgkqhkiG9w0BAQsFADA9MQ4wDAYDVQQDDAVrYW5p
3
+ czEXMBUGCgmSJomT8ixkARkWB2NvbWNhcmQxEjAQBgoJkiaJk/IsZAEZFgJkZTAe
4
+ Fw0yMzA0MjgwOTI0NDhaFw0yNDA0MjcwOTI0NDhaMD0xDjAMBgNVBAMMBWthbmlz
5
+ MRcwFQYKCZImiZPyLGQBGRYHY29tY2FyZDESMBAGCgmSJomT8ixkARkWAmRlMIIB
6
+ IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApop+rNmg35bzRugZ21VMGqI6
7
+ HGzPLO4VHYncWn/xmgPU/ZMcZdfj6MzIaZJ/czXyt4eHpBk1r8QOV3gBXnRXEjVW
8
+ 9xi+EdVOkTV2/AVFKThcbTAQGiF/bT1n2M+B1GTybRzMg6hyhOJeGPqIhLfJEpxn
9
+ lJi4+ENAVT4MpqHEAGB8yFoPC0GqiOHQsdHxQV3P3c2OZqG+yJey74QtwA2tLcLn
10
+ Q53c63+VLGsOjODl1yPn/2ejyq8qWu6ahfTxiIlSar2UbwtaQGBDFdb2CXgEufXT
11
+ L7oaPxlmj+Q2oLOfOnInd2Oxop59HoJCQPsg8f921J43NCQGA8VHK6paxIRDLQID
12
+ AQABozkwNzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQUvgTdT7fe
13
+ x17ugO3IOsjEJwW7KP4wDQYJKoZIhvcNAQELBQADggEBACAxNXwfMGG7paZjnG/c
14
+ smdi/ocW2GmCNtILaSzDZqlD5LoA68MiO7u5vwWyBaDJ6giUB330VJoGRbWMxvxN
15
+ JU6Bnwa4yYp9YtF91wYIi7FXwIrCPKd9bk3bf4M5wECdsv+zvVceq2zRXqD7fci8
16
+ 1LRG8ort/f4TgaT7B4aNwOaabA2UT6u0FGeglqxLkhir86MY3QQyBfJZUoTKWGkz
17
+ S9a7GXsYpe+8HMOaE4+SZp8SORKPgATND5m/4VdzuO59VXjE5UP7QpXigbxAt7H7
18
+ ciK5Du2ZDhowmWzZwNzR7VvVmfAK6RQJlRB03VkkQRWGld5yApOrYDne6WbD8kE0
19
+ uM8=
20
+ -----END CERTIFICATE-----
@@ -0,0 +1,26 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIETTCCArWgAwIBAgIBATANBgkqhkiG9w0BAQsFADAoMSYwJAYDVQQDDB1sYXJz
3
+ L0RDPWdyZWl6LXJlaW5zZG9yZi9EQz1kZTAeFw0yMjAyMTQxMzMwNTZaFw0yMzAy
4
+ MTQxMzMwNTZaMCgxJjAkBgNVBAMMHWxhcnMvREM9Z3JlaXotcmVpbnNkb3JmL0RD
5
+ PWRlMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAwum6Y1KznfpzXOT/
6
+ mZgJTBbxZuuZF49Fq3K0WA67YBzNlDv95qzSp7V/7Ek3NCcnT7G+2kSuhNo1FhdN
7
+ eSDO/moYebZNAcu3iqLsuzuULXPLuoU0GsMnVMqV9DZPh7cQHE5EBZ7hlzDBK7k/
8
+ 8nBMvR0mHo77kIkapHc26UzVq/G0nKLfDsIHXVylto3PjzOumjG6GhmFN4r3cP6e
9
+ SDfl1FSeRYVpt4kmQULz/zdSaOH3AjAq7PM2Z91iGwQvoUXMANH2v89OWjQO/NHe
10
+ JMNDFsmHK/6Ji4Kk48Z3TyscHQnipAID5GhS1oD21/WePdj7GhmbF5gBzkV5uepd
11
+ eJQPgWGwrQW/Z2oPjRuJrRofzWfrMWqbOahj9uth6WSxhNexUtbjk6P8emmXOJi5
12
+ chQPnWX+N3Gj+jjYxqTFdwT7Mj3pv1VHa+aNUbqSPpvJeDyxRIuo9hvzDaBHb/Cg
13
+ 9qRVcm8a96n4t7y2lrX1oookY6bkBaxWOMtWlqIprq8JZXM9AgMBAAGjgYEwfzAJ
14
+ BgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQUOIdbSMr3VFrTCO9/cTM0
15
+ 0exHzBcwIgYDVR0RBBswGYEXbGFyc0BncmVpei1yZWluc2RvcmYuZGUwIgYDVR0S
16
+ BBswGYEXbGFyc0BncmVpei1yZWluc2RvcmYuZGUwDQYJKoZIhvcNAQELBQADggGB
17
+ AFWP7F/y3Oq3NgrqUOnjKOeDaBa7AqNhHS+PZg+C90lnJzMgOs4KKgZYxqSQVSab
18
+ SCEmzIO/StkXY4NpJ4fYLrHemf/fJy1wPyu+fNdp5SEEUwEo+2toRFlzTe4u4LdS
19
+ QC636nPPTMt8H3xz2wf/lUIUeo2Qc95Qt2BQM465ibbG9kmA3c7Sopx6yOabYOAl
20
+ KPRbOSEPiWYcF9Suuz8Gdf8jxEtPlnZiwRvnYJ+IHMq3XQCJWPpMzdDMbtlgHbXE
21
+ vq1zOTLMSYAS0UB3uionR4yo1hLz60odwkCm7qf0o2Ci/5OjtB0a89VuyqRU2vUJ
22
+ QH95WBjDJ6lCCW7J0mrMPnJQSUFTmufsU6jOChvPaCeAzW1YwrsP/YKnvwueG7ip
23
+ VOdW6RitjtFxhS7evRL0201+KUvLz12zZWWjOcujlQs64QprxOtiv/MiisKb1Ng+
24
+ oL1mUdzB8KrZL4/WbG5YNX6UTtJbIOu9qEFbBAy4/jtIkJX+dlNoFwd4GXQW1YNO
25
+ nA==
26
+ -----END CERTIFICATE-----
@@ -0,0 +1,24 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIEBDCCAmygAwIBAgIBAjANBgkqhkiG9w0BAQsFADAoMSYwJAYDVQQDDB1sYXJz
3
+ L0RDPWdyZWl6LXJlaW5zZG9yZi9EQz1kZTAeFw0yMzAyMTUxNzQxMTVaFw0yNDAy
4
+ MTUxNzQxMTVaMCgxJjAkBgNVBAMMHWxhcnMvREM9Z3JlaXotcmVpbnNkb3JmL0RD
5
+ PWRlMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAwum6Y1KznfpzXOT/
6
+ mZgJTBbxZuuZF49Fq3K0WA67YBzNlDv95qzSp7V/7Ek3NCcnT7G+2kSuhNo1FhdN
7
+ eSDO/moYebZNAcu3iqLsuzuULXPLuoU0GsMnVMqV9DZPh7cQHE5EBZ7hlzDBK7k/
8
+ 8nBMvR0mHo77kIkapHc26UzVq/G0nKLfDsIHXVylto3PjzOumjG6GhmFN4r3cP6e
9
+ SDfl1FSeRYVpt4kmQULz/zdSaOH3AjAq7PM2Z91iGwQvoUXMANH2v89OWjQO/NHe
10
+ JMNDFsmHK/6Ji4Kk48Z3TyscHQnipAID5GhS1oD21/WePdj7GhmbF5gBzkV5uepd
11
+ eJQPgWGwrQW/Z2oPjRuJrRofzWfrMWqbOahj9uth6WSxhNexUtbjk6P8emmXOJi5
12
+ chQPnWX+N3Gj+jjYxqTFdwT7Mj3pv1VHa+aNUbqSPpvJeDyxRIuo9hvzDaBHb/Cg
13
+ 9qRVcm8a96n4t7y2lrX1oookY6bkBaxWOMtWlqIprq8JZXM9AgMBAAGjOTA3MAkG
14
+ A1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBQ4h1tIyvdUWtMI739xMzTR
15
+ 7EfMFzANBgkqhkiG9w0BAQsFAAOCAYEAQAcuTARfiiVUVx5KURICfdTM2Kd7LhOn
16
+ qt3Vs4ANGvT226LEp3RnQ+kWGQYMRb3cw3LY2TNQRPlnZxE994mgjBscN4fbjXqO
17
+ T0JbVpeszRZa5k1goggbnWT7CO7yU7WcHh13DaSubY7HUpAJn2xz9w2stxQfN/EE
18
+ VMlnDJ1P7mUHAvpK8X9j9h7Xlc1niViT18MYwux8mboVTryrLr+clATUkkM3yBF0
19
+ RV+c34ReW5eXO9Tr6aKTxh/pFC9ggDT6jOxuJgSvG8HWJzVf4NDvMavIas4KYjiI
20
+ BU6CpWaG5NxicqL3BERi52U43HV08br+LNVpb7Rekgve/PJuSFnAR015bhSRXe5U
21
+ vBioD1qW2ZW9tXg8Ww2IfDaO5a1So5Xby51rhNlyo6ATj2NkuLWZUKPKHhAz0TKm
22
+ Dzx/gFSOrRoCt2mXNgrmcAfr386AfaMvCh7cXqdxZwmVo7ILZCYXck0pajvubsDd
23
+ NUIIFkVXvd1odFyK9LF1RFAtxn/iAmpx
24
+ -----END CERTIFICATE-----
@@ -0,0 +1,24 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIEBDCCAmygAwIBAgIBAzANBgkqhkiG9w0BAQsFADAoMSYwJAYDVQQDDB1sYXJz
3
+ L0RDPWdyZWl6LXJlaW5zZG9yZi9EQz1kZTAeFw0yNDAyMjgxOTMxNDdaFw0yNTAy
4
+ MjcxOTMxNDdaMCgxJjAkBgNVBAMMHWxhcnMvREM9Z3JlaXotcmVpbnNkb3JmL0RD
5
+ PWRlMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAwum6Y1KznfpzXOT/
6
+ mZgJTBbxZuuZF49Fq3K0WA67YBzNlDv95qzSp7V/7Ek3NCcnT7G+2kSuhNo1FhdN
7
+ eSDO/moYebZNAcu3iqLsuzuULXPLuoU0GsMnVMqV9DZPh7cQHE5EBZ7hlzDBK7k/
8
+ 8nBMvR0mHo77kIkapHc26UzVq/G0nKLfDsIHXVylto3PjzOumjG6GhmFN4r3cP6e
9
+ SDfl1FSeRYVpt4kmQULz/zdSaOH3AjAq7PM2Z91iGwQvoUXMANH2v89OWjQO/NHe
10
+ JMNDFsmHK/6Ji4Kk48Z3TyscHQnipAID5GhS1oD21/WePdj7GhmbF5gBzkV5uepd
11
+ eJQPgWGwrQW/Z2oPjRuJrRofzWfrMWqbOahj9uth6WSxhNexUtbjk6P8emmXOJi5
12
+ chQPnWX+N3Gj+jjYxqTFdwT7Mj3pv1VHa+aNUbqSPpvJeDyxRIuo9hvzDaBHb/Cg
13
+ 9qRVcm8a96n4t7y2lrX1oookY6bkBaxWOMtWlqIprq8JZXM9AgMBAAGjOTA3MAkG
14
+ A1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBQ4h1tIyvdUWtMI739xMzTR
15
+ 7EfMFzANBgkqhkiG9w0BAQsFAAOCAYEArBmHSfnUyNWf3R1Fx0mMHloWGdcKn2D2
16
+ BsqTApXU2nADiyppIqRq4b9e7hw342uzadSLkoQcEFOxThLRhAcijoWfQVBcsbV/
17
+ ZsCY1qlUTIJuSWxaSyS4efUX+N4eMNyPM9oW/sphlWFo0DgI34Y9WB6HDzH+O71y
18
+ R7PARke3f4kYnRJf5yRQLPDrH9UYt9KlBQm6l7XMtr5EMnQt0EfcmZEi9H4t/vS2
19
+ haxvpFMdAKo4H46GBYNO96r6b74t++vgQSBTg/AFVwvRZwNSrPPcBfb4xxeEAhRR
20
+ x+LU7feIH7lZ//3buiyD03gLAEtHXai0Y+/VfuWIpwYJAl2BO/tU7FS/dtbJq9oc
21
+ dI36Yyzy+BrCM0WT4oCsagePNb97FaNhl4F6sM5JEPT0ZPxRx0i3G4TNNIYziVos
22
+ 5wFER6XhvvLDFAMh/jMg+s7Wd5SbSHgHNSUaUGVtdWkVPOer6oF0aLdZUR3CETkn
23
+ 5nWXZma/BUd3YgYA/Xumc6QQqIS4p7mr
24
+ -----END CERTIFICATE-----