pg_conn 0.33.0 → 0.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/pg_conn/version.rb +1 -1
- data/lib/pg_conn.rb +134 -24
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6d18d4244a00a767589287122f298966ccdd9e8d53a6467f84097df698be34a6
|
4
|
+
data.tar.gz: 6ad5c4c5cf19459996d744e25627cd852d03fa1fa25688572c40de71a5a61100
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9a476b27de6f211d02957c543cf2ee0742011e3d06a468a006fee143827c3cceb8ad32610ca5dee5692cf0230a4c188dd6a4a57335e1eb51d48bc23a9a52e7d3
|
7
|
+
data.tar.gz: 89dcdcec1bdd52d6b2a6ce56ee688e77661f7d438187e289d26e9344d9d030450caea180e260348050c9abcfd34261465fa1d82cefbded641e16ffde708250b5
|
data/lib/pg_conn/version.rb
CHANGED
data/lib/pg_conn.rb
CHANGED
@@ -147,13 +147,32 @@ module PgConn
|
|
147
147
|
attr_reader :session
|
148
148
|
|
149
149
|
# The transaction timestamp of the most recent SQL statement executed by
|
150
|
-
# #exec or #transaction block. The timestamp is without time zone
|
150
|
+
# #exec or #transaction block. The timestamp is without time zone and WRONG
|
151
|
+
# in most cases
|
151
152
|
attr_reader :timestamp
|
152
153
|
|
153
154
|
# The transaction timestamp of the most recent SQL statement executed by
|
154
155
|
# #exec or #transaction block. The timestamp includes the current time zone
|
155
156
|
attr_reader :timestamptz
|
156
157
|
|
158
|
+
# Controls notices. Valid values are true, false, nil, or a Proc
|
159
|
+
# object that recieves the message. True causes the message to be printed
|
160
|
+
# to standard output, false ignores it, and nil resets the state to the
|
161
|
+
# default given when the connection was initialized
|
162
|
+
def notice=(value) set_option(:notice, value) end
|
163
|
+
def notice() @options[:notice] end
|
164
|
+
|
165
|
+
# Controls warnings. Valid values are true, false, nil, or a Proc
|
166
|
+
# object that recieves the message. True causes the message to be printed
|
167
|
+
# to standard error, false ignores it, and nil resets the state to the
|
168
|
+
# default given when the connection was initialized
|
169
|
+
def warning=(value) set_option(:warning, value) end
|
170
|
+
def warning() @options[:warning] end
|
171
|
+
|
172
|
+
# TODO: Move error message handling into the same framework as notice and
|
173
|
+
# warning but we have a name collision just below that would need to be
|
174
|
+
# resolved somehow
|
175
|
+
|
157
176
|
# PG::Error object of the first failed statement in the transaction;
|
158
177
|
# otherwise nil. It is cleared at the beginning of a transaction so be sure
|
159
178
|
# to save it before you run any cleanup code that may initiate new
|
@@ -163,7 +182,7 @@ module PgConn
|
|
163
182
|
# True if the transaction is in a error state
|
164
183
|
def error?() !@error.nil? end
|
165
184
|
|
166
|
-
# Tuple of error message, lineno, and charno of the error object
|
185
|
+
# Tuple of error message, lineno, and charno of the error object. Each
|
167
186
|
# element defaults to nil if not found
|
168
187
|
def err
|
169
188
|
@err ||=
|
@@ -187,13 +206,17 @@ module PgConn
|
|
187
206
|
# if absent in the Postgres error message
|
188
207
|
def errchar = err[2]
|
189
208
|
|
209
|
+
DEFAULT_OPTIONS = { notice: false, warning: false }
|
210
|
+
|
190
211
|
# :call-seq:
|
191
|
-
# initialize(dbname = nil, user = nil,
|
192
|
-
# initialize(connection_hash,
|
193
|
-
# initialize(connection_string,
|
194
|
-
# initialize(host, port, dbname, user, password,
|
195
|
-
# initialize(array,
|
196
|
-
# initialize(pg_connection_object)
|
212
|
+
# initialize(dbname = nil, user = nil, **options)
|
213
|
+
# initialize(connection_hash, **options)
|
214
|
+
# initialize(connection_string, **options)
|
215
|
+
# initialize(host, port, dbname, user, password, **options)
|
216
|
+
# initialize(array, **options)
|
217
|
+
# initialize(pg_connection_object, **options)
|
218
|
+
#
|
219
|
+
# options can be :notice, :warning, :field_name_class, :timestamp, :timestamptz
|
197
220
|
#
|
198
221
|
# Initialize a connection object and connect to the database
|
199
222
|
#
|
@@ -216,6 +239,9 @@ module PgConn
|
|
216
239
|
# Symbol (the default) or String. The :timestamp option is used
|
217
240
|
# internally to set the timestamp for transactions
|
218
241
|
#
|
242
|
+
# The :notice and :warning options sets the default output handling this
|
243
|
+
# connection (FIXME fails on copied connections)
|
244
|
+
#
|
219
245
|
# Note that the connection hash and the connection string may support more
|
220
246
|
# parameters than documented here. Consult
|
221
247
|
# https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING
|
@@ -223,13 +249,22 @@ module PgConn
|
|
223
249
|
#
|
224
250
|
# TODO: Change to 'initialize(*args, **opts)'
|
225
251
|
def initialize(*args)
|
252
|
+
# Extract connection level options and leave other options (that should
|
253
|
+
# be the postgres authentication hash - postgres will emit an error if
|
254
|
+
# not)
|
226
255
|
if args.last.is_a?(Hash)
|
227
|
-
|
228
|
-
@
|
229
|
-
|
230
|
-
|
256
|
+
opts = args.last
|
257
|
+
@field_name_class = opts.delete(:field_name_class) || Symbol
|
258
|
+
options = DEFAULT_OPTIONS.transform_values! { |k,v| opts.key?(k) ? opts.delete(k) : v }
|
259
|
+
|
260
|
+
# FIXME: Is this used?
|
261
|
+
@timestamp = opts.delete(:timestamp)
|
262
|
+
@timestamptz = opts.delete(:timestamptz)
|
263
|
+
|
264
|
+
args.pop if opts.empty?
|
231
265
|
else
|
232
266
|
@field_name_class = Symbol
|
267
|
+
options = DEFAULT_OPTIONS
|
233
268
|
end
|
234
269
|
|
235
270
|
# else # We assume that the current user is a postgres superuser
|
@@ -265,12 +300,12 @@ module PgConn
|
|
265
300
|
elsif args.size == 5
|
266
301
|
make_connection args[0], args[1], nil, nil, args[2], args[3], args[4]
|
267
302
|
else
|
268
|
-
raise Error, "Illegal number of
|
303
|
+
raise Error, "Illegal number of arguments: #{args.size}"
|
269
304
|
end
|
270
305
|
|
271
|
-
if @pg_connection
|
272
|
-
# Set a
|
273
|
-
@pg_connection.set_notice_processor { |message|
|
306
|
+
if @pg_connection #&& !using_existing_connection
|
307
|
+
# Set a notice processor that separates notices and warnings
|
308
|
+
@pg_connection.set_notice_processor { |message| message_processor(message) }
|
274
309
|
|
275
310
|
# Auto-convert to ruby types
|
276
311
|
type_map = PG::BasicTypeMapForResults.new(@pg_connection)
|
@@ -279,21 +314,25 @@ module PgConn
|
|
279
314
|
# type "uuid" with oid 2950..' warnings
|
280
315
|
type_map.default_type_map = PG::TypeMapAllStrings.new
|
281
316
|
|
282
|
-
# Timestamp decoder
|
317
|
+
# Timestamp decoder. FIXME What is this?
|
283
318
|
type_map.add_coder PG::TextDecoder::Timestamp.new( # Timestamp without time zone
|
284
319
|
oid: 1114,
|
285
320
|
flags: PG::Coder::TIMESTAMP_DB_UTC | PG::Coder::TIMESTAMP_APP_UTC)
|
286
321
|
|
287
|
-
# Decode anonymous records but note that this is only useful to convert
|
288
|
-
# outermost structure into an array, the elements are not decoded
|
289
|
-
# returned as strings. It is best to avoid anonymous records if
|
322
|
+
# Decode anonymous records but note that this is only useful to convert
|
323
|
+
# the outermost structure into an array, the elements are not decoded
|
324
|
+
# and are returned as strings. It is best to avoid anonymous records if
|
325
|
+
# possible
|
290
326
|
type_map.add_coder PG::TextDecoder::Record.new(
|
291
327
|
oid: 2249
|
292
328
|
)
|
293
329
|
|
294
330
|
@pg_connection.type_map_for_results = type_map
|
295
331
|
@pg_connection.field_name_type = @field_name_class.to_s.downcase.to_sym # Use symbol field names
|
296
|
-
|
332
|
+
|
333
|
+
@options, @default_options = {}, DEFAULT_OPTIONS
|
334
|
+
set_options(options) # require @default_options
|
335
|
+
@default_options = @options.dup
|
297
336
|
end
|
298
337
|
|
299
338
|
@schema = SchemaMethods.new(self)
|
@@ -307,6 +346,8 @@ module PgConn
|
|
307
346
|
# per-session settings in #initialize? Are they cleared by #reset too?)
|
308
347
|
def reset
|
309
348
|
@pg_connection.reset
|
349
|
+
self.warning = false
|
350
|
+
self.notice = false
|
310
351
|
@pg_connection.exec "set client_min_messages to warning;" # Silence warnings
|
311
352
|
end
|
312
353
|
|
@@ -776,6 +817,21 @@ module PgConn
|
|
776
817
|
exec %(delete from #{table} where #{constraint})
|
777
818
|
end
|
778
819
|
|
820
|
+
# Execute block with global options and resets afterwards. Currently only
|
821
|
+
# :notice and :warning is supported. Very useful in RSpec tests
|
822
|
+
#
|
823
|
+
# TODO: :error, :fail, :symbol, :schema, :search_path
|
824
|
+
#
|
825
|
+
def with(**options, &block)
|
826
|
+
begin
|
827
|
+
saved_options = @options.dup
|
828
|
+
set_options(options)
|
829
|
+
yield
|
830
|
+
ensure
|
831
|
+
set_options(saved_options)
|
832
|
+
end
|
833
|
+
end
|
834
|
+
|
779
835
|
# Execute SQL statement(s) in a transaction and return the number of
|
780
836
|
# affected records (if any). Also sets #timestamp unless a transaction is
|
781
837
|
# already in progress. The +sql+ argument can be a command (String) or an
|
@@ -783,8 +839,8 @@ module PgConn
|
|
783
839
|
# that span multiple lines. The empty array is a NOP but the empty string
|
784
840
|
# is not.
|
785
841
|
#
|
786
|
-
# #exec pass Postgres exceptions to the caller unless :fail is false in
|
787
|
-
# it returns nil
|
842
|
+
# #exec pass Postgres exceptions to the caller unless :fail is false in
|
843
|
+
# which case it returns nil if an error occurred
|
788
844
|
#
|
789
845
|
# Note that postgres crashes the whole transaction stack if any error is
|
790
846
|
# met so if you're inside a transaction, the transaction will be in an
|
@@ -889,7 +945,7 @@ module PgConn
|
|
889
945
|
# and log as a side-effect)
|
890
946
|
if @pg_connection
|
891
947
|
@timestamp, @timestamptz = @pg_connection.exec(
|
892
|
-
'select current_timestamp
|
948
|
+
'select current_timestamp::timestamp without time zone, current_timestamp'
|
893
949
|
).tuple_values(0)
|
894
950
|
end
|
895
951
|
end
|
@@ -1102,6 +1158,60 @@ module PgConn
|
|
1102
1158
|
"select #{field_list} from #{table} where #{where_clause}"
|
1103
1159
|
end
|
1104
1160
|
|
1161
|
+
STDOUT_PRODUCER = lambda { |msg| $stdout.puts msg }
|
1162
|
+
STDERR_PRODUCER = lambda { |msg| $stderr.puts msg }
|
1163
|
+
|
1164
|
+
# FIXME Fails if connection is copied - requires a common options object
|
1165
|
+
# that is shared between all connection copies
|
1166
|
+
def set_option(option, value)
|
1167
|
+
case option
|
1168
|
+
when :notice, :warning
|
1169
|
+
@options[option] =
|
1170
|
+
case value
|
1171
|
+
when true; option == :notice ? STDOUT_PRODUCER : STDERR_PRODUCER
|
1172
|
+
when false; nil
|
1173
|
+
when nil; @default_options[option]
|
1174
|
+
when Proc; value
|
1175
|
+
else
|
1176
|
+
raise ArgumentError, "Illegal value #{value.inspect}"
|
1177
|
+
end
|
1178
|
+
enabled = !@options[option].nil?
|
1179
|
+
if option == :notice
|
1180
|
+
if enabled
|
1181
|
+
@pg_connection.exec "set client_min_messages to notice"
|
1182
|
+
elsif warning
|
1183
|
+
@pg_connection.exec "set client_min_messages to warning"
|
1184
|
+
else
|
1185
|
+
@pg_connection.exec "set client_min_messages to error"
|
1186
|
+
end
|
1187
|
+
elsif !notice
|
1188
|
+
if enabled
|
1189
|
+
@pg_connection.exec "set client_min_messages to notice"
|
1190
|
+
else
|
1191
|
+
@pg_connection.exec "set client_min_messages to error"
|
1192
|
+
end
|
1193
|
+
end
|
1194
|
+
else
|
1195
|
+
raise ArgumentError, "Illegal option: #{option.inspect}"
|
1196
|
+
end
|
1197
|
+
end
|
1198
|
+
|
1199
|
+
def set_options(opts)
|
1200
|
+
opts.each { |k,v| set_option(k,v) if !@options.key?(k) || @options[k] != v }
|
1201
|
+
end
|
1202
|
+
|
1203
|
+
def get_options() @options.dup end
|
1204
|
+
|
1205
|
+
# Called from postgres. Installed in #initialize
|
1206
|
+
def message_processor(message)
|
1207
|
+
case message
|
1208
|
+
when /^NOTICE:\s*(.*)$/; @options[:notice]&.call($1)
|
1209
|
+
when /^WARNING:\s*(.*)$/; @options[:warning]&.call($1)
|
1210
|
+
else
|
1211
|
+
raise "Oops"
|
1212
|
+
end
|
1213
|
+
end
|
1214
|
+
|
1105
1215
|
# :call-seq:
|
1106
1216
|
# pg_exec(string)
|
1107
1217
|
# pg_exec(array)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pg_conn
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.34.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Claus Rasmussen
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-
|
11
|
+
date: 2025-03-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pg
|