Skip to content

Commit 3a137d4

Browse files
Add missing documentation.
1 parent 17649ae commit 3a137d4

File tree

8 files changed

+153
-1
lines changed

8 files changed

+153
-1
lines changed

lib/db/postgres/adapter.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,19 @@
77

88
module DB
99
module Postgres
10+
# A database adapter for connecting to PostgreSQL servers.
1011
class Adapter
12+
# Initialize a new adapter with connection options.
13+
# @parameter options [Hash] Connection options to be passed to the connection.
1114
def initialize(**options)
1215
@options = options
1316
end
1417

18+
# @attribute [Hash] The connection options.
1519
attr :options
1620

21+
# Create a new database connection.
22+
# @returns [Connection] A new connection instance.
1723
def call
1824
Connection.new(**@options)
1925
end

lib/db/postgres/connection.rb

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,18 @@
99

1010
module DB
1111
module Postgres
12-
# This implements the interface between the underlying
12+
# A high-level database connection that implements the standardized connection interface.
13+
# This class provides a bridge between the underlying native PostgreSQL interface and the DB gem's unified connection API.
1314
class Connection < Async::Pool::Resource
15+
# Initialize a new database connection.
16+
# @parameter options [Hash] Connection options passed to the native connection.
1417
def initialize(**options)
1518
@native = Native::Connection.connect(**options)
1619

1720
super()
1821
end
1922

23+
# Close the database connection and release resources.
2024
def close
2125
if @native
2226
@native&.close
@@ -26,16 +30,26 @@ def close
2630
super
2731
end
2832

33+
# Get the type mapping for database types.
34+
# @returns [Hash] The type mapping configuration.
2935
def types
3036
@native.types
3137
end
3238

39+
# Append an escaped string value to the buffer.
40+
# @parameter value [String] The string value to escape and append.
41+
# @parameter buffer [String] The buffer to append to.
42+
# @returns [String] The buffer with the escaped string appended.
3343
def append_string(value, buffer = String.new)
3444
buffer << @native.escape_literal(value)
3545

3646
return buffer
3747
end
3848

49+
# Append a literal value to the buffer with appropriate formatting.
50+
# @parameter value [Object] The value to append (supports Time, Date, Numeric, Boolean, nil, and strings).
51+
# @parameter buffer [String] The buffer to append to.
52+
# @returns [String] The buffer with the formatted value appended.
3953
def append_literal(value, buffer = String.new)
4054
case value
4155
when Time, DateTime, Date
@@ -55,6 +69,10 @@ def append_literal(value, buffer = String.new)
5569
return buffer
5670
end
5771

72+
# Append an escaped identifier to the buffer.
73+
# @parameter value [String | Array(String)] The identifier or array of identifiers to escape.
74+
# @parameter buffer [String] The buffer to append to.
75+
# @returns [String] The buffer with the escaped identifier appended.
5876
def append_identifier(value, buffer = String.new)
5977
case value
6078
when Array
@@ -72,6 +90,11 @@ def append_identifier(value, buffer = String.new)
7290
return buffer
7391
end
7492

93+
# Generate a key column definition for table creation.
94+
# @parameter name [String] The column name.
95+
# @parameter primary [Boolean] Whether this is a primary key column.
96+
# @parameter null [Boolean] Whether this column allows null values.
97+
# @returns [String] The column definition string.
7598
def key_column(name = "id", primary: true, null: false)
7699
buffer = String.new
77100

@@ -92,16 +115,22 @@ def key_column(name = "id", primary: true, null: false)
92115
return buffer
93116
end
94117

118+
# Get the current connection status.
119+
# @returns [Symbol] The status symbol from the server.
95120
def status
96121
@native.status
97122
end
98123

124+
# Send a query to the database server.
125+
# @parameter statement [String] The SQL statement to execute.
99126
def send_query(statement)
100127
@native.discard_results
101128

102129
@native.send_query(statement)
103130
end
104131

132+
# Get the next result set from a multi-result query.
133+
# @returns [Native::Result | Nil] The next result set, or `nil` if no more results.
105134
def next_result
106135
@native.next_result
107136
end
@@ -117,6 +146,7 @@ def next_result
117146
)
118147

119148
# Database feature detection for migration and query building.
149+
# @returns [DB::Features] The supported database features.
120150
def features
121151
FEATURES
122152
end

lib/db/postgres/error.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
module DB
77
module Postgres
8+
# An error raised by the PostgreSQL adapter.
89
class Error < StandardError
910
end
1011
end

lib/db/postgres/native.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
module DB
1010
module Postgres
11+
# Provides FFI bindings to the native PostgreSQL client library (libpq).
1112
module Native
1213
extend FFI::Native::Library
1314
extend FFI::Native::Loader

lib/db/postgres/native/connection.rb

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@
1010
module DB
1111
module Postgres
1212
module Native
13+
# Helper class for managing FFI string arrays.
1314
class Strings
15+
# Initialize a string array for FFI.
16+
# @parameter values [Array] The array of values to convert to FFI strings.
1417
def initialize(values)
1518
@array = FFI::MemoryPointer.new(:pointer, values.size + 1)
1619
@pointers = values.map do |value|
@@ -19,6 +22,7 @@ def initialize(values)
1922
@array.write_array_of_pointer(@pointers)
2023
end
2124

25+
# @attribute [FFI::MemoryPointer] The FFI array pointer.
2226
attr :array
2327
end
2428

@@ -81,7 +85,13 @@ def initialize(values)
8185
ffi_attach_function :PQescapeLiteral, [:pointer, :string, :size_t], :pointer, as: :escape_literal
8286
ffi_attach_function :PQescapeIdentifier, [:pointer, :string, :size_t], :pointer, as: :escape_identifier
8387

88+
# A native FFI connection to the PostgreSQL client library.
8489
class Connection < FFI::Pointer
90+
# Establish a connection to the PostgreSQL server.
91+
# @parameter types [Hash] Type mapping configuration.
92+
# @parameter options [Hash] Connection options (database, username, password, host, port, etc.).
93+
# @returns [Connection] A new connected instance.
94+
# @raises [Error] If the connection fails.
8595
def self.connect(types: DEFAULT_TYPES, **options)
8696
# Postgres expects "dbname" as the key name:
8797
if database = options.delete(:database)
@@ -121,13 +131,18 @@ def self.connect(types: DEFAULT_TYPES, **options)
121131
return self.new(pointer, io, types)
122132
end
123133

134+
# Initialize a native connection wrapper.
135+
# @parameter address [FFI::Pointer] The pointer to the native connection.
136+
# @parameter io [IO] The IO object for the socket.
137+
# @parameter types [Hash] Type mapping configuration.
124138
def initialize(address, io, types)
125139
super(address)
126140

127141
@io = io
128142
@types = types
129143
end
130144

145+
# @attribute [Hash] The type mapping configuration.
131146
attr :types
132147

133148
# Return the status of the connection.
@@ -152,6 +167,9 @@ def close
152167
@io.close
153168
end
154169

170+
# Escape a literal string value for safe inclusion in SQL queries.
171+
# @parameter value [String] The value to escape.
172+
# @returns [String] The escaped string with quotes.
155173
def escape_literal(value)
156174
value = value.to_s
157175

@@ -164,6 +182,9 @@ def escape_literal(value)
164182
return string
165183
end
166184

185+
# Escape an identifier for safe inclusion in SQL queries.
186+
# @parameter value [String] The identifier to escape.
187+
# @returns [String] The escaped identifier with quotes.
167188
def escape_identifier(value)
168189
value = value.to_s
169190

@@ -176,16 +197,23 @@ def escape_identifier(value)
176197
return string
177198
end
178199

200+
# Enable single row mode for streaming large result sets.
179201
def single_row_mode!
180202
Native.set_single_row_mode(self)
181203
end
182204

205+
# Send a query to the server for execution.
206+
# @parameter statement [String] The SQL statement to execute.
183207
def send_query(statement)
184208
check! Native.send_query(self, statement)
185209

186210
flush
187211
end
188212

213+
# Get the next result set from a multi-result query.
214+
# @parameter types [Hash] Type mapping to use for this result.
215+
# @returns [Result | Nil] The next result set, or `nil` if no more results.
216+
# @raises [Error] If the query resulted in an error.
189217
def next_result(types: @types)
190218
if result = self.get_result
191219
status = Native.result_status(result)

lib/db/postgres/native/result.rb

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,12 @@ module Native
3838
ffi_attach_function :PQgetCopyData, [:pointer, :pointer, :int], :int, as: :get_copy_data
3939
ffi_attach_function :PQfreemem, [:pointer], :void, as: :free_memory
4040

41+
# A result set from a database query with row iteration and type casting.
4142
class Result < FFI::Pointer
43+
# Initialize a new result set wrapper.
44+
# @parameter connection [Connection] The connection that produced this result.
45+
# @parameter types [Hash] Type mapping for field conversion.
46+
# @parameter address [FFI::Pointer] The pointer to the native result.
4247
def initialize(connection, types = {}, address)
4348
super(address)
4449

@@ -48,22 +53,33 @@ def initialize(connection, types = {}, address)
4853
@casts = nil
4954
end
5055

56+
# Get the number of fields in this result set.
57+
# @returns [Integer] The field count.
5158
def field_count
5259
Native.field_count(self)
5360
end
5461

62+
# Get the type converters for each field.
63+
# @returns [Array] The array of type converter objects.
5564
def field_types
5665
field_count.times.collect{|i| @types[Native.field_type(self, i)]}
5766
end
5867

68+
# Get the field names for this result set.
69+
# @returns [Array(String)] The array of field names.
5970
def field_names
6071
field_count.times.collect{|i| Native.field_name(self, i)}
6172
end
6273

74+
# Get the number of rows in this result set.
75+
# @returns [Integer] The row count.
6376
def row_count
6477
Native.row_count(self)
6578
end
6679

80+
# Cast row values to appropriate Ruby types.
81+
# @parameter row [Array] The raw row data.
82+
# @returns [Array] The row with values cast to proper types.
6783
def cast!(row)
6884
@casts ||= self.field_types
6985

@@ -76,6 +92,9 @@ def cast!(row)
7692
return row
7793
end
7894

95+
# Iterate over each row in the result set.
96+
# @yields {|row| ...} Each row as an array.
97+
# @parameter row [Array] The current row data.
7998
def each
8099
row_count.times do |i|
81100
yield cast!(get_row(i))
@@ -84,6 +103,10 @@ def each
84103
Native.clear(self)
85104
end
86105

106+
# Map over each row in the result set.
107+
# @yields {|row| ...} Each row as an array.
108+
# @parameter row [Array] The current row data.
109+
# @returns [Array] The mapped results.
87110
def map(&block)
88111
results = []
89112

@@ -94,6 +117,8 @@ def map(&block)
94117
return results
95118
end
96119

120+
# Convert the entire result set to an array.
121+
# @returns [Array(Array)] All rows as arrays.
97122
def to_a
98123
rows = []
99124

0 commit comments

Comments
 (0)