db-postgres 0.2.2 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fd023d0017d7e3a5b859c0072e9c6073b1d2f0d33a80e2602e3b10ab3fc1774a
4
- data.tar.gz: 4df334b62fb206775e8d18bc2e9431d240098b84f67a4c6c8d04e3f1ee88f24b
3
+ metadata.gz: edb8f8a5768d89eb1bd6a69b1590f11ed20e8b07570f34887b3a7ba4ebcb5c75
4
+ data.tar.gz: 3a793acd806475a5716096b2475156d733953bf3cbafec09284f808b3f70c889
5
5
  SHA512:
6
- metadata.gz: d473ba682e4fc823c5945d05d6265d5c31a11edbc4946de842ee2ab42f6867fc6c1cdd01130374f11e9605f6ab4655bb7ad7232cf3655925c9ee20cf3beb9a3c
7
- data.tar.gz: 54c94c483f379b1b1d601c2d3ce8c86477a4a7395b73b196b1a546e166413393aa4534d28f8a77a3de3179b43f386791b4798fd4fcda170adeaf8720e9da3482
6
+ metadata.gz: a55115f3c47e2b6eacf5b05799682f3e2b9b5668e289944a5c890dd644deb0a0525ea7ae8520f08a17f2df4816354d0eece6a2d47f2895789b5575b9a1d4a127
7
+ data.tar.gz: 962fdcf60e96b32221e77b690f99b47b40b09050d3c93545a3841188c423e77a94b510ffa520642b243357a0d0b77eb5ec3181d5e2c078f32e14ded354db83af
data/lib/.DS_Store ADDED
Binary file
@@ -65,20 +65,33 @@ module DB
65
65
  end
66
66
 
67
67
  def append_identifier(value, buffer = String.new)
68
- buffer << @native.escape_identifier(value)
68
+ case value
69
+ when Array
70
+ first = true
71
+ value.each do |part|
72
+ buffer << '.' unless first
73
+ first = false
74
+
75
+ buffer << @native.escape_identifier(part)
76
+ end
77
+ else
78
+ buffer << @native.escape_identifier(value)
79
+ end
69
80
 
70
81
  return buffer
71
82
  end
72
83
 
73
- def id_column(name = 'id', primary_key: true)
84
+ def key_column(name = 'id', primary: true, null: false)
74
85
  buffer = String.new
75
86
 
76
87
  append_identifier(name, buffer)
77
88
 
78
89
  buffer << " BIGSERIAL"
79
90
 
80
- if primary_key
91
+ if primary
81
92
  buffer << " PRIMARY KEY"
93
+ elsif !null
94
+ buffer << " NOT NULL"
82
95
  end
83
96
 
84
97
  return buffer
@@ -18,14 +18,38 @@
18
18
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
19
  # THE SOFTWARE.
20
20
 
21
- require 'ffi'
21
+ require 'ffi/module'
22
+ require 'ffi/module/config_tool'
22
23
 
23
24
  module DB
24
25
  module Postgres
25
26
  module Native
26
- extend FFI::Library
27
+ extend FFI::Module::Library
28
+ extend FFI::Module::Loader
29
+ extend FFI::Module::ConfigTool
27
30
 
28
- ffi_lib 'pq'
31
+ ffi_load('pq') ||
32
+ ffi_load_using_config_tool(%w{pg_config --libdir}, names: ['pq']) ||
33
+ ffi_load_failure(<<~EOF)
34
+ Unable to load libpq!
35
+
36
+ ## Ubuntu
37
+
38
+ sudo apt-get install postgresql postgresql-contrib
39
+
40
+ ## Arch Linux
41
+
42
+ sudo pacman -S postgresql
43
+
44
+ ## MacPorts
45
+
46
+ sudo port install postgresql11
47
+
48
+ ## Homebrew
49
+
50
+ brew install postgresql
51
+
52
+ EOF
29
53
  end
30
54
  end
31
55
  end
@@ -25,35 +25,35 @@ require_relative '../error'
25
25
  module DB
26
26
  module Postgres
27
27
  module Native
28
- def self.array_of_strings(values)
29
- array = FFI::MemoryPointer.new(:pointer, values.size + 1)
30
-
31
- pointers = values.map do |value|
32
- FFI::MemoryPointer.from_string(value.to_s)
28
+ class Strings
29
+ def initialize(values)
30
+ @array = FFI::MemoryPointer.new(:pointer, values.size + 1)
31
+ @pointers = values.map do |value|
32
+ FFI::MemoryPointer.from_string(value.to_s)
33
+ end
34
+ @array.write_array_of_pointer(@pointers)
33
35
  end
34
36
 
35
- array.write_array_of_pointer(pointers)
36
-
37
- return array
37
+ attr :array
38
38
  end
39
39
 
40
- attach_function :connect_start_params, :PQconnectStartParams, [:pointer, :pointer, :int], :pointer
40
+ ffi_attach_function :PQconnectStartParams, [:pointer, :pointer, :int], :pointer, as: :connect_start_params
41
41
 
42
- enum :polling_status, [
42
+ ffi_define_enumeration :polling_status, [
43
43
  :failed,
44
44
  :wait_readable,
45
45
  :wait_writable,
46
46
  :ok,
47
47
  ]
48
48
 
49
- attach_function :connect_poll, :PQconnectPoll, [:pointer], :polling_status
49
+ ffi_attach_function :PQconnectPoll, [:pointer], :polling_status, as: :connect_poll
50
50
 
51
51
  # Close the connection and release underlying resources.
52
- attach_function :finish, :PQfinish, [:pointer], :void
52
+ ffi_attach_function :PQfinish, [:pointer], :void, as: :finish
53
53
 
54
- attach_function :error_message, :PQerrorMessage, [:pointer], :string
54
+ ffi_attach_function :PQerrorMessage, [:pointer], :string, as: :error_message
55
55
 
56
- enum :status, [
56
+ ffi_define_enumeration :status, [
57
57
  # Normal mode:
58
58
  :ok,
59
59
  :bad,
@@ -70,31 +70,31 @@ module DB
70
70
  :consume, # Wait for any pending message and consume them.
71
71
  ]
72
72
 
73
- attach_function :status, :PQstatus, [:pointer], :status
73
+ ffi_attach_function :PQstatus, [:pointer], :status, as: :status
74
74
 
75
- attach_function :socket, :PQsocket, [:pointer], :int
75
+ ffi_attach_function :PQsocket, [:pointer], :int, as: :socket
76
76
 
77
- attach_function :set_nonblocking, :PQsetnonblocking, [:pointer, :int], :int
78
- attach_function :flush, :PQflush, [:pointer], :int
77
+ ffi_attach_function :PQsetnonblocking, [:pointer, :int], :int, as: :set_nonblocking
78
+ ffi_attach_function :PQflush, [:pointer], :int, as: :flush
79
79
 
80
80
  # Submits a command to the server without waiting for the result(s). 1 is returned if the command was successfully dispatched and 0 if not (in which case, use PQerrorMessage to get more information about the failure).
81
- attach_function :send_query, :PQsendQuery, [:pointer, :string], :int
81
+ ffi_attach_function :PQsendQuery, [:pointer, :string], :int, as: :send_query
82
82
 
83
83
  # int PQsendQueryParams(PGconn *conn, const char *command, int nParams, const Oid *paramTypes, const char * const *paramValues, const int *paramLengths, const int *paramFormats, int resultFormat);
84
- attach_function :send_query_params, :PQsendQueryParams, [:pointer, :string, :int, :pointer, :pointer, :pointer, :pointer, :int], :int
84
+ ffi_attach_function :PQsendQueryParams, [:pointer, :string, :int, :pointer, :pointer, :pointer, :pointer, :int], :int, as: :send_query_params
85
85
 
86
- attach_function :set_single_row_mode, :PQsetSingleRowMode, [:pointer], :int
86
+ ffi_attach_function :PQsetSingleRowMode, [:pointer], :int, as: :set_single_row_mode
87
87
 
88
- attach_function :get_result, :PQgetResult, [:pointer], :pointer
88
+ ffi_attach_function :PQgetResult, [:pointer], :pointer, as: :get_result
89
89
 
90
90
  # If input is available from the server, consume it:
91
- attach_function :consume_input, :PQconsumeInput, [:pointer], :int
91
+ ffi_attach_function :PQconsumeInput, [:pointer], :int, as: :consume_input
92
92
 
93
93
  # Returns 1 if a command is busy, that is, PQgetResult would block waiting for input. A 0 return indicates that PQgetResult can be called with assurance of not blocking.
94
- attach_function :is_busy, :PQisBusy, [:pointer], :int
94
+ ffi_attach_function :PQisBusy, [:pointer], :int, as: :is_busy
95
95
 
96
- attach_function :escape_literal, :PQescapeLiteral, [:pointer, :string, :size_t], :pointer
97
- attach_function :escape_identifier, :PQescapeIdentifier, [:pointer, :string, :size_t], :pointer
96
+ ffi_attach_function :PQescapeLiteral, [:pointer, :string, :size_t], :pointer, as: :escape_literal
97
+ ffi_attach_function :PQescapeIdentifier, [:pointer, :string, :size_t], :pointer, as: :escape_identifier
98
98
 
99
99
  module IO
100
100
  def self.new(fd, mode)
@@ -104,15 +104,20 @@ module DB
104
104
 
105
105
  class Connection < FFI::Pointer
106
106
  def self.connect(wrapper: IO, types: DEFAULT_TYPES, **options)
107
- # Prefer 'database' key for 'dbname' parameter:
107
+ # Postgres expects "dbname" as the key name:
108
108
  if database = options.delete(:database)
109
109
  options[:dbname] = database
110
110
  end
111
111
 
112
- keys = Native.array_of_strings(options.keys)
113
- values = Native.array_of_strings(options.values)
112
+ # Postgres expects "user" as the key name:
113
+ if username = options.delete(:username)
114
+ options[:user] = username
115
+ end
116
+
117
+ keys = Strings.new(options.keys)
118
+ values = Strings.new(options.values)
114
119
 
115
- pointer = Native.connect_start_params(keys, values, 0)
120
+ pointer = Native.connect_start_params(keys.array, values.array, 0)
116
121
  Native.set_nonblocking(pointer, 1)
117
122
 
118
123
  io = wrapper.new(Native.socket(pointer), "r+")
@@ -23,7 +23,7 @@ require_relative '../native'
23
23
  module DB
24
24
  module Postgres
25
25
  module Native
26
- enum :query_status, [
26
+ ffi_define_enumeration :query_status, [
27
27
  :empty_query, # empty query string was executed
28
28
  :command_ok, # a query command that doesn't return anything was executed properly by the backend
29
29
  :tuples_ok, # a query command that returns tuples was executed properly by the backend, PGresult contains the result tuples
@@ -36,24 +36,26 @@ module DB
36
36
  :single_tuple, # single tuple from larger resultset
37
37
  ]
38
38
 
39
- attach_function :result_status, :PQresultStatus, [:pointer], :query_status
40
- attach_function :result_error_message, :PQresultErrorMessage, [:pointer], :string
39
+ ffi_attach_function :PQresultStatus, [:pointer], :query_status, as: :result_status
40
+ ffi_attach_function :PQresultErrorMessage, [:pointer], :string, as: :result_error_message
41
41
 
42
- attach_function :row_count, :PQntuples, [:pointer], :int
43
- attach_function :field_count, :PQnfields, [:pointer], :int
44
- attach_function :field_name, :PQfname, [:pointer, :int], :string
45
- attach_function :field_type, :PQftype, [:pointer, :int], :int
42
+ ffi_attach_function :PQntuples, [:pointer], :int, as: :row_count
43
+ ffi_attach_function :PQnfields, [:pointer], :int, as: :field_count
44
+ ffi_attach_function :PQfname, [:pointer, :int], :string, as: :field_name
45
+ ffi_attach_function :PQftype, [:pointer, :int], :int, as: :field_type
46
46
 
47
- attach_function :get_value, :PQgetvalue, [:pointer, :int, :int], :string
48
- attach_function :get_is_null, :PQgetisnull, [:pointer, :int, :int], :int
47
+ ffi_attach_function :PQgetvalue, [:pointer, :int, :int], :string, as: :get_value
48
+ ffi_attach_function :PQgetisnull, [:pointer, :int, :int], :int, as: :get_is_null
49
49
 
50
- attach_function :clear, :PQclear, [:pointer], :void
50
+ ffi_attach_function :PQclear, [:pointer], :void, as: :clear
51
51
 
52
- attach_function :put_copy_end, :PQputCopyEnd, [:pointer, :string], :int
53
- attach_function :get_copy_data, :PQgetCopyData, [:pointer, :pointer, :int], :int
54
- attach_function :free_memory, :PQfreemem, [:pointer], :void
52
+ ffi_attach_function :PQputCopyEnd, [:pointer, :string], :int, as: :put_copy_end
53
+ ffi_attach_function :PQgetCopyData, [:pointer, :pointer, :int], :int, as: :get_copy_data
54
+ ffi_attach_function :PQfreemem, [:pointer], :void, as: :free_memory
55
55
 
56
56
  class Result < FFI::Pointer
57
+ include Enumerable
58
+
57
59
  def initialize(connection, types = {}, address)
58
60
  super(address)
59
61
 
@@ -99,17 +101,8 @@ module DB
99
101
  Native.clear(self)
100
102
  end
101
103
 
102
- def to_a
103
- rows = []
104
-
105
- self.each do |row|
106
- rows << row
107
- end
108
-
109
- return rows
110
- end
111
-
112
104
  protected
105
+
113
106
  def get_value(row, field)
114
107
  if Native.get_is_null(self, row, field) == 0
115
108
  Native.get_value(self, row, field)
@@ -20,6 +20,6 @@
20
20
 
21
21
  module DB
22
22
  module Postgres
23
- VERSION = "0.2.2"
23
+ VERSION = "0.5.0"
24
24
  end
25
25
  end
metadata CHANGED
@@ -1,17 +1,31 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: db-postgres
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.5.0
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-07 00:00:00.000000000 Z
11
+ date: 2021-04-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: ffi
14
+ name: ffi-module
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.3.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.3.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: async-io
15
29
  requirement: !ruby/object:Gem::Requirement
16
30
  requirements:
17
31
  - - ">="
@@ -25,7 +39,7 @@ dependencies:
25
39
  - !ruby/object:Gem::Version
26
40
  version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
- name: async-io
42
+ name: async-pool
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
45
  - - ">="
@@ -114,6 +128,7 @@ executables: []
114
128
  extensions: []
115
129
  extra_rdoc_files: []
116
130
  files:
131
+ - lib/.DS_Store
117
132
  - lib/db/postgres.rb
118
133
  - lib/db/postgres/adapter.rb
119
134
  - lib/db/postgres/connection.rb
@@ -143,7 +158,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
143
158
  - !ruby/object:Gem::Version
144
159
  version: '0'
145
160
  requirements: []
146
- rubygems_version: 3.1.2
161
+ rubygems_version: 3.2.3
147
162
  signing_key:
148
163
  specification_version: 4
149
164
  summary: Ruby FFI bindings for libpq C interface.