Skip to content

Commit da5509e

Browse files
authored
Update decoders to parse float and return null on error (denodrivers#444)
* chore: format files * chore: add types and format file * add float decoders, return null on decode fail, improve boolean, box and line segment decode * chore: add decode tests * chore: remove unstable flag * docs: update test instructions to run with docker locally * chore: update float4 tests * chore: improve decoder logic to correctly parse geometric types * chore: add more tests for decoders * chore: update file style with denot fmt * chore: log decoding error * chore: fix file lint issues * chore: remove usntable flag from docs
1 parent d7a8b0c commit da5509e

20 files changed

+677
-394
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ a local testing environment, as shown in the following steps:
137137
use the local testing settings specified in `tests/config.json`, instead of
138138
the CI settings
139139
3. Run the tests manually by using the command\
140-
`deno test --unstable -A`
140+
`deno test -A`
141141

142142
## Deno compatibility
143143

client.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,7 @@ export abstract class QueryClient {
6767

6868
#assertOpenConnection() {
6969
if (this.#terminated) {
70-
throw new Error(
71-
"Connection to the database has been terminated",
72-
);
70+
throw new Error("Connection to the database has been terminated");
7371
}
7472
}
7573

@@ -243,9 +241,7 @@ export abstract class QueryClient {
243241
async #executeQuery<T>(
244242
_query: Query<ResultType.OBJECT>,
245243
): Promise<QueryObjectResult<T>>;
246-
async #executeQuery(
247-
query: Query<ResultType>,
248-
): Promise<QueryResult> {
244+
async #executeQuery(query: Query<ResultType>): Promise<QueryResult> {
249245
return await this.#connection.query(query);
250246
}
251247

@@ -397,9 +393,7 @@ export abstract class QueryClient {
397393
query: TemplateStringsArray,
398394
...args: unknown[]
399395
): Promise<QueryObjectResult<T>>;
400-
async queryObject<
401-
T = Record<string, unknown>,
402-
>(
396+
async queryObject<T = Record<string, unknown>>(
403397
query_template_or_config:
404398
| string
405399
| QueryObjectOptions

client/error.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,8 @@ export class PostgresError extends Error {
2525
}
2626

2727
export class TransactionError extends Error {
28-
constructor(
29-
transaction_name: string,
30-
cause: PostgresError,
31-
) {
32-
super(
33-
`The transaction "${transaction_name}" has been aborted`,
34-
{ cause },
35-
);
28+
constructor(transaction_name: string, cause: PostgresError) {
29+
super(`The transaction "${transaction_name}" has been aborted`, { cause });
3630
this.name = "TransactionError";
3731
}
3832
}

connection/connection.ts

Lines changed: 32 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,7 @@ function assertSuccessfulAuthentication(auth_message: Message) {
8686
throw new PostgresError(parseNoticeMessage(auth_message));
8787
}
8888

89-
if (
90-
auth_message.type !== INCOMING_AUTHENTICATION_MESSAGES.AUTHENTICATION
91-
) {
89+
if (auth_message.type !== INCOMING_AUTHENTICATION_MESSAGES.AUTHENTICATION) {
9290
throw new Error(`Unexpected auth response: ${auth_message.type}.`);
9391
}
9492

@@ -118,10 +116,7 @@ export class Connection {
118116
#onDisconnection: () => Promise<void>;
119117
#packetWriter = new PacketWriter();
120118
#pid?: number;
121-
#queryLock: DeferredStack<undefined> = new DeferredStack(
122-
1,
123-
[undefined],
124-
);
119+
#queryLock: DeferredStack<undefined> = new DeferredStack(1, [undefined]);
125120
// TODO
126121
// Find out what the secret key is for
127122
#secretKey?: number;
@@ -180,10 +175,7 @@ export class Connection {
180175
async #serverAcceptsTLS(): Promise<boolean> {
181176
const writer = this.#packetWriter;
182177
writer.clear();
183-
writer
184-
.addInt32(8)
185-
.addInt32(80877103)
186-
.join();
178+
writer.addInt32(8).addInt32(80877103).join();
187179

188180
await this.#bufWriter.write(writer.flush());
189181
await this.#bufWriter.flush();
@@ -216,16 +208,20 @@ export class Connection {
216208
// TODO: recognize other parameters
217209
writer.addCString("user").addCString(this.#connection_params.user);
218210
writer.addCString("database").addCString(this.#connection_params.database);
219-
writer.addCString("application_name").addCString(
220-
this.#connection_params.applicationName,
221-
);
211+
writer
212+
.addCString("application_name")
213+
.addCString(this.#connection_params.applicationName);
222214

223215
const connection_options = Object.entries(this.#connection_params.options);
224216
if (connection_options.length > 0) {
225217
// The database expects options in the --key=value
226-
writer.addCString("options").addCString(
227-
connection_options.map(([key, value]) => `--${key}=${value}`).join(" "),
228-
);
218+
writer
219+
.addCString("options")
220+
.addCString(
221+
connection_options
222+
.map(([key, value]) => `--${key}=${value}`)
223+
.join(" "),
224+
);
229225
}
230226

231227
// terminator after all parameters were writter
@@ -236,10 +232,7 @@ export class Connection {
236232

237233
writer.clear();
238234

239-
const finalBuffer = writer
240-
.addInt32(bodyLength)
241-
.add(bodyBuffer)
242-
.join();
235+
const finalBuffer = writer.addInt32(bodyLength).add(bodyBuffer).join();
243236

244237
await this.#bufWriter.write(finalBuffer);
245238
await this.#bufWriter.flush();
@@ -248,7 +241,7 @@ export class Connection {
248241
}
249242

250243
async #openConnection(options: ConnectOptions) {
251-
// @ts-ignore This will throw in runtime if the options passed to it are socket related and deno is running
244+
// @ts-expect-error This will throw in runtime if the options passed to it are socket related and deno is running
252245
// on stable
253246
this.#conn = await Deno.connect(options);
254247
this.#bufWriter = new BufWriter(this.#conn);
@@ -257,9 +250,7 @@ export class Connection {
257250

258251
async #openSocketConnection(path: string, port: number) {
259252
if (Deno.build.os === "windows") {
260-
throw new Error(
261-
"Socket connection is only available on UNIX systems",
262-
);
253+
throw new Error("Socket connection is only available on UNIX systems");
263254
}
264255
const socket = await Deno.stat(path);
265256

@@ -296,10 +287,7 @@ export class Connection {
296287
this.connected = false;
297288
this.#packetWriter = new PacketWriter();
298289
this.#pid = undefined;
299-
this.#queryLock = new DeferredStack(
300-
1,
301-
[undefined],
302-
);
290+
this.#queryLock = new DeferredStack(1, [undefined]);
303291
this.#secretKey = undefined;
304292
this.#tls = undefined;
305293
this.#transport = undefined;
@@ -319,14 +307,10 @@ export class Connection {
319307
this.#closeConnection();
320308

321309
const {
322-
hostname,
323310
host_type,
311+
hostname,
324312
port,
325-
tls: {
326-
enabled: tls_enabled,
327-
enforce: tls_enforced,
328-
caCertificates,
329-
},
313+
tls: { caCertificates, enabled: tls_enabled, enforce: tls_enforced },
330314
} = this.#connection_params;
331315

332316
if (host_type === "socket") {
@@ -341,12 +325,11 @@ export class Connection {
341325

342326
if (tls_enabled) {
343327
// If TLS is disabled, we don't even try to connect.
344-
const accepts_tls = await this.#serverAcceptsTLS()
345-
.catch((e) => {
346-
// Make sure to close the connection if the TLS validation throws
347-
this.#closeConnection();
348-
throw e;
349-
});
328+
const accepts_tls = await this.#serverAcceptsTLS().catch((e) => {
329+
// Make sure to close the connection if the TLS validation throws
330+
this.#closeConnection();
331+
throw e;
332+
});
350333

351334
// https://www.postgresql.org/docs/14/protocol-flow.html#id-1.10.5.7.11
352335
if (accepts_tls) {
@@ -657,24 +640,18 @@ export class Connection {
657640
`Unexpected message in SASL finalization: ${maybe_sasl_continue.type}`,
658641
);
659642
}
660-
const sasl_final = utf8.decode(
661-
maybe_sasl_final.reader.readAllBytes(),
662-
);
643+
const sasl_final = utf8.decode(maybe_sasl_final.reader.readAllBytes());
663644
await client.receiveResponse(sasl_final);
664645

665646
// Return authentication result
666647
return this.#readMessage();
667648
}
668649

669-
async #simpleQuery(
670-
query: Query<ResultType.ARRAY>,
671-
): Promise<QueryArrayResult>;
650+
async #simpleQuery(query: Query<ResultType.ARRAY>): Promise<QueryArrayResult>;
672651
async #simpleQuery(
673652
query: Query<ResultType.OBJECT>,
674653
): Promise<QueryObjectResult>;
675-
async #simpleQuery(
676-
query: Query<ResultType>,
677-
): Promise<QueryResult> {
654+
async #simpleQuery(query: Query<ResultType>): Promise<QueryResult> {
678655
this.#packetWriter.clear();
679656

680657
const buffer = this.#packetWriter.addCString(query.text).flush(0x51);
@@ -757,9 +734,7 @@ export class Connection {
757734
await this.#bufWriter.write(buffer);
758735
}
759736

760-
async #appendArgumentsToMessage<T extends ResultType>(
761-
query: Query<T>,
762-
) {
737+
async #appendArgumentsToMessage<T extends ResultType>(query: Query<T>) {
763738
this.#packetWriter.clear();
764739

765740
const hasBinaryArgs = query.args.some((arg) => arg instanceof Uint8Array);
@@ -830,10 +805,7 @@ export class Connection {
830805

831806
// TODO
832807
// Rename process function to a more meaningful name and move out of class
833-
async #processErrorUnsafe(
834-
msg: Message,
835-
recoverable = true,
836-
) {
808+
async #processErrorUnsafe(msg: Message, recoverable = true) {
837809
const error = new PostgresError(parseNoticeMessage(msg));
838810
if (recoverable) {
839811
let maybe_ready_message = await this.#readMessage();
@@ -930,15 +902,9 @@ export class Connection {
930902
return result;
931903
}
932904

933-
async query(
934-
query: Query<ResultType.ARRAY>,
935-
): Promise<QueryArrayResult>;
936-
async query(
937-
query: Query<ResultType.OBJECT>,
938-
): Promise<QueryObjectResult>;
939-
async query(
940-
query: Query<ResultType>,
941-
): Promise<QueryResult> {
905+
async query(query: Query<ResultType.ARRAY>): Promise<QueryArrayResult>;
906+
async query(query: Query<ResultType.OBJECT>): Promise<QueryObjectResult>;
907+
async query(query: Query<ResultType>): Promise<QueryResult> {
942908
if (!this.connected) {
943909
await this.startup(true);
944910
}

0 commit comments

Comments
 (0)