Skip to content

Commit 1fc06ba

Browse files
committed
improve handling of large results
1 parent e154ecf commit 1fc06ba

2 files changed

Lines changed: 1049 additions & 1024 deletions

File tree

src/connection.ts

Lines changed: 114 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import { EventEmitter } from "events";
1+
import {EventEmitter} from "events";
22
import {
3-
MapiConfig,
4-
MapiConnection,
5-
parseMapiUri,
6-
createMapiConfig,
7-
HandShakeOption,
8-
QueryResult,
9-
QueryStream,
3+
MapiConfig,
4+
MapiConnection,
5+
parseMapiUri,
6+
createMapiConfig,
7+
HandShakeOption,
8+
QueryResult,
9+
QueryStream,
1010
} from "./mapi";
1111
import PrepareStatement from "./PrepareStatement";
1212

@@ -18,108 +18,112 @@ type MAPI_URI = string;
1818
type ConnectCallback = (err?: Error) => void;
1919

2020
class Connection extends EventEmitter {
21-
autoCommit?: boolean;
22-
replySize?: number;
23-
sizeHeader?: boolean;
24-
mapi: MapiConnection;
25-
26-
constructor(params: MapiConfig | MAPI_URI) {
27-
super();
28-
const config =
29-
typeof params === "string"
30-
? createMapiConfig(parseMapiUri(params))
31-
: createMapiConfig(params);
32-
this.mapi = new MapiConnection(config);
33-
this.autoCommit = config.autoCommit;
34-
this.replySize = config.replySize;
35-
}
36-
37-
connect(callback?: ConnectCallback): Promise<boolean> {
38-
const options = [
39-
new HandShakeOption(
40-
1,
41-
"auto_commit",
42-
this.autoCommit,
43-
this.setAutocommit
44-
),
45-
new HandShakeOption(2, "reply_size", this.replySize, this.setReplySize),
46-
new HandShakeOption(3, "size_header", true, this.setSizeHeader),
47-
new HandShakeOption(
48-
5,
49-
"time_zone",
50-
new Date().getTimezoneOffset() * 60,
51-
this.setTimezone
52-
),
53-
];
54-
const mapi = this.mapi;
55-
return new Promise(async function (resolve, reject) {
56-
try {
57-
await mapi.connect(options);
58-
resolve(mapi.ready());
59-
if (callback) callback();
60-
} catch (err) {
61-
reject(err);
62-
if (callback) callback(err);
63-
}
64-
});
65-
}
66-
67-
close(): Promise<boolean> {
68-
return this.mapi.disconnect();
69-
}
70-
71-
commit(): Promise<void> {
72-
return this.execute("COMMIT");
73-
}
74-
75-
private command(str: string): Promise<any> {
76-
return this.mapi.request(str);
77-
}
78-
79-
execute(sql: string, stream: boolean = false): Promise<any> {
80-
const query = `s${sql};\n`;
81-
if (stream && this.replySize !== -1) this.setReplySize(-1);
82-
return this.mapi.request(query, stream);
83-
}
84-
85-
async prepare(sql: string): Promise<PrepareStatement> {
86-
const prepSQL = `PREPARE ${sql}`;
87-
const res = await this.execute(prepSQL);
88-
return new PrepareStatement(res, this.mapi);
89-
}
90-
91-
setAutocommit(v: boolean): Promise<boolean> {
92-
const cmd = `Xauto_commit ${Number(v)}`;
93-
return this.command(cmd).then(() => {
94-
this.autoCommit = v;
95-
return this.autoCommit;
96-
});
97-
}
98-
99-
setReplySize(v: number): Promise<number> {
100-
const cmd = `Xreply_size ${Number(v)}`;
101-
return this.command(cmd).then(() => {
102-
this.replySize = Number(v);
103-
return this.replySize;
104-
});
105-
}
106-
107-
setSizeHeader(v: boolean): Promise<boolean> {
108-
const cmd = `Xsizeheader ${Number(v)}`;
109-
return this.command(cmd).then(() => {
110-
this.sizeHeader = v;
111-
return this.sizeHeader;
112-
});
113-
}
114-
115-
setTimezone(sec: number): Promise<any> {
116-
const qry = `SET TIME ZONE INTERVAL '${sec}' SECOND`;
117-
return this.execute(qry);
118-
}
119-
120-
rollback(): Promise<void> {
121-
return this.execute("ROLLBACK");
122-
}
21+
autoCommit?: boolean;
22+
replySize?: number;
23+
sizeHeader?: boolean;
24+
mapi: MapiConnection;
25+
26+
constructor(params: MapiConfig | MAPI_URI) {
27+
super();
28+
const config =
29+
typeof params === "string"
30+
? createMapiConfig(parseMapiUri(params))
31+
: createMapiConfig(params);
32+
this.mapi = new MapiConnection(config);
33+
this.autoCommit = config.autoCommit;
34+
this.replySize = config.replySize;
35+
}
36+
37+
connect(callback?: ConnectCallback): Promise<boolean> {
38+
const options = [
39+
new HandShakeOption(
40+
1,
41+
"auto_commit",
42+
this.autoCommit,
43+
this.setAutocommit
44+
),
45+
new HandShakeOption(2, "reply_size", this.replySize, this.setReplySize),
46+
new HandShakeOption(3, "size_header", true, this.setSizeHeader),
47+
new HandShakeOption(
48+
5,
49+
"time_zone",
50+
new Date().getTimezoneOffset() * 60,
51+
this.setTimezone
52+
),
53+
];
54+
const mapi = this.mapi;
55+
return new Promise(async function (resolve, reject) {
56+
try {
57+
await mapi.connect(options);
58+
resolve(mapi.ready());
59+
if (callback) callback();
60+
} catch (err) {
61+
reject(err);
62+
if (callback) callback(err);
63+
}
64+
});
65+
}
66+
67+
close(): Promise<boolean> {
68+
return this.mapi.disconnect();
69+
}
70+
71+
commit(): Promise<void> {
72+
return this.execute("COMMIT");
73+
}
74+
75+
private command(str: string): Promise<any> {
76+
return this.mapi.request(str);
77+
}
78+
79+
destroy() {
80+
return this.mapi.destroy();
81+
}
82+
83+
execute(sql: string, stream: boolean = false): Promise<any> {
84+
const query = `s${sql};\n`;
85+
if (stream && this.replySize !== -1) this.setReplySize(-1);
86+
return this.mapi.request(query, stream);
87+
}
88+
89+
async prepare(sql: string): Promise<PrepareStatement> {
90+
const prepSQL = `PREPARE ${sql}`;
91+
const res = await this.execute(prepSQL);
92+
return new PrepareStatement(res, this.mapi);
93+
}
94+
95+
setAutocommit(v: boolean): Promise<boolean> {
96+
const cmd = `Xauto_commit ${Number(v)}`;
97+
return this.command(cmd).then(() => {
98+
this.autoCommit = v;
99+
return this.autoCommit;
100+
});
101+
}
102+
103+
setReplySize(v: number): Promise<number> {
104+
const cmd = `Xreply_size ${Number(v)}`;
105+
return this.command(cmd).then(() => {
106+
this.replySize = Number(v);
107+
return this.replySize;
108+
});
109+
}
110+
111+
setSizeHeader(v: boolean): Promise<boolean> {
112+
const cmd = `Xsizeheader ${Number(v)}`;
113+
return this.command(cmd).then(() => {
114+
this.sizeHeader = v;
115+
return this.sizeHeader;
116+
});
117+
}
118+
119+
setTimezone(sec: number): Promise<any> {
120+
const qry = `SET TIME ZONE INTERVAL '${sec}' SECOND`;
121+
return this.execute(qry);
122+
}
123+
124+
rollback(): Promise<void> {
125+
return this.execute("ROLLBACK");
126+
}
123127
}
124128

125129
export default Connection;

0 commit comments

Comments
 (0)