Skip to content

Commit 257f1cb

Browse files
author
Michael Kornelakis
committed
add typescript example and improve types
1 parent 1ea98e1 commit 257f1cb

File tree

10 files changed

+356
-13
lines changed

10 files changed

+356
-13
lines changed

examples/README.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
Examples
2-
==================
1+
# Examples
32

43
These examples run against the [test_db](https://github.com/datacharmer/test_db) dataset. It expects the database to be named `employees` and expects the root password to be `password`.
54

@@ -8,3 +7,11 @@ To run a docker container with this data and bound to the correct port, you can
87
```
98
docker run -p 3306:3306 --name mysql_container -e MYSQL_ROOT_PASSWORD=password -d genschsa/mysql-employees
109
```
10+
11+
### Typecript
12+
13+
In the `typescript` folder there are the equivalent examples. In order to run them you can use `npm run ts-node` followed by the path of the file. So for example you can run `npm run ts-node ./examples/connection/typescript/query`
14+
15+
### Note
16+
17+
I am using `ts-node` in order to avoid including a bundler. If you try to compile the typescript files to javascript using ithe `outDir` option in `tsconfig` then you will get import errors beacuse we are pulling the `index` file form the root of the project.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export type Employee = { first_name: string, last_name: string, emp_no: number };
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import Bluebird from 'bluebird';
2+
import * as mysql from '../../../index';
3+
4+
async function runReturn() {
5+
const connection = await mysql.createConnection({
6+
user: 'root',
7+
password: 'password',
8+
database: 'employees',
9+
mysqlWrapper: (mysqlInstance: mysql.mysqlModule) => wrapMysql(mysqlInstance, 'runReturn')
10+
});
11+
12+
connection.end();
13+
}
14+
15+
async function runPromise() {
16+
const connection = await mysql.createConnection({
17+
user: 'root',
18+
password: 'password',
19+
database: 'employees',
20+
mysqlWrapper: (mysqlInstance: mysql.mysqlModule) => Bluebird.resolve(wrapMysql(mysqlInstance, 'runPromise')) as unknown as Promise<mysql.mysqlModule>
21+
});
22+
23+
connection.end();
24+
}
25+
26+
async function runCallback() {
27+
const connection = await mysql.createConnection({
28+
user: 'root',
29+
password: 'password',
30+
database: 'employees',
31+
mysqlWrapper: (mysqlInstance: mysql.mysqlModule, callback) => callback?.(null, wrapMysql(mysqlInstance, 'runCallback'))
32+
});
33+
34+
connection.end();
35+
}
36+
37+
runReturn();
38+
runPromise();
39+
runCallback();
40+
41+
42+
function wrapMysql(mysqlInstance: mysql.mysqlModule, fnName: string) {
43+
const createConnection = mysqlInstance.createConnection;
44+
45+
mysqlInstance.createConnection = function (...args) {
46+
console.log(`createConnection called in ${fnName}!`);
47+
48+
mysqlInstance.createConnection = createConnection;
49+
50+
return createConnection(...args);
51+
}
52+
53+
return mysqlInstance;
54+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import * as mysql from '../../../index';
2+
import { Employee } from './employee';
3+
4+
async function run() {
5+
let connection: mysql.Connection;
6+
7+
mysql.createConnection({
8+
user: 'root',
9+
password: 'password',
10+
database: 'employees'
11+
}).then((conn) => {
12+
connection = conn;
13+
14+
return connection.query<Employee[]>('select * from employees limit 0, 10');
15+
}).then((employees) => {
16+
employees.forEach(employee => {
17+
console.log(`The employee with the employee number ${employee.emp_no} is ${employee.first_name} ${employee.last_name}`);
18+
});
19+
20+
connection.end();
21+
})
22+
}
23+
24+
async function runAwait() {
25+
const connection = await mysql.createConnection({
26+
user: 'root',
27+
password: 'password',
28+
database: 'employees'
29+
});
30+
31+
const employees = await connection.query<Employee[]>('select * from employees limit 0, 10');
32+
33+
employees.forEach(employee => {
34+
console.log(`The employee with the employee number ${employee.emp_no} is ${employee.first_name} ${employee.last_name}`);
35+
});
36+
37+
connection.end();
38+
}
39+
40+
run();
41+
runAwait();
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import * as mysql from '../../../index';
2+
import { Employee } from './employee';
3+
4+
function run() {
5+
mysql.createConnection({
6+
user: 'root',
7+
password: 'password',
8+
database: 'employees'
9+
}).then((connection) => {
10+
const employees = connection.queryStream<Employee>('select * from employees limit 0, 10');
11+
12+
employees.on('result', (employee) => {
13+
console.log(`The employee with the employee number ${employee.emp_no} is ${employee.first_name} ${employee.last_name}`);
14+
});
15+
16+
employees.on('end', () => {
17+
connection.end();
18+
})
19+
});
20+
}
21+
22+
async function runAwait() {
23+
const connection = await mysql.createConnection({
24+
user: 'root',
25+
password: 'password',
26+
database: 'employees'
27+
});
28+
29+
const employees = connection.queryStream<Employee>('select * from employees limit 0, 10');
30+
31+
employees.on('result', (employee) => {
32+
console.log(`The employee with the employee number ${employee.emp_no} is ${employee.first_name} ${employee.last_name}`);
33+
});
34+
35+
employees.on('end', () => {
36+
connection.end();
37+
})
38+
}
39+
40+
run();
41+
runAwait();
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { FieldInfo, Query } from 'mysql';
2+
import mysql from '../../../index';
3+
import { Employee } from './employee';
4+
5+
function run() {
6+
let connection: mysql.Connection;
7+
8+
mysql.createConnection({
9+
user: 'root',
10+
password: 'password',
11+
database: 'employees',
12+
returnArgumentsArray: true
13+
}).then((conn) => {
14+
connection = conn;
15+
16+
return connection.query<[data: Employee[], fields: FieldInfo[], query: Query]>('select * from employees limit 0, 10');
17+
}).then(([data, fields, query]) => {
18+
console.log(`The SQL for the query was: ${query.sql}\n`);
19+
20+
console.log(`The table 'employees' contains the following fields:`)
21+
fields.forEach(field => {
22+
console.log(` ${field.name}`);
23+
})
24+
25+
console.log('\nThe data retrieved was:')
26+
27+
data.forEach(employee => {
28+
console.log(` Employee number ${employee.emp_no}: ${employee.first_name} ${employee.last_name}`);
29+
});
30+
31+
connection.end();
32+
});
33+
}
34+
35+
async function runAwait() {
36+
const connection = await mysql.createConnection({
37+
user: 'root',
38+
password: 'password',
39+
database: 'employees',
40+
returnArgumentsArray: true
41+
});
42+
43+
const [data, fields, query] = await connection.query<[data: Employee[], fields: FieldInfo[], query: Query]>('select * from employees limit 0, 10');
44+
45+
console.log(`The SQL for the query was: ${query.sql}\n`);
46+
47+
console.log(`The table 'employees' contains the following fields:`)
48+
fields.forEach(field => {
49+
console.log(` ${field.name}`);
50+
})
51+
52+
console.log('\nThe data retrieved was:')
53+
54+
data.forEach(employee => {
55+
console.log(` Employee number ${employee.emp_no}: ${employee.first_name} ${employee.last_name}`);
56+
});
57+
58+
connection.end();
59+
}
60+
61+
run();
62+
runAwait();

index.d.ts

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export { Types, escape, escapeId, format, raw, ConnectionOptions, PoolClusterCon
1212
export type mysqlModule = typeof mysql;
1313

1414
export interface ConnectionConfig extends mysql.ConnectionConfig {
15-
mysqlWrapper?: (mysql: mysqlModule, callback: (err: Error | null, success?: mysqlModule) => void) => mysqlModule | Promise<mysqlModule> | void;
15+
mysqlWrapper?: (mysql: mysqlModule, callback?: (err: Error | null, success?: mysqlModule) => void) => mysqlModule | Promise<mysqlModule> | void;
1616
returnArgumentsArray?: boolean;
1717
reconnect?: boolean;
1818
}
@@ -23,16 +23,29 @@ export interface PoolConfig extends mysql.PoolConfig {
2323
reconnect?: boolean;
2424
}
2525

26-
export interface QueryFunction<T> {
27-
(query: mysql.Query | string | mysql.QueryOptions): T;
26+
export interface QueryFunction {
27+
<T extends unknown>(query: mysql.Query | string | mysql.QueryOptions): T;
28+
29+
<T extends unknown>(options: string, values?: any): T;
30+
}
31+
32+
export interface Query<T> extends mysql.Query {
33+
34+
on(ev: 'result', callback: (row: T, index: number) => void): mysql.Query;
35+
36+
on(ev: 'error', callback: (err: mysql.MysqlError) => void): mysql.Query;
37+
38+
on(ev: 'fields', callback: (fields: mysql.FieldInfo[], index: number) => void): mysql.Query;
39+
40+
on<T extends unknown>(ev: 'packet', callback: (packet: T) => void): mysql.Query;
2841

29-
(options: string, values: any): T;
42+
on(ev: 'end', callback: () => void): mysql.Query;
3043
}
3144

3245
export class Connection {
3346
constructor(config: string | ConnectionConfig, _connection?: Connection);
3447

35-
query: QueryFunction<Bluebird<any>>;
48+
query: QueryFunction;
3649

3750
beginTransaction(options?: mysql.QueryOptions): Bluebird<void>;
3851

@@ -44,7 +57,7 @@ export class Connection {
4457

4558
ping(options?: mysql.QueryOptions): Bluebird<void>;
4659

47-
queryStream: QueryFunction<mysql.Query>
60+
queryStream<T extends unknown>(options: string, values?: any): Query<T>;
4861

4962
statistics(options?: mysql.QueryOptions): Bluebird<void>;
5063

@@ -78,7 +91,7 @@ export class Pool {
7891

7992
getConnection(): Bluebird<PoolConnection>;
8093

81-
query: QueryFunction<Bluebird<any>>;
94+
query: QueryFunction;
8295

8396
end(options?: mysql.QueryOptions): Bluebird<void>;
8497

@@ -94,7 +107,7 @@ export class Pool {
94107

95108
on(ev: 'enqueue', callback: (err?: mysql.MysqlError) => void): mysql.Pool;
96109

97-
on(ev: string, callback: (...args: any[]) => void): mysql.Pool;
110+
on<T extends unknown>(ev: string, callback: (...args: T[]) => void): mysql.Pool;
98111
}
99112

100113
export class PoolCluster {
@@ -121,7 +134,7 @@ export class PoolCluster {
121134
/**
122135
* Set handler to be run on a certain event.
123136
*/
124-
on(ev: string, callback: (...args: any[]) => void): PoolCluster;
137+
on<T extends unknown>(ev: string, callback: (...args: T[]) => void): PoolCluster;
125138

126139
/**
127140
* Set handler to be run when a node is removed or goes offline.

0 commit comments

Comments
 (0)