Skip to content

Commit 533a836

Browse files
committed
WIP: Convert src to use Napi::Deferred::Promises
1 parent 1609684 commit 533a836

17 files changed

+922
-948
lines changed

lib/sqlite3.d.ts

+182-42
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,9 @@ export const LIMIT_TRIGGER_DEPTH: number;
5959
export const LIMIT_WORKER_THREADS: number;
6060

6161
export const cached: {
62-
Database(filename: string, callback?: (this: Database, err: Error | null) => void): Database;
63-
Database(filename: string, mode?: number, callback?: (this: Database, err: Error | null) => void): Database;
62+
Database: {
63+
create: (filename: string, mode?: number) => Promise<Database>
64+
};
6465
};
6566

6667
export interface RunResult extends Statement {
@@ -69,60 +70,52 @@ export interface RunResult extends Statement {
6970
}
7071

7172
export class Statement extends events.EventEmitter {
72-
bind(callback?: (err: Error | null) => void): this;
73-
bind(...params: any[]): this;
73+
lastID: number;
74+
changes: number;
75+
static create(database: Database, sql: string): Promise<Statement>;
76+
bind(): Promise<Statement>;
77+
bind(...params: any[]): Promise<Statement>;
7478

75-
reset(callback?: (err: null) => void): this;
79+
reset(): Promise<Statement>;
7680

77-
finalize(callback?: (err: Error) => void): Database;
81+
finalize(): Promise<Database>;
7882

79-
run(callback?: (err: Error | null) => void): this;
80-
run(params: any, callback?: (this: RunResult, err: Error | null) => void): this;
81-
run(...params: any[]): this;
83+
run(...params: any[]): Promise<Statement>;
8284

83-
get<T>(callback?: (err: Error | null, row?: T) => void): this;
84-
get<T>(params: any, callback?: (this: RunResult, err: Error | null, row?: T) => void): this;
85-
get(...params: any[]): this;
85+
get<T>(...params: any[]): T;
8686

87-
all<T>(callback?: (err: Error | null, rows: T[]) => void): this;
88-
all<T>(params: any, callback?: (this: RunResult, err: Error | null, rows: T[]) => void): this;
89-
all(...params: any[]): this;
87+
all<T>(params?: any, callback?: (this: RunResult, err: Error | null, rows: T[]) => void): Promise<T[]>;
9088

91-
each<T>(callback?: (err: Error | null, row: T) => void, complete?: (err: Error | null, count: number) => void): this;
92-
each<T>(params: any, callback?: (this: RunResult, err: Error | null, row: T) => void, complete?: (err: Error | null, count: number) => void): this;
93-
each(...params: any[]): this;
89+
// TODO: Async generator!
90+
// each<T>(callback?: (err: Error | null, row: T) => void, complete?: (err: Error | null, count: number) => void): this;
91+
// each<T>(params: any, callback?: (this: RunResult, err: Error | null, row: T) => void, complete?: (err: Error | null, count: number) => void): this;
92+
// each(...params: any[]): this;
9493
}
9594

9695
export class Database extends events.EventEmitter {
97-
constructor(filename: string, callback?: (err: Error | null) => void);
98-
constructor(filename: string, mode?: number, callback?: (err: Error | null) => void);
96+
private constructor(filename: string);
97+
private constructor(filename: string, mode?: number);
9998

100-
close(callback?: (err: Error | null) => void): void;
99+
static create(filename: string, mode?: number): Promise<Database>;
101100

102-
run(sql: string, callback?: (this: RunResult, err: Error | null) => void): this;
103-
run(sql: string, params: any, callback?: (this: RunResult, err: Error | null) => void): this;
104-
run(sql: string, ...params: any[]): this;
101+
close(): Promise<void>;
105102

106-
get<T>(sql: string, callback?: (this: Statement, err: Error | null, row: T) => void): this;
107-
get<T>(sql: string, params: any, callback?: (this: Statement, err: Error | null, row: T) => void): this;
108-
get(sql: string, ...params: any[]): this;
103+
run(sql: string, ...params: any[]): Promise<Statement>;
109104

110-
all<T>(sql: string, callback?: (this: Statement, err: Error | null, rows: T[]) => void): this;
111-
all<T>(sql: string, params: any, callback?: (this: Statement, err: Error | null, rows: T[]) => void): this;
112-
all(sql: string, ...params: any[]): this;
105+
get<T>(sql: string, ...params: any[]): Promise<T>;
113106

114-
each<T>(sql: string, callback?: (this: Statement, err: Error | null, row: T) => void, complete?: (err: Error | null, count: number) => void): this;
115-
each<T>(sql: string, params: any, callback?: (this: Statement, err: Error | null, row: T) => void, complete?: (err: Error | null, count: number) => void): this;
116-
each(sql: string, ...params: any[]): this;
107+
all<T>(sql: string, ...params: any[]): Promise<T[]>;
117108

118-
exec(sql: string, callback?: (this: Statement, err: Error | null) => void): this;
109+
// each<T>(sql: string, callback?: (this: Statement, err: Error | null, row: T) => void, complete?: (err: Error | null, count: number) => void): this;
110+
// each<T>(sql: string, params: any, callback?: (this: Statement, err: Error | null, row: T) => void, complete?: (err: Error | null, count: number) => void): this;
111+
// each(sql: string, ...params: any[]): this;
119112

120-
prepare(sql: string, callback?: (this: Statement, err: Error | null) => void): Statement;
121-
prepare(sql: string, params: any, callback?: (this: Statement, err: Error | null) => void): Statement;
122-
prepare(sql: string, ...params: any[]): Statement;
113+
exec(sql: string): Promise<Database>;
123114

124-
serialize(callback?: () => void): void;
125-
parallelize(callback?: () => void): void;
115+
prepare(sql: string, ...params: any[]): Promise<Statement>;
116+
117+
serialize<T>(callback?: () => Promise<T>): Promise<T>;
118+
parallelize<T>(callback?: () => Promise<T>): Promise<T>;
126119

127120
on(event: "trace", listener: (sql: string) => void): this;
128121
on(event: "profile", listener: (sql: string, time: number) => void): this;
@@ -134,11 +127,158 @@ export class Database extends events.EventEmitter {
134127
configure(option: "busyTimeout", value: number): void;
135128
configure(option: "limit", id: number, value: number): void;
136129

137-
loadExtension(filename: string, callback?: (err: Error | null) => void): this;
130+
loadExtension(filename: string): Promise<Database>;
138131

139-
wait(callback?: (param: null) => void): this;
132+
wait(): Promise<Database>;
140133

141134
interrupt(): void;
135+
136+
backup(path: string): Promise<Backup>
137+
backup(filename: string, destDbName: string, sourceDbName: string, filenameIsDest: boolean): Promise<Backup>
138+
}
139+
140+
/**
141+
*
142+
* A class for managing an sqlite3_backup object. For consistency
143+
* with other node-sqlite3 classes, it maintains an internal queue
144+
* of calls.
145+
*
146+
* Intended usage from node:
147+
*
148+
* var db = new sqlite3.Database('live.db');
149+
* var backup = db.backup('backup.db');
150+
* ...
151+
* // in event loop, move backup forward when we have time.
152+
* if (backup.idle) { backup.step(NPAGES); }
153+
* if (backup.completed) { ... success ... }
154+
* if (backup.failed) { ... sadness ... }
155+
* // do other work in event loop - fine to modify live.db
156+
* ...
157+
*
158+
* Here is how sqlite's backup api is exposed:
159+
*
160+
* - `sqlite3_backup_init`: This is implemented as
161+
* `db.backup(filename, [callback])` or
162+
* `db.backup(filename, destDbName, sourceDbName, filenameIsDest, [callback])`.
163+
* - `sqlite3_backup_step`: `backup.step(pages, [callback])`.
164+
* - `sqlite3_backup_finish`: `backup.finish([callback])`.
165+
* - `sqlite3_backup_remaining`: `backup.remaining`.
166+
* - `sqlite3_backup_pagecount`: `backup.pageCount`.
167+
*
168+
* There are the following read-only properties:
169+
*
170+
* - `backup.completed` is set to `true` when the backup
171+
* succeeeds.
172+
* - `backup.failed` is set to `true` when the backup
173+
* has a fatal error.
174+
* - `backup.message` is set to the error string
175+
* the backup has a fatal error.
176+
* - `backup.idle` is set to `true` when no operation
177+
* is currently in progress or queued for the backup.
178+
* - `backup.remaining` is an integer with the remaining
179+
* number of pages after the last call to `backup.step`
180+
* (-1 if `step` not yet called).
181+
* - `backup.pageCount` is an integer with the total number
182+
* of pages measured during the last call to `backup.step`
183+
* (-1 if `step` not yet called).
184+
*
185+
* There is the following writable property:
186+
*
187+
* - `backup.retryErrors`: an array of sqlite3 error codes
188+
* that are treated as non-fatal - meaning, if they occur,
189+
* backup.failed is not set, and the backup may continue.
190+
* By default, this is `[sqlite3.BUSY, sqlite3.LOCKED]`.
191+
*
192+
* The `db.backup(filename, [callback])` shorthand is sufficient
193+
* for making a backup of a database opened by node-sqlite3. If
194+
* using attached or temporary databases, or moving data in the
195+
* opposite direction, the more complete (but daunting)
196+
* `db.backup(filename, destDbName, sourceDbName, filenameIsDest, [callback])`
197+
* signature is provided.
198+
*
199+
* A backup will finish automatically when it succeeds or a fatal
200+
* error occurs, meaning it is not necessary to call `db.finish()`.
201+
* By default, SQLITE_LOCKED and SQLITE_BUSY errors are not
202+
* treated as failures, and the backup will continue if they
203+
* occur. The set of errors that are tolerated can be controlled
204+
* by setting `backup.retryErrors`. To disable automatic
205+
* finishing and stick strictly to sqlite's raw api, set
206+
* `backup.retryErrors` to `[]`. In that case, it is necessary
207+
* to call `backup.finish()`.
208+
*
209+
* In the same way as node-sqlite3 databases and statements,
210+
* backup methods can be called safely without callbacks, due
211+
* to an internal call queue. So for example this naive code
212+
* will correctly back up a db, if there are no errors:
213+
*
214+
* var backup = db.backup('backup.db');
215+
* backup.step(-1);
216+
* backup.finish();
217+
*
218+
*/
219+
export class Backup extends events.EventEmitter {
220+
/**
221+
* `true` when the backup is idle and ready for `step()` to
222+
* be called, `false` when busy.
223+
*/
224+
readonly idle: boolean
225+
226+
/**
227+
* `true` when the backup has completed, `false` otherwise.
228+
*/
229+
readonly completed: boolean
230+
231+
/**
232+
* `true` when the backup has failed, `false` otherwise. `Backup.message`
233+
* contains the error message.
234+
*/
235+
readonly failed: boolean
236+
237+
/**
238+
* Message failure string from sqlite3_errstr() if `Backup.failed` is `true`
239+
*/
240+
readonly message: boolean
241+
242+
/**
243+
* The number of remaining pages after the last call to `step()`,
244+
* or `-1` if `step()` has never been called.
245+
*/
246+
readonly remaining: number
247+
248+
/**
249+
* The total number of pages measured during the last call to `step()`,
250+
* or `-1` if `step()` has never been called.
251+
*/
252+
readonly pageCount: number
253+
254+
255+
/**
256+
* An array of sqlite3 error codes that are treated as non-fatal -
257+
* meaning, if they occur, `Backup.failed` is not set, and the backup
258+
* may continue. By default, this is `[sqlite3.BUSY, sqlite3.LOCKED]`.
259+
*/
260+
retryErrors: number[]
261+
262+
/**
263+
* Asynchronously finalize the backup (required).
264+
*
265+
* @param callback Called when the backup is finalized.
266+
*/
267+
finish(): Promise<void>
268+
269+
/**
270+
* Asynchronously perform an incremental segment of the backup.
271+
*
272+
* Example:
273+
*
274+
* ```
275+
* backup.step(5)
276+
* ```
277+
*
278+
* @param nPages Number of pages to process (5 recommended).
279+
* @param callback Called when the step is completed.
280+
*/
281+
step(nPages: number,): Promise<void>
142282
}
143283

144284
export function verbose(): sqlite3;
@@ -202,4 +342,4 @@ export interface sqlite3 {
202342
Statement: typeof Statement;
203343
Database: typeof Database;
204344
verbose(): this;
205-
}
345+
}

0 commit comments

Comments
 (0)