Skip to content

Commit 3549eb8

Browse files
committed
Change the native connection method to use expand_paths (#16)
Allows a full URL-like string in `dbname:`.
1 parent 3a137d4 commit 3549eb8

File tree

3 files changed

+103
-2
lines changed

3 files changed

+103
-2
lines changed

config/sus.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,7 @@
1212
database: "test",
1313
host: "127.0.0.1"
1414
}
15+
16+
::CREDENTIALS_URL = {
17+
dbname: "postgresql://test:test@127.0.0.1/test"
18+
}

lib/db/postgres/native/connection.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ def initialize(values)
5050
# Non-blocking mode:
5151
:started, # Waiting for connection to be made.
5252
:made, # Connection OK; waiting to send.
53-
:awaiting_response, #Waiting for a response from the postmaster.
53+
:awaiting_response, # Waiting for a response from the postmaster.
5454
:auth_ok, # Received authentication; waiting for backend startup.
5555
:setenv, # Negotiating environment.
5656
:ssl_startup, # Negotiating SSL.
@@ -106,7 +106,7 @@ def self.connect(types: DEFAULT_TYPES, **options)
106106
keys = Strings.new(options.keys)
107107
values = Strings.new(options.values)
108108

109-
pointer = Native.connect_start_params(keys.array, values.array, 0)
109+
pointer = Native.connect_start_params(keys.array, values.array, 1)
110110
Native.set_nonblocking(pointer, 1)
111111

112112
io = ::IO.new(Native.socket(pointer), "r+", autoclose: false)

test/db/postgres/connection_url.rb

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# frozen_string_literal: true
2+
3+
# Released under the MIT License.
4+
# Copyright, 2026, by securepii-dev.
5+
6+
require "db/postgres/connection"
7+
require "sus/fixtures/async"
8+
9+
describe DB::Postgres::Connection do
10+
include Sus::Fixtures::Async::ReactorContext
11+
12+
let(:connection) {subject.new(**CREDENTIALS_URL)}
13+
14+
after do
15+
@connection&.close
16+
end
17+
18+
it "should connect to local postgres" do
19+
expect(connection.status).to be == :ok
20+
end
21+
22+
it "should execute query" do
23+
connection.send_query("SELECT 42 AS LIFE")
24+
25+
result = connection.next_result
26+
27+
expect(result.to_a).to be == [[42]]
28+
end
29+
30+
it "should execute multiple queries" do
31+
connection.send_query("SELECT 42 AS LIFE; SELECT 24 AS LIFE")
32+
33+
result = connection.next_result
34+
expect(result.to_a).to be == [[42]]
35+
36+
result = connection.next_result
37+
expect(result.to_a).to be == [[24]]
38+
end
39+
40+
it "can get current time" do
41+
connection.send_query("SELECT (NOW() AT TIME ZONE 'UTC') AS NOW")
42+
43+
result = connection.next_result
44+
row = result.to_a.first
45+
46+
expect(row.first).to be_within(1).of(Time.now.utc)
47+
end
48+
49+
with "#append_string" do
50+
it "should escape string" do
51+
expect(connection.append_string("Hello 'World'")).to be == "'Hello ''World'''"
52+
expect(connection.append_string('Hello "World"')).to be == "'Hello \"World\"'"
53+
end
54+
end
55+
56+
with "#append_literal" do
57+
it "should escape string" do
58+
expect(connection.append_literal("Hello World")).to be == "'Hello World'"
59+
end
60+
61+
it "should not escape integers" do
62+
expect(connection.append_literal(42)).to be == "42"
63+
end
64+
end
65+
66+
with "#append_identifier" do
67+
it "should escape identifier" do
68+
expect(connection.append_identifier("Hello World")).to be == '"Hello World"'
69+
end
70+
71+
it "can handle booleans" do
72+
buffer = String.new
73+
buffer << "SELECT "
74+
connection.append_literal(true, buffer)
75+
76+
connection.send_query(buffer)
77+
78+
result = connection.next_result
79+
row = result.to_a.first
80+
81+
expect(row.first).to be == true
82+
end
83+
end
84+
85+
with "#features" do
86+
it "should return configured PostgreSQL features" do
87+
features = connection.features
88+
89+
expect(features.alter_column_type?).to be == true
90+
expect(features.using_clause?).to be == true
91+
expect(features.conditional_operations?).to be == true
92+
expect(features.transactional_schema?).to be == true
93+
expect(features.batch_alter_table?).to be == true
94+
expect(features.modify_column?).to be == false
95+
end
96+
end
97+
end

0 commit comments

Comments
 (0)