1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329
|
# pg
* home :: https://github.com/ged/ruby-pg
* docs :: http://deveiate.org/code/pg/README_md.html (English) ,
https://deveiate.org/code/pg/README_ja_md.html (Japanese)
* clog :: link:/CHANGELOG.md
[](https://gitter.im/ged/ruby-pg?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
## Description
Pg is the Ruby interface to the [PostgreSQL RDBMS](http://www.postgresql.org/).
It works with [PostgreSQL 10 and later](http://www.postgresql.org/support/versioning/).
A small example usage:
```ruby
#!/usr/bin/env ruby
require 'pg'
# Output a table of current connections to the DB
conn = PG.connect( dbname: 'sales' )
conn.exec( "SELECT * FROM pg_stat_activity" ) do |result|
puts " PID | User | Query"
result.each do |row|
puts " %7d | %-16s | %s " %
row.values_at('pid', 'usename', 'query')
end
end
```
See the PG::Connection class for query methods and the PG::Result class for information on working with the results of a query.
## Build Status
[](https://github.com/ged/ruby-pg/actions/workflows/source-gem.yml)
[](https://github.com/ged/ruby-pg/actions/workflows/binary-gems.yml)
[](https://ci.appveyor.com/project/ged/ruby-pg-9j8l3)
## Requirements
* Ruby 2.7 or newer
* PostgreSQL 10.x or later
* When installing the source gem: libpq with headers, -dev packages, etc.
## How To Install
Install via RubyGems:
gem install pg
This installs the binary gem, specific to the running platform by default.
### Binary gem
The binary gems don't depend on the libpq package on the running system.
They have libpq builtin.
The gems for platform `x86_64-linux` and `aarch64-linux` run on Alpine Linux, but require the package `gcompat`, while the native gems for platform `*-linux-musl` work without that dependency.
There is one use case the binary gems don't support: Retrieval of connection [options from LDAP](https://www.postgresql.org/docs/current/libpq-ldap.html). To support this `libldap` would be necessary, but it has a lot of dependencies. It doesn't seem to be a widely used feature and that it's worth to support it. If it's necessary, the source gem can be forced.
### Source gem
The source gem can be forced by:
gem uninstall pg --all
gem install pg --platform ruby
You may need to specify the path to the 'pg_config' program installed with
Postgres:
gem install pg -- --with-pg-config=<path to pg_config>
If you're installing via Bundler, you can provide compile hints like so:
bundle config build.pg --with-pg-config=<path to pg_config>
### Bundler
To make sure, the necessary platforms and the source gem are fetched by bundler, they can be added like so
```
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
```
A re-run of `bundle package` is also necessary after `bundle update`, in order to retrieve the new specific gems of all platforms.
If the binary gems don't work for some reason, it's easy to force the usage of the source gem in the Gemfile:
```
gem "pg", force_ruby_platform: true
```
### More
See README-OS_X.rdoc for more information about installing under MacOS X, and
README-Windows.rdoc for Windows build/installation instructions.
There's also [a Google+ group](http://goo.gl/TFy1U) and a
[mailing list](http://groups.google.com/group/ruby-pg) if you get stuck, or just
want to chat about something.
If you want to install as a signed gem, the public certs of the gem signers
can be found in [the `certs` directory](https://github.com/ged/ruby-pg/tree/master/certs)
of the repository.
## Versioning
We tag and release gems according to the [Semantic Versioning](http://semver.org/) principle.
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.
For example:
```ruby
spec.add_dependency 'pg', '~> 1.0'
```
## Type Casts
Pg can optionally type cast result values and query parameters in Ruby or
native C code. This can speed up data transfers to and from the database,
because String allocations are reduced and conversions in (slower) Ruby code
can be omitted.
Very basic type casting can be enabled by:
```ruby
conn.type_map_for_results = PG::BasicTypeMapForResults.new conn
# ... this works for result value mapping:
conn.exec("select 1, now(), '{2,3}'::int[]").values
# => [[1, 2014-09-21 20:51:56 +0200, [2, 3]]]
conn.type_map_for_queries = PG::BasicTypeMapForQueries.new conn
# ... and this for param value mapping:
conn.exec_params("SELECT $1::text, $2::text, $3::text", [1, 1.23, [2,3]]).values
# => [["1", "1.2300000000000000E+00", "{2,3}"]]
```
But Pg's type casting is highly customizable. That's why it's divided into
2 layers:
### Encoders / Decoders (ext/pg_\*coder.c, lib/pg/\*coder.rb)
This is the lower layer, containing encoding classes that convert Ruby
objects for transmission to the DBMS and decoding classes to convert
received data back to Ruby objects. The classes are namespaced according
to their format and direction in PG::TextEncoder, PG::TextDecoder,
PG::BinaryEncoder and PG::BinaryDecoder.
It is possible to assign a type OID, format code (text or binary) and
optionally a name to an encoder or decoder object. It's also possible
to build composite types by assigning an element encoder/decoder.
PG::Coder objects can be used to set up a PG::TypeMap or alternatively
to convert single values to/from their string representation.
The following PostgreSQL column types are supported by ruby-pg (TE = Text Encoder, TD = Text Decoder, BE = Binary Encoder, BD = Binary Decoder):
* 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) 💡
* BE: [Int2](rdoc-ref:PG::BinaryEncoder::Int2), [Int4](rdoc-ref:PG::BinaryEncoder::Int4), [Int8](rdoc-ref:PG::BinaryEncoder::Int8)
* Float: [TE](rdoc-ref:PG::TextEncoder::Float), [TD](rdoc-ref:PG::TextDecoder::Float), [BD](rdoc-ref:PG::BinaryDecoder::Float)
* BE: [Float4](rdoc-ref:PG::BinaryEncoder::Float4), [Float8](rdoc-ref:PG::BinaryEncoder::Float8)
* Numeric: [TE](rdoc-ref:PG::TextEncoder::Numeric), [TD](rdoc-ref:PG::TextDecoder::Numeric)
* 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)
* 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)
* 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)
* 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)
* Timestamp:
* TE: [local](rdoc-ref:PG::TextEncoder::TimestampWithoutTimeZone), [UTC](rdoc-ref:PG::TextEncoder::TimestampUtc), [with-TZ](rdoc-ref:PG::TextEncoder::TimestampWithTimeZone)
* TD: [local](rdoc-ref:PG::TextDecoder::TimestampLocal), [UTC](rdoc-ref:PG::TextDecoder::TimestampUtc), [UTC-to-local](rdoc-ref:PG::TextDecoder::TimestampUtcToLocal)
* BE: [local](rdoc-ref:PG::BinaryEncoder::TimestampLocal), [UTC](rdoc-ref:PG::BinaryEncoder::TimestampUtc)
* BD: [local](rdoc-ref:PG::BinaryDecoder::TimestampLocal), [UTC](rdoc-ref:PG::BinaryDecoder::TimestampUtc), [UTC-to-local](rdoc-ref:PG::BinaryDecoder::TimestampUtcToLocal)
* 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 and 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), [BE](rdoc-ref:PG::BinaryEncoder::Array), [BD](rdoc-ref:PG::BinaryDecoder::Array)
* Composite Type (also called "Row" or "Record"): [TE](rdoc-ref:PG::TextEncoder::Record), [TD](rdoc-ref:PG::TextDecoder::Record)
The following text and binary formats can also be encoded although they are not used as column type:
* 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)
* Literal for insertion into SQL string: [TE](rdoc-ref:PG::TextEncoder::QuotedLiteral)
* SQL-Identifier: [TE](rdoc-ref:PG::TextEncoder::Identifier), [TD](rdoc-ref:PG::TextDecoder::Identifier)
### TypeMap and derivations (ext/pg_type_map\*.c, lib/pg/type_map\*.rb)
A PG::TypeMap defines which value will be converted by which encoder/decoder.
There are different type map strategies, implemented by several derivations
of this class. They can be chosen and configured according to the particular
needs for type casting. The default type map is PG::TypeMapAllStrings.
A type map can be assigned per connection or per query respectively per
result set. Type maps can also be used for COPY in and out data streaming.
See PG::Connection#copy_data .
The following base type maps are available:
* PG::TypeMapAllStrings - encodes and decodes all values to and from strings (default)
* PG::TypeMapByClass - selects encoder based on the class of the value to be sent
* PG::TypeMapByColumn - selects encoder and decoder by column order
* PG::TypeMapByOid - selects decoder by PostgreSQL type OID
* PG::TypeMapInRuby - define a custom type map in ruby
The following type maps are prefilled with type mappings from the PG::BasicTypeRegistry :
* PG::BasicTypeMapForResults - a PG::TypeMapByOid prefilled with decoders for common PostgreSQL column types
* PG::BasicTypeMapBasedOnResult - a PG::TypeMapByOid prefilled with encoders for common PostgreSQL column types
* PG::BasicTypeMapForQueries - a PG::TypeMapByClass prefilled with encoders for common Ruby value classes
Several type maps can be chained by setting PG::TypeMap::DefaultTypeMappable#default_type_map .
## Thread support
PG is thread safe in such a way that different threads or fibers can use different PG::Connection objects concurrently.
However it is not safe to access any PG object simultaneously from more than one thread or fiber unless the object is frozen.
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.
If messages like the following are printed to stderr, you're probably using one connection from several threads:
message type 0x31 arrived from server while idle
message type 0x32 arrived from server while idle
message type 0x54 arrived from server while idle
message type 0x43 arrived from server while idle
message type 0x5a arrived from server while idle
## Fiber IO scheduler support
Pg is fully compatible with `Fiber.scheduler` introduced in Ruby-3.0 since pg-1.3.0.
On Windows support for `Fiber.scheduler` is available on Ruby-3.1 or newer.
All possibly blocking IO operations are routed through the `Fiber.scheduler` if one is registered for the running thread.
That is why pg internally uses the asynchronous libpq interface even for synchronous/blocking method calls.
It also uses Ruby's DNS resolution instead of libpq's builtin functions.
Internally Pg always uses the nonblocking connection mode of libpq.
It then behaves like running in blocking mode but ensures, that all blocking IO is handled in Ruby through a possibly registered `Fiber.scheduler`.
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.
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).
They are not compatible with `Fiber.scheduler`, so that blocking states are not passed to the registered IO scheduler.
That means the operation will work properly, but IO waiting states can not be used to switch to another Fiber doing IO.
## Ractor support
Pg is fully compatible with Ractor introduced in Ruby-3.0 since pg-1.5.0.
All type en/decoders and type maps are shareable between ractors if they are made frozen by `Ractor.make_shareable`.
Also frozen PG::Result and PG::Tuple objects can be shared.
All frozen objects (except PG::Connection) can still be used to do communication with the PostgreSQL server or to read retrieved data.
PG::Connection is not shareable and must be created within each Ractor to establish a dedicated connection.
## Contributing
To report bugs, suggest features, or check out the source with Git,
[check out the project page](https://github.com/ged/ruby-pg).
After checking out the source, install all dependencies:
$ bundle install
Cleanup extension files, packaging files, test databases.
Run this to change between PostgreSQL versions:
$ rake clean
Compile extension:
$ rake compile
Run tests/specs on the PostgreSQL version that `pg_config --bindir` points to:
$ rake test
Or run a specific test per file and line number on a specific PostgreSQL version:
$ PATH=/usr/lib/postgresql/14/bin:$PATH rspec -Ilib -fd spec/pg/connection_spec.rb:455
Generate the API documentation:
$ rake docs
Make sure, that all bugs and new features are verified by tests.
The current maintainers are Michael Granger <ged@FaerieMUD.org> and
Lars Kanis <lars@greiz-reinsdorf.de>.
## Copying
Copyright (c) 1997-2022 by the authors.
* Jeff Davis <ruby-pg@j-davis.com>
* Guy Decoux (ts) <decoux@moulon.inra.fr>
* Michael Granger <ged@FaerieMUD.org>
* Lars Kanis <lars@greiz-reinsdorf.de>
* Dave Lee
* Eiji Matsumoto <usagi@ruby.club.or.jp>
* Yukihiro Matsumoto <matz@ruby-lang.org>
* Noboru Saitou <noborus@netlab.jp>
You may redistribute this software under the same terms as Ruby itself; see
https://www.ruby-lang.org/en/about/license.txt or the BSDL file in the source
for details.
Portions of the code are from the PostgreSQL project, and are distributed
under the terms of the PostgreSQL license, included in the file POSTGRES.
Portions copyright LAIKA, Inc.
## Acknowledgments
See Contributors.rdoc for the many additional fine people that have contributed
to this library over the years.
We are thankful to the people at the ruby-list and ruby-dev mailing lists.
And to the people who developed PostgreSQL.
|