Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@
/lib/libpq.dll
/lib/pg/postgresql_lib_path.rb
/test_trace.out
/translation/po/en.pot
108 changes: 80 additions & 28 deletions README.ja.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# pg

* ホーム :: https://github.com/ged/ruby-pg
* ドキュメント :: http://deveiate.org/code/pg (英語)、 https://deveiate.org/code/pg/README_ja_md.html (日本語)
* ドキュメント :: http://deveiate.org/code/pg/README_md.html (英語)、 https://deveiate.org/code/pg/README_ja_md.html (日本語)
* 変更履歴 :: link:/CHANGELOG.md

[![https://gitter.im/ged/ruby-pg
Expand Down Expand Up @@ -31,6 +31,10 @@ RDBMS](http://www.postgresql.org/)へのRubyのインターフェースです。
end
```

問い合わせのメソッドについては PG::Connection クラスを、問い合わせの結果を取り回す際の情報については PG::Result
クラスを参照してください。


## ビルド状況

[![Github
Expand All @@ -42,28 +46,37 @@ Actionsのビルド状況](https://github.com/ged/ruby-pg/actions/workflows/sour
## 要件

* Ruby 2.7かそれより新しいバージョン
* PostgreSQL 10.xかそれ以降のバージョン(ヘッダー付属のもの、例えば-devの名前のパッケージ)。
* PostgreSQL 10.x以降
* ソースからgemをインストールする場合:-devのパッケージなど、ヘッダ付きのlibpq

それより前のバージョンのRubyやPostgreSQLでも通常は同様に動作しますが、定期的なテストはされていません。

## インストール方法

## バージョン管理
RubyGemsを経由してインストールするには以下とします。

[セマンティックバージョニング](http://semver.org/)の原則にしたがってgemをタグ付けしてリリースしています。
gem install pg

この方針の結果として、2つの数字を指定する[悲観的バージョン制約](http://guides.rubygems.org/patterns/#pessimistic-version-constraint)を使ってこのgemへの依存関係を指定することができます(またそうすべきです)
こうするとバイナリgem、とりわけ実行しているプラットフォームに固有のものが既定でインストールされます

例えば次の通りです。
### バイナリgem

```ruby
spec.add_dependency 'pg', '~> 1.0'
```
バイナリgemは実行中のシステムのlibpqパッケージに依存しません。
組込みでlibpqを持ちます。

## インストール方法
`x86_64-linux`と`aarch64-linux`のプラットフォームのgemはAlpine
Linuxで走りますが、`gcompat`パッケージが要求されます。一方、`*-linux-musl`のプラットフォームのネイティブgemはその依存関係なしに動作します。

RubyGemsを経由してインストールするには以下とします。
バイナリgemが対応していない用途が1つあり、それが[LDAPからの接続オプション](https://www.postgresql.org/docs/current/libpq-ldap.html)の取得です。
これに対応するには`libldap`が必要でしょうが、沢山の依存関係があります。
広く使われている機能のようにも対応する価値があるとも思われません。
必要であれば、ソースgemに強制できます。

gem install pg
### ソースgem

ソースgemは次のように強制できます。

gem uninstall pg --all
gem install pg --platform ruby

Postgresと一緒にインストールされた'pg_config'プログラムへのパスを指定する必要があるかもしれません。

Expand All @@ -73,6 +86,29 @@ Bundlerを介してインストールした場合は次のようにコンパイ

bundle config build.pg --with-pg-config=<path to pg_config>

### Bundler

必要なプラットフォームとソースgemがbundlerにより取得されることを確実にするためには、次のように加えられます。

```
bundle lock --add-platform x86_64-linux
bundle lock --add-platform arm64-darwin
bundle lock --add-platform x64-mingw-ucrt
bundle lock --add-platform ruby
bundle package --all-platforms
```

`bundle package`の再実行は`bundle
update`後にも必須であり、これはすべてのプラットフォームの新しい特定のgemを取得するためです。

バイナリgemが何らかの理由で動作しないなら、Gemfileでソースgemの利用を簡単に強制できます。

```
gem "pg", force_ruby_platform: true
```

### その他

MacOS Xへインストールする詳しい情報については README-OS_X.rdoc を、Windows用のビルドやインストールの説明については
README-Windows.rdoc を参照してください。

Expand All @@ -81,9 +117,22 @@ README-Windows.rdoc を参照してください。
署名されたgemとしてインストールしたい場合は、リポジトリの[`certs`ディレクトリ](https://github.com/ged/ruby-pg/tree/master/certs)にgemの署名をする公開証明書があります。


## バージョン管理

[セマンティックバージョニング](http://semver.org/)の原則にしたがってgemをタグ付けしてリリースしています。

この方針の結果として、2つの数字を指定する[悲観的バージョン制約](http://guides.rubygems.org/patterns/#pessimistic-version-constraint)を使ってこのgemへの依存関係を指定することができます(またそうすべきです)。

例えば次の通りです。

```ruby
spec.add_dependency 'pg', '~> 1.0'
```


## 型変換

Pgでは任意でRubyと素のCコードにある結果の値やクエリ引数の型変換ができます
Pgでは任意でRubyと素のCコードにある結果の値や問い合わせ引数の型変換ができます
こうすることでデータベースとのデータの往来を加速させられます。
なぜなら文字列のアロケーションが減り、(比較的遅い)Rubyのコードでの変換部分が省かれるからです。

Expand All @@ -102,10 +151,10 @@ Pgでは任意でRubyと素のCコードにある結果の値やクエリ引数

しかしPgの型変換はかなり調整が効きます。2層に分かれているのがその理由です。

### エンコーダーとデコーダー (ext/pg_*coder.c, lib/pg/*coder.rb)
### エンコーダーとデコーダー (ext/pg_\*coder.c, lib/pg/\*coder.rb)

こちらはより低層で、DBMSへ転送するためにRubyのオブジェクトを変換するエンコーディングクラスと、取得してきたデータをRubyのオブジェクトに変換し戻すデコーディングクラスが含まれています。
クラスはそれぞれの形式によって名前空間 PG::TextEncoder, PG::TextDecoder, PG::BinaryEncoder, そして
クラスはそれぞれの形式によって名前空間 PG::TextEncoder, PG::TextDecoder, PG::BinaryEncoder,
PG::BinaryDecoder に分かれています。

エンコーダーないしデコーダーオブジェクトにOIDデータ型や形式コード(テキストないしバイナリ)や任意で名前を割り当てることができます。
Expand Down Expand Up @@ -145,13 +194,14 @@ Binary Encoder、BD = Binary Decoder)。
[現地時間](rdoc-ref:PG::BinaryEncoder::TimestampLocal)、[UTC](rdoc-ref:PG::BinaryEncoder::TimestampUtc)
* BD:
[現地時間](rdoc-ref:PG::BinaryDecoder::TimestampLocal)、[UTC](rdoc-ref:PG::BinaryDecoder::TimestampUtc)、[UTCから現地時間へ](rdoc-ref:PG::BinaryDecoder::TimestampUtcToLocal)
* 日付:[TE](rdoc-ref:PG::TextEncoder::Date)、[TD](rdoc-ref:PG::TextDecoder::Date)、[BE](rdoc-ref:PG::BinaryEncoder::Date)、[BD](rdoc-ref:PG::BinaryDecoder::Date)
* 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)
* JSONとJSONB:
[TE](rdoc-ref:PG::TextEncoder::JSON)、[TD](rdoc-ref:PG::TextDecoder::JSON)
* Inet:
[TE](rdoc-ref:PG::TextEncoder::Inet)、[TD](rdoc-ref:PG::TextDecoder::Inet)
* Array:
[TE](rdoc-ref:PG::TextEncoder::Array)、[TD](rdoc-ref:PG::TextDecoder::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)
* 複合型(「行」や「レコード」などとも言います):[TE](rdoc-ref:PG::TextEncoder::Record)、[TD](rdoc-ref:PG::TextDecoder::Record)

カラム型として使われていませんが、以下のテキスト形式とバイナリ形式もエンコードできます。
Expand All @@ -163,14 +213,14 @@ Binary Encoder、BD = Binary Decoder)。
* SQLの識別子:
[TE](rdoc-ref:PG::TextEncoder::Identifier)、[TD](rdoc-ref:PG::TextDecoder::Identifier)

### PG::TypeMap とその派生 (ext/pg_type_map*.c, lib/pg/type_map*.rb)
### TypeMap とその派生 (ext/pg_type_map\*.c, lib/pg/type_map\*.rb)

TypeMapはエンコーダーまたはデコーダーのどちらによってどの値を変換するかを定義します
様々な型の対応付け戦略があるので、このクラスにはいくつかの派生が実装されています
型変換の特有の需要に合わせてそれらの派生から選んで調整を加えることができます
PG::TypeMap はどのエンコーダーないしデコーダーによってどの値が変換されるかを定義します
様々な型の対応付けの戦略があり、このクラスの複数の派生により実装されています
型変換の特有の需要に合わせてそれらから選んで構成できます
既定の型の対応付けは PG::TypeMapAllStrings です。

型の対応付けは、結果の集合それぞれに対し、接続毎ないしクエリ毎に割り当てることができます
型の対応付けは、結果の集合それぞれに対し、接続毎ないし問い合わせ毎に割り当てることができます
型の対応付けはCOPYの入出力データストリーミングでも使うことができます。
PG::Connection#copy_data を参照してください。

Expand All @@ -191,12 +241,14 @@ PG::Connection#copy_data を参照してください。
* PG::BasicTypeMapForQueries - PG::TypeMapByClass
によくあるRubyの値クラス用にエンコーダーが入った状態になっています

PG::TypeMap::DefaultTypeMappable#default_type_map
を設定することで複数の型の対応付けを連鎖させられます。

## スレッド対応

PGには個々のスレッドが別々の PG::Connection オブジェクトを同時に使えるという点でスレッド安全性があります
しかし1つ以上のスレッドから同時にPgのオブジェクトにアクセスすると安全ではありません
そのため必ず、毎回新しいスレッドを作るときに新しいデータベースサーバー接続を開くか、スレッド安全性のある方法で接続を管理するActiveRecordのようなラッパーライブラリを使うようにしてください
PG には個々のスレッドないしファイバが個々の PG::Connection オブジェクトを並行に使えるという点でスレッド安全です
しかしながら1つ以上のスレッドないしファイバから同時に何らかの PG のオブジェクトにアクセスするのは安全ではありません
そのため必ず、新しいスレッドないしファイバの一つ一つに対して新しいデータベースサーバー接続を開くか、スレッド安全な方法で接続を管理するActiveRecordのようなラッパーライブラリを使ってください

以下のようなメッセージが標準エラー出力に表示された場合、恐らく複数のスレッドが1つの接続を使っています。

Expand All @@ -215,8 +267,8 @@ Windowsでは、`Fiber.scheduler`対応はRuby-3.1以降で使えます。
同期的であったりブロックしたりするメソッド呼び出しについてもpgが内部的に非同期のlibpqインターフェースを使っているのはそれが理由です。
またlibpqの組み込み関数に代えてRubyのDNS解決を使っています。

内部的にPgは常にlibpqのノンブロッキング接続モードを使います
それからブロッキングモードで走っているように振舞いますが、もし`Fiber.scheduler`が登録されていれば全てのブロッキングIOはそのスケジューラーを通じてRubyで制御されます
内部的に Pg は常にlibpqのノンブロッキング接続モードを使います
それからブロッキングモードで走っているように振舞いますが、すべてのブロッキングIOが、可能であれば登録された`Fiber.schedular`を通じて、確実にRubyで制御されます
`PG::Connection.setnonblocking(true)`が呼ばれたらノンブロッキング状態が有効になったままになりますが、それ以降のブロッキング状態の制御が無効になるので、呼び出しているプログラムはブロッキング状態を自力で制御しなければなりません。

この規則の1つの例外には、`PG::Connection#lo_create`や外部ライブラリを使う認証メソッド(GSSAPI認証など)のような、大きめのオブジェクト用のメソッドがあります。これらは`Fiber.scheduler`と互換性がないため、ブロッキング状態は登録されたIOスケジューラに渡されません。つまり操作は適切に実行されますが、IO待ち状態に別のIOを扱うFiberから使用を切り替えてくることができなくなります。
Expand Down
12 changes: 7 additions & 5 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -173,10 +173,12 @@ end

desc "Translate readme"
task :translate do
cd "translation" do
# po4a's lexer might change, so record its version for reference
sh "LANG=C po4a --version > .po4a-version"
cd "translation" do
# po4a's lexer might change, so record its version for reference
sh "LANG=C po4a --version > .po4a-version"

sh "po4a po4a.cfg"
end
pot = 'po/en.pot'
File.file?(pot) or FileUtils.touch(pot)
sh "po4a po4a.cfg"
end
end
2 changes: 1 addition & 1 deletion translation/.po4a-version
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
po4a version 0.68.
po4a version 0.75-alpha.
Written by Martin Quinson and Denis Barbier.

Copyright © 2002-2022 Software in the Public Interest, Inc.
Expand Down
Loading
Loading