pg 1.4.3 → 1.5.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/.appveyor.yml +15 -9
  4. data/.github/workflows/binary-gems.yml +43 -12
  5. data/.github/workflows/source-gem.yml +28 -20
  6. data/.gitignore +11 -2
  7. data/.travis.yml +2 -2
  8. data/{History.rdoc → History.md} +251 -145
  9. data/README.ja.md +276 -0
  10. data/README.md +286 -0
  11. data/Rakefile +15 -6
  12. data/Rakefile.cross +7 -11
  13. data/certs/larskanis-2023.pem +24 -0
  14. data/ext/errorcodes.def +4 -0
  15. data/ext/errorcodes.txt +2 -1
  16. data/ext/pg.c +14 -30
  17. data/ext/pg.h +11 -5
  18. data/ext/pg_binary_decoder.c +80 -1
  19. data/ext/pg_binary_encoder.c +225 -1
  20. data/ext/pg_coder.c +17 -8
  21. data/ext/pg_connection.c +162 -64
  22. data/ext/pg_copy_coder.c +307 -18
  23. data/ext/pg_errors.c +1 -1
  24. data/ext/pg_record_coder.c +6 -5
  25. data/ext/pg_result.c +102 -26
  26. data/ext/pg_text_decoder.c +28 -10
  27. data/ext/pg_text_encoder.c +23 -10
  28. data/ext/pg_tuple.c +35 -32
  29. data/ext/pg_type_map.c +4 -3
  30. data/ext/pg_type_map_all_strings.c +3 -3
  31. data/ext/pg_type_map_by_class.c +6 -4
  32. data/ext/pg_type_map_by_column.c +9 -5
  33. data/ext/pg_type_map_by_mri_type.c +1 -1
  34. data/ext/pg_type_map_by_oid.c +8 -5
  35. data/ext/pg_type_map_in_ruby.c +6 -3
  36. data/lib/pg/basic_type_map_based_on_result.rb +21 -1
  37. data/lib/pg/basic_type_map_for_queries.rb +13 -8
  38. data/lib/pg/basic_type_map_for_results.rb +26 -3
  39. data/lib/pg/basic_type_registry.rb +30 -32
  40. data/lib/pg/binary_decoder/date.rb +9 -0
  41. data/lib/pg/binary_decoder/timestamp.rb +26 -0
  42. data/lib/pg/binary_encoder/timestamp.rb +20 -0
  43. data/lib/pg/coder.rb +15 -13
  44. data/lib/pg/connection.rb +148 -86
  45. data/lib/pg/exceptions.rb +7 -0
  46. data/lib/pg/text_decoder/date.rb +18 -0
  47. data/lib/pg/text_decoder/inet.rb +9 -0
  48. data/lib/pg/text_decoder/json.rb +14 -0
  49. data/lib/pg/text_decoder/numeric.rb +9 -0
  50. data/lib/pg/text_decoder/timestamp.rb +30 -0
  51. data/lib/pg/text_encoder/date.rb +12 -0
  52. data/lib/pg/text_encoder/inet.rb +28 -0
  53. data/lib/pg/text_encoder/json.rb +14 -0
  54. data/lib/pg/text_encoder/numeric.rb +9 -0
  55. data/lib/pg/text_encoder/timestamp.rb +24 -0
  56. data/lib/pg/version.rb +1 -1
  57. data/lib/pg.rb +55 -15
  58. data/pg.gemspec +4 -2
  59. data/rakelib/task_extension.rb +1 -1
  60. data/translation/.po4a-version +7 -0
  61. data/translation/po/all.pot +910 -0
  62. data/translation/po/ja.po +1047 -0
  63. data/translation/po4a.cfg +12 -0
  64. data.tar.gz.sig +0 -0
  65. metadata +101 -32
  66. metadata.gz.sig +0 -0
  67. data/README.ja.rdoc +0 -13
  68. data/README.rdoc +0 -214
  69. data/lib/pg/binary_decoder.rb +0 -23
  70. data/lib/pg/constants.rb +0 -12
  71. data/lib/pg/text_decoder.rb +0 -46
  72. data/lib/pg/text_encoder.rb +0 -59
data/README.ja.md ADDED
@@ -0,0 +1,276 @@
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
+ [![https://gitter.im/ged/ruby-pg
9
+ でチャットに参加](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)
10
+
11
+
12
+ ## 説明
13
+
14
+ Pgは[PostgreSQL
15
+ RDBMS](http://www.postgresql.org/)へのRubyのインターフェースです。[PostgreSQL
16
+ 9.3以降](http://www.postgresql.org/support/versioning/)で動作します。
17
+
18
+ 簡単な使用例は次の通りです。
19
+ ```ruby
20
+ #!/usr/bin/env ruby
21
+
22
+ require 'pg'
23
+
24
+ # データベースへの現在の接続を表に出力します
25
+ conn = PG.connect( dbname: 'sales' )
26
+ conn.exec( "SELECT * FROM pg_stat_activity" ) do |result|
27
+ puts " PID | User | Query"
28
+ result.each do |row|
29
+ puts " %7d | %-16s | %s " %
30
+ row.values_at('pid', 'usename', 'query')
31
+ end
32
+ end
33
+ ```
34
+
35
+ ## ビルド状況
36
+
37
+ [![Github
38
+ 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)
39
+ [![バイナリgem](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)
40
+ [![Appveyorのビルド状況](https://ci.appveyor.com/api/projects/status/gjx5axouf3b1wicp?svg=true)](https://ci.appveyor.com/project/ged/ruby-pg-9j8l3)
41
+
42
+
43
+ ## 要件
44
+
45
+ * Ruby 2.5かそれより新しいバージョン
46
+ * PostgreSQL 9.3.xかそれ以降のバージョン(ヘッダー付属のもの、例えば-devの名前のパッケージ)。
47
+
48
+ それより前のバージョンのRubyやPostgreSQLでも通常は同様に動作しますが、定期的なテストはされていません。
49
+
50
+
51
+ ## バージョン管理
52
+
53
+ [セマンティックバージョニング](http://semver.org/)の原則にしたがってgemをタグ付けしてリリースしています。
54
+
55
+ この方針の結果として、2つの数字を指定する[悲観的バージョン制約](http://guides.rubygems.org/patterns/#pessimistic-version-constraint)を使ってこのgemへの依存関係を指定することができます(またそうすべきです)。
56
+
57
+ 例えば次の通りです。
58
+
59
+ ```ruby
60
+ spec.add_dependency 'pg', '~> 1.0'
61
+ ```
62
+
63
+ ## インストール方法
64
+
65
+ RubyGemsを経由してインストールするには以下とします。
66
+
67
+ gem install pg
68
+
69
+ Postgresと一緒にインストールされた'pg_config'プログラムへのパスを指定する必要があるかもしれません。
70
+
71
+ gem install pg -- --with-pg-config=<path to pg_config>
72
+
73
+ Bundlerを介してインストールした場合は次のようにコンパイルのためのヒントを与えられます。
74
+
75
+ bundle config build.pg --with-pg-config=<path to pg_config>
76
+
77
+ MacOS Xへインストールする詳しい情報については README-OS_X.rdoc を、Windows用のビルドやインストールの説明については
78
+ README-Windows.rdoc を参照してください。
79
+
80
+ 詰まったときやただ何か喋りたいときのために[Google+グループ](http://goo.gl/TFy1U)と[メーリングリスト](http://groups.google.com/group/ruby-pg)もあります。
81
+
82
+ 署名されたgemとしてインストールしたい場合は、リポジトリの[`certs`ディレクトリ](https://github.com/ged/ruby-pg/tree/master/certs)にgemの署名をする公開証明書があります。
83
+
84
+
85
+ ## 型変換
86
+
87
+ PgにはおまけとしてRubyとネイティブCコードにある結果の値やクエリ引数の型変換ができます。
88
+ こうすることでデータベースとのデータの往来を加速させられますが、それは文字列のアロケーションが減り、(より遅い)Rubyのコードでの変換部分が除かれるからです。
89
+
90
+ とても基本的な型変換は次のようにできます。
91
+ ```ruby
92
+ conn.type_map_for_results = PG::BasicTypeMapForResults.new conn
93
+ # ……これは結果の値の対応付けに作用します。
94
+ conn.exec("select 1, now(), '{2,3}'::int[]").values
95
+ # => [[1, 2014-09-21 20:51:56 +0200, [2, 3]]]
96
+
97
+ conn.type_map_for_queries = PG::BasicTypeMapForQueries.new conn
98
+ # ……そしてこれは引数値の対応付けのためのものです。
99
+ conn.exec_params("SELECT $1::text, $2::text, $3::text", [1, 1.23, [2,3]]).values
100
+ # => [["1", "1.2300000000000000E+00", "{2,3}"]]
101
+ ```
102
+
103
+ しかしPgの型変換はかなり調整が効きます。2層に分かれているのがその理由です。
104
+
105
+ ### エンコーダーとデコーダー (ext/pg_*coder.c, lib/pg/*coder.rb)
106
+
107
+ こちらはより低層で、DBMSへ転送するためにRubyのオブジェクトを変換するエンコーディングクラスと取得してきたデータをRubyのオブジェクトに変換し戻すデコーディングクラスが含まれています。クラスはそれぞれの形式によって名前空間PG::TextEncoder、PG::TextDecoder、PG::BinaryEncoder、そしてPG::BinaryDecoderに分かれています。
108
+
109
+ エンコーダーないしデコーダーオブジェクトにOIDデータ型や形式コード(テキストないしバイナリ)や任意で名前を割り当てることができます。要素のエンコーダーないしデコーダーを割り当てることによって複合型を構築することもできます。PG::CoderオブジェクトはPG::TypeMapをセットアップしたりその代わりに単一の値と文字列表現とを相互に変換したりするのに使えます。
110
+
111
+ ruby-pgでは以下のPostgreSQLカラム型に対応しています(TE = Text Encoder、TD = Text Decoder、BE =
112
+ Binary Encoder、BD = Binary Decoder)。
113
+
114
+ * Integer:
115
+ [TE](rdoc-ref:PG::TextEncoder::Integer)、[TD](rdoc-ref:PG::TextDecoder::Integer)、[BD](rdoc-ref:PG::BinaryDecoder::Integer)
116
+ 💡
117
+ リンクがないでしょうか。[こちら](https://deveiate.org/code/pg/README_ja_md.html#label-E5-9E-8B-E5-A4-89-E6-8F-9B)を代わりに見てください
118
+ 💡
119
+ * BE:
120
+ [Int2](rdoc-ref:PG::BinaryEncoder::Int2)、[Int4](rdoc-ref:PG::BinaryEncoder::Int4)、[Int8](rdoc-ref:PG::BinaryEncoder::Int8)
121
+ * Float:
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)
125
+ * Numeric:
126
+ [TE](rdoc-ref:PG::TextEncoder::Numeric)、[TD](rdoc-ref:PG::TextDecoder::Numeric)
127
+ * Boolean:
128
+ [TE](rdoc-ref:PG::TextEncoder::Boolean)、[TD](rdoc-ref:PG::TextDecoder::Boolean)、[BE](rdoc-ref:PG::BinaryEncoder::Boolean)、[BD](rdoc-ref:PG::BinaryDecoder::Boolean)
129
+ * String:
130
+ [TE](rdoc-ref:PG::TextEncoder::String)、[TD](rdoc-ref:PG::TextDecoder::String)、[BE](rdoc-ref:PG::BinaryEncoder::String)、[BD](rdoc-ref:PG::BinaryDecoder::String)
131
+ * Bytea:
132
+ [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
+ * Base64:
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)
135
+ * Timestamp:
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)
148
+ * JSONとJSONB:
149
+ [TE](rdoc-ref:PG::TextEncoder::JSON)、[TD](rdoc-ref:PG::TextDecoder::JSON)
150
+ * Inet:
151
+ [TE](rdoc-ref:PG::TextEncoder::Inet)、[TD](rdoc-ref:PG::TextDecoder::Inet)
152
+ * Array:
153
+ [TE](rdoc-ref:PG::TextEncoder::Array)、[TD](rdoc-ref:PG::TextDecoder::Array)
154
+ * 複合型(「行」や「レコード」などとも言います):[TE](rdoc-ref:PG::TextEncoder::Record)、[TD](rdoc-ref:PG::TextDecoder::Record)
155
+
156
+ The following text and binary formats can also be encoded although they are
157
+ not used as column type:
158
+
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)
162
+ * SQL文字列に挿入するリテラル:[TE](rdoc-ref:PG::TextEncoder::QuotedLiteral)
163
+ * SQLの識別子:
164
+ [TE](rdoc-ref:PG::TextEncoder::Identifier)、[TD](rdoc-ref:PG::TextDecoder::Identifier)
165
+
166
+ ### PG::TypeMapとその派生 (ext/pg_type_map*.c, lib/pg/type_map*.rb)
167
+
168
+ TypeMapはエンコーダーまたはデコーダーのどちらによってどの値を変換するかを定義します。様々な型の対応付け戦略があるので、このクラスにはいくつかの派生が実装されています。型変換の特有の需要に合わせてそれらの派生から選んで調整を加えることができます。既定の型の対応付けはPG::TypeMapAllStringsです。
169
+
170
+ 型の対応付けは、結果の集合それぞれに対し、接続毎ないしクエリ毎に割り当てることができます。型の対応付けはCOPYの入出力データストリーミングでも使うことができます。PG::Connection#copy_dataを参照してください。
171
+
172
+ 以下の基底となる型の対応付けが使えます。
173
+
174
+ * PG::TypeMapAllStrings - 全ての値と文字列について相互にエンコードとデコードを行います(既定)
175
+ * PG::TypeMapByClass - 送信する値のクラスに基づいてエンコーダーを選択します
176
+ * PG::TypeMapByColumn - カラムの順番によってエンコーダーとデコーダーを選択します
177
+ * PG::TypeMapByOid - PostgreSQLのOIDデータ型によってデコーダーを選択します
178
+ * PG::TypeMapInRuby - Rubyで独自の型の対応付けを定義します
179
+
180
+ 以下の型の対応付けはPG::BasicTypeRegistry由来の型の対応付けが入った状態になっています。
181
+
182
+ * PG::BasicTypeMapForResults -
183
+ PG::TypeMapByOidによくあるPostgreSQLカラム型用にデコーダーが入った状態になっています
184
+ * PG::BasicTypeMapBasedOnResult -
185
+ PG::TypeMapByOidによくあるPostgreSQLカラム型用のエンコーダーが入った状態になっています
186
+ * PG::BasicTypeMapForQueries -
187
+ PG::TypeMapByClassによくあるRubyの値クラス用にエンコーダーが入った状態になっています
188
+
189
+
190
+ ## スレッド対応
191
+
192
+ PGには個々のスレッドが別々のPG::Connectionオブジェクトを同時に使えるという点でスレッド安全性があります。しかし1つ以上のスレッドから同時にPgのオブジェクトにアクセスすると安全ではありません。そのため必ず、毎回新しいスレッドを作るときに新しいデータベースサーバー接続を開くか、スレッド安全性のある方法で接続を管理するActiveRecordのようなラッパーライブラリを使うようにしてください。
193
+
194
+ 以下のようなメッセージが標準エラー出力に表示された場合、恐らく複数のスレッドが1つの接続を使っています。
195
+
196
+ message type 0x31 arrived from server while idle
197
+ message type 0x32 arrived from server while idle
198
+ message type 0x54 arrived from server while idle
199
+ message type 0x43 arrived from server while idle
200
+ message type 0x5a arrived from server while idle
201
+
202
+
203
+ ## Fiber IOスケジューラー対応
204
+
205
+ PgはRuby-3.0で導入された`Fiber.scheduler`に完全に対応しています。`Fiber.scheduler`のWindows対応についてはRuby-3.1以降で使えます。`Fiber.scheduler`が走らせているスレッドに登録されている場合、起こりうる全てのブロッキングIO操作はそのスケジューラーを経由します。同期的であったりブロックしたりするメソッド呼び出しについてもpgが内部的に非同期のlibpqインターフェースを使っているのはそれが理由です。またlibpqの組み込み関数に代えてRubyのDNS解決を使っています。
206
+
207
+ 内部的にPgは常にlibpqのノンブロッキング接続モードを使います。それからブロッキングモードで走っているように振舞いますが、もし`Fiber.scheduler`が登録されていれば全てのブロッキングIOはそのスケジューラーを通じてRubyで制御されます。`PG::Connection.setnonblocking(true)`が呼ばれたらノンブロッキング状態が有効になったままになりますが、それ以降のブロッキング状態の制御が無効になるので、呼び出しているプログラムはブロッキング状態を自力で制御しなければなりません。
208
+
209
+ この規則の1つの例外には、`PG::Connection#lo_create`や外部ライブラリを使う認証メソッド(GSSAPI認証など)のような、大きめのオブジェクト用のメソッドがあります。これらは`Fiber.scheduler`と互換性がないため、ブロッキング状態は登録されたIOスケジューラに渡されません。つまり操作は適切に実行されますが、IO待ち状態に別のIOを扱うFiberから使用を切り替えてくることができなくなります。
210
+
211
+
212
+ ## 貢献
213
+
214
+ バグを報告したり機能を提案したりGitでソースをチェックアウトしたりするには[プロジェクトページをご確認ください](https://github.com/ged/ruby-pg)。
215
+
216
+ ソースをチェックアウトしたあとは全ての依存関係をインストールします。
217
+
218
+ $ bundle install
219
+
220
+ 拡張ファイル、パッケージファイル、テストデータベースを一掃するには、このコマンドを走らせてください。PostgreSQLのバージョンも切り替わります。
221
+
222
+ $ rake clean
223
+
224
+ 拡張をコンパイルするには次のようにします。
225
+
226
+ $ rake compile
227
+
228
+ `pg_config --bindir`が指すPostgreSQLのバージョンでテストやスペックを走らせるには次のようにします。
229
+
230
+ $ rake test
231
+
232
+ あるいは特定のPostgreSQLのバージョンで、ファイル中の行番号を使って特定のテストを走らせるには次のようにします。
233
+
234
+ $ PATH=/usr/lib/postgresql/14/bin:$PATH rspec -Ilib -fd spec/pg/connection_spec.rb:455
235
+
236
+ APIドキュメントを生成するには次のようにします。
237
+
238
+ $ rake docs
239
+
240
+ 必ず全てのバグと新機能についてテストを使って検証してください。
241
+
242
+ 現在のメンテナはMichael Granger <ged@FaerieMUD.org>とLars Kanis
243
+ <lars@greiz-reinsdorf.de>です。
244
+
245
+
246
+ ## 著作権
247
+
248
+ Copyright (c) 1997-2022 by the authors.
249
+
250
+ * Jeff Davis <ruby-pg@j-davis.com>
251
+ * Guy Decoux (ts) <decoux@moulon.inra.fr>
252
+ * Michael Granger <ged@FaerieMUD.org>
253
+ * Lars Kanis <lars@greiz-reinsdorf.de>
254
+ * Dave Lee
255
+ * Eiji Matsumoto <usagi@ruby.club.or.jp>
256
+ * Yukihiro Matsumoto <matz@ruby-lang.org>
257
+ * Noboru Saitou <noborus@netlab.jp>
258
+
259
+ You may redistribute this software under the same terms as Ruby itself; see
260
+ https://www.ruby-lang.org/en/about/license.txt or the BSDL file in the
261
+ source for details.
262
+ (参考訳:このソフトウェアはRuby自体と同じ条件の元で再配布することができます。詳細については
263
+ https://www.ruby-lang.org/en/about/license.txt やソース中のBSDLファイルを参照してください)
264
+
265
+ Portions of the code are from the PostgreSQL project, and are distributed "
266
+ "under the terms of the PostgreSQL license, included in the file POSTGRES.
267
+ (参考訳:コードの一部はPostgreSQLプロジェクトから来ており、PostgreSQLの使用許諾の条件の元で配布されます。ファイルPOSTGRESに含まれています)
268
+
269
+ Portions copyright LAIKA, Inc.
270
+
271
+
272
+ ## 謝辞
273
+
274
+ 長年にわたって貢献してくださった方々についてはContributors.rdocを参照してください。
275
+
276
+ ruby-listとruby-devメーリングリストの方々に感謝します。またPostgreSQLを開発された方々へも謝意を表します。
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 9.3 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.5 or newer
43
+ * PostgreSQL 9.3.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)
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 CHANGED
@@ -16,14 +16,14 @@ LIBDIR = BASEDIR + 'lib'
16
16
  EXTDIR = BASEDIR + 'ext'
17
17
  PKGDIR = BASEDIR + 'pkg'
18
18
  TMPDIR = BASEDIR + 'tmp'
19
- TESTDIR = BASEDIR + "tmp_test_specs"
19
+ TESTDIR = BASEDIR + "tmp_test_*"
20
20
 
21
21
  DLEXT = RbConfig::CONFIG['DLEXT']
22
22
  EXT = LIBDIR + "pg_ext.#{DLEXT}"
23
23
 
24
24
  GEMSPEC = 'pg.gemspec'
25
25
 
26
- CLOBBER.include( TESTDIR.to_s )
26
+ CLEAN.include( TESTDIR.to_s )
27
27
  CLEAN.include( PKGDIR.to_s, TMPDIR.to_s )
28
28
  CLEAN.include "lib/*/libpq.dll"
29
29
  CLEAN.include "lib/pg_ext.*"
@@ -74,10 +74,9 @@ task :test => :spec
74
74
  require 'rdoc/task'
75
75
 
76
76
  RDoc::Task.new( 'docs' ) do |rdoc|
77
- rdoc.main = "README.rdoc"
78
- rdoc.rdoc_files.include( "*.rdoc", "lib/**/*.rb", 'ext/**/*.{c,h}' )
77
+ rdoc.options = $gem_spec.rdoc_options
78
+ rdoc.rdoc_files = $gem_spec.extra_rdoc_files
79
79
  rdoc.generator = :fivefish
80
- rdoc.title = "PG: The Ruby PostgreSQL Driver"
81
80
  rdoc.rdoc_dir = 'doc'
82
81
  end
83
82
 
@@ -92,7 +91,7 @@ end
92
91
 
93
92
  desc "Update list of server error codes"
94
93
  task :update_error_codes do
95
- URL_ERRORCODES_TXT = "http://git.postgresql.org/gitweb/?p=postgresql.git;a=blob_plain;f=src/backend/utils/errcodes.txt;hb=refs/tags/REL_14_0"
94
+ URL_ERRORCODES_TXT = "http://git.postgresql.org/gitweb/?p=postgresql.git;a=blob_plain;f=src/backend/utils/errcodes.txt;hb=refs/tags/REL_15_0"
96
95
 
97
96
  ERRORCODES_TXT = "ext/errorcodes.txt"
98
97
  sh "wget #{URL_ERRORCODES_TXT.inspect} -O #{ERRORCODES_TXT.inspect} || curl #{URL_ERRORCODES_TXT.inspect} -o #{ERRORCODES_TXT.inspect}"
@@ -104,3 +103,13 @@ file 'ext/pg_errors.c' => ['ext/errorcodes.def'] do
104
103
  # trigger compilation of changed errorcodes.def
105
104
  touch 'ext/pg_errors.c'
106
105
  end
106
+
107
+ desc "Translate readme"
108
+ task :translate do
109
+ cd "translation" do
110
+ # po4a's lexer might change, so record its version for reference
111
+ sh "LANG=C po4a --version > .po4a-version"
112
+
113
+ sh "po4a po4a.cfg"
114
+ end
115
+ end
data/Rakefile.cross CHANGED
@@ -31,8 +31,8 @@ class CrossLibrary < OpenStruct
31
31
  self.host_platform = toolchain
32
32
 
33
33
  # Cross-compilation constants
34
- self.openssl_version = ENV['OPENSSL_VERSION'] || '1.1.1q'
35
- self.postgresql_version = ENV['POSTGRESQL_VERSION'] || '14.4'
34
+ self.openssl_version = ENV['OPENSSL_VERSION'] || '3.1.0'
35
+ self.postgresql_version = ENV['POSTGRESQL_VERSION'] || '15.2'
36
36
 
37
37
  # Check if symlinks work in the current working directory.
38
38
  # This fails, if rake-compiler-dock is running on a Windows box.
@@ -127,7 +127,7 @@ class CrossLibrary < OpenStruct
127
127
  file openssl_makefile => static_openssl_builddir do |t|
128
128
  chdir( static_openssl_builddir ) do
129
129
  cmd = cmd_prelude.dup
130
- cmd << "./Configure" << openssl_config
130
+ cmd << "./Configure" << "-static" << openssl_config
131
131
 
132
132
  run( *cmd )
133
133
  end
@@ -146,14 +146,10 @@ class CrossLibrary < OpenStruct
146
146
  end
147
147
 
148
148
  desc "compile static #{libssl}"
149
- file libssl => "compile_static_openssl:#{for_platform}" do |t|
150
- rm t.name.gsub(/\.a$/, ".dll.a")
151
- end
149
+ file libssl => "compile_static_openssl:#{for_platform}"
152
150
 
153
151
  desc "compile static #{libcrypto}"
154
- file libcrypto => "compile_static_openssl:#{for_platform}" do |t|
155
- rm t.name.gsub(/\.a$/, ".dll.a")
156
- end
152
+ file libcrypto => "compile_static_openssl:#{for_platform}"
157
153
 
158
154
 
159
155
 
@@ -196,7 +192,7 @@ class CrossLibrary < OpenStruct
196
192
  cmd << "CFLAGS=-L#{static_openssl_builddir}"
197
193
  cmd << "LDFLAGS=-L#{static_openssl_builddir}"
198
194
  cmd << "LDFLAGS_SL=-L#{static_openssl_builddir}"
199
- cmd << "LIBS=-lwsock32 -lgdi32 -lws2_32"
195
+ cmd << "LIBS=-lwsock32 -lgdi32 -lws2_32 -lcrypt32"
200
196
  cmd << "CPPFLAGS=-I#{static_openssl_builddir}/include"
201
197
 
202
198
  run( *cmd )
@@ -294,7 +290,7 @@ CrossLibraries.each do |xlib|
294
290
  RakeCompilerDock.sh <<-EOT, platform: platform
295
291
  (cp build/gem/gem-*.pem ~/.gem/ || true) &&
296
292
  bundle install --local &&
297
- rake native:#{platform} pkg/#{$gem_spec.full_name}-#{platform}.gem MAKE="make -j`nproc`" RUBY_CC_VERSION=3.1.0:3.0.0:2.7.0:2.6.0:2.5.0
293
+ rake native:#{platform} pkg/#{$gem_spec.full_name}-#{platform}.gem MAKE="make -j`nproc`" RUBY_CC_VERSION=3.2.0:3.1.0:3.0.0:2.7.0:2.6.0:2.5.0
298
294
  EOT
299
295
  end
300
296
  desc "Build the windows binary gems"