@asla/yoursql 0.8.0 → 0.8.2
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/DbPoolConnection.d.ts +29 -0
- package/dist/client/DbPoolTransaction.d.ts +29 -0
- package/dist/client/DbQuery.d.ts +68 -0
- package/dist/client/errors.d.ts +9 -0
- package/dist/client/interfaces.d.ts +66 -0
- package/dist/client/mod.d.ts +7 -0
- package/dist/client.js +209 -0
- package/dist/{select → sql_gen/select}/_statement.d.ts +0 -4
- package/dist/{select → sql_gen/select}/query_chain_abstract.d.ts +4 -4
- package/dist/{select → sql_gen/select}/query_chain_insert.d.ts +3 -3
- package/dist/{select → sql_gen/select}/type.d.ts +0 -18
- package/dist/{util.d.ts → sql_gen/util.d.ts} +1 -1
- package/dist/{mod.js → sql_gen.js} +71 -112
- package/package.json +5 -2
- /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}/query_chain_select.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/{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,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,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,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,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
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,209 @@
|
|
|
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
|
+
/**
|
|
15
|
+
* SQL 查询相关操作
|
|
16
|
+
* @public
|
|
17
|
+
*/
|
|
18
|
+
class DbQuery {
|
|
19
|
+
/** 单语句查询受影响的行 */
|
|
20
|
+
queryCount(sql) {
|
|
21
|
+
return this.query(sql.toString()).then((res) => {
|
|
22
|
+
if (res.rowCount === null)
|
|
23
|
+
return 0;
|
|
24
|
+
return res.rowCount;
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
queryRows(sql) {
|
|
28
|
+
return this.query(sql.toString()).then((res) => res.rows);
|
|
29
|
+
}
|
|
30
|
+
multipleQueryRows(sql) {
|
|
31
|
+
return this.multipleQuery(sql.toString()).then((res) => res.map((item) => item.rows ?? []));
|
|
32
|
+
}
|
|
33
|
+
async queryMap(sql, key) {
|
|
34
|
+
const { rows } = await this.query(sql.toString());
|
|
35
|
+
let map = new Map();
|
|
36
|
+
for (let i = 0; i < rows.length; i++) {
|
|
37
|
+
map.set(rows[i][key], rows[i]);
|
|
38
|
+
}
|
|
39
|
+
return map;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** @public */
|
|
44
|
+
class DbCursor {
|
|
45
|
+
// implement
|
|
46
|
+
[Symbol.asyncDispose]() {
|
|
47
|
+
return this.close();
|
|
48
|
+
}
|
|
49
|
+
async *[Symbol.asyncIterator]() {
|
|
50
|
+
let data = await this.read();
|
|
51
|
+
try {
|
|
52
|
+
while (data.length) {
|
|
53
|
+
yield* data;
|
|
54
|
+
data = await this.read();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
finally {
|
|
58
|
+
await this.close();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* 池连接
|
|
67
|
+
* @public
|
|
68
|
+
*/
|
|
69
|
+
class DbPoolConnection extends DbQuery {
|
|
70
|
+
constructor(conn, onRelease) {
|
|
71
|
+
super();
|
|
72
|
+
this.#conn = conn;
|
|
73
|
+
this.#onRelease = onRelease;
|
|
74
|
+
}
|
|
75
|
+
#onRelease;
|
|
76
|
+
//implement
|
|
77
|
+
async begin(mode) {
|
|
78
|
+
await this.query("BEGIN" + (mode ? " TRANSACTION ISOLATION LEVEL " + mode : ""));
|
|
79
|
+
}
|
|
80
|
+
#conn;
|
|
81
|
+
query(sql) {
|
|
82
|
+
if (!this.#conn)
|
|
83
|
+
return Promise.reject(new ConnectionNotAvailableError("Connection already release"));
|
|
84
|
+
return this.#conn.query(sql);
|
|
85
|
+
}
|
|
86
|
+
multipleQuery(sql) {
|
|
87
|
+
if (!this.#conn)
|
|
88
|
+
return Promise.reject(new ConnectionNotAvailableError("Connection already release"));
|
|
89
|
+
return this.#conn.multipleQuery(sql);
|
|
90
|
+
}
|
|
91
|
+
//implement
|
|
92
|
+
async rollback() {
|
|
93
|
+
await this.query("ROLLBACK");
|
|
94
|
+
}
|
|
95
|
+
//implement
|
|
96
|
+
async commit() {
|
|
97
|
+
await this.query("COMMIT");
|
|
98
|
+
}
|
|
99
|
+
get released() {
|
|
100
|
+
return !this.#conn;
|
|
101
|
+
}
|
|
102
|
+
/** 调用 release() 时,如果事务未提交,则抛出异常 */
|
|
103
|
+
release() {
|
|
104
|
+
if (this.#conn) {
|
|
105
|
+
this.#conn = undefined;
|
|
106
|
+
this.#onRelease();
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
//implement
|
|
110
|
+
[Symbol.dispose]() {
|
|
111
|
+
return this.release();
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* @public
|
|
117
|
+
* 池连接事务
|
|
118
|
+
*/
|
|
119
|
+
class DbPoolTransaction extends DbQuery {
|
|
120
|
+
mode;
|
|
121
|
+
constructor(connect, mode) {
|
|
122
|
+
super();
|
|
123
|
+
this.mode = mode;
|
|
124
|
+
this.#query = (sql) => {
|
|
125
|
+
return new Promise((resolve, reject) => {
|
|
126
|
+
this.#pending = connect()
|
|
127
|
+
.then((conn) => {
|
|
128
|
+
this.#conn = conn;
|
|
129
|
+
const promise = conn.multipleQuery("BEGIN" + (this.mode ? " TRANSACTION ISOLATION LEVEL " + this.mode : "") + ";\n" + sql);
|
|
130
|
+
this.#pending = promise;
|
|
131
|
+
this.#query = this.#queryAfter;
|
|
132
|
+
return promise;
|
|
133
|
+
})
|
|
134
|
+
.then((res) => {
|
|
135
|
+
this.#pending = undefined;
|
|
136
|
+
resolve(res[1]);
|
|
137
|
+
}, (e) => {
|
|
138
|
+
this.#pending = undefined;
|
|
139
|
+
reject(e);
|
|
140
|
+
if (this.#conn)
|
|
141
|
+
this.#release(this.#conn, e);
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
#pending;
|
|
147
|
+
#conn;
|
|
148
|
+
async commit() {
|
|
149
|
+
if (this.#pending)
|
|
150
|
+
throw new ParallelQueryError();
|
|
151
|
+
if (this.#conn) {
|
|
152
|
+
const promise = this.#conn.query("COMMIT");
|
|
153
|
+
this.#release(this.#conn);
|
|
154
|
+
await promise;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
async rollback() {
|
|
158
|
+
if (this.#pending)
|
|
159
|
+
throw new ParallelQueryError();
|
|
160
|
+
if (this.#conn) {
|
|
161
|
+
const promise = this.#conn.query("ROLLBACK");
|
|
162
|
+
this.#release(this.#conn);
|
|
163
|
+
await promise;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
savePoint(savePoint) {
|
|
167
|
+
return this.query("SAVEPOINT" + savePoint).then(() => { });
|
|
168
|
+
}
|
|
169
|
+
rollbackTo(savePoint) {
|
|
170
|
+
return this.query("ROLLBACK TO " + savePoint).then(() => { });
|
|
171
|
+
}
|
|
172
|
+
/** 拿到连接后执行这个 */
|
|
173
|
+
#queryAfter(sql) {
|
|
174
|
+
return this.#conn.query(sql).then((res) => {
|
|
175
|
+
this.#pending = undefined;
|
|
176
|
+
return res;
|
|
177
|
+
}, (e) => {
|
|
178
|
+
this.#pending = undefined;
|
|
179
|
+
this.#release(this.#conn, e);
|
|
180
|
+
throw e;
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
#query;
|
|
184
|
+
query(sql) {
|
|
185
|
+
if (this.#pending)
|
|
186
|
+
return Promise.reject(new ParallelQueryError());
|
|
187
|
+
return this.#query(sql.toString());
|
|
188
|
+
}
|
|
189
|
+
multipleQuery(sql) {
|
|
190
|
+
if (this.#pending)
|
|
191
|
+
return Promise.reject(new ParallelQueryError());
|
|
192
|
+
return this.#query(sql.toString());
|
|
193
|
+
}
|
|
194
|
+
#error;
|
|
195
|
+
#release(conn, error = new ConnectionNotAvailableError("Connection already release")) {
|
|
196
|
+
this.#error = error;
|
|
197
|
+
this.#query = () => Promise.reject(this.#error);
|
|
198
|
+
this.#conn = undefined;
|
|
199
|
+
conn.release();
|
|
200
|
+
}
|
|
201
|
+
get released() {
|
|
202
|
+
return !!this.#error;
|
|
203
|
+
}
|
|
204
|
+
[Symbol.asyncDispose]() {
|
|
205
|
+
return this.rollback();
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
export { ConnectionNotAvailableError, DbCursor, DbPoolConnection, DbPoolTransaction, DbQuery, ParallelQueryError };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ConditionParam, Constructable, OrderByParam } from "../util.ts";
|
|
2
|
-
import {
|
|
1
|
+
import { ConditionParam, Constructable, OrderByParam, SelectParam } from "../util.ts";
|
|
2
|
+
import { TableType } from "./type.ts";
|
|
3
3
|
/** @public */
|
|
4
4
|
export declare abstract class SqlStatement {
|
|
5
5
|
/** 获取 SQL 语句 */
|
|
@@ -55,8 +55,8 @@ export interface ChainSelectWhere<T extends TableType> extends ChainSelectGroupB
|
|
|
55
55
|
/** @public */
|
|
56
56
|
export interface ChainModifyReturning<T extends TableType = {}> extends SqlStatement {
|
|
57
57
|
returning(columns: "*"): SqlStatementDataset<T>;
|
|
58
|
-
returning(columns: Constructable<
|
|
59
|
-
returning<R extends TableType>(columns: Constructable<
|
|
58
|
+
returning(columns: Constructable<SelectParam>): SqlStatementDataset<Record<string, any>>;
|
|
59
|
+
returning<R extends TableType>(columns: Constructable<SelectParam>): SqlStatementDataset<R>;
|
|
60
60
|
}
|
|
61
61
|
/** @public */
|
|
62
62
|
export interface ChainModifyWhere<T extends TableType = {}> extends ChainModifyReturning<T> {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { ConditionParam, Constructable } from "../util.ts";
|
|
1
|
+
import { ConditionParam, Constructable, SelectParam } from "../util.ts";
|
|
2
2
|
import { SqlStatementDataset, SqlStatement, ChainModifyWhere, ChainOnConflict, ChainConflictDo, ChainModifyReturning } from "./query_chain_abstract.ts";
|
|
3
|
-
import {
|
|
3
|
+
import { TableType } from "./type.ts";
|
|
4
4
|
export declare class SqlChainModify<T extends TableType = {}> extends SqlStatement implements ChainOnConflict<T>, ChainModifyWhere<T> {
|
|
5
5
|
readonly sql: string;
|
|
6
6
|
constructor(sql: string);
|
|
7
|
-
returning<R extends {}>(returns: Constructable<
|
|
7
|
+
returning<R extends {}>(returns: Constructable<SelectParam | "*">): SqlStatementDataset<R>;
|
|
8
8
|
onConflict(onConflict: Constructable<readonly string[] | string>): ChainConflictDo<T>;
|
|
9
9
|
where(where: Constructable<ConditionParam | void>): ChainModifyReturning<T>;
|
|
10
10
|
toString(): string;
|
|
@@ -20,26 +20,8 @@ export type UpdateRowValue<T extends object> = {
|
|
|
20
20
|
};
|
|
21
21
|
/** @public */
|
|
22
22
|
export type OrderValue = "ASC" | "DESC";
|
|
23
|
-
/**
|
|
24
|
-
* 表的选择参数
|
|
25
|
-
* @public
|
|
26
|
-
*/
|
|
27
|
-
export type ColumnsSelected<T extends TableType> = {
|
|
28
|
-
[key in keyof T]?: boolean | string;
|
|
29
|
-
};
|
|
30
|
-
/**
|
|
31
|
-
* 从一个表格选择列,生成新的表格类型
|
|
32
|
-
* @public
|
|
33
|
-
*/
|
|
34
|
-
export type SelectColumns<T extends TableType, R extends ColumnsSelected<T>> = R extends {
|
|
35
|
-
[key in keyof T]?: boolean | string;
|
|
36
|
-
} ? {
|
|
37
|
-
[key in keyof T as R[key] extends true ? key : StringOnly<R[key]>]: T[key];
|
|
38
|
-
} : never;
|
|
39
|
-
type StringOnly<T> = T extends string ? T : never;
|
|
40
23
|
/** @public */
|
|
41
24
|
export type TableType = {
|
|
42
25
|
[key: string]: any;
|
|
43
26
|
};
|
|
44
|
-
export {};
|
|
45
27
|
//# sourceMappingURL=type.d.ts.map
|
|
@@ -30,7 +30,7 @@ export declare function where(conditions?: Constructable<ConditionParam | void>,
|
|
|
30
30
|
*/
|
|
31
31
|
export declare function having(conditions?: Constructable<ConditionParam | void>, type?: "AND" | "OR"): string;
|
|
32
32
|
/** @public */
|
|
33
|
-
export type SelectParam = string | Record<string, string | boolean>;
|
|
33
|
+
export type SelectParam = string | string[] | Record<string, string | boolean>;
|
|
34
34
|
/**
|
|
35
35
|
* @public
|
|
36
36
|
* @example
|
|
@@ -1,65 +1,3 @@
|
|
|
1
|
-
/******************************************************************************
|
|
2
|
-
Copyright (c) Microsoft Corporation.
|
|
3
|
-
|
|
4
|
-
Permission to use, copy, modify, and/or distribute this software for any
|
|
5
|
-
purpose with or without fee is hereby granted.
|
|
6
|
-
|
|
7
|
-
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
8
|
-
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
9
|
-
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
10
|
-
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
11
|
-
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
12
|
-
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
13
|
-
PERFORMANCE OF THIS SOFTWARE.
|
|
14
|
-
***************************************************************************** */
|
|
15
|
-
/* global Reflect, Promise, SuppressedError, Symbol, Iterator */
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
function __classPrivateFieldGet(receiver, state, kind, f) {
|
|
19
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
20
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
21
|
-
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
function __classPrivateFieldSet(receiver, state, value, kind, f) {
|
|
25
|
-
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
26
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
27
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
28
|
-
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
32
|
-
var e = new Error(message);
|
|
33
|
-
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
function selectColumnsOrTable(columns) {
|
|
37
|
-
let sqlSelect;
|
|
38
|
-
let select;
|
|
39
|
-
if (columns instanceof Array) {
|
|
40
|
-
sqlSelect = columns;
|
|
41
|
-
select = columns;
|
|
42
|
-
}
|
|
43
|
-
else {
|
|
44
|
-
sqlSelect = [];
|
|
45
|
-
select = [];
|
|
46
|
-
let c;
|
|
47
|
-
for (const key of Object.keys(columns)) {
|
|
48
|
-
c = columns[key];
|
|
49
|
-
if (typeof c === "string" && c !== key) {
|
|
50
|
-
sqlSelect.push(key + " AS " + c);
|
|
51
|
-
select.push(c);
|
|
52
|
-
}
|
|
53
|
-
else if (c) {
|
|
54
|
-
sqlSelect.push(key);
|
|
55
|
-
select.push(key);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
if (select.length === 0)
|
|
60
|
-
throw new Error("选择列为空");
|
|
61
|
-
return { columns: select, sqlColumns: sqlSelect.join(", ") };
|
|
62
|
-
}
|
|
63
1
|
function condition(conditions, type = "AND") {
|
|
64
2
|
if (typeof conditions === "function")
|
|
65
3
|
conditions = conditions();
|
|
@@ -186,26 +124,33 @@ function selectColumns(columns) {
|
|
|
186
124
|
case "string":
|
|
187
125
|
return columns;
|
|
188
126
|
case "object": {
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
v = columns[k];
|
|
202
|
-
sql += ",";
|
|
127
|
+
if (columns instanceof Array) {
|
|
128
|
+
if (columns.length === 0)
|
|
129
|
+
throw new Error("没有选择任何列");
|
|
130
|
+
return columns.join(",");
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
let sql = "";
|
|
134
|
+
const keys = Object.keys(columns);
|
|
135
|
+
if (keys.length === 0)
|
|
136
|
+
throw new Error("没有选择任何列");
|
|
137
|
+
let k = keys[0];
|
|
138
|
+
let v = columns[k];
|
|
203
139
|
if (typeof v === "string")
|
|
204
140
|
sql += v + " AS " + k;
|
|
205
141
|
else
|
|
206
142
|
sql += k;
|
|
143
|
+
for (let i = 1; i < keys.length; i++) {
|
|
144
|
+
k = keys[i];
|
|
145
|
+
v = columns[k];
|
|
146
|
+
sql += ",";
|
|
147
|
+
if (typeof v === "string")
|
|
148
|
+
sql += v + " AS " + k;
|
|
149
|
+
else
|
|
150
|
+
sql += k;
|
|
151
|
+
}
|
|
152
|
+
return sql;
|
|
207
153
|
}
|
|
208
|
-
return sql;
|
|
209
154
|
}
|
|
210
155
|
default:
|
|
211
156
|
throw new TypeError("columns 应为 string 或 object 类型");
|
|
@@ -291,6 +236,7 @@ class SqlStatementDataset extends SqlStatement {
|
|
|
291
236
|
}
|
|
292
237
|
/** @public */
|
|
293
238
|
class SqlTextStatementDataset extends SqlStatementDataset {
|
|
239
|
+
sql;
|
|
294
240
|
constructor(sql) {
|
|
295
241
|
super();
|
|
296
242
|
this.sql = sql;
|
|
@@ -300,7 +246,6 @@ class SqlTextStatementDataset extends SqlStatementDataset {
|
|
|
300
246
|
}
|
|
301
247
|
}
|
|
302
248
|
|
|
303
|
-
var _YourValuesAs_asName, _YourValuesAs_valuesStr, _YourValuesAs_sql;
|
|
304
249
|
/**
|
|
305
250
|
* SQL 原始字符类。可以使用 String 类代替,这只是为了推断类型
|
|
306
251
|
* @public
|
|
@@ -346,6 +291,7 @@ class SqlValuesCreator {
|
|
|
346
291
|
}
|
|
347
292
|
}
|
|
348
293
|
}
|
|
294
|
+
_map;
|
|
349
295
|
/**
|
|
350
296
|
* 将 JS 对象转为 SQL 的字符值的形式 。 undefined 将被转换为 DEFAULT
|
|
351
297
|
* ```ts
|
|
@@ -564,21 +510,20 @@ class SqlValuesCreator {
|
|
|
564
510
|
class YourValuesAs extends SqlStatementDataset {
|
|
565
511
|
constructor(columns, asName, valuesStr) {
|
|
566
512
|
super();
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
__classPrivateFieldSet(this, _YourValuesAs_asName, asName, "f");
|
|
571
|
-
__classPrivateFieldSet(this, _YourValuesAs_valuesStr, valuesStr, "f");
|
|
572
|
-
__classPrivateFieldSet(this, _YourValuesAs_sql, `(VALUES\n${__classPrivateFieldGet(this, _YourValuesAs_valuesStr, "f")})\nAS ${__classPrivateFieldGet(this, _YourValuesAs_asName, "f")}(${columns.join(",")})`, "f");
|
|
513
|
+
this.#asName = asName;
|
|
514
|
+
this.#valuesStr = valuesStr;
|
|
515
|
+
this.#sql = `(VALUES\n${this.#valuesStr})\nAS ${this.#asName}(${columns.join(",")})`;
|
|
573
516
|
}
|
|
517
|
+
#asName;
|
|
518
|
+
#valuesStr;
|
|
519
|
+
#sql;
|
|
574
520
|
toSelect() {
|
|
575
|
-
return
|
|
521
|
+
return this.#sql;
|
|
576
522
|
}
|
|
577
523
|
toString() {
|
|
578
|
-
return
|
|
524
|
+
return this.#sql;
|
|
579
525
|
}
|
|
580
526
|
}
|
|
581
|
-
_YourValuesAs_asName = new WeakMap(), _YourValuesAs_valuesStr = new WeakMap(), _YourValuesAs_sql = new WeakMap();
|
|
582
527
|
function initColumnAssert(keys, keys_types) {
|
|
583
528
|
let key;
|
|
584
529
|
let value;
|
|
@@ -638,7 +583,7 @@ const pgSqlTransformer = new Map([
|
|
|
638
583
|
],
|
|
639
584
|
]);
|
|
640
585
|
|
|
641
|
-
var
|
|
586
|
+
var _a;
|
|
642
587
|
/**
|
|
643
588
|
* @public ChainSelectWhere 的默认实现
|
|
644
589
|
*/
|
|
@@ -693,34 +638,40 @@ class Selection {
|
|
|
693
638
|
static from(selectable, as) {
|
|
694
639
|
return new this(selectable, as);
|
|
695
640
|
}
|
|
641
|
+
#sql;
|
|
696
642
|
constructor(selectable, as) {
|
|
697
|
-
|
|
698
|
-
_Selection_sql.set(this, void 0);
|
|
699
|
-
__classPrivateFieldSet(this, _Selection_sql, fromAs(selectable, as), "f");
|
|
643
|
+
this.#sql = fromAs(selectable, as);
|
|
700
644
|
}
|
|
701
645
|
toString() {
|
|
702
|
-
return "FROM " +
|
|
646
|
+
return "FROM " + this.#sql;
|
|
647
|
+
}
|
|
648
|
+
#join(type, selectable, as, on) {
|
|
649
|
+
let sql = this.#sql + "\n" + type + " " + fromAs(selectable, as);
|
|
650
|
+
if (on) {
|
|
651
|
+
sql += " ON " + condition(on);
|
|
652
|
+
}
|
|
653
|
+
return new _a(sql);
|
|
703
654
|
}
|
|
704
655
|
fullJoin(selectable, as, on) {
|
|
705
|
-
return
|
|
656
|
+
return this.#join("FULL JOIN", selectable, as, on);
|
|
706
657
|
}
|
|
707
658
|
innerJoin(selectable, as, on) {
|
|
708
|
-
return
|
|
659
|
+
return this.#join("INNER JOIN", selectable, as, on);
|
|
709
660
|
}
|
|
710
661
|
leftJoin(selectable, as, on) {
|
|
711
|
-
return
|
|
662
|
+
return this.#join("LEFT JOIN", selectable, as, on);
|
|
712
663
|
}
|
|
713
664
|
rightJoin(selectable, as, on) {
|
|
714
|
-
return
|
|
665
|
+
return this.#join("RIGHT JOIN", selectable, as, on);
|
|
715
666
|
}
|
|
716
667
|
naturalJoin(selectable, as) {
|
|
717
|
-
return
|
|
668
|
+
return this.#join("NATURAL JOIN", selectable, as);
|
|
718
669
|
}
|
|
719
670
|
crossJoin(selectable, as) {
|
|
720
|
-
return
|
|
671
|
+
return this.#join("CROSS JOIN", selectable, as);
|
|
721
672
|
}
|
|
722
673
|
from(selectable, as) {
|
|
723
|
-
return new _a(
|
|
674
|
+
return new _a(this.#sql + "," + fromAs(selectable, as));
|
|
724
675
|
}
|
|
725
676
|
select(columnsIn) {
|
|
726
677
|
if (typeof columnsIn === "function")
|
|
@@ -730,15 +681,10 @@ class Selection {
|
|
|
730
681
|
return new SqlSelectChain(sql);
|
|
731
682
|
}
|
|
732
683
|
}
|
|
733
|
-
_a = Selection
|
|
734
|
-
let sql = __classPrivateFieldGet(this, _Selection_sql, "f") + "\n" + type + " " + fromAs(selectable, as);
|
|
735
|
-
if (on) {
|
|
736
|
-
sql += " ON " + condition(on);
|
|
737
|
-
}
|
|
738
|
-
return new _a(sql);
|
|
739
|
-
};
|
|
684
|
+
_a = Selection;
|
|
740
685
|
|
|
741
686
|
class SqlChainModify extends SqlStatement {
|
|
687
|
+
sql;
|
|
742
688
|
constructor(sql) {
|
|
743
689
|
super();
|
|
744
690
|
this.sql = sql;
|
|
@@ -751,8 +697,7 @@ class SqlChainModify extends SqlStatement {
|
|
|
751
697
|
columnsStr = "*";
|
|
752
698
|
}
|
|
753
699
|
else {
|
|
754
|
-
|
|
755
|
-
columnsStr = res.sqlColumns;
|
|
700
|
+
columnsStr = selectColumns(returns);
|
|
756
701
|
}
|
|
757
702
|
let sql = this.toString() + "\nRETURNING " + columnsStr;
|
|
758
703
|
return new SqlTextStatementDataset(sql);
|
|
@@ -774,6 +719,7 @@ class SqlChainModify extends SqlStatement {
|
|
|
774
719
|
}
|
|
775
720
|
}
|
|
776
721
|
class SqlInsertConflictBranch {
|
|
722
|
+
sql;
|
|
777
723
|
constructor(sql) {
|
|
778
724
|
this.sql = sql;
|
|
779
725
|
}
|
|
@@ -801,6 +747,7 @@ class SqlInsertConflictBranch {
|
|
|
801
747
|
* @public
|
|
802
748
|
*/
|
|
803
749
|
class DbTable {
|
|
750
|
+
name;
|
|
804
751
|
constructor(name) {
|
|
805
752
|
this.name = name;
|
|
806
753
|
}
|
|
@@ -861,6 +808,7 @@ class DbTable {
|
|
|
861
808
|
|
|
862
809
|
/** @public */
|
|
863
810
|
class DbTableQuery extends DbTable {
|
|
811
|
+
statement;
|
|
864
812
|
constructor(name, statement) {
|
|
865
813
|
super(name);
|
|
866
814
|
this.statement = statement;
|
|
@@ -926,6 +874,11 @@ class DbTableQuery extends DbTable {
|
|
|
926
874
|
* @public
|
|
927
875
|
*/
|
|
928
876
|
class ColumnMeta {
|
|
877
|
+
type;
|
|
878
|
+
sqlType;
|
|
879
|
+
notNull;
|
|
880
|
+
isArray;
|
|
881
|
+
sqlDefault;
|
|
929
882
|
constructor(type,
|
|
930
883
|
/** 数据库原始数据类型 */
|
|
931
884
|
sqlType,
|
|
@@ -953,6 +906,7 @@ class ColumnMeta {
|
|
|
953
906
|
* @public
|
|
954
907
|
*/
|
|
955
908
|
class YourTypeMap {
|
|
909
|
+
typeMap;
|
|
956
910
|
static create(rawTypeMap) {
|
|
957
911
|
return new this(rawTypeMap);
|
|
958
912
|
}
|
|
@@ -978,18 +932,21 @@ function baseType(v) {
|
|
|
978
932
|
* @public
|
|
979
933
|
*/
|
|
980
934
|
class CustomDbType {
|
|
935
|
+
is;
|
|
936
|
+
name;
|
|
937
|
+
static bigint = new CustomDbType(baseType, "bigint");
|
|
938
|
+
static number = new CustomDbType(baseType, "number");
|
|
939
|
+
static string = new CustomDbType(baseType, "string");
|
|
940
|
+
static boolean = new CustomDbType(baseType, "boolean");
|
|
981
941
|
constructor(is, name) {
|
|
982
942
|
this.is = is;
|
|
983
943
|
this.name = name;
|
|
984
944
|
}
|
|
985
945
|
}
|
|
986
|
-
CustomDbType.bigint = new CustomDbType(baseType, "bigint");
|
|
987
|
-
CustomDbType.number = new CustomDbType(baseType, "number");
|
|
988
|
-
CustomDbType.string = new CustomDbType(baseType, "string");
|
|
989
|
-
CustomDbType.boolean = new CustomDbType(baseType, "boolean");
|
|
990
946
|
|
|
991
947
|
/** @public */
|
|
992
948
|
class TypeChecker {
|
|
949
|
+
map;
|
|
993
950
|
constructor(map) {
|
|
994
951
|
this.map = map;
|
|
995
952
|
}
|
|
@@ -1071,11 +1028,13 @@ function getErrStr(expect, actual) {
|
|
|
1071
1028
|
* @public
|
|
1072
1029
|
*/
|
|
1073
1030
|
class YourTable extends DbTableQuery {
|
|
1031
|
+
define;
|
|
1074
1032
|
constructor(name, define, sqlValue) {
|
|
1075
1033
|
super(name, sqlValue);
|
|
1076
1034
|
this.define = define;
|
|
1077
1035
|
this.columns = Object.keys(define);
|
|
1078
1036
|
}
|
|
1037
|
+
columns;
|
|
1079
1038
|
getColumnMeta(name) {
|
|
1080
1039
|
return Reflect.get(this.define, name);
|
|
1081
1040
|
}
|
package/package.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@asla/yoursql",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.2",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"types": "./dist/mod.d.ts",
|
|
7
|
+
"packageManager": "pnpm@10.4.0",
|
|
7
8
|
"scripts": {
|
|
8
9
|
"ci:test": "vitest run",
|
|
9
10
|
"ci:build": "pnpm rollup -c build/rollup.config.js",
|
|
@@ -16,6 +17,7 @@
|
|
|
16
17
|
"devDependencies": {
|
|
17
18
|
"@microsoft/api-extractor": "^7.47.9",
|
|
18
19
|
"@rollup/plugin-typescript": "^12.1.0",
|
|
20
|
+
"prettier": "^3.5.3",
|
|
19
21
|
"rollup": "^4.22.4",
|
|
20
22
|
"tslib": "^2.7.0",
|
|
21
23
|
"typescript": "^5.6.2",
|
|
@@ -27,7 +29,8 @@
|
|
|
27
29
|
"url": "https://github.com/asnowc/yoursql"
|
|
28
30
|
},
|
|
29
31
|
"exports": {
|
|
30
|
-
".": "./dist/
|
|
32
|
+
".": "./dist/sql_gen.js",
|
|
33
|
+
"./client": "./dist/client.js"
|
|
31
34
|
},
|
|
32
35
|
"files": [
|
|
33
36
|
"dist/**/*.js",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|