yugabyte_ysql 0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (121) hide show
  1. checksums.yaml +7 -0
  2. data/.appveyor.yml +42 -0
  3. data/.gems +6 -0
  4. data/.gemtest +0 -0
  5. data/.github/workflows/binary-gems.yml +117 -0
  6. data/.github/workflows/source-gem.yml +143 -0
  7. data/.gitignore +24 -0
  8. data/.hgsigs +34 -0
  9. data/.hgtags +41 -0
  10. data/.irbrc +23 -0
  11. data/.pryrc +23 -0
  12. data/.tm_properties +21 -0
  13. data/.travis.yml +49 -0
  14. data/BSDL +22 -0
  15. data/Contributors.rdoc +46 -0
  16. data/Gemfile +18 -0
  17. data/History.md +901 -0
  18. data/LICENSE +56 -0
  19. data/Manifest.txt +73 -0
  20. data/POSTGRES +23 -0
  21. data/README-OS_X.rdoc +68 -0
  22. data/README-Windows.rdoc +56 -0
  23. data/README.ja.md +302 -0
  24. data/README.md +373 -0
  25. data/Rakefile +118 -0
  26. data/Rakefile.cross +299 -0
  27. data/certs/ged.pem +24 -0
  28. data/certs/kanis@comcard.de.pem +20 -0
  29. data/certs/larskanis-2022.pem +26 -0
  30. data/certs/larskanis-2023.pem +24 -0
  31. data/certs/larskanis-2024.pem +24 -0
  32. data/ext/errorcodes.def +1044 -0
  33. data/ext/errorcodes.rb +45 -0
  34. data/ext/errorcodes.txt +497 -0
  35. data/ext/extconf.rb +174 -0
  36. data/ext/gvl_wrappers.c +21 -0
  37. data/ext/gvl_wrappers.h +264 -0
  38. data/ext/pg.c +692 -0
  39. data/ext/pg.h +392 -0
  40. data/ext/pg_binary_decoder.c +308 -0
  41. data/ext/pg_binary_encoder.c +387 -0
  42. data/ext/pg_coder.c +624 -0
  43. data/ext/pg_connection.c +4681 -0
  44. data/ext/pg_copy_coder.c +917 -0
  45. data/ext/pg_errors.c +95 -0
  46. data/ext/pg_record_coder.c +522 -0
  47. data/ext/pg_result.c +1766 -0
  48. data/ext/pg_text_decoder.c +1005 -0
  49. data/ext/pg_text_encoder.c +827 -0
  50. data/ext/pg_tuple.c +572 -0
  51. data/ext/pg_type_map.c +200 -0
  52. data/ext/pg_type_map_all_strings.c +130 -0
  53. data/ext/pg_type_map_by_class.c +271 -0
  54. data/ext/pg_type_map_by_column.c +355 -0
  55. data/ext/pg_type_map_by_mri_type.c +313 -0
  56. data/ext/pg_type_map_by_oid.c +388 -0
  57. data/ext/pg_type_map_in_ruby.c +333 -0
  58. data/ext/pg_util.c +149 -0
  59. data/ext/pg_util.h +65 -0
  60. data/ext/vc/pg.sln +26 -0
  61. data/ext/vc/pg_18/pg.vcproj +216 -0
  62. data/ext/vc/pg_19/pg_19.vcproj +209 -0
  63. data/lib/pg/basic_type_map_based_on_result.rb +67 -0
  64. data/lib/pg/basic_type_map_for_queries.rb +202 -0
  65. data/lib/pg/basic_type_map_for_results.rb +104 -0
  66. data/lib/pg/basic_type_registry.rb +303 -0
  67. data/lib/pg/binary_decoder/date.rb +9 -0
  68. data/lib/pg/binary_decoder/timestamp.rb +26 -0
  69. data/lib/pg/binary_encoder/timestamp.rb +20 -0
  70. data/lib/pg/coder.rb +106 -0
  71. data/lib/pg/connection.rb +990 -0
  72. data/lib/pg/exceptions.rb +25 -0
  73. data/lib/pg/load_balance_service.rb +406 -0
  74. data/lib/pg/result.rb +43 -0
  75. data/lib/pg/text_decoder/date.rb +18 -0
  76. data/lib/pg/text_decoder/inet.rb +9 -0
  77. data/lib/pg/text_decoder/json.rb +14 -0
  78. data/lib/pg/text_decoder/numeric.rb +9 -0
  79. data/lib/pg/text_decoder/timestamp.rb +30 -0
  80. data/lib/pg/text_encoder/date.rb +12 -0
  81. data/lib/pg/text_encoder/inet.rb +28 -0
  82. data/lib/pg/text_encoder/json.rb +14 -0
  83. data/lib/pg/text_encoder/numeric.rb +9 -0
  84. data/lib/pg/text_encoder/timestamp.rb +24 -0
  85. data/lib/pg/tuple.rb +30 -0
  86. data/lib/pg/type_map_by_column.rb +16 -0
  87. data/lib/pg/version.rb +5 -0
  88. data/lib/yugabyte_ysql.rb +130 -0
  89. data/misc/openssl-pg-segfault.rb +31 -0
  90. data/misc/postgres/History.txt +9 -0
  91. data/misc/postgres/Manifest.txt +5 -0
  92. data/misc/postgres/README.txt +21 -0
  93. data/misc/postgres/Rakefile +21 -0
  94. data/misc/postgres/lib/postgres.rb +16 -0
  95. data/misc/ruby-pg/History.txt +9 -0
  96. data/misc/ruby-pg/Manifest.txt +5 -0
  97. data/misc/ruby-pg/README.txt +21 -0
  98. data/misc/ruby-pg/Rakefile +21 -0
  99. data/misc/ruby-pg/lib/ruby/pg.rb +16 -0
  100. data/rakelib/task_extension.rb +46 -0
  101. data/sample/array_insert.rb +20 -0
  102. data/sample/async_api.rb +102 -0
  103. data/sample/async_copyto.rb +39 -0
  104. data/sample/async_mixed.rb +56 -0
  105. data/sample/check_conn.rb +21 -0
  106. data/sample/copydata.rb +71 -0
  107. data/sample/copyfrom.rb +81 -0
  108. data/sample/copyto.rb +19 -0
  109. data/sample/cursor.rb +21 -0
  110. data/sample/disk_usage_report.rb +177 -0
  111. data/sample/issue-119.rb +94 -0
  112. data/sample/losample.rb +69 -0
  113. data/sample/minimal-testcase.rb +17 -0
  114. data/sample/notify_wait.rb +72 -0
  115. data/sample/pg_statistics.rb +285 -0
  116. data/sample/replication_monitor.rb +222 -0
  117. data/sample/test_binary_values.rb +33 -0
  118. data/sample/wal_shipper.rb +434 -0
  119. data/sample/warehouse_partitions.rb +311 -0
  120. data/yugabyte_ysql.gemspec +33 -0
  121. metadata +232 -0
data/README.md ADDED
@@ -0,0 +1,373 @@
1
+ # yugabyte_ysql
2
+
3
+ This is a fork of [Ruby interface to the PostgreSQL RDBMS](https://github.com/ged/ruby-pg) to develop a Ruby interface to YugabyteDB.
4
+
5
+ ## Features
6
+
7
+ This driver has the following features in addition to those that come with the upstream driver:
8
+
9
+ ### Cluster Awareness to eliminate need for a load balancer
10
+
11
+ This driver requires only an initial _contact point_ for the YugabyteDB cluster, using which it discovers the rest of the nodes. Additionally, it automatically learns about the nodes being started/added or stopped/removed. Internally the driver keeps track of number of connections it has created to each server endpoint and every new connection request is connected to the least loaded server as per the driver's view.
12
+
13
+ ### Topology Awareness to enable geo-distributed apps
14
+
15
+ This is similar to 'Cluster Awareness' but uses those servers which are part of a given set of geo-locations specified by _topology_keys_.
16
+
17
+ ### Connection Properties added for load balancing
18
+
19
+ - _load_balance_ - It expects **true/false** as its possible values. The 'load_balance' property needs to be set to 'true' to enable cluster-awareness.
20
+ - _topology_keys_ - It takes a comma separated geo-location values. A single geo-location can be given as 'cloud.region.zone'. Multiple geo-locations too can be specified, separated by comma (`,`). Optionally, you can also register your preference for particular geo-locations by appending the preference value with prefix `:`. For example, `cloud.regionA.zoneA:1,cloud.regionA.zoneB:2`.
21
+ - _yb_servers_refresh_interval_ - Minimum time interval, in seconds, between two attempts to refresh the information about cluster nodes. This is checked only when a new connection is requested. Default is 300. Valid values are integers between 0 and 600. Value 0 means refresh for each connection request. Any value outside this range is ignored and the default is used.
22
+ - _fallback_to_topology_keys_only_ - When set to true, the driver does not attempt to connect to nodes outside of the geo-locations specified via _topology_keys_. Default value is false.
23
+ - _failed_host_reconnect_delay_secs_ - The time interval for which the driver ignores a failed node even if it shows up in refreshed metadata from `yb_servers()` function. Default value is 5 seconds.
24
+
25
+ Please refer to the [Use the Driver](#Use the Driver) section for examples.
26
+
27
+ ## Install the Driver
28
+
29
+ ```shell
30
+ gem install -- --with-pg-config=<yugabyte-install-dir>/postgres/bin/pg_config
31
+ ```
32
+
33
+ ## Use the Driver
34
+
35
+ - Passing new connection properties for load balancing in connection url
36
+
37
+ For uniform load balancing across all the server you just need to specify the _load_balance=true_ property in the url.
38
+ ```
39
+ require 'yugabyte_ysql'
40
+ ...
41
+ yburl = "postgresql://yugabyte:yugabyte@127.0.0.1:5433/yugabyte?load_balance=true"
42
+ connection = YugabyteYSQL.connect(url)
43
+ ...
44
+ ```
45
+
46
+ For specifying topology keys you need to set the additional property with a valid comma separated value.
47
+
48
+ ```
49
+ require 'yugabyte_ysql'
50
+ ...
51
+ yburl = "postgresql://yugabyte:yugabyte@127.0.0.1:5433/yugabyte?load_balance=true&topology_keys=cloud.regionA.zoneA,cloud.regionA.zoneB"
52
+ connection = YugabyteYSQL.connect(url)
53
+ ...
54
+ ```
55
+
56
+ ### Specifying fallback zones
57
+
58
+ For topology-aware load balancing, you can specify fallback placements too. This is not applicable for cluster-aware load balancing.
59
+ Each placement value can be suffixed with a colon (`:`) followed by a preference value between 1 and 10.
60
+ A preference value of `:1` means it is a primary placement. A preference value of `:2` means it is the first fallback placement and so on.
61
+ If no preference value is provided, it is considered to be a primary placement (equivalent to one with preference value `:1`). Example given below.
62
+
63
+ ```
64
+ yburl = "postgresql://yugabyte:yugabyte@127.0.0.1:5433/yugabyte?load_balance=true&topology_keys=cloud.regionA.zoneA:1,cloud.regionA.zoneB:2"
65
+
66
+ ```
67
+
68
+ You can also use `*` for specifying all the zones in a given region as shown below. This is not allowed for cloud or region values.
69
+
70
+ ```
71
+ yburl = "postgresql://yugabyte:yugabyte@127.0.0.1:5433/yugabyte?load_balance=true&topology_keys=cloud.regionA.*:1,cloud.regionB.*:2";
72
+ ```
73
+
74
+ The driver attempts connection to servers in the first fallback placement(s) if it does not find any servers available in the primary placement(s). If no servers are available in the first fallback placement(s),
75
+ then it attempts to connect to servers in the second fallback placement(s), if specified. This continues until the driver finds a server to connect to, else an error is returned to the application.
76
+ And this repeats for each connection request.
77
+
78
+ ### Limitations
79
+
80
+ - The load balancing feature of the Ruby Smart driver for YugabyteDB does not work with ActiveRecords - the ORM tool for Ruby apps.
81
+
82
+ Rest of the README is from upstream repository.
83
+
84
+ ---
85
+
86
+ # pg
87
+
88
+ * home :: https://github.com/ged/ruby-pg
89
+ * docs :: http://deveiate.org/code/pg (English) ,
90
+ https://deveiate.org/code/pg/README_ja_md.html (Japanese)
91
+ * clog :: link:/History.md
92
+
93
+ [![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)
94
+
95
+
96
+ ## Description
97
+
98
+ Pg is the Ruby interface to the [PostgreSQL RDBMS](http://www.postgresql.org/).
99
+ It works with [PostgreSQL 9.3 and later](http://www.postgresql.org/support/versioning/).
100
+
101
+ A small example usage:
102
+
103
+ ```ruby
104
+ #!/usr/bin/env ruby
105
+
106
+ require 'pg'
107
+
108
+ # Output a table of current connections to the DB
109
+ conn = YugabyteYSQL.connect(dbname: 'sales')
110
+ conn.exec("SELECT * FROM pg_stat_activity") do |result|
111
+ puts " PID | User | Query"
112
+ result.each do |row|
113
+ puts " %7d | %-16s | %s " %
114
+ row.values_at('pid', 'usename', 'query')
115
+ end
116
+ end
117
+ ```
118
+
119
+ ## Build Status
120
+
121
+ [![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)
122
+ [![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)
123
+ [![Build Status Appveyor](https://ci.appveyor.com/api/projects/status/gjx5axouf3b1wicp?svg=true)](https://ci.appveyor.com/project/ged/ruby-pg-9j8l3)
124
+
125
+
126
+ ## Requirements
127
+
128
+ * Ruby 2.5 or newer
129
+ * PostgreSQL 9.3.x or later (with headers, -dev packages, etc).
130
+
131
+ It usually works with earlier versions of Ruby/PostgreSQL as well, but those are
132
+ not regularly tested.
133
+
134
+
135
+ ## Versioning
136
+
137
+ We tag and release gems according to the [Semantic Versioning](http://semver.org/) principle.
138
+
139
+ 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.
140
+
141
+ For example:
142
+
143
+ ```ruby
144
+ spec.add_dependency 'pg', '~> 1.0'
145
+ ```
146
+
147
+ ## How To Install
148
+
149
+ Install via RubyGems:
150
+
151
+ gem install pg
152
+
153
+ You may need to specify the path to the 'pg_config' program installed with
154
+ Postgres:
155
+
156
+ gem install pg -- --with-pg-config=<path to pg_config>
157
+
158
+ If you're installing via Bundler, you can provide compile hints like so:
159
+
160
+ bundle config build.pg --with-pg-config=<path to pg_config>
161
+
162
+ See README-OS_X.rdoc for more information about installing under MacOS X, and
163
+ README-Windows.rdoc for Windows build/installation instructions.
164
+
165
+ There's also [a Google+ group](http://goo.gl/TFy1U) and a
166
+ [mailing list](http://groups.google.com/group/ruby-pg) if you get stuck, or just
167
+ want to chat about something.
168
+
169
+ If you want to install as a signed gem, the public certs of the gem signers
170
+ can be found in [the `certs` directory](https://github.com/ged/ruby-pg/tree/master/certs)
171
+ of the repository.
172
+
173
+
174
+ ## Type Casts
175
+
176
+ Pg can optionally type cast result values and query parameters in Ruby or
177
+ native C code. This can speed up data transfers to and from the database,
178
+ because String allocations are reduced and conversions in (slower) Ruby code
179
+ can be omitted.
180
+
181
+ Very basic type casting can be enabled by:
182
+
183
+ ```ruby
184
+ conn.type_map_for_results = YugabyteYSQL::BasicTypeMapForResults.new conn
185
+ # ... this works for result value mapping:
186
+ conn.exec("select 1, now(), '{2,3}'::int[]").values
187
+ # => [[1, 2014-09-21 20:51:56 +0200, [2, 3]]]
188
+
189
+ conn.type_map_for_queries = YugabyteYSQL::BasicTypeMapForQueries.new conn
190
+ # ... and this for param value mapping:
191
+ conn.exec_params("SELECT $1::text, $2::text, $3::text", [1, 1.23, [2, 3]]).values
192
+ # => [["1", "1.2300000000000000E+00", "{2,3}"]]
193
+ ```
194
+
195
+ But Pg's type casting is highly customizable. That's why it's divided into
196
+ 2 layers:
197
+
198
+ ### Encoders / Decoders (ext/pg_*coder.c, lib/pg/*coder.rb)
199
+
200
+ This is the lower layer, containing encoding classes that convert Ruby
201
+ objects for transmission to the DBMS and decoding classes to convert
202
+ received data back to Ruby objects. The classes are namespaced according
203
+ to their format and direction in PG::TextEncoder, PG::TextDecoder,
204
+ PG::BinaryEncoder and PG::BinaryDecoder.
205
+
206
+ It is possible to assign a type OID, format code (text or binary) and
207
+ optionally a name to an encoder or decoder object. It's also possible
208
+ to build composite types by assigning an element encoder/decoder.
209
+ PG::Coder objects can be used to set up a PG::TypeMap or alternatively
210
+ to convert single values to/from their string representation.
211
+
212
+ The following PostgreSQL column types are supported by ruby-pg (TE = Text Encoder, TD = Text Decoder, BE = Binary Encoder, BD = Binary Decoder):
213
+
214
+ * 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) 💡
215
+ * BE: [Int2](rdoc-ref:PG::BinaryEncoder::Int2), [Int4](rdoc-ref:PG::BinaryEncoder::Int4), [Int8](rdoc-ref:PG::BinaryEncoder::Int8)
216
+ * Float: [TE](rdoc-ref:PG::TextEncoder::Float), [TD](rdoc-ref:PG::TextDecoder::Float), [BD](rdoc-ref:PG::BinaryDecoder::Float)
217
+ * BE: [Float4](rdoc-ref:PG::BinaryEncoder::Float4), [Float8](rdoc-ref:PG::BinaryEncoder::Float8)
218
+ * Numeric: [TE](rdoc-ref:PG::TextEncoder::Numeric), [TD](rdoc-ref:PG::TextDecoder::Numeric)
219
+ * 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)
220
+ * 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)
221
+ * 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)
222
+ * 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)
223
+ * Timestamp:
224
+ * TE: [local](rdoc-ref:PG::TextEncoder::TimestampWithoutTimeZone), [UTC](rdoc-ref:PG::TextEncoder::TimestampUtc), [with-TZ](rdoc-ref:PG::TextEncoder::TimestampWithTimeZone)
225
+ * TD: [local](rdoc-ref:PG::TextDecoder::TimestampLocal), [UTC](rdoc-ref:PG::TextDecoder::TimestampUtc), [UTC-to-local](rdoc-ref:PG::TextDecoder::TimestampUtcToLocal)
226
+ * BE: [local](rdoc-ref:PG::BinaryEncoder::TimestampLocal), [UTC](rdoc-ref:PG::BinaryEncoder::TimestampUtc)
227
+ * BD: [local](rdoc-ref:PG::BinaryDecoder::TimestampLocal), [UTC](rdoc-ref:PG::BinaryDecoder::TimestampUtc), [UTC-to-local](rdoc-ref:PG::BinaryDecoder::TimestampUtcToLocal)
228
+ * 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)
229
+ * JSON and JSONB: [TE](rdoc-ref:PG::TextEncoder::JSON), [TD](rdoc-ref:PG::TextDecoder::JSON)
230
+ * Inet: [TE](rdoc-ref:PG::TextEncoder::Inet), [TD](rdoc-ref:PG::TextDecoder::Inet)
231
+ * Array: [TE](rdoc-ref:PG::TextEncoder::Array), [TD](rdoc-ref:PG::TextDecoder::Array)
232
+ * Composite Type (also called "Row" or "Record"): [TE](rdoc-ref:PG::TextEncoder::Record), [TD](rdoc-ref:PG::TextDecoder::Record)
233
+
234
+ The following text and binary formats can also be encoded although they are not used as column type:
235
+
236
+ * 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)
237
+ * Literal for insertion into SQL string: [TE](rdoc-ref:PG::TextEncoder::QuotedLiteral)
238
+ * SQL-Identifier: [TE](rdoc-ref:PG::TextEncoder::Identifier), [TD](rdoc-ref:PG::TextDecoder::Identifier)
239
+
240
+ ### PG::TypeMap and derivations (ext/pg_type_map*.c, lib/pg/type_map*.rb)
241
+
242
+ A TypeMap defines which value will be converted by which encoder/decoder.
243
+ There are different type map strategies, implemented by several derivations
244
+ of this class. They can be chosen and configured according to the particular
245
+ needs for type casting. The default type map is PG::TypeMapAllStrings.
246
+
247
+ A type map can be assigned per connection or per query respectively per
248
+ result set. Type maps can also be used for COPY in and out data streaming.
249
+ See PG::Connection#copy_data .
250
+
251
+ The following base type maps are available:
252
+
253
+ * PG::TypeMapAllStrings - encodes and decodes all values to and from strings (default)
254
+ * PG::TypeMapByClass - selects encoder based on the class of the value to be sent
255
+ * PG::TypeMapByColumn - selects encoder and decoder by column order
256
+ * PG::TypeMapByOid - selects decoder by PostgreSQL type OID
257
+ * PG::TypeMapInRuby - define a custom type map in ruby
258
+
259
+ The following type maps are prefilled with type mappings from the PG::BasicTypeRegistry :
260
+
261
+ * PG::BasicTypeMapForResults - a PG::TypeMapByOid prefilled with decoders for common PostgreSQL column types
262
+ * PG::BasicTypeMapBasedOnResult - a PG::TypeMapByOid prefilled with encoders for common PostgreSQL column types
263
+ * PG::BasicTypeMapForQueries - a PG::TypeMapByClass prefilled with encoders for common Ruby value classes
264
+
265
+
266
+ ## Thread support
267
+
268
+ PG is thread safe in such a way that different threads can use different PG::Connection objects concurrently.
269
+ However it is not safe to access any Pg objects simultaneously from more than one thread.
270
+ 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.
271
+
272
+ If messages like the following are printed to stderr, you're probably using one connection from several threads:
273
+
274
+ message type 0x31 arrived from server while idle
275
+ message type 0x32 arrived from server while idle
276
+ message type 0x54 arrived from server while idle
277
+ message type 0x43 arrived from server while idle
278
+ message type 0x5a arrived from server while idle
279
+
280
+
281
+ ## Fiber IO scheduler support
282
+
283
+ Pg is fully compatible with `Fiber.scheduler` introduced in Ruby-3.0 since pg-1.3.0.
284
+ On Windows support for `Fiber.scheduler` is available on Ruby-3.1 or newer.
285
+ All possibly blocking IO operations are routed through the `Fiber.scheduler` if one is registered for the running thread.
286
+ That is why pg internally uses the asynchronous libpq interface even for synchronous/blocking method calls.
287
+ It also uses Ruby's DNS resolution instead of libpq's builtin functions.
288
+
289
+ Internally Pg always uses the nonblocking connection mode of libpq.
290
+ It then behaves like running in blocking mode but ensures, that all blocking IO is handled in Ruby through a possibly registered `Fiber.scheduler`.
291
+ 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.
292
+
293
+ 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).
294
+ They are not compatible with `Fiber.scheduler`, so that blocking states are not passed to the registered IO scheduler.
295
+ That means the operation will work properly, but IO waiting states can not be used to switch to another Fiber doing IO.
296
+
297
+
298
+ ## Ractor support
299
+
300
+ Pg is fully compatible with Ractor introduced in Ruby-3.0 since pg-1.5.0.
301
+ All type en/decoders and type maps are shareable between ractors if they are made frozen by `Ractor.make_shareable`.
302
+ Also frozen PG::Result and PG::Tuple objects can be shared.
303
+ All frozen objects (except PG::Connection) can still be used to do communication with the PostgreSQL server or to read retrieved data.
304
+
305
+ PG::Connection is not shareable and must be created within each Ractor to establish a dedicated connection.
306
+
307
+
308
+ ## Contributing
309
+
310
+ To report bugs, suggest features, or check out the source with Git,
311
+ [check out the project page](https://github.com/ged/ruby-pg).
312
+
313
+ After checking out the source, install all dependencies:
314
+
315
+ $ bundle install
316
+
317
+ Cleanup extension files, packaging files, test databases.
318
+ Run this to change between PostgreSQL versions:
319
+
320
+ $ rake clean
321
+
322
+ Compile extension:
323
+
324
+ $ rake compile
325
+
326
+ Run tests/specs on the PostgreSQL version that `pg_config --bindir` points to:
327
+
328
+ $ rake test
329
+
330
+ Or run a specific test per file and line number on a specific PostgreSQL version:
331
+
332
+ $ PATH=/usr/lib/postgresql/14/bin:$PATH rspec -Ilib -fd spec/pg/connection_spec.rb:455
333
+
334
+ Generate the API documentation:
335
+
336
+ $ rake docs
337
+
338
+ Make sure, that all bugs and new features are verified by tests.
339
+
340
+ The current maintainers are Michael Granger <ged@FaerieMUD.org> and
341
+ Lars Kanis <lars@greiz-reinsdorf.de>.
342
+
343
+
344
+ ## Copying
345
+
346
+ Copyright (c) 1997-2022 by the authors.
347
+
348
+ * Jeff Davis <ruby-pg@j-davis.com>
349
+ * Guy Decoux (ts) <decoux@moulon.inra.fr>
350
+ * Michael Granger <ged@FaerieMUD.org>
351
+ * Lars Kanis <lars@greiz-reinsdorf.de>
352
+ * Dave Lee
353
+ * Eiji Matsumoto <usagi@ruby.club.or.jp>
354
+ * Yukihiro Matsumoto <matz@ruby-lang.org>
355
+ * Noboru Saitou <noborus@netlab.jp>
356
+
357
+ You may redistribute this software under the same terms as Ruby itself; see
358
+ https://www.ruby-lang.org/en/about/license.txt or the BSDL file in the source
359
+ for details.
360
+
361
+ Portions of the code are from the PostgreSQL project, and are distributed
362
+ under the terms of the PostgreSQL license, included in the file POSTGRES.
363
+
364
+ Portions copyright LAIKA, Inc.
365
+
366
+
367
+ ## Acknowledgments
368
+
369
+ See Contributors.rdoc for the many additional fine people that have contributed
370
+ to this library over the years.
371
+
372
+ We are thankful to the people at the ruby-list and ruby-dev mailing lists.
373
+ And to the people who developed PostgreSQL.
data/Rakefile ADDED
@@ -0,0 +1,118 @@
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 = 'yugabyte_ysql.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
+
35
+ load 'Rakefile.cross'
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
+ # Rake-compiler task
46
+ Rake::ExtensionTask.new do |ext|
47
+ ext.name = 'pg_ext'
48
+ ext.gem_spec = $gem_spec
49
+ ext.ext_dir = 'ext'
50
+ ext.lib_dir = 'lib'
51
+ ext.source_pattern = "*.{c,h}"
52
+ ext.cross_compile = true
53
+ ext.cross_platform = CrossLibraries.map(&:for_platform)
54
+
55
+ ext.cross_config_options += CrossLibraries.map do |lib|
56
+ {
57
+ lib.for_platform => [
58
+ "--enable-windows-cross",
59
+ "--with-pg-include=#{lib.static_postgresql_incdir}",
60
+ "--with-pg-lib=#{lib.static_postgresql_libdir}",
61
+ # libpq-fe.h resides in src/interfaces/libpq/ before make install
62
+ "--with-opt-include=#{lib.static_postgresql_libdir}",
63
+ ]
64
+ }
65
+ end
66
+
67
+ # Add libpq.dll to windows binary gemspec
68
+ ext.cross_compiling do |spec|
69
+ spec.files << "lib/#{spec.platform}/libpq.dll"
70
+ end
71
+ end
72
+
73
+ RSpec::Core::RakeTask.new(:spec).rspec_opts = "--profile -cfdoc"
74
+ task :test => :spec
75
+
76
+ # Use the fivefish formatter for docs generated from development checkout
77
+ require 'rdoc/task'
78
+
79
+ RDoc::Task.new( 'docs' ) do |rdoc|
80
+ rdoc.options = $gem_spec.rdoc_options
81
+ rdoc.rdoc_files = $gem_spec.extra_rdoc_files
82
+ rdoc.generator = :fivefish
83
+ rdoc.rdoc_dir = 'doc'
84
+ end
85
+
86
+ desc "Build the source gem #{$gem_spec.full_name}.gem into the pkg directory"
87
+ task :gem => :build
88
+
89
+ task :clobber do
90
+ puts "Stop any Postmaster instances that remain after testing."
91
+ require_relative 'spec/helpers'
92
+ YugabyteYSQL::TestingHelpers.stop_existing_postmasters()
93
+ end
94
+
95
+ desc "Update list of server error codes"
96
+ task :update_error_codes do
97
+ URL_ERRORCODES_TXT = "http://git.postgresql.org/gitweb/?p=postgresql.git;a=blob_plain;f=src/backend/utils/errcodes.txt;hb=refs/tags/REL_16_0"
98
+
99
+ ERRORCODES_TXT = "ext/errorcodes.txt"
100
+ sh "wget #{URL_ERRORCODES_TXT.inspect} -O #{ERRORCODES_TXT.inspect} || curl #{URL_ERRORCODES_TXT.inspect} -o #{ERRORCODES_TXT.inspect}"
101
+
102
+ ruby 'ext/errorcodes.rb', 'ext/errorcodes.txt', 'ext/errorcodes.def'
103
+ end
104
+
105
+ file 'ext/pg_errors.c' => ['ext/errorcodes.def'] do
106
+ # trigger compilation of changed errorcodes.def
107
+ touch 'ext/pg_errors.c'
108
+ end
109
+
110
+ desc "Translate readme"
111
+ task :translate do
112
+ cd "translation" do
113
+ # po4a's lexer might change, so record its version for reference
114
+ sh "LANG=C po4a --version > .po4a-version"
115
+
116
+ sh "po4a po4a.cfg"
117
+ end
118
+ end