pg 1.4.6 → 1.5.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/.appveyor.yml +1 -1
  4. data/.gitignore +3 -0
  5. data/History.md +72 -0
  6. data/README.ja.md +29 -19
  7. data/README.md +29 -15
  8. data/Rakefile.cross +1 -1
  9. data/ext/pg.c +10 -28
  10. data/ext/pg.h +10 -5
  11. data/ext/pg_binary_decoder.c +79 -0
  12. data/ext/pg_binary_encoder.c +224 -0
  13. data/ext/pg_coder.c +16 -7
  14. data/ext/pg_connection.c +50 -34
  15. data/ext/pg_copy_coder.c +306 -17
  16. data/ext/pg_record_coder.c +5 -4
  17. data/ext/pg_result.c +91 -17
  18. data/ext/pg_text_decoder.c +28 -10
  19. data/ext/pg_text_encoder.c +22 -9
  20. data/ext/pg_tuple.c +34 -31
  21. data/ext/pg_type_map.c +3 -2
  22. data/ext/pg_type_map_all_strings.c +2 -2
  23. data/ext/pg_type_map_by_class.c +5 -3
  24. data/ext/pg_type_map_by_column.c +7 -3
  25. data/ext/pg_type_map_by_oid.c +7 -4
  26. data/ext/pg_type_map_in_ruby.c +5 -2
  27. data/lib/pg/basic_type_map_based_on_result.rb +21 -1
  28. data/lib/pg/basic_type_map_for_queries.rb +13 -8
  29. data/lib/pg/basic_type_map_for_results.rb +26 -3
  30. data/lib/pg/basic_type_registry.rb +30 -32
  31. data/lib/pg/binary_decoder/date.rb +9 -0
  32. data/lib/pg/binary_decoder/timestamp.rb +26 -0
  33. data/lib/pg/binary_encoder/timestamp.rb +20 -0
  34. data/lib/pg/coder.rb +15 -13
  35. data/lib/pg/connection.rb +84 -12
  36. data/lib/pg/text_decoder/date.rb +18 -0
  37. data/lib/pg/text_decoder/inet.rb +9 -0
  38. data/lib/pg/text_decoder/json.rb +14 -0
  39. data/lib/pg/text_decoder/numeric.rb +9 -0
  40. data/lib/pg/text_decoder/timestamp.rb +30 -0
  41. data/lib/pg/text_encoder/date.rb +12 -0
  42. data/lib/pg/text_encoder/inet.rb +28 -0
  43. data/lib/pg/text_encoder/json.rb +14 -0
  44. data/lib/pg/text_encoder/numeric.rb +9 -0
  45. data/lib/pg/text_encoder/timestamp.rb +24 -0
  46. data/lib/pg/version.rb +1 -1
  47. data/lib/pg.rb +55 -9
  48. data/pg.gemspec +1 -1
  49. data/translation/po/all.pot +170 -135
  50. data/translation/po/ja.po +365 -186
  51. data/translation/po4a.cfg +4 -1
  52. data.tar.gz.sig +0 -0
  53. metadata +28 -10
  54. metadata.gz.sig +0 -0
  55. data/lib/pg/binary_decoder.rb +0 -23
  56. data/lib/pg/constants.rb +0 -12
  57. data/lib/pg/text_decoder.rb +0 -46
  58. data/lib/pg/text_encoder.rb +0 -59
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8c13f68e0e75751b8b4abc7981de62045998fdf4e8685fd90e74bcd609dc85a8
4
- data.tar.gz: 33c65915b3c04a9232bacbf39486738e7a3cd033fefd2f2947107fd9a3b70ebc
3
+ metadata.gz: 7cbac60d76e50f034bb84d601d55d816cd3d3b8c05a3067b9ccd3103fc293699
4
+ data.tar.gz: e9e5d36b50bd17e8cfd3d2191a0bbc499ca09a466f9c73dc81c2799be82a3346
5
5
  SHA512:
6
- metadata.gz: 3d7144fb8feaa713aae83a12f90890d82c554cb26b81e76f245f47f0f99bac8f2a290bdfbf27deb069f6e4852ff692203799f1a9bf5914e616abb4d3037e6b7a
7
- data.tar.gz: 06fb1dbe5e4ff3626c4c1fb24ef2862f32c97baa983400585379ffbbde55079fd449c1ae895296947c29a9316bacfa1f8c173059c426aa8659bccdb676c461f7
6
+ metadata.gz: b9bc096fb5410cc044f0f5fb7f688d8047fcc5c7ea8ff025bb6ada32f92288f1f6c076da157e8812aa01a47fe2b025798bafa92aab7fd1294bfcc60f03e53f09
7
+ data.tar.gz: 120f870057de3c7552e4beef0c81dd90e5ce03a4557bf3b01d518197596dfa149c7612375028451c0b07f6714567ee5e2c80040ec9470226d045e6b9fc3153eb
checksums.yaml.gz.sig CHANGED
Binary file
data/.appveyor.yml CHANGED
@@ -1,4 +1,4 @@
1
- image: Visual Studio 2019
1
+ image: Visual Studio 2022
2
2
 
3
3
  init:
4
4
  - set PATH=C:/Ruby%ruby_version%/bin;c:/Program Files/Git/cmd;c:/Windows/system32;C:/Windows/System32/WindowsPowerShell/v1.0;C:/Program Files/Mercurial
data/.gitignore CHANGED
@@ -6,6 +6,9 @@
6
6
  *_REMOTE_*
7
7
  /.test_symlink
8
8
  /build/
9
+ /ext/Makefile
10
+ /ext/mkmf.log
11
+ /ext/postgresql_lib_path.rb
9
12
  /doc/
10
13
  /lib/*.bundle
11
14
  /lib/*.so
data/History.md CHANGED
@@ -1,3 +1,75 @@
1
+ ## v1.5.3 [2023-04-28] Lars Kanis <lars@greiz-reinsdorf.de>
2
+
3
+ - Fix possible segfault when creating a new PG::Result with type map. [#530](https://github.com/ged/ruby-pg/pull/530)
4
+ - Add category to deprecation warnings of Coder.new, so that they are suppressed for most users. [#528](https://github.com/ged/ruby-pg/pull/528)
5
+
6
+
7
+ ## v1.5.2 [2023-04-26] Lars Kanis <lars@greiz-reinsdorf.de>
8
+
9
+ - Fix regression in copy_data regarding binary format when using no coder. [#527](https://github.com/ged/ruby-pg/pull/527)
10
+
11
+
12
+ ## v1.5.1 [2023-04-24] Lars Kanis <lars@greiz-reinsdorf.de>
13
+
14
+ - Don't overwrite flags of timestamp coders. [#524](https://github.com/ged/ruby-pg/pull/524)
15
+ Fixes a regression in rails: https://github.com/rails/rails/issues/48049
16
+
17
+
18
+ ## v1.5.0 [2023-04-24] Lars Kanis <lars@greiz-reinsdorf.de>
19
+
20
+ Enhancements:
21
+
22
+ - Better support for binary format:
23
+ - Extend PG::Connection#copy_data to better support binary transfers [#511](https://github.com/ged/ruby-pg/pull/511)
24
+ - Add binary COPY encoder and decoder:
25
+ * PG::BinaryEncoder::CopyRow
26
+ * PG::BinaryDecoder::CopyRow
27
+ - Add binary timestamp encoders:
28
+ * PG::BinaryEncoder::TimestampUtc
29
+ * PG::BinaryEncoder::TimestampLocal
30
+ * PG::BinaryEncoder::Timestamp
31
+ - Add PG::BinaryEncoder::Float4 and Float8
32
+ - Add binary date type: [#515](https://github.com/ged/ruby-pg/pull/515)
33
+ * PG::BinaryEncoder::Date
34
+ * PG::BinaryDecoder::Date
35
+ - Add PG::Result#binary_tuples [#511](https://github.com/ged/ruby-pg/pull/511)
36
+ It is useful for COPY and not deprecated in that context.
37
+ - Add PG::TextEncoder::Bytea to BasicTypeRegistry [#506](https://github.com/ged/ruby-pg/pull/506)
38
+ - Ractor support: [#519](https://github.com/ged/ruby-pg/pull/519)
39
+ - Pg is now fully compatible with Ractor introduced in Ruby-3.0 and doesn't use any global mutable state.
40
+ - All type en/decoders and type maps are shareable between ractors if they are made frozen by `Ractor.make_shareable`.
41
+ - Also frozen PG::Result and PG::Tuple objects can be shared.
42
+ - All frozen objects (except PG::Connection) can still be used to do communication with the PostgreSQL server or to read retrieved data.
43
+ - PG::Connection is not shareable and must be created within each Ractor to establish a dedicated connection.
44
+ - Use keyword arguments instead of hashes for Coder initialization and #to_h. [#511](https://github.com/ged/ruby-pg/pull/511)
45
+ - Add PG::Result.res_status as a class method and extend Result#res_status to return the status of self. [#508](https://github.com/ged/ruby-pg/pull/508)
46
+ - Reduce the number of files loaded at `require 'pg'` by using autoload. [#513](https://github.com/ged/ruby-pg/pull/513)
47
+ Previously stdlib libraries `date`, `json`, `ipaddr` and `bigdecimal` were static dependencies, but now only `socket` is mandatory.
48
+ - Improve garbage collector performance by adding write barriers to all PG classes. [#518](https://github.com/ged/ruby-pg/pull/518)
49
+ Now they can be promoted to the old generation, which means they only get marked on major GC.
50
+ - New method PG::Connection#check_socket to check the socket state. [#521](https://github.com/ged/ruby-pg/pull/521)
51
+ - Mark many internal constants as private. [#522](https://github.com/ged/ruby-pg/pull/522)
52
+ - Update Windows fat binary gem to OpenSSL-3.1.0.
53
+
54
+ Bugfixes:
55
+
56
+ - Move nfields-check of stream-methods after result status check [#507](https://github.com/ged/ruby-pg/pull/507)
57
+ This ensures that the nfield-check doesn't hide errors like statement timeout.
58
+
59
+ Removed:
60
+
61
+ - Remove deprecated PG::BasicTypeRegistry.register_type and co. [Part of #519](https://github.com/ged/ruby-pg/commit/2919ee1a0c6b216e18e1d06c95c2616ef69d2f97)
62
+ - Add deprecation warning about PG::Coder initialization per Hash argument. [#514](https://github.com/ged/ruby-pg/pull/514)
63
+ It is recommended to use keyword arguments instead.
64
+ - The internal encoding cache was removed. [#516](https://github.com/ged/ruby-pg/pull/516)
65
+ It shouldn't have a practical performance impact.
66
+
67
+ Repository:
68
+
69
+ - `rake test` tries to find PostgreSQL server commands by pg_config [#503](https://github.com/ged/ruby-pg/pull/503)
70
+ So there's no need to set the PATH manuelly any longer.
71
+
72
+
1
73
  ## v1.4.6 [2023-02-26] Lars Kanis <lars@greiz-reinsdorf.de>
2
74
 
3
75
  - Add japanese README file. [#502](https://github.com/ged/ruby-pg/pull/502)
data/README.ja.md CHANGED
@@ -1,7 +1,8 @@
1
1
  # pg
2
2
 
3
3
  * home :: https://github.com/ged/ruby-pg
4
- * docs :: http://deveiate.org/code/pg
4
+ * docs :: http://deveiate.org/code/pg (English) ,
5
+ https://deveiate.org/code/pg/README_ja_md.html (Japanese)
5
6
  * clog :: link:/History.md
6
7
 
7
8
  [![https://gitter.im/ged/ruby-pg
@@ -41,7 +42,7 @@ Actionsのビルド状況](https://github.com/ged/ruby-pg/actions/workflows/sour
41
42
 
42
43
  ## 要件
43
44
 
44
- * Ruby 2.4かそれより新しいバージョン
45
+ * Ruby 2.5かそれより新しいバージョン
45
46
  * PostgreSQL 9.3.xかそれ以降のバージョン(ヘッダー付属のもの、例えば-devの名前のパッケージ)。
46
47
 
47
48
  それより前のバージョンのRubyやPostgreSQLでも通常は同様に動作しますが、定期的なテストはされていません。
@@ -115,10 +116,12 @@ Binary Encoder、BD = Binary Decoder)。
115
116
  💡
116
117
  リンクがないでしょうか。[こちら](https://deveiate.org/code/pg/README_ja_md.html#label-E5-9E-8B-E5-A4-89-E6-8F-9B)を代わりに見てください
117
118
  💡
118
- * BE:
119
- [Int2](rdoc-ref:PG::BinaryEncoder::Int2)、[Int4](rdoc-ref:PG::BinaryEncoder::Int4)、[Int8](rdoc-ref:PG::BinaryEncoder::Int8)
119
+ * BE:
120
+ [Int2](rdoc-ref:PG::BinaryEncoder::Int2)、[Int4](rdoc-ref:PG::BinaryEncoder::Int4)、[Int8](rdoc-ref:PG::BinaryEncoder::Int8)
120
121
  * Float:
121
122
  [TE](rdoc-ref:PG::TextEncoder::Float)、[TD](rdoc-ref:PG::TextDecoder::Float)、[BD](rdoc-ref:PG::BinaryDecoder::Float)
123
+ * BE: [Float4](rdoc-ref:PG::BinaryEncoder::Float4),
124
+ [Float8](rdoc-ref:PG::BinaryEncoder::Float8)
122
125
  * Numeric:
123
126
  [TE](rdoc-ref:PG::TextEncoder::Numeric)、[TD](rdoc-ref:PG::TextDecoder::Numeric)
124
127
  * Boolean:
@@ -130,14 +133,18 @@ Binary Encoder、BD = Binary Decoder)。
130
133
  * Base64:
131
134
  [TE](rdoc-ref:PG::TextEncoder::ToBase64)、[TD](rdoc-ref:PG::TextDecoder::FromBase64)、[BE](rdoc-ref:PG::BinaryEncoder::FromBase64)、[BD](rdoc-ref:PG::BinaryDecoder::ToBase64)
132
135
  * Timestamp:
133
- * TE:
134
- [現地時間](rdoc-ref:PG::TextEncoder::TimestampWithoutTimeZone)、[UTC](rdoc-ref:PG::TextEncoder::TimestampUtc)、[タイムゾーン付き](rdoc-ref:PG::TextEncoder::TimestampWithTimeZone)
135
- * TD:
136
- [現地時間](rdoc-ref:PG::TextDecoder::TimestampLocal)、[UTC](rdoc-ref:PG::TextDecoder::TimestampUtc)、[UTCから現地時間へ](rdoc-ref:PG::TextDecoder::TimestampUtcToLocal)
137
- * BD:
138
- [現地時間](rdoc-ref:PG::BinaryDecoder::TimestampLocal)、[UTC](rdoc-ref:PG::BinaryDecoder::TimestampUtc)、[UTCから現地時間へ](rdoc-ref:PG::BinaryDecoder::TimestampUtcToLocal)
139
- * Date:
140
- [TE](rdoc-ref:PG::TextEncoder::Date)、[TD](rdoc-ref:PG::TextDecoder::Date)
136
+ * TE:
137
+ [現地時間](rdoc-ref:PG::TextEncoder::TimestampWithoutTimeZone)、[UTC](rdoc-ref:PG::TextEncoder::TimestampUtc)、[タイムゾーン付き](rdoc-ref:PG::TextEncoder::TimestampWithTimeZone)
138
+ * TD:
139
+ [現地時間](rdoc-ref:PG::TextDecoder::TimestampLocal)、[UTC](rdoc-ref:PG::TextDecoder::TimestampUtc)、[UTCから現地時間へ](rdoc-ref:PG::TextDecoder::TimestampUtcToLocal)
140
+ * BE: [local](rdoc-ref:PG::BinaryEncoder::TimestampLocal),
141
+ [UTC](rdoc-ref:PG::BinaryEncoder::TimestampUtc)
142
+ * BD:
143
+ [現地時間](rdoc-ref:PG::BinaryDecoder::TimestampLocal)、[UTC](rdoc-ref:PG::BinaryDecoder::TimestampUtc)、[UTCから現地時間へ](rdoc-ref:PG::BinaryDecoder::TimestampUtcToLocal)
144
+ * Date: [TE](rdoc-ref:PG::TextEncoder::Date),
145
+ [TD](rdoc-ref:PG::TextDecoder::Date),
146
+ [BE](rdoc-ref:PG::BinaryEncoder::Date),
147
+ [BD](rdoc-ref:PG::BinaryDecoder::Date)
141
148
  * JSONとJSONB:
142
149
  [TE](rdoc-ref:PG::TextEncoder::JSON)、[TD](rdoc-ref:PG::TextDecoder::JSON)
143
150
  * Inet:
@@ -146,9 +153,12 @@ Binary Encoder、BD = Binary Decoder)。
146
153
  [TE](rdoc-ref:PG::TextEncoder::Array)、[TD](rdoc-ref:PG::TextDecoder::Array)
147
154
  * 複合型(「行」や「レコード」などとも言います):[TE](rdoc-ref:PG::TextEncoder::Record)、[TD](rdoc-ref:PG::TextDecoder::Record)
148
155
 
149
- カラム型として使われていませんが以下のテキスト形式もエンコードできます。
156
+ The following text and binary formats can also be encoded although they are
157
+ not used as column type:
150
158
 
151
- * COPYの入出力データ:[TE](rdoc-ref:PG::TextEncoder::CopyRow)、[TD](rdoc-ref:PG::TextDecoder::CopyRow)
159
+ * COPYの入出力データ:[TE](rdoc-ref:PG::TextEncoder::CopyRow)、[TD](rdoc-ref:PG::TextDecoder::CopyRow),
160
+ [BE](rdoc-ref:PG::BinaryEncoder::CopyRow),
161
+ [BD](rdoc-ref:PG::BinaryDecoder::CopyRow)
152
162
  * SQL文字列に挿入するリテラル:[TE](rdoc-ref:PG::TextEncoder::QuotedLiteral)
153
163
  * SQLの識別子:
154
164
  [TE](rdoc-ref:PG::TextEncoder::Identifier)、[TD](rdoc-ref:PG::TextDecoder::Identifier)
@@ -207,7 +217,7 @@ PgはRuby-3.0で導入された`Fiber.scheduler`に完全に対応していま
207
217
 
208
218
  $ bundle install
209
219
 
210
- 拡張ファイル、パッケージファイル、テストデータベースを一掃するには次のようにします。
220
+ 拡張ファイル、パッケージファイル、テストデータベースを一掃するには、このコマンドを走らせてください。PostgreSQLのバージョンも切り替わります。
211
221
 
212
222
  $ rake clean
213
223
 
@@ -215,13 +225,13 @@ PgはRuby-3.0で導入された`Fiber.scheduler`に完全に対応していま
215
225
 
216
226
  $ rake compile
217
227
 
218
- パスにある`initdb`といったPostgreSQLのツールを使ってテストやスペックを走らせるには次のようにします。
228
+ `pg_config --bindir`が指すPostgreSQLのバージョンでテストやスペックを走らせるには次のようにします。
219
229
 
220
- $ PATH=$PATH:/usr/lib/postgresql/14/bin rake test
230
+ $ rake test
221
231
 
222
- あるいは行番号を使って特定のテストを走らせるには次のようにします。
232
+ あるいは特定のPostgreSQLのバージョンで、ファイル中の行番号を使って特定のテストを走らせるには次のようにします。
223
233
 
224
- $ PATH=$PATH:/usr/lib/postgresql/14/bin rspec -Ilib -fd spec/pg/connection_spec.rb:455
234
+ $ PATH=/usr/lib/postgresql/14/bin:$PATH rspec -Ilib -fd spec/pg/connection_spec.rb:455
225
235
 
226
236
  APIドキュメントを生成するには次のようにします。
227
237
 
data/README.md CHANGED
@@ -1,7 +1,8 @@
1
1
  # pg
2
2
 
3
3
  * home :: https://github.com/ged/ruby-pg
4
- * docs :: http://deveiate.org/code/pg
4
+ * docs :: http://deveiate.org/code/pg (English) ,
5
+ https://deveiate.org/code/pg/README_ja_md.html (Japanese)
5
6
  * clog :: link:/History.md
6
7
 
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)
@@ -38,7 +39,7 @@ A small example usage:
38
39
 
39
40
  ## Requirements
40
41
 
41
- * Ruby 2.4 or newer
42
+ * Ruby 2.5 or newer
42
43
  * PostgreSQL 9.3.x or later (with headers, -dev packages, etc).
43
44
 
44
45
  It usually works with earlier versions of Ruby/PostgreSQL as well, but those are
@@ -124,26 +125,28 @@ 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):
125
126
 
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) 💡
127
- * BE: [Int2](rdoc-ref:PG::BinaryEncoder::Int2), [Int4](rdoc-ref:PG::BinaryEncoder::Int4), [Int8](rdoc-ref:PG::BinaryEncoder::Int8)
128
+ * BE: [Int2](rdoc-ref:PG::BinaryEncoder::Int2), [Int4](rdoc-ref:PG::BinaryEncoder::Int4), [Int8](rdoc-ref:PG::BinaryEncoder::Int8)
128
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)
129
131
  * Numeric: [TE](rdoc-ref:PG::TextEncoder::Numeric), [TD](rdoc-ref:PG::TextDecoder::Numeric)
130
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)
131
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)
132
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)
133
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)
134
136
  * Timestamp:
135
- * TE: [local](rdoc-ref:PG::TextEncoder::TimestampWithoutTimeZone), [UTC](rdoc-ref:PG::TextEncoder::TimestampUtc), [with-TZ](rdoc-ref:PG::TextEncoder::TimestampWithTimeZone)
136
- * TD: [local](rdoc-ref:PG::TextDecoder::TimestampLocal), [UTC](rdoc-ref:PG::TextDecoder::TimestampUtc), [UTC-to-local](rdoc-ref:PG::TextDecoder::TimestampUtcToLocal)
137
- * BD: [local](rdoc-ref:PG::BinaryDecoder::TimestampLocal), [UTC](rdoc-ref:PG::BinaryDecoder::TimestampUtc), [UTC-to-local](rdoc-ref:PG::BinaryDecoder::TimestampUtcToLocal)
138
- * Date: [TE](rdoc-ref:PG::TextEncoder::Date), [TD](rdoc-ref:PG::TextDecoder::Date)
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)
139
142
  * JSON and JSONB: [TE](rdoc-ref:PG::TextEncoder::JSON), [TD](rdoc-ref:PG::TextDecoder::JSON)
140
143
  * Inet: [TE](rdoc-ref:PG::TextEncoder::Inet), [TD](rdoc-ref:PG::TextDecoder::Inet)
141
144
  * Array: [TE](rdoc-ref:PG::TextEncoder::Array), [TD](rdoc-ref:PG::TextDecoder::Array)
142
145
  * Composite Type (also called "Row" or "Record"): [TE](rdoc-ref:PG::TextEncoder::Record), [TD](rdoc-ref:PG::TextDecoder::Record)
143
146
 
144
- The following text formats can also be encoded although they are not used as column type:
147
+ The following text and binary formats can also be encoded although they are not used as column type:
145
148
 
146
- * COPY input and output data: [TE](rdoc-ref:PG::TextEncoder::CopyRow), [TD](rdoc-ref:PG::TextDecoder::CopyRow)
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)
147
150
  * Literal for insertion into SQL string: [TE](rdoc-ref:PG::TextEncoder::QuotedLiteral)
148
151
  * SQL-Identifier: [TE](rdoc-ref:PG::TextEncoder::Identifier), [TD](rdoc-ref:PG::TextDecoder::Identifier)
149
152
 
@@ -190,7 +193,7 @@ If messages like the following are printed to stderr, you're probably using one
190
193
 
191
194
  ## Fiber IO scheduler support
192
195
 
193
- Pg is fully compatible with `Fiber.scheduler` introduced in Ruby-3.0.
196
+ Pg is fully compatible with `Fiber.scheduler` introduced in Ruby-3.0 since pg-1.3.0.
194
197
  On Windows support for `Fiber.scheduler` is available on Ruby-3.1 or newer.
195
198
  All possibly blocking IO operations are routed through the `Fiber.scheduler` if one is registered for the running thread.
196
199
  That is why pg internally uses the asynchronous libpq interface even for synchronous/blocking method calls.
@@ -205,6 +208,16 @@ They are not compatible with `Fiber.scheduler`, so that blocking states are not
205
208
  That means the operation will work properly, but IO waiting states can not be used to switch to another Fiber doing IO.
206
209
 
207
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
+
208
221
  ## Contributing
209
222
 
210
223
  To report bugs, suggest features, or check out the source with Git,
@@ -214,7 +227,8 @@ After checking out the source, install all dependencies:
214
227
 
215
228
  $ bundle install
216
229
 
217
- Cleanup extension files, packaging files, test databases:
230
+ Cleanup extension files, packaging files, test databases.
231
+ Run this to change between PostgreSQL versions:
218
232
 
219
233
  $ rake clean
220
234
 
@@ -222,13 +236,13 @@ Compile extension:
222
236
 
223
237
  $ rake compile
224
238
 
225
- Run tests/specs with PostgreSQL tools like `initdb` in the path:
239
+ Run tests/specs on the PostgreSQL version that `pg_config --bindir` points to:
226
240
 
227
- $ PATH=$PATH:/usr/lib/postgresql/14/bin rake test
241
+ $ rake test
228
242
 
229
- Or run a specific test with the line number:
243
+ Or run a specific test per file and line number on a specific PostgreSQL version:
230
244
 
231
- $ PATH=$PATH:/usr/lib/postgresql/14/bin rspec -Ilib -fd spec/pg/connection_spec.rb:455
245
+ $ PATH=/usr/lib/postgresql/14/bin:$PATH rspec -Ilib -fd spec/pg/connection_spec.rb:455
232
246
 
233
247
  Generate the API documentation:
234
248
 
data/Rakefile.cross CHANGED
@@ -31,7 +31,7 @@ class CrossLibrary < OpenStruct
31
31
  self.host_platform = toolchain
32
32
 
33
33
  # Cross-compilation constants
34
- self.openssl_version = ENV['OPENSSL_VERSION'] || '3.0.8'
34
+ self.openssl_version = ENV['OPENSSL_VERSION'] || '3.1.0'
35
35
  self.postgresql_version = ENV['POSTGRESQL_VERSION'] || '15.2'
36
36
 
37
37
  # Check if symlinks work in the current working directory.
data/ext/pg.c CHANGED
@@ -33,7 +33,6 @@
33
33
  *
34
34
  * - PQfreemem -- unnecessary: copied to ruby object, then freed. Ruby object's
35
35
  * memory is freed when it is garbage collected.
36
- * - PQbinaryTuples -- better to use PQfformat
37
36
  * - PQprint -- not very useful
38
37
  * - PQsetdb -- not very useful
39
38
  * - PQoidStatus -- deprecated, use PQoidValue
@@ -74,6 +73,7 @@ VALUE rb_mPGconstants;
74
73
  * The mapping from canonical encoding names in PostgreSQL to ones in Ruby.
75
74
  */
76
75
  const char * const (pg_enc_pg2ruby_mapping[][2]) = {
76
+ {"UTF8", "UTF-8" },
77
77
  {"BIG5", "Big5" },
78
78
  {"EUC_CN", "GB2312" },
79
79
  {"EUC_JP", "EUC-JP" },
@@ -105,7 +105,6 @@ const char * const (pg_enc_pg2ruby_mapping[][2]) = {
105
105
  {"SHIFT_JIS_2004","Windows-31J" },
106
106
  /* {"SQL_ASCII", NULL }, special case*/
107
107
  {"UHC", "CP949" },
108
- {"UTF8", "UTF-8" },
109
108
  {"WIN866", "IBM866" },
110
109
  {"WIN874", "Windows-874" },
111
110
  {"WIN1250", "Windows-1250"},
@@ -120,12 +119,6 @@ const char * const (pg_enc_pg2ruby_mapping[][2]) = {
120
119
  };
121
120
 
122
121
 
123
- /*
124
- * A cache of mapping from PostgreSQL's encoding indices to Ruby's rb_encoding*s.
125
- */
126
- static struct st_table *enc_pg2ruby;
127
-
128
-
129
122
  /*
130
123
  * Return the given PostgreSQL encoding ID as an rb_encoding.
131
124
  *
@@ -135,21 +128,8 @@ static struct st_table *enc_pg2ruby;
135
128
  rb_encoding *
136
129
  pg_get_pg_encoding_as_rb_encoding( int enc_id )
137
130
  {
138
- rb_encoding *enc;
139
-
140
- /* Use the cached value if it exists */
141
- if ( st_lookup(enc_pg2ruby, (st_data_t)enc_id, (st_data_t*)&enc) ) {
142
- return enc;
143
- }
144
- else {
145
- const char *name = pg_encoding_to_char( enc_id );
146
-
147
- enc = pg_get_pg_encname_as_rb_encoding( name );
148
- st_insert( enc_pg2ruby, (st_data_t)enc_id, (st_data_t)enc );
149
-
150
- return enc;
151
- }
152
-
131
+ const char *name = pg_encoding_to_char( enc_id );
132
+ return pg_get_pg_encname_as_rb_encoding( name );
153
133
  }
154
134
 
155
135
  /*
@@ -354,6 +334,11 @@ pg_s_init_ssl(VALUE self, VALUE do_ssl)
354
334
  void
355
335
  Init_pg_ext(void)
356
336
  {
337
+
338
+ #ifdef HAVE_RB_EXT_RACTOR_SAFE
339
+ rb_ext_ractor_safe(PQisthreadsafe());
340
+ #endif
341
+
357
342
  if( RTEST(rb_eval_string("ENV['PG_SKIP_DEPRECATION_WARNING']")) ){
358
343
  /* Set all bits to disable all deprecation warnings. */
359
344
  pg_skip_deprecation_warning = 0xFFFF;
@@ -372,8 +357,8 @@ Init_pg_ext(void)
372
357
  SINGLETON_ALIAS( rb_mPG, "is_threadsafe?", "isthreadsafe" );
373
358
  SINGLETON_ALIAS( rb_mPG, "threadsafe?", "isthreadsafe" );
374
359
 
375
- rb_define_singleton_method( rb_mPG, "init_openssl", pg_s_init_openssl, 2 );
376
- rb_define_singleton_method( rb_mPG, "init_ssl", pg_s_init_ssl, 1 );
360
+ rb_define_singleton_method( rb_mPG, "init_openssl", pg_s_init_openssl, 2 );
361
+ rb_define_singleton_method( rb_mPG, "init_ssl", pg_s_init_ssl, 1 );
377
362
 
378
363
 
379
364
  /****** PG::Connection CLASS CONSTANTS: Connection Status ******/
@@ -685,8 +670,6 @@ Init_pg_ext(void)
685
670
  /* Add the constants to the toplevel namespace */
686
671
  rb_include_module( rb_mPG, rb_mPGconstants );
687
672
 
688
- enc_pg2ruby = st_init_numtable();
689
-
690
673
  /* Initialize the main extension classes */
691
674
  init_pg_connection();
692
675
  init_pg_result();
@@ -707,4 +690,3 @@ Init_pg_ext(void)
707
690
  init_pg_recordcoder();
708
691
  init_pg_tuple();
709
692
  }
710
-
data/ext/pg.h CHANGED
@@ -76,10 +76,6 @@ typedef long suseconds_t;
76
76
  #define PG_MAX_COLUMNS 4000
77
77
  #endif
78
78
 
79
- #ifndef RARRAY_AREF
80
- #define RARRAY_AREF(a, i) (RARRAY_PTR(a)[i])
81
- #endif
82
-
83
79
  #ifdef HAVE_RB_GC_MARK_MOVABLE
84
80
  #define pg_compact_callback(x) (x)
85
81
  #define pg_gc_location(x) x = rb_gc_location(x)
@@ -89,6 +85,12 @@ typedef long suseconds_t;
89
85
  #define pg_gc_location(x) UNUSED(x)
90
86
  #endif
91
87
 
88
+ /* For compatibility with ruby < 3.0 */
89
+ #ifndef RUBY_TYPED_FROZEN_SHAREABLE
90
+ #define PG_RUBY_TYPED_FROZEN_SHAREABLE 0
91
+ #else
92
+ #define PG_RUBY_TYPED_FROZEN_SHAREABLE RUBY_TYPED_FROZEN_SHAREABLE
93
+ #endif
92
94
  #define PG_ENC_IDX_BITS 28
93
95
 
94
96
  /* The data behind each PG::Connection object */
@@ -97,6 +99,9 @@ typedef struct {
97
99
 
98
100
  /* Cached IO object for the socket descriptor */
99
101
  VALUE socket_io;
102
+ /* function pointers of the original libpq notice receivers */
103
+ PQnoticeReceiver default_notice_receiver;
104
+ PQnoticeProcessor default_notice_processor;
100
105
  /* Proc object that receives notices as PG::Result objects */
101
106
  VALUE notice_receiver;
102
107
  /* Proc object that receives notices as String objects */
@@ -314,7 +319,7 @@ int pg_coder_enc_to_s _(( t_pg_coder*, VALUE, c
314
319
  int pg_text_enc_identifier _(( t_pg_coder*, VALUE, char *, VALUE *, int));
315
320
  t_pg_coder_enc_func pg_coder_enc_func _(( t_pg_coder* ));
316
321
  t_pg_coder_dec_func pg_coder_dec_func _(( t_pg_coder*, int ));
317
- void pg_define_coder _(( const char *, void *, VALUE, VALUE ));
322
+ VALUE pg_define_coder _(( const char *, void *, VALUE, VALUE ));
318
323
  VALUE pg_obj_to_i _(( VALUE ));
319
324
  VALUE pg_tmbc_allocate _(( void ));
320
325
  void pg_coder_init_encoder _(( VALUE ));
@@ -12,6 +12,8 @@
12
12
  #endif
13
13
 
14
14
  VALUE rb_mPG_BinaryDecoder;
15
+ static VALUE s_Date;
16
+ static ID s_id_new;
15
17
 
16
18
 
17
19
  /*
@@ -195,6 +197,82 @@ pg_bin_dec_timestamp(t_pg_coder *conv, const char *val, int len, int tuple, int
195
197
  }
196
198
  }
197
199
 
200
+ #define PG_INT32_MIN (-0x7FFFFFFF-1)
201
+ #define PG_INT32_MAX (0x7FFFFFFF)
202
+ #define POSTGRES_EPOCH_JDATE 2451545 /* == date2j(2000, 1, 1) */
203
+ #define MONTHS_PER_YEAR 12
204
+
205
+ /* taken from PostgreSQL sources at src/backend/utils/adt/datetime.c */
206
+ void
207
+ j2date(int jd, int *year, int *month, int *day)
208
+ {
209
+ unsigned int julian;
210
+ unsigned int quad;
211
+ unsigned int extra;
212
+ int y;
213
+
214
+ julian = jd;
215
+ julian += 32044;
216
+ quad = julian / 146097;
217
+ extra = (julian - quad * 146097) * 4 + 3;
218
+ julian += 60 + quad * 3 + extra / 146097;
219
+ quad = julian / 1461;
220
+ julian -= quad * 1461;
221
+ y = julian * 4 / 1461;
222
+ julian = ((y != 0) ? ((julian + 305) % 365) : ((julian + 306) % 366))
223
+ + 123;
224
+ y += quad * 4;
225
+ *year = y - 4800;
226
+ quad = julian * 2141 / 65536;
227
+ *day = julian - 7834 * quad / 256;
228
+ *month = (quad + 10) % MONTHS_PER_YEAR + 1;
229
+ } /* j2date() */
230
+
231
+ /*
232
+ * Document-class: PG::BinaryDecoder::Date < PG::SimpleDecoder
233
+ *
234
+ * This is a decoder class for conversion of PostgreSQL binary date
235
+ * to Ruby Date objects.
236
+ */
237
+ static VALUE
238
+ pg_bin_dec_date(t_pg_coder *conv, const char *val, int len, int tuple, int field, int enc_idx)
239
+ {
240
+ int year, month, day;
241
+ int date;
242
+
243
+ if (len != 4) {
244
+ rb_raise(rb_eTypeError, "unexpected date format != 4 bytes");
245
+ }
246
+
247
+ date = read_nbo32(val);
248
+ switch(date){
249
+ case PG_INT32_MAX:
250
+ return rb_str_new2("infinity");
251
+ case PG_INT32_MIN:
252
+ return rb_str_new2("-infinity");
253
+ default:
254
+ j2date(date + POSTGRES_EPOCH_JDATE, &year, &month, &day);
255
+
256
+ return rb_funcall(s_Date, s_id_new, 3, INT2NUM(year), INT2NUM(month), INT2NUM(day));
257
+ }
258
+ }
259
+
260
+ /* called per autoload when BinaryDecoder::Date is used */
261
+ static VALUE
262
+ init_pg_bin_decoder_date(VALUE rb_mPG_BinaryDecoder)
263
+ {
264
+ rb_require("date");
265
+ s_Date = rb_const_get(rb_cObject, rb_intern("Date"));
266
+ rb_gc_register_mark_object(s_Date);
267
+ s_id_new = rb_intern("new");
268
+
269
+ /* dummy = rb_define_class_under( rb_mPG_BinaryDecoder, "Date", rb_cPG_SimpleDecoder ); */
270
+ pg_define_coder( "Date", pg_bin_dec_date, rb_cPG_SimpleDecoder, rb_mPG_BinaryDecoder );
271
+
272
+ return Qnil;
273
+ }
274
+
275
+
198
276
  /*
199
277
  * Document-class: PG::BinaryDecoder::String < PG::SimpleDecoder
200
278
  *
@@ -209,6 +287,7 @@ init_pg_binary_decoder(void)
209
287
  {
210
288
  /* This module encapsulates all decoder classes with binary input format */
211
289
  rb_mPG_BinaryDecoder = rb_define_module_under( rb_mPG, "BinaryDecoder" );
290
+ rb_define_private_method(rb_singleton_class(rb_mPG_BinaryDecoder), "init_date", init_pg_bin_decoder_date, 0);
212
291
 
213
292
  /* Make RDoc aware of the decoder classes... */
214
293
  /* dummy = rb_define_class_under( rb_mPG_BinaryDecoder, "Boolean", rb_cPG_SimpleDecoder ); */