Skip to content

Commit 6488763

Browse files
committed
Remove 'execute' method
1 parent da79aa2 commit 6488763

File tree

5 files changed

+76
-110
lines changed

5 files changed

+76
-110
lines changed

CHANGES.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
In the next release ...
22

3+
- The `execute` method has been removed.
4+
35
- The query options now supports an optional `transform` parameter which takes
46
a column name input, allowing the transformation of column names into for
57
example camelcase.
68

7-
- The `query` method now accepts a `QueryParameter` object as the
9+
- The `query` method now accepts a `Query` object as the
810
first value, in addition to the query string, making it easier to
911
make a query with additional configuration.
1012

src/client.ts

Lines changed: 50 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import * as logger from './logging';
99

1010
import { postgresqlErrorCodes } from './errors';
1111
import { Queue } from './queue';
12-
import { Query, QueryParameter } from './query';
12+
import { Query } from './query';
1313

1414
import { ConnectionOptions, TLSSocket, connect as tls, createSecureContext } from 'tls';
1515

@@ -515,7 +515,7 @@ export class Client {
515515
}
516516

517517
prepare<T = ResultRecord>(
518-
text: QueryParameter | string,
518+
text: Query | string,
519519
name?: string,
520520
types?: DataType[]): Promise<PreparedStatement<T>> {
521521

@@ -592,10 +592,10 @@ export class Client {
592592
/**
593593
* Send a query to the database.
594594
*
595-
* The query string is given as the first argument, or pass a {@link QueryParameter}
595+
* The query string is given as the first argument, or pass a {@link Query}
596596
* object which provides more control.
597597
*
598-
* @param text - The query string, or pass a {@link QueryParameter}
598+
* @param text - The query string, or pass a {@link Query}
599599
* object which provides more control (including streaming values into a socket).
600600
* @param values - The query parameters, corresponding to $1, $2, etc.
601601
* @param types - Allows making the database native type explicit for some or all
@@ -605,70 +605,23 @@ export class Client {
605605
* @returns A promise for the query results.
606606
*/
607607
query<T = ResultRecord>(
608-
text: QueryParameter | string,
608+
text: Query | string,
609609
values?: any[],
610610
types?: DataType[],
611611
format?: DataFormat | DataFormat[],
612612
streams?: Record<string, Writable>):
613613
ResultIterator<T> {
614-
const query = new Query(
615-
text,
616-
values, {
617-
types: types,
618-
format: format,
619-
streams: streams,
620-
});
621-
return this.execute<T>(query);
622-
}
623-
624-
private bindAndExecute(
625-
info: RowDataHandlerInfo,
626-
bind: Bind,
627-
types: DataType[]) {
628-
try {
629-
this.writer.bind(
630-
bind.name,
631-
bind.portal,
632-
bind.format,
633-
bind.values,
634-
types
635-
);
636-
} catch (error) {
637-
info.handler.callback(error as Error);
638-
return;
639-
}
640-
641-
this.bindQueue.push(info);
642-
this.writer.execute(bind.portal);
643-
this.cleanupQueue.push(Cleanup.Bind);
644-
645-
if (bind.close) {
646-
this.writer.close(bind.name, 'S');
647-
this.closeHandlerQueue.push(null);
648-
this.cleanupQueue.push(Cleanup.Close);
649-
}
650-
651-
this.writer.sync();
652-
this.errorHandlerQueue.push(
653-
(error) => { info.handler.callback(error); }
654-
);
655-
this.cleanupQueue.push(Cleanup.ErrorHandler);
656-
this.send();
657-
}
614+
const query = typeof text === 'string' ? {text} : text;
658615

659-
execute<T = ResultRecord>(query: Query): ResultIterator<T> {
660616
if (this.closed && !this.connecting) {
661617
throw new Error('Connection is closed.');
662618
}
663619

664-
const text = query.text;
665-
const values = query.values || [];
666-
const options = query.options;
667-
const format = options?.format;
668-
const types = options?.types;
669-
const streams = options?.streams;
670-
const portal = options?.portal || '';
671-
const result = makeResult<T>(options?.transform);
620+
format = format || query?.format;
621+
types = types || query?.types;
622+
streams = streams || query?.streams;
623+
const portal = query?.portal || '';
624+
const result = makeResult<T>(query?.transform);
672625

673626
const descriptionHandler = (description: RowDescription) => {
674627
result.nameHandler(description.names);
@@ -680,13 +633,13 @@ export class Client {
680633
};
681634

682635
if (values && values.length) {
683-
const name = (options?.name) || (
636+
const name = (query?.name) || (
684637
(this.config.preparedStatementPrefix ||
685638
defaults.preparedStatementPrefix) + (
686639
this.nextPreparedStatementId++
687640
));
688641

689-
this.writer.parse(name, text, types || []);
642+
this.writer.parse(name, query.text, types || []);
690643
this.writer.describe(name, 'S');
691644
this.preFlightQueue.push({
692645
descriptionHandler: descriptionHandler,
@@ -701,8 +654,8 @@ export class Client {
701654
});
702655
this.cleanupQueue.push(Cleanup.PreFlight);
703656
} else {
704-
const name = (options ? options.name : undefined) || '';
705-
this.writer.parse(name, text);
657+
const name = query.name || '';
658+
this.writer.parse(name, query.text);
706659
this.writer.bind(name, portal);
707660
this.bindQueue.push(null);
708661
this.writer.describe(portal, 'P');
@@ -738,6 +691,41 @@ export class Client {
738691
return result.iterator;
739692
}
740693

694+
private bindAndExecute(
695+
info: RowDataHandlerInfo,
696+
bind: Bind,
697+
types: DataType[]) {
698+
try {
699+
this.writer.bind(
700+
bind.name,
701+
bind.portal,
702+
bind.format,
703+
bind.values,
704+
types
705+
);
706+
} catch (error) {
707+
info.handler.callback(error as Error);
708+
return;
709+
}
710+
711+
this.bindQueue.push(info);
712+
this.writer.execute(bind.portal);
713+
this.cleanupQueue.push(Cleanup.Bind);
714+
715+
if (bind.close) {
716+
this.writer.close(bind.name, 'S');
717+
this.closeHandlerQueue.push(null);
718+
this.cleanupQueue.push(Cleanup.Close);
719+
}
720+
721+
this.writer.sync();
722+
this.errorHandlerQueue.push(
723+
(error) => { info.handler.callback(error); }
724+
);
725+
this.cleanupQueue.push(Cleanup.ErrorHandler);
726+
this.send();
727+
}
728+
741729
private handleError(error: Error): boolean {
742730
while (true) {
743731
switch (this.cleanupQueue.shiftMaybe()) {

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export * from './client';
1+
export { Client, PreparedStatement } from './client';
22
export {
33
DataFormat,
44
DataType,

src/query.ts

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -24,27 +24,4 @@ export interface QueryOptions {
2424
* to the {@link Client.query} method.
2525
* @interface
2626
*/
27-
export type QueryParameter = Partial<QueryOptions> & { text: string };
28-
29-
/**
30-
* A complete query object, ready to send to the database.
31-
*/
32-
export class Query {
33-
public readonly text: string;
34-
public readonly values?: any[];
35-
public readonly options?: Partial<QueryOptions>;
36-
37-
constructor(
38-
text: QueryParameter | string,
39-
values?: any[],
40-
options?: Partial<QueryOptions>
41-
) {
42-
this.values = values;
43-
this.options = options;
44-
if (typeof text === 'string') {
45-
this.text = text;
46-
} else {
47-
({ text: this.text, ...this.options } = {...this.options, ...text});
48-
}
49-
}
50-
}
27+
export type Query = Partial<QueryOptions> & { text: string };

test/client.test.ts

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import {
66
DataFormat,
77
DataType,
88
PreparedStatement,
9-
Query,
109
Result,
1110
ResultIterator,
1211
} from '../src/index';
@@ -20,6 +19,11 @@ const enum TestQuery {
2019
Array
2120
}
2221

22+
interface Query {
23+
text: string;
24+
values?: any[]
25+
}
26+
2327
function makeRandomizer(seed: number) {
2428
return (n: number): number => {
2529
const x = Math.sin(seed++) * 10000;
@@ -40,7 +44,7 @@ function unsafeToSimpleQuery(query: Query) {
4044
const param = params[i];
4145
text = text.replace('$' + (i + 1), param);
4246
}
43-
return new Query(text);
47+
return {text};
4448
}
4549

4650
function testSelect(
@@ -52,18 +56,18 @@ function testSelect(
5256
switch (testQuery) {
5357
case TestQuery.Array: return {
5458
name: 'Array',
55-
query: new Query(
59+
query: {
5660
// tslint:disable-next-line
57-
'select (select array_agg(i) from generate_series(1, 100) as s(i)) from generate_series(1, 100)'
58-
)
61+
text: 'select (select array_agg(i) from generate_series(1, 100) as s(i)) from generate_series(1, 100)'
62+
}
5963
};
6064
case TestQuery.PgType: return {
6165
name: 'PgType',
62-
query: new Query(
66+
query: {
6367
// tslint:disable-next-line
64-
'select typname, typnamespace, typowner, typlen, typbyval, typcategory, typispreferred, typisdefined, typdelim, typrelid, typelem, typarray from pg_type where typtypmod = $1 and typisdefined = $2',
65-
[-1, true]
66-
)
68+
text: 'select typname, typnamespace, typowner, typlen, typbyval, typcategory, typispreferred, typisdefined, typdelim, typrelid, typelem, typarray from pg_type where typtypmod = $1 and typisdefined = $2',
69+
values: [-1, true]
70+
}
6771
};
6872
}
6973
})();
@@ -94,7 +98,7 @@ function testSelect(
9498
const promises: Promise<void>[] = [];
9599

96100
while (i--) {
97-
const p = client.execute(query).then(
101+
const p = client.query(query.text, query.values).then(
98102
(result: Result) => {
99103
acknowledged += 1;
100104
results += result.rows.length;
@@ -199,22 +203,19 @@ describe('Timeout', () => {
199203
describe('Query', () => {
200204
testWithClient('Without parameters', async (client) => {
201205
expect.assertions(1);
202-
const query = new Query('select 1');
203-
const result = await client.execute(query);
206+
const result = await client.query('select 1');
204207
expect(result.rows.length).toEqual(1);
205208
});
206209

207210
testWithClient('With parameters', async (client) => {
208211
expect.assertions(1);
209-
const query = new Query('select $1::int', [1]);
210-
const result = await client.execute(query);
212+
const result = await client.query('select $1::int', [1]);
211213
expect(result.rows.length).toEqual(1);
212214
});
213215

214216
testWithClient('Named portal', async (client) => {
215217
expect.assertions(1);
216-
const query = new Query('select $1::int', [1]);
217-
const result = await client.execute(query);
218+
const result = await client.query('select $1::int', [1]);
218219
expect(result.rows.length).toEqual(1);
219220
});
220221

@@ -285,12 +286,10 @@ describe('Query', () => {
285286
const address = server.address() as AddressInfo;
286287
const socket = new Socket();
287288
socket.connect(address.port);
288-
const query = new Query(
289-
'select upper($1)::bytea as col',
290-
[Buffer.from(s)],
291-
{ streams: { col: socket } }
292-
);
293-
await client.execute(query);
289+
await client.query({
290+
text: 'select upper($1)::bytea as col',
291+
streams: { col: socket }
292+
}, [Buffer.from(s)]);
294293

295294
// At this point we're done really done streaming, and how can
296295
// we know when that happens?

0 commit comments

Comments
 (0)