cl-orm 0.1.0 → 0.1.1
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/lib/drivers/_utils.d.ts +4 -0
- package/lib/drivers/_utils.js +23 -0
- package/lib/drivers/d1.d.ts +2 -0
- package/lib/drivers/d1.js +48 -0
- package/lib/drivers/do.d.ts +2 -0
- package/lib/drivers/do.js +45 -0
- package/{src/index.ts → lib/index.d.ts} +1 -10
- package/lib/index.js +9 -0
- package/lib/queries/_utils.d.ts +1 -0
- package/lib/queries/_utils.js +13 -0
- package/lib/queries/delete.d.ts +5 -0
- package/lib/queries/delete.js +22 -0
- package/lib/queries/insert.d.ts +5 -0
- package/lib/queries/insert.js +19 -0
- package/lib/queries/select.d.ts +5 -0
- package/lib/queries/select.js +55 -0
- package/lib/queries/update.d.ts +5 -0
- package/lib/queries/update.js +25 -0
- package/lib/queries/where/operators.d.ts +23 -0
- package/lib/queries/where/operators.js +60 -0
- package/lib/queries/where/where.d.ts +5 -0
- package/lib/queries/where/where.js +34 -0
- package/lib/types.d.ts +64 -0
- package/lib/types.js +2 -0
- package/package.json +27 -2
- package/.editorconfig +0 -12
- package/.gitattributes +0 -1
- package/.prettierignore +0 -3
- package/.prettierrc +0 -34
- package/.vscode/settings.json +0 -14
- package/mcr.config.ts +0 -12
- package/src/drivers/_utils.ts +0 -31
- package/src/drivers/d1.ts +0 -70
- package/src/drivers/do.ts +0 -81
- package/src/queries/_utils.ts +0 -10
- package/src/queries/delete.ts +0 -26
- package/src/queries/insert.ts +0 -22
- package/src/queries/select.ts +0 -64
- package/src/queries/update.ts +0 -28
- package/src/queries/where/operators.ts +0 -96
- package/src/queries/where/where.ts +0 -50
- package/src/types.ts +0 -76
- package/test/__fixtures__/d1/worker.ts +0 -70
- package/test/__fixtures__/d1/wrangler.jsonc +0 -13
- package/test/__fixtures__/do/worker.ts +0 -106
- package/test/__fixtures__/do/wrangler.jsonc +0 -20
- package/test/e2e/d1.test.ts +0 -113
- package/test/e2e/do.test.ts +0 -116
- package/test/unit/buildDelete.test.ts +0 -36
- package/test/unit/buildInsert.test.ts +0 -36
- package/test/unit/buildSelect.test.ts +0 -137
- package/test/unit/buildUpdate.test.ts +0 -34
- package/test/unit/buildWhere.test.ts +0 -249
- package/test/unit/operators.test.ts +0 -98
- package/test/unit/prepare.test.ts +0 -22
- package/test/unit/quoteIdentifier.test.ts +0 -12
- package/test/unit/returnsRows.test.ts +0 -41
- package/test/unit/setMeta.test.ts +0 -31
- package/tsconfig.build.json +0 -4
- package/tsconfig.json +0 -34
- package/website/.prettierignore +0 -4
- package/website/.prettierrc +0 -34
- package/website/README.md +0 -3
- package/website/docs/documentation/connection.mdx +0 -123
- package/website/docs/documentation/queries/_category_.json +0 -7
- package/website/docs/documentation/queries/delete.mdx +0 -51
- package/website/docs/documentation/queries/insert.mdx +0 -63
- package/website/docs/documentation/queries/operators/_category_.json +0 -7
- package/website/docs/documentation/queries/operators/between.mdx +0 -17
- package/website/docs/documentation/queries/operators/eq.mdx +0 -22
- package/website/docs/documentation/queries/operators/gt.mdx +0 -22
- package/website/docs/documentation/queries/operators/gte.mdx +0 -22
- package/website/docs/documentation/queries/operators/in.mdx +0 -28
- package/website/docs/documentation/queries/operators/is-not-null.mdx +0 -22
- package/website/docs/documentation/queries/operators/is-null.mdx +0 -22
- package/website/docs/documentation/queries/operators/like.mdx +0 -27
- package/website/docs/documentation/queries/operators/lt.mdx +0 -22
- package/website/docs/documentation/queries/operators/lte.mdx +0 -22
- package/website/docs/documentation/queries/operators/ne.mdx +0 -22
- package/website/docs/documentation/queries/operators/not-between.mdx +0 -17
- package/website/docs/documentation/queries/operators/not-like.mdx +0 -27
- package/website/docs/documentation/queries/operators/notIn.mdx +0 -28
- package/website/docs/documentation/queries/select.mdx +0 -294
- package/website/docs/documentation/queries/update.mdx +0 -61
- package/website/docs/documentation/queries/where.mdx +0 -176
- package/website/docs/index.mdx +0 -228
- package/website/docusaurus.config.ts +0 -82
- package/website/package-lock.json +0 -21348
- package/website/package.json +0 -59
- package/website/plugins/locale.ts +0 -16
- package/website/sidebars.ts +0 -18
- package/website/src/components/FAQ.tsx +0 -35
- package/website/src/components/Loading.tsx +0 -4
- package/website/src/components/PageTitle.tsx +0 -29
- package/website/src/css/_faq.scss +0 -39
- package/website/src/css/_loading.scss +0 -43
- package/website/src/css/_mixins.scss +0 -19
- package/website/src/css/custom.scss +0 -149
- package/website/src/pages/index.tsx +0 -17
- package/website/static/.nojekyll +0 -0
- package/website/static/img/favicon.svg +0 -1
- package/website/test/unit/check-extensions.test.ts +0 -48
- package/website/tsconfig.json +0 -14
package/src/drivers/_utils.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import type { Meta } from '../types.js';
|
|
2
|
-
|
|
3
|
-
export const returnsRows = (sql: string): boolean => {
|
|
4
|
-
const trimmed = sql.trimStart().toUpperCase();
|
|
5
|
-
|
|
6
|
-
return (
|
|
7
|
-
trimmed.indexOf('SELECT') === 0 ||
|
|
8
|
-
trimmed.indexOf('WITH') === 0 ||
|
|
9
|
-
trimmed.indexOf('PRAGMA') === 0 ||
|
|
10
|
-
trimmed.indexOf('RETURNING') !== -1
|
|
11
|
-
);
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
export const prepare = (
|
|
15
|
-
db: D1Database,
|
|
16
|
-
sql: string,
|
|
17
|
-
params: unknown[]
|
|
18
|
-
): D1PreparedStatement =>
|
|
19
|
-
params.length > 0 ? db.prepare(sql).bind(...params) : db.prepare(sql);
|
|
20
|
-
|
|
21
|
-
export const setMeta = (
|
|
22
|
-
cursor: SqlStorageCursor<Record<string, SqlStorageValue>>
|
|
23
|
-
): Meta => ({
|
|
24
|
-
duration: 0,
|
|
25
|
-
size_after: 0,
|
|
26
|
-
rows_read: cursor.rowsRead,
|
|
27
|
-
rows_written: cursor.rowsWritten,
|
|
28
|
-
last_row_id: 0,
|
|
29
|
-
changed_db: cursor.rowsWritten > 0,
|
|
30
|
-
changes: cursor.rowsWritten,
|
|
31
|
-
});
|
package/src/drivers/d1.ts
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
Connection,
|
|
3
|
-
DeleteOptions,
|
|
4
|
-
InsertOptions,
|
|
5
|
-
Meta,
|
|
6
|
-
QueryResult,
|
|
7
|
-
SelectOptions,
|
|
8
|
-
UpdateOptions,
|
|
9
|
-
} from '../types.js';
|
|
10
|
-
import { buildDelete } from '../queries/delete.js';
|
|
11
|
-
import { buildInsert } from '../queries/insert.js';
|
|
12
|
-
import { buildSelect } from '../queries/select.js';
|
|
13
|
-
import { buildUpdate } from '../queries/update.js';
|
|
14
|
-
import { prepare, returnsRows } from './_utils.js';
|
|
15
|
-
|
|
16
|
-
export const useD1 = (db: D1Database): Connection => {
|
|
17
|
-
const query = async <T = Record<string, unknown>>(
|
|
18
|
-
sql: string,
|
|
19
|
-
values?: unknown[]
|
|
20
|
-
): Promise<QueryResult<T>> => {
|
|
21
|
-
const statement = values
|
|
22
|
-
? db.prepare(sql).bind(...values)
|
|
23
|
-
: db.prepare(sql);
|
|
24
|
-
|
|
25
|
-
if (returnsRows(sql)) {
|
|
26
|
-
const { results, meta } = await statement.all<T>();
|
|
27
|
-
return { rows: results, meta: meta as Meta };
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const { meta } = await statement.run();
|
|
31
|
-
return { rows: [], meta: meta as Meta };
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
const select = async <T = Record<string, unknown>>(
|
|
35
|
-
options: SelectOptions
|
|
36
|
-
): Promise<T | null | T[]> => {
|
|
37
|
-
const { sql, params } = buildSelect(options);
|
|
38
|
-
const statement = prepare(db, sql, params);
|
|
39
|
-
|
|
40
|
-
if (options.limit === 1) return statement.first<T>();
|
|
41
|
-
|
|
42
|
-
const { results } = await statement.all<T>();
|
|
43
|
-
return results;
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
const insert = async (options: InsertOptions): Promise<Meta> => {
|
|
47
|
-
const { sql, params } = buildInsert(options);
|
|
48
|
-
const { meta } = await query(sql, params);
|
|
49
|
-
|
|
50
|
-
return meta;
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
const update = async (options: UpdateOptions): Promise<Meta> => {
|
|
54
|
-
const { sql, params } = buildUpdate(options);
|
|
55
|
-
const statement = prepare(db, sql, params);
|
|
56
|
-
const { meta } = await statement.run();
|
|
57
|
-
|
|
58
|
-
return meta as Meta;
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
const del = async (options: DeleteOptions): Promise<Meta> => {
|
|
62
|
-
const { sql, params } = buildDelete(options);
|
|
63
|
-
const statement = prepare(db, sql, params);
|
|
64
|
-
const { meta } = await statement.run();
|
|
65
|
-
|
|
66
|
-
return meta as Meta;
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
return { query, select, insert, update, delete: del };
|
|
70
|
-
};
|
package/src/drivers/do.ts
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
Connection,
|
|
3
|
-
DeleteOptions,
|
|
4
|
-
InsertOptions,
|
|
5
|
-
Meta,
|
|
6
|
-
QueryResult,
|
|
7
|
-
SelectOptions,
|
|
8
|
-
UpdateOptions,
|
|
9
|
-
} from '../types.js';
|
|
10
|
-
import { buildDelete } from '../queries/delete.js';
|
|
11
|
-
import { buildInsert } from '../queries/insert.js';
|
|
12
|
-
import { buildSelect } from '../queries/select.js';
|
|
13
|
-
import { buildUpdate } from '../queries/update.js';
|
|
14
|
-
import { returnsRows, setMeta } from './_utils.js';
|
|
15
|
-
|
|
16
|
-
export const useDO = (sql: SqlStorage): Connection => {
|
|
17
|
-
const exec = <T extends Record<string, SqlStorageValue>>(
|
|
18
|
-
query: string,
|
|
19
|
-
values?: unknown[]
|
|
20
|
-
) => (values ? sql.exec<T>(query, ...values) : sql.exec<T>(query));
|
|
21
|
-
|
|
22
|
-
const query = async <T = Record<string, unknown>>(
|
|
23
|
-
queryStr: string,
|
|
24
|
-
values?: unknown[]
|
|
25
|
-
): Promise<QueryResult<T>> => {
|
|
26
|
-
const cursor = exec(queryStr, values);
|
|
27
|
-
|
|
28
|
-
if (returnsRows(queryStr)) {
|
|
29
|
-
const rows = cursor.toArray() as T[];
|
|
30
|
-
return { rows, meta: setMeta(cursor) };
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
return { rows: [], meta: setMeta(cursor) };
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
const select = async <T = Record<string, unknown>>(
|
|
37
|
-
options: SelectOptions
|
|
38
|
-
): Promise<T | null | T[]> => {
|
|
39
|
-
const built = buildSelect(options);
|
|
40
|
-
const cursor = exec(
|
|
41
|
-
built.sql,
|
|
42
|
-
built.params.length > 0 ? built.params : undefined
|
|
43
|
-
);
|
|
44
|
-
|
|
45
|
-
if (options.limit === 1) {
|
|
46
|
-
const rows = cursor.toArray() as T[];
|
|
47
|
-
return rows[0] ?? null;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
return cursor.toArray() as T[];
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
const insert = async (options: InsertOptions): Promise<Meta> => {
|
|
54
|
-
const built = buildInsert(options);
|
|
55
|
-
const cursor = exec(built.sql, built.params);
|
|
56
|
-
|
|
57
|
-
return setMeta(cursor);
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
const update = async (options: UpdateOptions): Promise<Meta> => {
|
|
61
|
-
const built = buildUpdate(options);
|
|
62
|
-
const cursor = exec(
|
|
63
|
-
built.sql,
|
|
64
|
-
built.params.length > 0 ? built.params : undefined
|
|
65
|
-
);
|
|
66
|
-
|
|
67
|
-
return setMeta(cursor);
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
const del = async (options: DeleteOptions): Promise<Meta> => {
|
|
71
|
-
const built = buildDelete(options);
|
|
72
|
-
const cursor = exec(
|
|
73
|
-
built.sql,
|
|
74
|
-
built.params.length > 0 ? built.params : undefined
|
|
75
|
-
);
|
|
76
|
-
|
|
77
|
-
return setMeta(cursor);
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
return { query, select, insert, update, delete: del };
|
|
81
|
-
};
|
package/src/queries/_utils.ts
DELETED
package/src/queries/delete.ts
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import type { DeleteOptions } from '../types.js';
|
|
2
|
-
import { quoteIdentifier } from './_utils.js';
|
|
3
|
-
import { buildWhere } from './where/where.js';
|
|
4
|
-
|
|
5
|
-
export const buildDelete = (
|
|
6
|
-
options: DeleteOptions
|
|
7
|
-
): { sql: string; params: unknown[] } => {
|
|
8
|
-
const parts: string[] = ['DELETE FROM', quoteIdentifier(options.table)];
|
|
9
|
-
const params: unknown[] = [];
|
|
10
|
-
|
|
11
|
-
if (options.where) {
|
|
12
|
-
const where = buildWhere(options.where);
|
|
13
|
-
|
|
14
|
-
parts.push('WHERE', where.sql);
|
|
15
|
-
params.push(...where.params);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
if (options.limit !== undefined) {
|
|
19
|
-
parts.push('LIMIT ?');
|
|
20
|
-
params.push(options.limit);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
if (options.params) params.unshift(...options.params);
|
|
24
|
-
|
|
25
|
-
return { sql: parts.join(' '), params };
|
|
26
|
-
};
|
package/src/queries/insert.ts
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import type { InsertOptions } from '../types.js';
|
|
2
|
-
import { quoteIdentifier } from './_utils.js';
|
|
3
|
-
|
|
4
|
-
export const buildInsert = (
|
|
5
|
-
options: InsertOptions
|
|
6
|
-
): { sql: string; params: unknown[] } => {
|
|
7
|
-
const rows = Array.isArray(options.values)
|
|
8
|
-
? options.values
|
|
9
|
-
: [options.values];
|
|
10
|
-
const columns = Object.keys(rows[0]);
|
|
11
|
-
|
|
12
|
-
const columnsSql = columns.map(quoteIdentifier).join(', ');
|
|
13
|
-
const placeholders = `(${columns.map(() => '?').join(', ')})`;
|
|
14
|
-
const valuesSql = rows.map(() => placeholders).join(', ');
|
|
15
|
-
|
|
16
|
-
const params = rows.flatMap((row) => columns.map((col) => row[col]));
|
|
17
|
-
|
|
18
|
-
return {
|
|
19
|
-
sql: `INSERT INTO ${quoteIdentifier(options.table)} (${columnsSql}) VALUES ${valuesSql}`,
|
|
20
|
-
params,
|
|
21
|
-
};
|
|
22
|
-
};
|
package/src/queries/select.ts
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import type { JoinOptions, SelectOptions } from '../types.js';
|
|
2
|
-
import { quoteIdentifier } from './_utils.js';
|
|
3
|
-
import { buildWhere } from './where/where.js';
|
|
4
|
-
|
|
5
|
-
const buildColumns = (columns?: string | string[]): string => {
|
|
6
|
-
if (!columns) return '*';
|
|
7
|
-
if (typeof columns === 'string') return columns;
|
|
8
|
-
|
|
9
|
-
return columns.map(quoteIdentifier).join(', ');
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
const buildJoin = (join: JoinOptions): string => {
|
|
13
|
-
const type = join.outer
|
|
14
|
-
? `${join.type.toUpperCase()} OUTER`
|
|
15
|
-
: join.type.toUpperCase();
|
|
16
|
-
|
|
17
|
-
return `${type} JOIN ${quoteIdentifier(join.table)} ON ${quoteIdentifier(join.on.a)} = ${quoteIdentifier(join.on.b)}`;
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
export const buildSelect = (
|
|
21
|
-
options: SelectOptions
|
|
22
|
-
): { sql: string; params: unknown[] } => {
|
|
23
|
-
const parts: string[] = ['SELECT'];
|
|
24
|
-
const params: unknown[] = [];
|
|
25
|
-
|
|
26
|
-
if (options.distinct) parts.push('DISTINCT');
|
|
27
|
-
|
|
28
|
-
parts.push(buildColumns(options.columns));
|
|
29
|
-
parts.push('FROM', quoteIdentifier(options.table));
|
|
30
|
-
|
|
31
|
-
if (options.join) {
|
|
32
|
-
const joins = Array.isArray(options.join) ? options.join : [options.join];
|
|
33
|
-
for (const join of joins) {
|
|
34
|
-
parts.push(buildJoin(join));
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
if (options.where) {
|
|
39
|
-
const where = buildWhere(options.where);
|
|
40
|
-
parts.push('WHERE', where.sql);
|
|
41
|
-
params.push(...where.params);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
if (options.groupBy) parts.push('GROUP BY', quoteIdentifier(options.groupBy));
|
|
45
|
-
|
|
46
|
-
if (options.orderBy) {
|
|
47
|
-
const [column, direction = 'ASC'] = options.orderBy;
|
|
48
|
-
parts.push('ORDER BY', quoteIdentifier(column), direction);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
if (options.limit !== undefined) {
|
|
52
|
-
parts.push('LIMIT ?');
|
|
53
|
-
params.push(options.limit);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
if (options.offset !== undefined) {
|
|
57
|
-
parts.push('OFFSET ?');
|
|
58
|
-
params.push(options.offset);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
if (options.params) params.unshift(...options.params);
|
|
62
|
-
|
|
63
|
-
return { sql: parts.join(' '), params };
|
|
64
|
-
};
|
package/src/queries/update.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import type { UpdateOptions } from '../types.js';
|
|
2
|
-
import { quoteIdentifier } from './_utils.js';
|
|
3
|
-
import { buildWhere } from './where/where.js';
|
|
4
|
-
|
|
5
|
-
export const buildUpdate = (
|
|
6
|
-
options: UpdateOptions
|
|
7
|
-
): { sql: string; params: unknown[] } => {
|
|
8
|
-
const columns = Object.keys(options.set);
|
|
9
|
-
const setSql = columns.map((col) => `${quoteIdentifier(col)} = ?`).join(', ');
|
|
10
|
-
const params: unknown[] = columns.map((col) => options.set[col]);
|
|
11
|
-
|
|
12
|
-
const parts: string[] = [
|
|
13
|
-
'UPDATE',
|
|
14
|
-
quoteIdentifier(options.table),
|
|
15
|
-
'SET',
|
|
16
|
-
setSql,
|
|
17
|
-
];
|
|
18
|
-
|
|
19
|
-
if (options.where) {
|
|
20
|
-
const where = buildWhere(options.where);
|
|
21
|
-
parts.push('WHERE', where.sql);
|
|
22
|
-
params.push(...where.params);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
if (options.params) params.push(...options.params);
|
|
26
|
-
|
|
27
|
-
return { sql: parts.join(' '), params };
|
|
28
|
-
};
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import type { Condition, Param } from '../../types.js';
|
|
2
|
-
import { quoteIdentifier } from '../_utils.js';
|
|
3
|
-
|
|
4
|
-
const comparison = (
|
|
5
|
-
column: string,
|
|
6
|
-
operator: string,
|
|
7
|
-
param: Param
|
|
8
|
-
): Condition => ({
|
|
9
|
-
condition: `${quoteIdentifier(column)} ${operator} ?`,
|
|
10
|
-
params: [param],
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
export const OP = {
|
|
14
|
-
eq: (column: string, param: Param): Condition =>
|
|
15
|
-
comparison(column, '=', param),
|
|
16
|
-
ne: (column: string, param: Param): Condition =>
|
|
17
|
-
comparison(column, '!=', param),
|
|
18
|
-
gt: (column: string, param: Param): Condition =>
|
|
19
|
-
comparison(column, '>', param),
|
|
20
|
-
lt: (column: string, param: Param): Condition =>
|
|
21
|
-
comparison(column, '<', param),
|
|
22
|
-
gte: (column: string, param: Param): Condition =>
|
|
23
|
-
comparison(column, '>=', param),
|
|
24
|
-
lte: (column: string, param: Param): Condition =>
|
|
25
|
-
comparison(column, '<=', param),
|
|
26
|
-
like: (column: string, param: Param): Condition =>
|
|
27
|
-
comparison(column, 'LIKE', param),
|
|
28
|
-
notLike: (column: string, param: Param): Condition =>
|
|
29
|
-
comparison(column, 'NOT LIKE', param),
|
|
30
|
-
|
|
31
|
-
isNull: (column: string): Condition => ({
|
|
32
|
-
condition: `${quoteIdentifier(column)} IS NULL`,
|
|
33
|
-
params: [],
|
|
34
|
-
}),
|
|
35
|
-
|
|
36
|
-
isNotNull: (column: string): Condition => ({
|
|
37
|
-
condition: `${quoteIdentifier(column)} IS NOT NULL`,
|
|
38
|
-
params: [],
|
|
39
|
-
}),
|
|
40
|
-
|
|
41
|
-
in: ((
|
|
42
|
-
column: string,
|
|
43
|
-
valuesOrSubquery: Param[] | string,
|
|
44
|
-
subqueryParams?: Param[]
|
|
45
|
-
): Condition => {
|
|
46
|
-
if (typeof valuesOrSubquery === 'string') {
|
|
47
|
-
return {
|
|
48
|
-
condition: `${quoteIdentifier(column)} IN (${valuesOrSubquery})`,
|
|
49
|
-
params: subqueryParams ?? [],
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const placeholders = valuesOrSubquery.map(() => '?').join(', ');
|
|
54
|
-
|
|
55
|
-
return {
|
|
56
|
-
condition: `${quoteIdentifier(column)} IN (${placeholders})`,
|
|
57
|
-
params: valuesOrSubquery,
|
|
58
|
-
};
|
|
59
|
-
}) as {
|
|
60
|
-
(column: string, params: Param[]): Condition;
|
|
61
|
-
(column: string, subquery: string, params: Param[]): Condition;
|
|
62
|
-
},
|
|
63
|
-
|
|
64
|
-
notIn: ((
|
|
65
|
-
column: string,
|
|
66
|
-
valuesOrSubquery: Param[] | string,
|
|
67
|
-
subqueryParams?: Param[]
|
|
68
|
-
): Condition => {
|
|
69
|
-
if (typeof valuesOrSubquery === 'string') {
|
|
70
|
-
return {
|
|
71
|
-
condition: `${quoteIdentifier(column)} NOT IN (${valuesOrSubquery})`,
|
|
72
|
-
params: subqueryParams ?? [],
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
const placeholders = valuesOrSubquery.map(() => '?').join(', ');
|
|
77
|
-
|
|
78
|
-
return {
|
|
79
|
-
condition: `${quoteIdentifier(column)} NOT IN (${placeholders})`,
|
|
80
|
-
params: valuesOrSubquery,
|
|
81
|
-
};
|
|
82
|
-
}) as {
|
|
83
|
-
(column: string, params: Param[]): Condition;
|
|
84
|
-
(column: string, subquery: string, params: Param[]): Condition;
|
|
85
|
-
},
|
|
86
|
-
|
|
87
|
-
between: (column: string, params: [Param, Param]): Condition => ({
|
|
88
|
-
condition: `${quoteIdentifier(column)} BETWEEN ? AND ?`,
|
|
89
|
-
params,
|
|
90
|
-
}),
|
|
91
|
-
|
|
92
|
-
notBetween: (column: string, params: [Param, Param]): Condition => ({
|
|
93
|
-
condition: `${quoteIdentifier(column)} NOT BETWEEN ? AND ?`,
|
|
94
|
-
params,
|
|
95
|
-
}),
|
|
96
|
-
};
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
Condition,
|
|
3
|
-
Connector,
|
|
4
|
-
Param,
|
|
5
|
-
WhereClause,
|
|
6
|
-
WhereItem,
|
|
7
|
-
} from '../../types.js';
|
|
8
|
-
|
|
9
|
-
const isConnector = (value: WhereItem): value is Connector =>
|
|
10
|
-
typeof value === 'string' && ['AND', 'OR', 'XOR', 'NOT'].includes(value);
|
|
11
|
-
|
|
12
|
-
const isCondition = (value: WhereItem): value is Condition =>
|
|
13
|
-
typeof value === 'object' && !Array.isArray(value) && 'condition' in value;
|
|
14
|
-
|
|
15
|
-
const processItems = (items: WhereItem[]): { sql: string; params: Param[] } => {
|
|
16
|
-
const parts: string[] = [];
|
|
17
|
-
const params: Param[] = [];
|
|
18
|
-
|
|
19
|
-
for (const item of items) {
|
|
20
|
-
if (isConnector(item)) {
|
|
21
|
-
parts.push(item);
|
|
22
|
-
continue;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
if (isCondition(item)) {
|
|
26
|
-
parts.push(item.condition);
|
|
27
|
-
params.push(...item.params);
|
|
28
|
-
continue;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
if (Array.isArray(item)) {
|
|
32
|
-
const group = processItems(item);
|
|
33
|
-
|
|
34
|
-
parts.push(`(${group.sql})`);
|
|
35
|
-
params.push(...group.params);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
return { sql: parts.join(' '), params };
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
export const buildWhere = (
|
|
43
|
-
where: WhereClause
|
|
44
|
-
): { sql: string; params: Param[] } => {
|
|
45
|
-
if (typeof where === 'string') return { sql: where, params: [] };
|
|
46
|
-
if (isCondition(where))
|
|
47
|
-
return { sql: where.condition, params: [...where.params] };
|
|
48
|
-
|
|
49
|
-
return processItems(where);
|
|
50
|
-
};
|
package/src/types.ts
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
export type Param = string | number | boolean | null;
|
|
2
|
-
|
|
3
|
-
export type Condition = {
|
|
4
|
-
condition: string;
|
|
5
|
-
params: Param[];
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
export type Connector = 'AND' | 'OR' | 'XOR' | 'NOT';
|
|
9
|
-
|
|
10
|
-
export type WhereItem = Condition | Connector | WhereItem[];
|
|
11
|
-
|
|
12
|
-
export type WhereClause = string | Condition | WhereItem[];
|
|
13
|
-
|
|
14
|
-
type Values = Record<string, unknown>;
|
|
15
|
-
|
|
16
|
-
export type InsertOptions = {
|
|
17
|
-
table: string;
|
|
18
|
-
values: Values | Values[];
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
export type JoinOptions = {
|
|
22
|
-
type: 'left' | 'right' | 'inner' | 'cross';
|
|
23
|
-
table: string;
|
|
24
|
-
on: {
|
|
25
|
-
a: string;
|
|
26
|
-
b: string;
|
|
27
|
-
};
|
|
28
|
-
outer?: boolean;
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
export type SelectOptions = {
|
|
32
|
-
distinct?: boolean;
|
|
33
|
-
columns?: string | string[];
|
|
34
|
-
table: string;
|
|
35
|
-
join?: JoinOptions | JoinOptions[];
|
|
36
|
-
where?: WhereClause;
|
|
37
|
-
limit?: number;
|
|
38
|
-
offset?: number;
|
|
39
|
-
groupBy?: string;
|
|
40
|
-
orderBy?: [string] | [string, 'ASC' | 'DESC'];
|
|
41
|
-
params?: unknown[];
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
export type UpdateOptions = {
|
|
45
|
-
table: string;
|
|
46
|
-
set: Record<string, unknown>;
|
|
47
|
-
where?: WhereClause;
|
|
48
|
-
params?: unknown[];
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
export type DeleteOptions = {
|
|
52
|
-
table: string;
|
|
53
|
-
where?: WhereClause;
|
|
54
|
-
limit?: number;
|
|
55
|
-
params?: unknown[];
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
export type Meta = D1Meta & Record<string, unknown>;
|
|
59
|
-
|
|
60
|
-
export type QueryResult<T> = { rows: T[]; meta: Meta };
|
|
61
|
-
|
|
62
|
-
export type Connection = {
|
|
63
|
-
query: <T = Record<string, unknown>>(
|
|
64
|
-
sql: string,
|
|
65
|
-
values?: unknown[]
|
|
66
|
-
) => Promise<QueryResult<T>>;
|
|
67
|
-
select: {
|
|
68
|
-
<T = Record<string, unknown>>(
|
|
69
|
-
options: SelectOptions & { limit: 1 }
|
|
70
|
-
): Promise<T | null>;
|
|
71
|
-
<T = Record<string, unknown>>(options: SelectOptions): Promise<T[]>;
|
|
72
|
-
};
|
|
73
|
-
insert: (options: InsertOptions) => Promise<Meta>;
|
|
74
|
-
update: (options: UpdateOptions) => Promise<Meta>;
|
|
75
|
-
delete: (options: DeleteOptions) => Promise<Meta>;
|
|
76
|
-
};
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import { OP, useD1 } from '../../../src/index.js';
|
|
2
|
-
|
|
3
|
-
interface Env {
|
|
4
|
-
DB: D1Database;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export default {
|
|
8
|
-
async fetch(request: Request, env: Env): Promise<Response> {
|
|
9
|
-
const url = new URL(request.url);
|
|
10
|
-
const db = useD1(env.DB);
|
|
11
|
-
|
|
12
|
-
switch (url.pathname) {
|
|
13
|
-
case '/setup': {
|
|
14
|
-
await db.query('DROP TABLE IF EXISTS users');
|
|
15
|
-
await db.query(
|
|
16
|
-
'CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, email TEXT NOT NULL)'
|
|
17
|
-
);
|
|
18
|
-
return Response.json({ ok: true });
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
case '/query': {
|
|
22
|
-
const sql = url.searchParams.get('sql')!;
|
|
23
|
-
const result = await db.query(sql);
|
|
24
|
-
return Response.json(result);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
case '/insert': {
|
|
28
|
-
const name = url.searchParams.get('name')!;
|
|
29
|
-
const email = url.searchParams.get('email')!;
|
|
30
|
-
const meta = await db.insert({
|
|
31
|
-
table: 'users',
|
|
32
|
-
values: { name, email },
|
|
33
|
-
});
|
|
34
|
-
return Response.json(meta);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
case '/select': {
|
|
38
|
-
const limit = url.searchParams.get('limit');
|
|
39
|
-
const rows = await db.select({
|
|
40
|
-
table: 'users',
|
|
41
|
-
...(limit ? { limit: Number(limit) } : {}),
|
|
42
|
-
});
|
|
43
|
-
return Response.json({ rows });
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
case '/update': {
|
|
47
|
-
const name = url.searchParams.get('name')!;
|
|
48
|
-
const where = url.searchParams.get('where')!;
|
|
49
|
-
const meta = await db.update({
|
|
50
|
-
table: 'users',
|
|
51
|
-
set: { name },
|
|
52
|
-
where: OP.eq('name', where),
|
|
53
|
-
});
|
|
54
|
-
return Response.json(meta);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
case '/delete': {
|
|
58
|
-
const name = url.searchParams.get('name')!;
|
|
59
|
-
const meta = await db.delete({
|
|
60
|
-
table: 'users',
|
|
61
|
-
where: OP.eq('name', name),
|
|
62
|
-
});
|
|
63
|
-
return Response.json(meta);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
default:
|
|
67
|
-
return new Response('Not found', { status: 404 });
|
|
68
|
-
}
|
|
69
|
-
},
|
|
70
|
-
};
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "../../../node_modules/wrangler/config-schema.json",
|
|
3
|
-
"name": "d1-test",
|
|
4
|
-
"main": "worker.ts",
|
|
5
|
-
"compatibility_date": "2026-01-28",
|
|
6
|
-
"d1_databases": [
|
|
7
|
-
{
|
|
8
|
-
"binding": "DB",
|
|
9
|
-
"database_name": "d1-tutorial-db",
|
|
10
|
-
"database_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
11
|
-
}
|
|
12
|
-
]
|
|
13
|
-
}
|