@asla/yoursql 0.8.1 → 0.8.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/DbCursor.d.ts +14 -0
- package/dist/client/DbCursor.js +21 -0
- package/dist/client/DbPoolConnection.d.ts +29 -0
- package/dist/client/DbPoolConnection.js +56 -0
- package/dist/client/DbPoolTransaction.d.ts +29 -0
- package/dist/client/DbPoolTransaction.js +98 -0
- package/dist/client/DbQuery.d.ts +68 -0
- package/dist/client/DbQuery.js +30 -0
- package/dist/client/errors.d.ts +9 -0
- package/dist/client/errors.js +14 -0
- package/dist/client/interfaces.d.ts +66 -0
- package/dist/client/mod.d.ts +7 -0
- package/dist/client/mod.js +5 -0
- package/dist/sql_gen/mod.js +19 -0
- package/dist/sql_gen/select/DbTable.js +70 -0
- package/dist/sql_gen/select/TableQuery.js +68 -0
- package/dist/sql_gen/select/_statement.js +60 -0
- package/dist/sql_gen/select/query_chain_abstract.js +27 -0
- package/dist/sql_gen/select/query_chain_insert.js +64 -0
- package/dist/sql_gen/select/query_chain_select.js +105 -0
- package/dist/sql_gen/sql_value/db_type.js +40 -0
- package/dist/sql_gen/sql_value/sql_value.js +304 -0
- package/dist/sql_gen/util.js +166 -0
- package/dist/sql_gen/your_table/checker.js +82 -0
- package/dist/sql_gen/your_table/infer_db_type.js +76 -0
- package/dist/sql_gen/your_table/table.js +33 -0
- package/package.json +5 -2
- package/dist/mod.js +0 -1081
- /package/dist/{mod.d.ts → sql_gen/mod.d.ts} +0 -0
- /package/dist/{select → sql_gen/select}/DbTable.d.ts +0 -0
- /package/dist/{select → sql_gen/select}/TableQuery.d.ts +0 -0
- /package/dist/{select → sql_gen/select}/_statement.d.ts +0 -0
- /package/dist/{select → sql_gen/select}/query_chain_abstract.d.ts +0 -0
- /package/dist/{select → sql_gen/select}/query_chain_insert.d.ts +0 -0
- /package/dist/{select → sql_gen/select}/query_chain_select.d.ts +0 -0
- /package/dist/{select → sql_gen/select}/type.d.ts +0 -0
- /package/dist/{sql_value → sql_gen/sql_value}/db_type.d.ts +0 -0
- /package/dist/{sql_value → sql_gen/sql_value}/sql_value.d.ts +0 -0
- /package/dist/{util.d.ts → sql_gen/util.d.ts} +0 -0
- /package/dist/{your_table → sql_gen/your_table}/checker.d.ts +0 -0
- /package/dist/{your_table → sql_gen/your_table}/infer_db_type.d.ts +0 -0
- /package/dist/{your_table → sql_gen/your_table}/mod.d.ts +0 -0
- /package/dist/{your_table → sql_gen/your_table}/table.d.ts +0 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** @public */
|
|
2
|
+
export interface DbCursorOption {
|
|
3
|
+
defaultSize?: number;
|
|
4
|
+
}
|
|
5
|
+
/** @public */
|
|
6
|
+
export declare abstract class DbCursor<T> {
|
|
7
|
+
/** 读取游标,如果读取结束,返回空数组 */
|
|
8
|
+
abstract read(maxSize?: number): Promise<T[]>;
|
|
9
|
+
/** 提前关闭游标,如果多次调用,会被忽略 */
|
|
10
|
+
abstract close(): Promise<void>;
|
|
11
|
+
[Symbol.asyncDispose](): Promise<void>;
|
|
12
|
+
[Symbol.asyncIterator](): AsyncGenerator<T, undefined, void>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=DbCursor.d.ts.map
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** @public */
|
|
2
|
+
class DbCursor {
|
|
3
|
+
// implement
|
|
4
|
+
[Symbol.asyncDispose]() {
|
|
5
|
+
return this.close();
|
|
6
|
+
}
|
|
7
|
+
async *[Symbol.asyncIterator]() {
|
|
8
|
+
let data = await this.read();
|
|
9
|
+
try {
|
|
10
|
+
while (data.length) {
|
|
11
|
+
yield* data;
|
|
12
|
+
data = await this.read();
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
finally {
|
|
16
|
+
await this.close();
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export { DbCursor };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { SqlStatementDataset } from "../sql_gen/mod.ts";
|
|
2
|
+
import { DbQuery } from "./DbQuery.ts";
|
|
3
|
+
import type { MultipleQueryResult, QueryRowsResult } from "./DbQuery.ts";
|
|
4
|
+
import type { DbConnection, TransactionMode } from "./interfaces.ts";
|
|
5
|
+
/**
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* 池连接
|
|
9
|
+
* @public
|
|
10
|
+
*/
|
|
11
|
+
export declare class DbPoolConnection extends DbQuery {
|
|
12
|
+
#private;
|
|
13
|
+
constructor(conn: DbConnection, onRelease: () => void);
|
|
14
|
+
begin(mode?: TransactionMode): Promise<void>;
|
|
15
|
+
query<T = any>(sql: SqlStatementDataset<T>): Promise<QueryRowsResult<T>>;
|
|
16
|
+
query<T = any>(sql: {
|
|
17
|
+
toString(): string;
|
|
18
|
+
}): Promise<QueryRowsResult<T>>;
|
|
19
|
+
multipleQuery<T extends MultipleQueryResult = MultipleQueryResult>(sql: {
|
|
20
|
+
toString(): string;
|
|
21
|
+
}): Promise<T>;
|
|
22
|
+
rollback(): Promise<void>;
|
|
23
|
+
commit(): Promise<void>;
|
|
24
|
+
get released(): boolean;
|
|
25
|
+
/** 调用 release() 时,如果事务未提交,则抛出异常 */
|
|
26
|
+
release(): void;
|
|
27
|
+
[Symbol.dispose](): void;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=DbPoolConnection.d.ts.map
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { DbQuery } from './DbQuery.js';
|
|
2
|
+
import { ConnectionNotAvailableError } from './errors.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 池连接
|
|
8
|
+
* @public
|
|
9
|
+
*/
|
|
10
|
+
class DbPoolConnection extends DbQuery {
|
|
11
|
+
constructor(conn, onRelease) {
|
|
12
|
+
super();
|
|
13
|
+
this.#conn = conn;
|
|
14
|
+
this.#onRelease = onRelease;
|
|
15
|
+
}
|
|
16
|
+
#onRelease;
|
|
17
|
+
//implement
|
|
18
|
+
async begin(mode) {
|
|
19
|
+
await this.query("BEGIN" + (mode ? " TRANSACTION ISOLATION LEVEL " + mode : ""));
|
|
20
|
+
}
|
|
21
|
+
#conn;
|
|
22
|
+
query(sql) {
|
|
23
|
+
if (!this.#conn)
|
|
24
|
+
return Promise.reject(new ConnectionNotAvailableError("Connection already release"));
|
|
25
|
+
return this.#conn.query(sql);
|
|
26
|
+
}
|
|
27
|
+
multipleQuery(sql) {
|
|
28
|
+
if (!this.#conn)
|
|
29
|
+
return Promise.reject(new ConnectionNotAvailableError("Connection already release"));
|
|
30
|
+
return this.#conn.multipleQuery(sql);
|
|
31
|
+
}
|
|
32
|
+
//implement
|
|
33
|
+
async rollback() {
|
|
34
|
+
await this.query("ROLLBACK");
|
|
35
|
+
}
|
|
36
|
+
//implement
|
|
37
|
+
async commit() {
|
|
38
|
+
await this.query("COMMIT");
|
|
39
|
+
}
|
|
40
|
+
get released() {
|
|
41
|
+
return !this.#conn;
|
|
42
|
+
}
|
|
43
|
+
/** 调用 release() 时,如果事务未提交,则抛出异常 */
|
|
44
|
+
release() {
|
|
45
|
+
if (this.#conn) {
|
|
46
|
+
this.#conn = undefined;
|
|
47
|
+
this.#onRelease();
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
//implement
|
|
51
|
+
[Symbol.dispose]() {
|
|
52
|
+
return this.release();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export { DbPoolConnection };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { SqlStatementDataset } from "../sql_gen/mod.ts";
|
|
2
|
+
import { DbQuery } from "./DbQuery.ts";
|
|
3
|
+
import type { MultipleQueryResult, QueryRowsResult } from "./DbQuery.ts";
|
|
4
|
+
import type { DbPoolConnection } from "./DbPoolConnection.ts";
|
|
5
|
+
import type { DbTransaction, TransactionMode } from "./interfaces.ts";
|
|
6
|
+
/**
|
|
7
|
+
* @public
|
|
8
|
+
* 池连接事务
|
|
9
|
+
*/
|
|
10
|
+
export declare class DbPoolTransaction extends DbQuery implements DbTransaction {
|
|
11
|
+
#private;
|
|
12
|
+
readonly mode?: TransactionMode | undefined;
|
|
13
|
+
constructor(connect: () => Promise<DbPoolConnection>, mode?: TransactionMode | undefined);
|
|
14
|
+
commit(): Promise<void>;
|
|
15
|
+
rollback(): Promise<void>;
|
|
16
|
+
savePoint(savePoint: string): Promise<void>;
|
|
17
|
+
rollbackTo(savePoint: string): Promise<void>;
|
|
18
|
+
query<T extends object = any>(sql: SqlStatementDataset<T>): Promise<QueryRowsResult<T>>;
|
|
19
|
+
query<T extends object = any>(sql: {
|
|
20
|
+
toString(): string;
|
|
21
|
+
}): Promise<QueryRowsResult<T>>;
|
|
22
|
+
multipleQuery<T extends MultipleQueryResult = MultipleQueryResult>(sql: SqlStatementDataset<T>): Promise<T>;
|
|
23
|
+
multipleQuery<T extends MultipleQueryResult = MultipleQueryResult>(sql: {
|
|
24
|
+
toString(): string;
|
|
25
|
+
}): Promise<T>;
|
|
26
|
+
get released(): boolean;
|
|
27
|
+
[Symbol.asyncDispose](): Promise<void>;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=DbPoolTransaction.d.ts.map
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { DbQuery } from './DbQuery.js';
|
|
2
|
+
import { ParallelQueryError, ConnectionNotAvailableError } from './errors.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @public
|
|
6
|
+
* 池连接事务
|
|
7
|
+
*/
|
|
8
|
+
class DbPoolTransaction extends DbQuery {
|
|
9
|
+
mode;
|
|
10
|
+
constructor(connect, mode) {
|
|
11
|
+
super();
|
|
12
|
+
this.mode = mode;
|
|
13
|
+
this.#query = (sql) => {
|
|
14
|
+
return new Promise((resolve, reject) => {
|
|
15
|
+
this.#pending = connect()
|
|
16
|
+
.then((conn) => {
|
|
17
|
+
this.#conn = conn;
|
|
18
|
+
const promise = conn.multipleQuery("BEGIN" + (this.mode ? " TRANSACTION ISOLATION LEVEL " + this.mode : "") + ";\n" + sql);
|
|
19
|
+
this.#pending = promise;
|
|
20
|
+
this.#query = this.#queryAfter;
|
|
21
|
+
return promise;
|
|
22
|
+
})
|
|
23
|
+
.then((res) => {
|
|
24
|
+
this.#pending = undefined;
|
|
25
|
+
resolve(res[1]);
|
|
26
|
+
}, (e) => {
|
|
27
|
+
this.#pending = undefined;
|
|
28
|
+
reject(e);
|
|
29
|
+
if (this.#conn)
|
|
30
|
+
this.#release(this.#conn, e);
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
#pending;
|
|
36
|
+
#conn;
|
|
37
|
+
async commit() {
|
|
38
|
+
if (this.#pending)
|
|
39
|
+
throw new ParallelQueryError();
|
|
40
|
+
if (this.#conn) {
|
|
41
|
+
const promise = this.#conn.query("COMMIT");
|
|
42
|
+
this.#release(this.#conn);
|
|
43
|
+
await promise;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
async rollback() {
|
|
47
|
+
if (this.#pending)
|
|
48
|
+
throw new ParallelQueryError();
|
|
49
|
+
if (this.#conn) {
|
|
50
|
+
const promise = this.#conn.query("ROLLBACK");
|
|
51
|
+
this.#release(this.#conn);
|
|
52
|
+
await promise;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
savePoint(savePoint) {
|
|
56
|
+
return this.query("SAVEPOINT" + savePoint).then(() => { });
|
|
57
|
+
}
|
|
58
|
+
rollbackTo(savePoint) {
|
|
59
|
+
return this.query("ROLLBACK TO " + savePoint).then(() => { });
|
|
60
|
+
}
|
|
61
|
+
/** 拿到连接后执行这个 */
|
|
62
|
+
#queryAfter(sql) {
|
|
63
|
+
return this.#conn.query(sql).then((res) => {
|
|
64
|
+
this.#pending = undefined;
|
|
65
|
+
return res;
|
|
66
|
+
}, (e) => {
|
|
67
|
+
this.#pending = undefined;
|
|
68
|
+
this.#release(this.#conn, e);
|
|
69
|
+
throw e;
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
#query;
|
|
73
|
+
query(sql) {
|
|
74
|
+
if (this.#pending)
|
|
75
|
+
return Promise.reject(new ParallelQueryError());
|
|
76
|
+
return this.#query(sql.toString());
|
|
77
|
+
}
|
|
78
|
+
multipleQuery(sql) {
|
|
79
|
+
if (this.#pending)
|
|
80
|
+
return Promise.reject(new ParallelQueryError());
|
|
81
|
+
return this.#query(sql.toString());
|
|
82
|
+
}
|
|
83
|
+
#error;
|
|
84
|
+
#release(conn, error = new ConnectionNotAvailableError("Connection already release")) {
|
|
85
|
+
this.#error = error;
|
|
86
|
+
this.#query = () => Promise.reject(this.#error);
|
|
87
|
+
this.#conn = undefined;
|
|
88
|
+
conn.release();
|
|
89
|
+
}
|
|
90
|
+
get released() {
|
|
91
|
+
return !!this.#error;
|
|
92
|
+
}
|
|
93
|
+
[Symbol.asyncDispose]() {
|
|
94
|
+
return this.rollback();
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export { DbPoolTransaction };
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { SqlStatementDataset } from "../sql_gen/mod.ts";
|
|
2
|
+
/** @public */
|
|
3
|
+
export interface SingleQueryResult {
|
|
4
|
+
rowCount: number;
|
|
5
|
+
rows?: any[];
|
|
6
|
+
}
|
|
7
|
+
/** @public */
|
|
8
|
+
export interface QueryRowsResult<T = any> extends SingleQueryResult {
|
|
9
|
+
rowCount: number;
|
|
10
|
+
rows: T[];
|
|
11
|
+
}
|
|
12
|
+
/** @public */
|
|
13
|
+
export type MultipleQueryResult = SingleQueryResult[];
|
|
14
|
+
/** @public */
|
|
15
|
+
export type QueryResult = MultipleQueryResult | SingleQueryResult;
|
|
16
|
+
/**
|
|
17
|
+
* SQL 查询相关操作
|
|
18
|
+
* @public
|
|
19
|
+
*/
|
|
20
|
+
export declare abstract class DbQuery {
|
|
21
|
+
/** 单语句查询,不应查询条语句,否则返回错误值 */
|
|
22
|
+
abstract query<T = any>(sql: SqlStatementDataset<T>): Promise<QueryRowsResult<T>>;
|
|
23
|
+
/** 单语句查询,不应查询条语句,否则返回错误值 */
|
|
24
|
+
abstract query<T = any>(sql: {
|
|
25
|
+
toString(): string;
|
|
26
|
+
}): Promise<QueryRowsResult<T>>;
|
|
27
|
+
/** 多语句查询 */
|
|
28
|
+
abstract multipleQuery<T extends MultipleQueryResult = MultipleQueryResult>(sql: SqlStatementDataset<T>): Promise<T>;
|
|
29
|
+
/** 多语句查询 */
|
|
30
|
+
abstract multipleQuery<T extends MultipleQueryResult = MultipleQueryResult>(sql: {
|
|
31
|
+
toString(): string;
|
|
32
|
+
}): Promise<T>;
|
|
33
|
+
/** 单语句查询受影响的行 */
|
|
34
|
+
queryCount(sql: string | {
|
|
35
|
+
toString(): string;
|
|
36
|
+
}): Promise<number>;
|
|
37
|
+
/** 单语句查询,不应查询条语句,否则返回错误值 */
|
|
38
|
+
queryRows<T = any>(sql: SqlStatementDataset<T>): Promise<T[]>;
|
|
39
|
+
/** 单语句查询,不应查询条语句,否则返回错误值 */
|
|
40
|
+
queryRows<T = any>(sql: {
|
|
41
|
+
toString(): string;
|
|
42
|
+
}): Promise<T[]>;
|
|
43
|
+
/**
|
|
44
|
+
* 查询行
|
|
45
|
+
* 不应查询单条语句,否则返回错误值
|
|
46
|
+
*/
|
|
47
|
+
multipleQueryRows<T extends any[] = any[]>(sql: SqlStatementDataset<T>): Promise<T[]>;
|
|
48
|
+
/**
|
|
49
|
+
* 查询行
|
|
50
|
+
* 不应查询条语句,否则返回错误值
|
|
51
|
+
*/
|
|
52
|
+
multipleQueryRows<T extends any[] = any[]>(sql: {
|
|
53
|
+
toString(): string;
|
|
54
|
+
}): Promise<T[]>;
|
|
55
|
+
/**
|
|
56
|
+
* 指定某一列为key,返回 key 到 row 的映射
|
|
57
|
+
* 单语句查询,不应查询条语句,否则返回错误值
|
|
58
|
+
*/
|
|
59
|
+
queryMap<T extends Record<string, any> = Record<string, any>, K extends keyof T = string>(sql: SqlStatementDataset<T>, key: K): Promise<Map<T[K], T>>;
|
|
60
|
+
/**
|
|
61
|
+
* 指定某一列为key,返回 key 到 row 的映射
|
|
62
|
+
* 单语句查询,不应查询条语句,否则返回错误值
|
|
63
|
+
*/
|
|
64
|
+
queryMap<T extends Record<string, any> = Record<string, any>, K extends keyof T = string>(sql: {
|
|
65
|
+
toString(): string;
|
|
66
|
+
}, key: K): Promise<Map<T[K], T>>;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=DbQuery.d.ts.map
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQL 查询相关操作
|
|
3
|
+
* @public
|
|
4
|
+
*/
|
|
5
|
+
class DbQuery {
|
|
6
|
+
/** 单语句查询受影响的行 */
|
|
7
|
+
queryCount(sql) {
|
|
8
|
+
return this.query(sql.toString()).then((res) => {
|
|
9
|
+
if (res.rowCount === null)
|
|
10
|
+
return 0;
|
|
11
|
+
return res.rowCount;
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
queryRows(sql) {
|
|
15
|
+
return this.query(sql.toString()).then((res) => res.rows);
|
|
16
|
+
}
|
|
17
|
+
multipleQueryRows(sql) {
|
|
18
|
+
return this.multipleQuery(sql.toString()).then((res) => res.map((item) => item.rows ?? []));
|
|
19
|
+
}
|
|
20
|
+
async queryMap(sql, key) {
|
|
21
|
+
const { rows } = await this.query(sql.toString());
|
|
22
|
+
let map = new Map();
|
|
23
|
+
for (let i = 0; i < rows.length; i++) {
|
|
24
|
+
map.set(rows[i][key], rows[i]);
|
|
25
|
+
}
|
|
26
|
+
return map;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export { DbQuery };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** @public */
|
|
2
|
+
class ParallelQueryError extends Error {
|
|
3
|
+
constructor() {
|
|
4
|
+
super("The previous query was not completed and cannot be executed");
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
/** @public */
|
|
8
|
+
class ConnectionNotAvailableError extends Error {
|
|
9
|
+
constructor(message) {
|
|
10
|
+
super(message);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export { ConnectionNotAvailableError, ParallelQueryError };
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { SqlStatementDataset } from "../sql_gen/mod.ts";
|
|
2
|
+
import { DbQuery } from "./DbQuery.ts";
|
|
3
|
+
import { DbPoolConnection } from "./DbPoolConnection.ts";
|
|
4
|
+
import { DbCursor, DbCursorOption } from "./DbCursor.ts";
|
|
5
|
+
/**
|
|
6
|
+
* 数据库连接
|
|
7
|
+
* @public
|
|
8
|
+
*/
|
|
9
|
+
export interface DbConnection extends DbQuery, AsyncDisposable {
|
|
10
|
+
close(): Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
/** @public */
|
|
13
|
+
export type TransactionMode = "SERIALIZABLE" | "REPEATABLE READ" | "READ COMMITTED" | "READ UNCOMMITTED";
|
|
14
|
+
/**
|
|
15
|
+
* SQL 事务查询操作
|
|
16
|
+
*
|
|
17
|
+
* 使用 `await using` 语法离开作用域时,如果没有 `commit()` 或 `rollback(`) , 则调用 `rollback()`
|
|
18
|
+
*
|
|
19
|
+
* ```ts
|
|
20
|
+
* async function doSomeTransaction(){
|
|
21
|
+
* await using transaction = pool.begin()
|
|
22
|
+
* await transaction.query("SELECT * FROM user")
|
|
23
|
+
* throw new Error("error")
|
|
24
|
+
* }
|
|
25
|
+
* try{
|
|
26
|
+
* await doSomeTransaction()
|
|
27
|
+
* }catch(e){
|
|
28
|
+
* console.error(e)
|
|
29
|
+
* }
|
|
30
|
+
* ```
|
|
31
|
+
* 下面的写法会造成连接池泄露
|
|
32
|
+
* ```ts
|
|
33
|
+
* async function doSomeTransaction(){
|
|
34
|
+
* const transaction = pool.begin()
|
|
35
|
+
* await transaction.query("SELECT * FROM user")
|
|
36
|
+
* }
|
|
37
|
+
* await doSomeTransaction() // 离开作用域后连接不会被回收
|
|
38
|
+
* console.warn("连接未被回收!")
|
|
39
|
+
*
|
|
40
|
+
* ```
|
|
41
|
+
* @public
|
|
42
|
+
*/
|
|
43
|
+
export interface DbTransaction extends DbQuery, AsyncDisposable {
|
|
44
|
+
/** 回滚,并释放连接 */
|
|
45
|
+
rollback(): Promise<void>;
|
|
46
|
+
/** 回滚到保存点 */
|
|
47
|
+
rollbackTo(savePoint: string): Promise<void>;
|
|
48
|
+
savePoint(savePoint: string): Promise<void>;
|
|
49
|
+
/** 提交,并释放连接 */
|
|
50
|
+
commit(): Promise<void>;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* @public
|
|
54
|
+
* 池链接查询
|
|
55
|
+
*/
|
|
56
|
+
export interface DbQueryPool extends DbQuery {
|
|
57
|
+
connect(): Promise<DbPoolConnection>;
|
|
58
|
+
idleCount: number;
|
|
59
|
+
totalCount: number;
|
|
60
|
+
begin(mode?: TransactionMode): DbTransaction;
|
|
61
|
+
cursor<T extends {}>(sql: SqlStatementDataset<T>): Promise<DbCursor<T>>;
|
|
62
|
+
cursor<T>(sql: {
|
|
63
|
+
toString(): string;
|
|
64
|
+
}, option?: DbCursorOption): Promise<DbCursor<T>>;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=interfaces.d.ts.map
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { ConnectionNotAvailableError, ParallelQueryError } from './errors.js';
|
|
2
|
+
export { DbQuery } from './DbQuery.js';
|
|
3
|
+
export { DbCursor } from './DbCursor.js';
|
|
4
|
+
export { DbPoolConnection } from './DbPoolConnection.js';
|
|
5
|
+
export { DbPoolTransaction } from './DbPoolTransaction.js';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { pgSqlTransformer } from './sql_value/db_type.js';
|
|
2
|
+
import { SqlValuesCreator } from './sql_value/sql_value.js';
|
|
3
|
+
export { SqlRaw } from './sql_value/sql_value.js';
|
|
4
|
+
export { DbTable } from './select/DbTable.js';
|
|
5
|
+
export { Selection, SqlSelectChain } from './select/query_chain_select.js';
|
|
6
|
+
export { SqlStatement, SqlStatementDataset, SqlTextStatementDataset } from './select/query_chain_abstract.js';
|
|
7
|
+
export { DbTableQuery } from './select/TableQuery.js';
|
|
8
|
+
export { getObjectListKeys, having, orderBy, selectColumns, where } from './util.js';
|
|
9
|
+
export { TypeChecker } from './your_table/checker.js';
|
|
10
|
+
export { ColumnMeta, CustomDbType, YourTypeMap } from './your_table/infer_db_type.js';
|
|
11
|
+
export { YourTable } from './your_table/table.js';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* 默认的 SqlValuesCreator 实列
|
|
15
|
+
* @public
|
|
16
|
+
*/
|
|
17
|
+
const v = SqlValuesCreator.create(pgSqlTransformer);
|
|
18
|
+
|
|
19
|
+
export { SqlValuesCreator, pgSqlTransformer, v };
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { where } from '../util.js';
|
|
2
|
+
import { Selection } from './query_chain_select.js';
|
|
3
|
+
import { SqlChainModify } from './query_chain_insert.js';
|
|
4
|
+
import { createUpdateSetFromObject } from './_statement.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 数据库表
|
|
8
|
+
* @public
|
|
9
|
+
*/
|
|
10
|
+
class DbTable {
|
|
11
|
+
name;
|
|
12
|
+
constructor(name) {
|
|
13
|
+
this.name = name;
|
|
14
|
+
}
|
|
15
|
+
fromAs(as) {
|
|
16
|
+
return new Selection(this.name, as);
|
|
17
|
+
}
|
|
18
|
+
select(columns, as) {
|
|
19
|
+
return this.fromAs(as).select(columns);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* INSERT 语句,需要注意 SQL 注入
|
|
23
|
+
* @example
|
|
24
|
+
* ```ts
|
|
25
|
+
* table.insert(["age","name"], "VALUES (18, 'hi'), (17, 'hh')") // INSERT INTO table(age,name) VALUES(18, 'hi'), (17, 'hh')
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
insert(columns, values) {
|
|
29
|
+
if (typeof columns !== "string" || !columns)
|
|
30
|
+
throw new TypeError("columns 必须是有效的 string 类型");
|
|
31
|
+
if (typeof values === "function")
|
|
32
|
+
values = values();
|
|
33
|
+
if (typeof values !== "string")
|
|
34
|
+
throw new TypeError("values 必须是 string 或 function 类型");
|
|
35
|
+
let sql = `INSERT INTO ${this.name}(${columns})\n${values}`;
|
|
36
|
+
return new SqlChainModify(sql);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* UPDATE 语句,需要注意 SQL 注入
|
|
40
|
+
* @example
|
|
41
|
+
* ```ts
|
|
42
|
+
* table.update("age=3, name='hi'") // "UPDATE table SET age=3, name='hi'"
|
|
43
|
+
* table.update({age: "3", name: "'hi'", k1: undefined, k2: ""}) // "UPDATE table SET age=3, name='hi'"
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
update(values) {
|
|
47
|
+
if (typeof values === "function")
|
|
48
|
+
values = values();
|
|
49
|
+
switch (typeof values) {
|
|
50
|
+
case "object": {
|
|
51
|
+
let sql = createUpdateSetFromObject(values);
|
|
52
|
+
return new SqlChainModify("UPDATE " + this.name + " " + sql);
|
|
53
|
+
}
|
|
54
|
+
case "string":
|
|
55
|
+
return new SqlChainModify("UPDATE " + this.name + " SET\n" + values);
|
|
56
|
+
default:
|
|
57
|
+
throw new TypeError("参数 values 错误");
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
delete(option = {}) {
|
|
61
|
+
let sql = "DELETE FROM " + this.name;
|
|
62
|
+
sql += where(option.where);
|
|
63
|
+
return new SqlChainModify(sql);
|
|
64
|
+
}
|
|
65
|
+
toSelect() {
|
|
66
|
+
return this.name;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export { DbTable };
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { getObjectListKeys } from '../util.js';
|
|
2
|
+
import { SqlChainModify } from './query_chain_insert.js';
|
|
3
|
+
import { DbTable } from './DbTable.js';
|
|
4
|
+
|
|
5
|
+
/** @public */
|
|
6
|
+
class DbTableQuery extends DbTable {
|
|
7
|
+
statement;
|
|
8
|
+
constructor(name, statement) {
|
|
9
|
+
super(name);
|
|
10
|
+
this.statement = statement;
|
|
11
|
+
}
|
|
12
|
+
insert(values_column, _values) {
|
|
13
|
+
if (_values)
|
|
14
|
+
return super.insert(values_column, _values);
|
|
15
|
+
let values = values_column;
|
|
16
|
+
if (typeof values === "function")
|
|
17
|
+
values = values();
|
|
18
|
+
if (typeof values !== "object")
|
|
19
|
+
throw new TypeError("values 类型错误");
|
|
20
|
+
let valuesStr;
|
|
21
|
+
let insertCol;
|
|
22
|
+
if (values instanceof Array) {
|
|
23
|
+
if (values.length === 0)
|
|
24
|
+
throw new Error("值不能为空");
|
|
25
|
+
insertCol = Array.from(getObjectListKeys(values));
|
|
26
|
+
valuesStr = `VALUES\n${this.statement.objectListToValuesList(values, insertCol)}`;
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
insertCol = Object.keys(values);
|
|
30
|
+
valuesStr = `VALUES\n(${this.statement.objectToValues(values, insertCol)})`;
|
|
31
|
+
}
|
|
32
|
+
if (insertCol.length === 0)
|
|
33
|
+
throw new Error("插入列不能为空");
|
|
34
|
+
const columnStr = insertCol.join(",");
|
|
35
|
+
let sql = `INSERT INTO ${this.name} (${columnStr})\n${valuesStr}`;
|
|
36
|
+
return new SqlChainModify(sql);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* UPDATE 语句,与 update() 不同的是,它会将值进行安全转换
|
|
40
|
+
* @example
|
|
41
|
+
* ```ts
|
|
42
|
+
* table.update({age:3, name:"hi"}, true) // "UPDATE table SET age=3, name='hi'"
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
updateFrom(values) {
|
|
46
|
+
if (typeof values === "function")
|
|
47
|
+
values = values();
|
|
48
|
+
let setStr;
|
|
49
|
+
if (typeof values === "string")
|
|
50
|
+
setStr = values;
|
|
51
|
+
else {
|
|
52
|
+
const updateKey = Object.entries(values);
|
|
53
|
+
let setList = [];
|
|
54
|
+
for (const [k, v] of updateKey) {
|
|
55
|
+
if (v === undefined)
|
|
56
|
+
continue;
|
|
57
|
+
setList.push(k + "= " + this.statement.toSqlStr(v));
|
|
58
|
+
}
|
|
59
|
+
setStr = setList.join(",\n");
|
|
60
|
+
}
|
|
61
|
+
if (!setStr)
|
|
62
|
+
throw new Error("值不能为空");
|
|
63
|
+
let sql = `UPDATE ${this.name} SET\n${setStr}`;
|
|
64
|
+
return new SqlChainModify(sql);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export { DbTableQuery };
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
function condition(conditions, type = "AND") {
|
|
2
|
+
if (typeof conditions === "function")
|
|
3
|
+
conditions = conditions();
|
|
4
|
+
if (!conditions)
|
|
5
|
+
return;
|
|
6
|
+
if (typeof conditions === "string")
|
|
7
|
+
return conditions;
|
|
8
|
+
else {
|
|
9
|
+
if (conditions.length) {
|
|
10
|
+
let sql = "";
|
|
11
|
+
type = " " + type + " ";
|
|
12
|
+
sql += conditions[0];
|
|
13
|
+
for (let i = 1; i < conditions.length; i++)
|
|
14
|
+
sql += type + conditions[i];
|
|
15
|
+
return sql;
|
|
16
|
+
}
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function createUpdateSetFromObject(set) {
|
|
21
|
+
const updateKey = Object.keys(set);
|
|
22
|
+
let i = 0;
|
|
23
|
+
let key;
|
|
24
|
+
let value;
|
|
25
|
+
let sql;
|
|
26
|
+
for (; i < updateKey.length; i++) {
|
|
27
|
+
key = updateKey[i];
|
|
28
|
+
value = set[key];
|
|
29
|
+
if (value === undefined)
|
|
30
|
+
continue;
|
|
31
|
+
if (typeof value === "string") {
|
|
32
|
+
if (value) {
|
|
33
|
+
sql = "SET\n" + key + "= " + value;
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
else
|
|
38
|
+
throw new TypeError(`key ${key} 类型错误(${typeof value})`);
|
|
39
|
+
}
|
|
40
|
+
if (sql) {
|
|
41
|
+
i++;
|
|
42
|
+
for (; i < updateKey.length; i++) {
|
|
43
|
+
key = updateKey[i];
|
|
44
|
+
value = set[key];
|
|
45
|
+
if (value === undefined)
|
|
46
|
+
continue;
|
|
47
|
+
if (typeof value === "string") {
|
|
48
|
+
if (value)
|
|
49
|
+
sql += "," + key + "= " + value;
|
|
50
|
+
}
|
|
51
|
+
else
|
|
52
|
+
throw new TypeError(`key ${key} 类型错误(${typeof value})`);
|
|
53
|
+
}
|
|
54
|
+
return sql;
|
|
55
|
+
}
|
|
56
|
+
else
|
|
57
|
+
throw new Error("值不能为空");
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export { condition, createUpdateSetFromObject };
|