db-postgres 0.1.1 → 0.2.2
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/db/postgres/connection.rb +18 -22
- data/lib/db/postgres/error.rb +28 -0
- data/lib/db/postgres/native/connection.rb +25 -9
- data/lib/db/postgres/native/result.rb +5 -1
- data/lib/db/postgres/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fd023d0017d7e3a5b859c0072e9c6073b1d2f0d33a80e2602e3b10ab3fc1774a
|
4
|
+
data.tar.gz: 4df334b62fb206775e8d18bc2e9431d240098b84f67a4c6c8d04e3f1ee88f24b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d473ba682e4fc823c5945d05d6265d5c31a11edbc4946de842ee2ab42f6867fc6c1cdd01130374f11e9605f6ab4655bb7ad7232cf3655925c9ee20cf3beb9a3c
|
7
|
+
data.tar.gz: 54c94c483f379b1b1d601c2d3ce8c86477a4a7395b73b196b1a546e166413393aa4534d28f8a77a3de3179b43f386791b4798fd4fcda170adeaf8720e9da3482
|
@@ -21,18 +21,12 @@
|
|
21
21
|
# THE SOFTWARE.
|
22
22
|
|
23
23
|
require 'async/pool/resource'
|
24
|
-
require_relative 'native/connection'
|
25
|
-
|
26
24
|
require 'async/io/generic'
|
27
25
|
|
26
|
+
require_relative 'native/connection'
|
27
|
+
|
28
28
|
module DB
|
29
29
|
module Postgres
|
30
|
-
module IO
|
31
|
-
def self.new(fd, mode)
|
32
|
-
Async::IO::Generic.new(::IO.new(fd, mode, autoclose: false))
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
30
|
# This implements the interface between the underlying
|
37
31
|
class Connection < Async::Pool::Resource
|
38
32
|
def initialize(**options)
|
@@ -76,31 +70,33 @@ module DB
|
|
76
70
|
return buffer
|
77
71
|
end
|
78
72
|
|
73
|
+
def id_column(name = 'id', primary_key: true)
|
74
|
+
buffer = String.new
|
75
|
+
|
76
|
+
append_identifier(name, buffer)
|
77
|
+
|
78
|
+
buffer << " BIGSERIAL"
|
79
|
+
|
80
|
+
if primary_key
|
81
|
+
buffer << " PRIMARY KEY"
|
82
|
+
end
|
83
|
+
|
84
|
+
return buffer
|
85
|
+
end
|
86
|
+
|
79
87
|
def status
|
80
88
|
@native.status
|
81
89
|
end
|
82
90
|
|
83
91
|
def send_query(statement)
|
92
|
+
@native.discard_results
|
93
|
+
|
84
94
|
@native.send_query(statement)
|
85
95
|
end
|
86
96
|
|
87
97
|
def next_result
|
88
98
|
@native.next_result
|
89
99
|
end
|
90
|
-
|
91
|
-
def call(statement, streaming: false)
|
92
|
-
@native.send_query(statement)
|
93
|
-
|
94
|
-
@native.single_row_mode! if streaming
|
95
|
-
|
96
|
-
last_result = nil
|
97
|
-
|
98
|
-
while result = @native.next_result
|
99
|
-
last_result = result
|
100
|
-
end
|
101
|
-
|
102
|
-
return last_result
|
103
|
-
end
|
104
100
|
end
|
105
101
|
end
|
106
102
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
# THE SOFTWARE.
|
22
|
+
|
23
|
+
module DB
|
24
|
+
module Postgres
|
25
|
+
class Error < StandardError
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -20,6 +20,7 @@
|
|
20
20
|
|
21
21
|
require_relative 'result'
|
22
22
|
require_relative 'field'
|
23
|
+
require_relative '../error'
|
23
24
|
|
24
25
|
module DB
|
25
26
|
module Postgres
|
@@ -95,8 +96,14 @@ module DB
|
|
95
96
|
attach_function :escape_literal, :PQescapeLiteral, [:pointer, :string, :size_t], :pointer
|
96
97
|
attach_function :escape_identifier, :PQescapeIdentifier, [:pointer, :string, :size_t], :pointer
|
97
98
|
|
99
|
+
module IO
|
100
|
+
def self.new(fd, mode)
|
101
|
+
Async::IO::Generic.new(::IO.new(fd, mode, autoclose: false))
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
98
105
|
class Connection < FFI::Pointer
|
99
|
-
def self.connect(
|
106
|
+
def self.connect(wrapper: IO, types: DEFAULT_TYPES, **options)
|
100
107
|
# Prefer 'database' key for 'dbname' parameter:
|
101
108
|
if database = options.delete(:database)
|
102
109
|
options[:dbname] = database
|
@@ -106,8 +113,9 @@ module DB
|
|
106
113
|
values = Native.array_of_strings(options.values)
|
107
114
|
|
108
115
|
pointer = Native.connect_start_params(keys, values, 0)
|
116
|
+
Native.set_nonblocking(pointer, 1)
|
109
117
|
|
110
|
-
io =
|
118
|
+
io = wrapper.new(Native.socket(pointer), "r+")
|
111
119
|
|
112
120
|
while status = Native.connect_poll(pointer)
|
113
121
|
break if status == :ok || status == :failed
|
@@ -123,11 +131,9 @@ module DB
|
|
123
131
|
|
124
132
|
Native.finish(pointer)
|
125
133
|
|
126
|
-
raise "connect: #{error_message}"
|
134
|
+
raise Error, "Could not connect: #{error_message}"
|
127
135
|
end
|
128
136
|
|
129
|
-
Native.set_nonblocking(pointer, 1)
|
130
|
-
|
131
137
|
return self.new(pointer, io, types)
|
132
138
|
end
|
133
139
|
|
@@ -196,6 +202,16 @@ module DB
|
|
196
202
|
|
197
203
|
def next_result(types: @types)
|
198
204
|
if result = self.get_result
|
205
|
+
status = Native.result_status(result)
|
206
|
+
|
207
|
+
if status == :fatal_error
|
208
|
+
message = Native.result_error_message(result)
|
209
|
+
|
210
|
+
Native.clear(result)
|
211
|
+
|
212
|
+
raise Error, "Could not get next result: #{message}"
|
213
|
+
end
|
214
|
+
|
199
215
|
return Result.new(self, types, result)
|
200
216
|
end
|
201
217
|
end
|
@@ -208,7 +224,7 @@ module DB
|
|
208
224
|
|
209
225
|
case status
|
210
226
|
when :copy_in
|
211
|
-
self.put_copy_end("
|
227
|
+
self.put_copy_end("Discard results")
|
212
228
|
when :copy_out
|
213
229
|
self.flush_copy_out
|
214
230
|
end
|
@@ -244,7 +260,7 @@ module DB
|
|
244
260
|
|
245
261
|
if status == -1
|
246
262
|
message = Native.error_message(self)
|
247
|
-
raise Error
|
263
|
+
raise Error, message
|
248
264
|
elsif status == 0
|
249
265
|
@io.wait_writable
|
250
266
|
else
|
@@ -261,7 +277,7 @@ module DB
|
|
261
277
|
|
262
278
|
if status == -2
|
263
279
|
message = Native.error_message(self)
|
264
|
-
raise Error
|
280
|
+
raise Error, message
|
265
281
|
elsif status == -1
|
266
282
|
break
|
267
283
|
elsif status == 0
|
@@ -289,7 +305,7 @@ module DB
|
|
289
305
|
def check!(result)
|
290
306
|
if result == 0
|
291
307
|
message = Native.error_message(self)
|
292
|
-
raise Error
|
308
|
+
raise Error, message
|
293
309
|
end
|
294
310
|
end
|
295
311
|
end
|
@@ -43,7 +43,9 @@ module DB
|
|
43
43
|
attach_function :field_count, :PQnfields, [:pointer], :int
|
44
44
|
attach_function :field_name, :PQfname, [:pointer, :int], :string
|
45
45
|
attach_function :field_type, :PQftype, [:pointer, :int], :int
|
46
|
+
|
46
47
|
attach_function :get_value, :PQgetvalue, [:pointer, :int, :int], :string
|
48
|
+
attach_function :get_is_null, :PQgetisnull, [:pointer, :int, :int], :int
|
47
49
|
|
48
50
|
attach_function :clear, :PQclear, [:pointer], :void
|
49
51
|
|
@@ -109,7 +111,9 @@ module DB
|
|
109
111
|
|
110
112
|
protected
|
111
113
|
def get_value(row, field)
|
112
|
-
Native.
|
114
|
+
if Native.get_is_null(self, row, field) == 0
|
115
|
+
Native.get_value(self, row, field)
|
116
|
+
end
|
113
117
|
end
|
114
118
|
|
115
119
|
def get_row(row)
|
data/lib/db/postgres/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: db-postgres
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-07-
|
11
|
+
date: 2020-07-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ffi
|
@@ -117,6 +117,7 @@ files:
|
|
117
117
|
- lib/db/postgres.rb
|
118
118
|
- lib/db/postgres/adapter.rb
|
119
119
|
- lib/db/postgres/connection.rb
|
120
|
+
- lib/db/postgres/error.rb
|
120
121
|
- lib/db/postgres/native.rb
|
121
122
|
- lib/db/postgres/native/connection.rb
|
122
123
|
- lib/db/postgres/native/field.rb
|