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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 61a45c4212bcf4b8c3fdf1a244292581da1a1df513450d51fcd322ea625ccd94
4
- data.tar.gz: 18310b502a0cae91906948fa5ce8c5c07c07e81590612e902588abba7fdd37e1
3
+ metadata.gz: fd023d0017d7e3a5b859c0072e9c6073b1d2f0d33a80e2602e3b10ab3fc1774a
4
+ data.tar.gz: 4df334b62fb206775e8d18bc2e9431d240098b84f67a4c6c8d04e3f1ee88f24b
5
5
  SHA512:
6
- metadata.gz: '039afaa56fac564fbb12e66d164ab0d0700eeb6c22d6bcbb7a56ecbd209da1b065ab16c28c5b14cac513ff0af15d7ece1f549cf4fe055db62e8f742fac4406a2'
7
- data.tar.gz: 94e9caed1d36af0a15b9efb71f96a1c151c171fe062bdd789e23c0eab023a2aadd759dbbda996809d93de7fa32323e4fdc67fa52592b7a4e6a1eb784033234bb
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(io: IO, types: DEFAULT_TYPES, **options)
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 = io.new(Native.socket(pointer), "r+")
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("discard results")
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.new(message)
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.new(message)
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.new(message)
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.get_value(self, row, field)
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)
@@ -20,6 +20,6 @@
20
20
 
21
21
  module DB
22
22
  module Postgres
23
- VERSION = "0.1.1"
23
+ VERSION = "0.2.2"
24
24
  end
25
25
  end
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.1.1
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-05 00:00:00.000000000 Z
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