@ignisia/sql 0.1.0
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/README.md +113 -0
- package/dist/chunk-4DQRB5XS.js +94 -0
- package/dist/chunk-CIWX3UCZ.js +51 -0
- package/dist/chunk-D2ASIT4Q.js +44 -0
- package/dist/chunk-FYSNJAGD.js +19 -0
- package/dist/chunk-G3LSCLIQ.js +104 -0
- package/dist/chunk-GLOHF5CP.js +9 -0
- package/dist/chunk-GY7R637S.js +113 -0
- package/dist/chunk-HKTHKQLK.js +98 -0
- package/dist/chunk-JF7OSNH4.js +40 -0
- package/dist/chunk-MG2S4V4N.js +60 -0
- package/dist/chunk-TQ2GXAE7.js +663 -0
- package/dist/chunk-V4OMHVJN.js +96 -0
- package/dist/chunk-W2DR3ZVK.js +59 -0
- package/dist/chunk-WVJGTZFI.js +60 -0
- package/dist/chunk-Y7FSRHH3.js +22 -0
- package/dist/column/constants.d.ts +97 -0
- package/dist/column/constants.js +9 -0
- package/dist/column/index.d.ts +42 -0
- package/dist/column/index.js +8 -0
- package/dist/column/types.d.ts +43 -0
- package/dist/column/types.js +2 -0
- package/dist/database/alter.d.ts +52 -0
- package/dist/database/alter.js +15 -0
- package/dist/database/column.d.ts +24 -0
- package/dist/database/column.js +11 -0
- package/dist/database/contract.d.ts +8 -0
- package/dist/database/contract.js +0 -0
- package/dist/database/index.d.ts +8 -0
- package/dist/database/index.js +19 -0
- package/dist/database/table.d.ts +21 -0
- package/dist/database/table.js +19 -0
- package/dist/database/types.d.ts +7 -0
- package/dist/database/types.js +0 -0
- package/dist/database/wrapper.d.ts +36 -0
- package/dist/database/wrapper.js +9 -0
- package/dist/index-DJhQVUY3.d.ts +344 -0
- package/dist/index-Dcm5xIpR.d.ts +99 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +32 -0
- package/dist/migration/index.d.ts +30 -0
- package/dist/migration/index.js +6 -0
- package/dist/migration/runner.d.ts +3 -0
- package/dist/migration/runner.js +69 -0
- package/dist/migration/type.d.ts +19 -0
- package/dist/migration/type.js +0 -0
- package/dist/query/builder.d.ts +14 -0
- package/dist/query/builder.js +16 -0
- package/dist/query/condition.d.ts +7 -0
- package/dist/query/condition.js +24 -0
- package/dist/query/constants.d.ts +58 -0
- package/dist/query/constants.js +18 -0
- package/dist/query/contract.d.ts +7 -0
- package/dist/query/contract.js +0 -0
- package/dist/query/helper.d.ts +7 -0
- package/dist/query/helper.js +18 -0
- package/dist/query/index.d.ts +7 -0
- package/dist/query/index.js +10 -0
- package/dist/query/join.d.ts +16 -0
- package/dist/query/join.js +6 -0
- package/dist/query/sql.d.ts +17 -0
- package/dist/query/sql.js +16 -0
- package/dist/query/types.d.ts +7 -0
- package/dist/query/types.js +0 -0
- package/dist/query/utilities.d.ts +34 -0
- package/dist/query/utilities.js +24 -0
- package/dist/table/constants.d.ts +7 -0
- package/dist/table/constants.js +6 -0
- package/dist/table/index.d.ts +7 -0
- package/dist/table/index.js +14 -0
- package/dist/table/types.d.ts +7 -0
- package/dist/table/types.js +0 -0
- package/dist/table/utilities.d.ts +7 -0
- package/dist/table/utilities.js +15 -0
- package/dist/types.d.ts +3 -0
- package/dist/types.js +0 -0
- package/dist/utilities.d.ts +4 -0
- package/dist/utilities.js +8 -0
- package/package.json +20 -0
package/README.md
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# @Ignisia/SQL
|
|
2
|
+
|
|
3
|
+
Type-safe SQL query builder for Bun SQL and SQLite.
|
|
4
|
+
|
|
5
|
+
## Requirements
|
|
6
|
+
|
|
7
|
+
- [Bun](https://bun.sh/)
|
|
8
|
+
- [PostgreSQL](https://www.postgresql.org/) (optional, only for PostgreSQL dialect)
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
bun add @ignisia/sql
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Usage
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
import { Table, Column, Database } from '@ignisia/sql';
|
|
20
|
+
|
|
21
|
+
// Define a table
|
|
22
|
+
const users = Table.define(
|
|
23
|
+
name: 'users',
|
|
24
|
+
columns: {
|
|
25
|
+
// Define a column called "id"
|
|
26
|
+
id: Column.define({
|
|
27
|
+
type: 'SERIAL',
|
|
28
|
+
})
|
|
29
|
+
.primaryKey(),
|
|
30
|
+
name: Column.define({
|
|
31
|
+
type: 'TEXT',
|
|
32
|
+
length: 255,
|
|
33
|
+
}).notNull(),
|
|
34
|
+
email: Column.define({
|
|
35
|
+
type: 'TEXT',
|
|
36
|
+
length: 255,
|
|
37
|
+
}).notNull(),
|
|
38
|
+
password: Column.define({
|
|
39
|
+
type: 'TEXT',
|
|
40
|
+
length: 255,
|
|
41
|
+
}).notNull(),
|
|
42
|
+
},
|
|
43
|
+
// Use soft delete, set `paranoid` to `false` to use hard delete
|
|
44
|
+
// By default the name of the paranoid column called "deletedAt", pass a string to renames it
|
|
45
|
+
paranoid: true,
|
|
46
|
+
// Enable timestamps to track created at and updated at, set `timestamp` to `false` to disable timestamp
|
|
47
|
+
// By default the name of the created at column called "createdAt" and the name of the updated at column called "updatedAt"
|
|
48
|
+
// Pass an object with `createdAt` and `updatedAt` to rename them
|
|
49
|
+
timestamp: true,
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
// Define a database
|
|
53
|
+
const db = Database.define({
|
|
54
|
+
// Define a connection with PostgreSQL
|
|
55
|
+
dialect: 'postgres',
|
|
56
|
+
// Define a PostgreSQL connection
|
|
57
|
+
config: {
|
|
58
|
+
host: 'localhost',
|
|
59
|
+
port: 5432,
|
|
60
|
+
username: 'postgres',
|
|
61
|
+
password: 'postgres',
|
|
62
|
+
database: 'my_database',
|
|
63
|
+
},
|
|
64
|
+
// Define tables that connected to the database
|
|
65
|
+
// This will automatically assign db properties to each table so it can do query
|
|
66
|
+
tables: {
|
|
67
|
+
users,
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// Using the database
|
|
72
|
+
|
|
73
|
+
// Fetch all users
|
|
74
|
+
const listUsers = await db.table('users').select().query()
|
|
75
|
+
// ^ Add .limit before the .query() to limit the number of results
|
|
76
|
+
// ^ Add .offset before the .query() to offset the results
|
|
77
|
+
// ^ Add .orderBy before the .query() to order the results
|
|
78
|
+
// ^ Add .where before the .query() to filter the results
|
|
79
|
+
// ^ Replace .query() with .toQuery() to know what is the generated query and what are the parameters that will be passed on the query
|
|
80
|
+
|
|
81
|
+
// Create a new user
|
|
82
|
+
const newUsers = await db.table('users').insert(
|
|
83
|
+
{
|
|
84
|
+
name: 'John Doe',
|
|
85
|
+
email: 'jRZQ3@example.com',
|
|
86
|
+
password: 'password',
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
name: 'Jane Doe',
|
|
90
|
+
email: 'YKt0x@example.com',
|
|
91
|
+
password: 'password',
|
|
92
|
+
}
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
// Delete a user
|
|
96
|
+
const deletedUsers = await db.table('users').delete()
|
|
97
|
+
// ^ Add .where before the .query() to filter the deleted rows
|
|
98
|
+
|
|
99
|
+
// Update a user
|
|
100
|
+
const updatedUsers = await db.table('users').update({
|
|
101
|
+
name: 'John Doe',
|
|
102
|
+
email: 'jRZQ3@example.com',
|
|
103
|
+
password: 'password',
|
|
104
|
+
});
|
|
105
|
+
// ^ Add .where before the .query() to filter the updated rows
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
> Some of the functions is not covered in the usage example above
|
|
109
|
+
> **Note**: `@ignisia/sql` does not do any input validations, therefore it is your responsibility to validate the user input on your own.
|
|
110
|
+
|
|
111
|
+
## Security Considerations
|
|
112
|
+
|
|
113
|
+
- For SQLite Dialect, we recommend to use along with the `@ignisia/securedb` package to encrypt/decrypt the database file.
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DatabasePsql,
|
|
3
|
+
DatabaseSqlite
|
|
4
|
+
} from "./chunk-HKTHKQLK.js";
|
|
5
|
+
import {
|
|
6
|
+
addColumn,
|
|
7
|
+
dropColumn,
|
|
8
|
+
renameColumn
|
|
9
|
+
} from "./chunk-JF7OSNH4.js";
|
|
10
|
+
import {
|
|
11
|
+
createTable,
|
|
12
|
+
dropTable,
|
|
13
|
+
renameTable
|
|
14
|
+
} from "./chunk-D2ASIT4Q.js";
|
|
15
|
+
import {
|
|
16
|
+
alterColumnType,
|
|
17
|
+
dropColumnDefault,
|
|
18
|
+
dropColumnNotNull,
|
|
19
|
+
setColumnDefault
|
|
20
|
+
} from "./chunk-V4OMHVJN.js";
|
|
21
|
+
import {
|
|
22
|
+
Dialect
|
|
23
|
+
} from "./chunk-GLOHF5CP.js";
|
|
24
|
+
|
|
25
|
+
// src/database/index.ts
|
|
26
|
+
var Database = class _Database {
|
|
27
|
+
dialect;
|
|
28
|
+
defintion;
|
|
29
|
+
tables;
|
|
30
|
+
client;
|
|
31
|
+
createTable;
|
|
32
|
+
renameTable;
|
|
33
|
+
dropTable;
|
|
34
|
+
addColumn;
|
|
35
|
+
renameColumn;
|
|
36
|
+
dropColumn;
|
|
37
|
+
alterColumnType;
|
|
38
|
+
setColumnDefault;
|
|
39
|
+
dropColumnDefault;
|
|
40
|
+
setColumnNotNull;
|
|
41
|
+
dropColumnNotNull;
|
|
42
|
+
constructor(options) {
|
|
43
|
+
this.dialect = options.dialect;
|
|
44
|
+
this.tables = options.tables ?? {};
|
|
45
|
+
this.defintion = {
|
|
46
|
+
dialect: options.dialect,
|
|
47
|
+
config: options.config
|
|
48
|
+
};
|
|
49
|
+
this.client = options.dialect === Dialect.POSTGRES ? new DatabasePsql(options.config) : new DatabaseSqlite(options.config);
|
|
50
|
+
if (options.tables) {
|
|
51
|
+
for (const tableName in options.tables) {
|
|
52
|
+
options.tables[tableName].database = this.client;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
this.createTable = createTable.bind(this);
|
|
56
|
+
this.renameTable = renameTable.bind(this);
|
|
57
|
+
this.dropTable = dropTable.bind(this);
|
|
58
|
+
this.addColumn = addColumn.bind(this);
|
|
59
|
+
this.renameColumn = renameColumn.bind(this);
|
|
60
|
+
this.dropColumn = dropColumn.bind(this);
|
|
61
|
+
this.alterColumnType = alterColumnType.bind(
|
|
62
|
+
this
|
|
63
|
+
);
|
|
64
|
+
this.setColumnDefault = setColumnDefault.bind(
|
|
65
|
+
this
|
|
66
|
+
);
|
|
67
|
+
this.dropColumnDefault = dropColumnDefault.bind(
|
|
68
|
+
this
|
|
69
|
+
);
|
|
70
|
+
this.setColumnNotNull = setColumnDefault.bind(
|
|
71
|
+
this
|
|
72
|
+
);
|
|
73
|
+
this.dropColumnNotNull = dropColumnNotNull.bind(
|
|
74
|
+
this
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
table(tableName) {
|
|
78
|
+
if (!this.tables[tableName]) {
|
|
79
|
+
throw new Error(`Table ${tableName} does not exist`);
|
|
80
|
+
}
|
|
81
|
+
const table = this.tables[tableName];
|
|
82
|
+
return table.query();
|
|
83
|
+
}
|
|
84
|
+
async transaction(fn) {
|
|
85
|
+
return this.client.transaction(fn);
|
|
86
|
+
}
|
|
87
|
+
static define(options) {
|
|
88
|
+
return new _Database(options);
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
export {
|
|
93
|
+
Database
|
|
94
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// src/migration/index.ts
|
|
2
|
+
var Migration = class _Migration {
|
|
3
|
+
db;
|
|
4
|
+
_up;
|
|
5
|
+
_down;
|
|
6
|
+
constructor(options) {
|
|
7
|
+
this.db = options.db;
|
|
8
|
+
this._up = options.up;
|
|
9
|
+
this._down = options.down;
|
|
10
|
+
}
|
|
11
|
+
get up() {
|
|
12
|
+
return this._up;
|
|
13
|
+
}
|
|
14
|
+
get down() {
|
|
15
|
+
return this._down;
|
|
16
|
+
}
|
|
17
|
+
static setUp(migrator, fn) {
|
|
18
|
+
migrator._up = () => fn(migrator.db);
|
|
19
|
+
return migrator;
|
|
20
|
+
}
|
|
21
|
+
static setDown(migrator, fn) {
|
|
22
|
+
migrator._down = () => fn(migrator.db);
|
|
23
|
+
return migrator;
|
|
24
|
+
}
|
|
25
|
+
static define(db, options) {
|
|
26
|
+
const migration = new _Migration({
|
|
27
|
+
db,
|
|
28
|
+
up: options?.up ? () => options.up(db) : null,
|
|
29
|
+
down: options?.down ? () => options.down(db) : null
|
|
30
|
+
});
|
|
31
|
+
return {
|
|
32
|
+
migration,
|
|
33
|
+
setUp(fn) {
|
|
34
|
+
return _Migration.setUp(
|
|
35
|
+
migration,
|
|
36
|
+
fn
|
|
37
|
+
);
|
|
38
|
+
},
|
|
39
|
+
setDown(fn) {
|
|
40
|
+
return _Migration.setDown(
|
|
41
|
+
migration,
|
|
42
|
+
fn
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export {
|
|
50
|
+
Migration
|
|
51
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Table
|
|
3
|
+
} from "./chunk-W2DR3ZVK.js";
|
|
4
|
+
|
|
5
|
+
// src/database/table.ts
|
|
6
|
+
async function createTable(tableName, columns, options) {
|
|
7
|
+
const table = Table.define({
|
|
8
|
+
name: tableName,
|
|
9
|
+
dialect: this.dialect,
|
|
10
|
+
columns,
|
|
11
|
+
...options
|
|
12
|
+
});
|
|
13
|
+
table.database = this.client;
|
|
14
|
+
this.tables[tableName] = table;
|
|
15
|
+
if (!this?.client) {
|
|
16
|
+
throw new Error("Database not connected");
|
|
17
|
+
}
|
|
18
|
+
while (this.client.status === "connecting") {
|
|
19
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
20
|
+
}
|
|
21
|
+
await table.create(this.client);
|
|
22
|
+
return this;
|
|
23
|
+
}
|
|
24
|
+
async function renameTable(oldName, newName) {
|
|
25
|
+
await this.client.exec(`ALTER TABLE ${oldName} RENAME TO ${newName};`);
|
|
26
|
+
this.tables[newName] = this.tables[oldName];
|
|
27
|
+
delete this.tables[oldName];
|
|
28
|
+
return this;
|
|
29
|
+
}
|
|
30
|
+
async function dropTable(tableName) {
|
|
31
|
+
if (!this.tables[tableName]) {
|
|
32
|
+
await this.client.exec(`DROP TABLE IF EXISTS ${tableName};`);
|
|
33
|
+
return this;
|
|
34
|
+
}
|
|
35
|
+
await this.tables[tableName].drop(this.client);
|
|
36
|
+
delete this.tables[tableName];
|
|
37
|
+
return this;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export {
|
|
41
|
+
createTable,
|
|
42
|
+
renameTable,
|
|
43
|
+
dropTable
|
|
44
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// src/query/join.ts
|
|
2
|
+
function addJoin(query, joinType, alias, joinTable, baseColumn, joinColumn) {
|
|
3
|
+
if (!query.definition.joins) query.definition.joins = [];
|
|
4
|
+
query.definition.joins.push(
|
|
5
|
+
`${joinType} JOIN ${joinTable.name} AS ${alias} ON ${baseColumn} = ${joinColumn}`
|
|
6
|
+
);
|
|
7
|
+
if (!query.definition.joinedTables) {
|
|
8
|
+
query.definition.joinedTables = {};
|
|
9
|
+
}
|
|
10
|
+
query.definition.joinedTables = {
|
|
11
|
+
...query.definition.joinedTables,
|
|
12
|
+
[alias]: joinTable
|
|
13
|
+
};
|
|
14
|
+
return query;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export {
|
|
18
|
+
addJoin
|
|
19
|
+
};
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Dialect
|
|
3
|
+
} from "./chunk-GLOHF5CP.js";
|
|
4
|
+
|
|
5
|
+
// src/column/constants.ts
|
|
6
|
+
var AcceptedColumnTypes = {
|
|
7
|
+
INTEGER: "INTEGER",
|
|
8
|
+
STRING: "STRING",
|
|
9
|
+
BOOLEAN: "BOOLEAN",
|
|
10
|
+
DATE: "DATE",
|
|
11
|
+
FLOAT: "FLOAT",
|
|
12
|
+
DECIMAL: "DECIMAL",
|
|
13
|
+
BIGINT: "BIGINT",
|
|
14
|
+
TEXT: "TEXT",
|
|
15
|
+
BLOB: "BLOB",
|
|
16
|
+
JSON: "JSON",
|
|
17
|
+
VARCHAR: "VARCHAR",
|
|
18
|
+
TIME: "TIME",
|
|
19
|
+
TIMESTAMP: "TIMESTAMP",
|
|
20
|
+
DOUBLE: "DOUBLE",
|
|
21
|
+
DATETIME: "DATETIME",
|
|
22
|
+
DATEONLY: "DATEONLY",
|
|
23
|
+
ENUM: "ENUM",
|
|
24
|
+
SERIAL: "SERIAL"
|
|
25
|
+
};
|
|
26
|
+
var ColumnTypeMapping = {
|
|
27
|
+
[AcceptedColumnTypes.INTEGER]: {
|
|
28
|
+
[Dialect.SQLITE]: "INTEGER",
|
|
29
|
+
[Dialect.POSTGRES]: "INTEGER"
|
|
30
|
+
},
|
|
31
|
+
[AcceptedColumnTypes.STRING]: {
|
|
32
|
+
[Dialect.SQLITE]: "TEXT",
|
|
33
|
+
[Dialect.POSTGRES]: "VARCHAR"
|
|
34
|
+
},
|
|
35
|
+
[AcceptedColumnTypes.BOOLEAN]: {
|
|
36
|
+
[Dialect.SQLITE]: "INTEGER",
|
|
37
|
+
[Dialect.POSTGRES]: "BOOLEAN"
|
|
38
|
+
},
|
|
39
|
+
[AcceptedColumnTypes.DATE]: {
|
|
40
|
+
[Dialect.SQLITE]: "TEXT",
|
|
41
|
+
[Dialect.POSTGRES]: "DATE"
|
|
42
|
+
},
|
|
43
|
+
[AcceptedColumnTypes.FLOAT]: {
|
|
44
|
+
[Dialect.SQLITE]: "REAL",
|
|
45
|
+
[Dialect.POSTGRES]: "FLOAT"
|
|
46
|
+
},
|
|
47
|
+
[AcceptedColumnTypes.DECIMAL]: {
|
|
48
|
+
[Dialect.SQLITE]: "TEXT",
|
|
49
|
+
[Dialect.POSTGRES]: "DECIMAL"
|
|
50
|
+
},
|
|
51
|
+
[AcceptedColumnTypes.BIGINT]: {
|
|
52
|
+
[Dialect.SQLITE]: "TEXT",
|
|
53
|
+
[Dialect.POSTGRES]: "BIGINT"
|
|
54
|
+
},
|
|
55
|
+
[AcceptedColumnTypes.TEXT]: {
|
|
56
|
+
[Dialect.SQLITE]: "TEXT",
|
|
57
|
+
[Dialect.POSTGRES]: "TEXT"
|
|
58
|
+
},
|
|
59
|
+
[AcceptedColumnTypes.BLOB]: {
|
|
60
|
+
[Dialect.SQLITE]: "BLOB",
|
|
61
|
+
[Dialect.POSTGRES]: "BYTEA"
|
|
62
|
+
},
|
|
63
|
+
[AcceptedColumnTypes.JSON]: {
|
|
64
|
+
[Dialect.SQLITE]: "TEXT",
|
|
65
|
+
[Dialect.POSTGRES]: "JSONB"
|
|
66
|
+
},
|
|
67
|
+
[AcceptedColumnTypes.VARCHAR]: {
|
|
68
|
+
[Dialect.SQLITE]: "TEXT",
|
|
69
|
+
[Dialect.POSTGRES]: "VARCHAR"
|
|
70
|
+
},
|
|
71
|
+
[AcceptedColumnTypes.TIME]: {
|
|
72
|
+
[Dialect.SQLITE]: "TEXT",
|
|
73
|
+
[Dialect.POSTGRES]: "TIME"
|
|
74
|
+
},
|
|
75
|
+
[AcceptedColumnTypes.TIMESTAMP]: {
|
|
76
|
+
[Dialect.SQLITE]: "TEXT",
|
|
77
|
+
[Dialect.POSTGRES]: "TIMESTAMP"
|
|
78
|
+
},
|
|
79
|
+
[AcceptedColumnTypes.DOUBLE]: {
|
|
80
|
+
[Dialect.SQLITE]: "REAL",
|
|
81
|
+
[Dialect.POSTGRES]: "DOUBLE PRECISION"
|
|
82
|
+
},
|
|
83
|
+
[AcceptedColumnTypes.DATETIME]: {
|
|
84
|
+
[Dialect.SQLITE]: "TEXT",
|
|
85
|
+
[Dialect.POSTGRES]: "TIMESTAMP"
|
|
86
|
+
},
|
|
87
|
+
[AcceptedColumnTypes.DATEONLY]: {
|
|
88
|
+
[Dialect.SQLITE]: "TEXT",
|
|
89
|
+
[Dialect.POSTGRES]: "DATE"
|
|
90
|
+
},
|
|
91
|
+
[AcceptedColumnTypes.ENUM]: {
|
|
92
|
+
[Dialect.SQLITE]: "TEXT",
|
|
93
|
+
[Dialect.POSTGRES]: "TEXT"
|
|
94
|
+
},
|
|
95
|
+
[AcceptedColumnTypes.SERIAL]: {
|
|
96
|
+
[Dialect.SQLITE]: "INTEGER AUTOINCREMENT",
|
|
97
|
+
[Dialect.POSTGRES]: "SERIAL"
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
export {
|
|
102
|
+
AcceptedColumnTypes,
|
|
103
|
+
ColumnTypeMapping
|
|
104
|
+
};
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AcceptedColumnTypes,
|
|
3
|
+
ColumnTypeMapping
|
|
4
|
+
} from "./chunk-G3LSCLIQ.js";
|
|
5
|
+
import {
|
|
6
|
+
Dialect
|
|
7
|
+
} from "./chunk-GLOHF5CP.js";
|
|
8
|
+
|
|
9
|
+
// src/column/index.ts
|
|
10
|
+
var Column = class _Column {
|
|
11
|
+
definition;
|
|
12
|
+
type;
|
|
13
|
+
length;
|
|
14
|
+
enums;
|
|
15
|
+
_output;
|
|
16
|
+
constructor(options) {
|
|
17
|
+
this.type = options.type;
|
|
18
|
+
this.enums = [];
|
|
19
|
+
this.length = null;
|
|
20
|
+
if ("length" in options) {
|
|
21
|
+
this.length = options.length;
|
|
22
|
+
}
|
|
23
|
+
if ("values" in options) {
|
|
24
|
+
this.enums = options.values;
|
|
25
|
+
}
|
|
26
|
+
this.definition = {
|
|
27
|
+
autoIncrement: false,
|
|
28
|
+
primaryKey: false,
|
|
29
|
+
notNull: false,
|
|
30
|
+
unique: false,
|
|
31
|
+
comment: null,
|
|
32
|
+
default: void 0
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
static define(options) {
|
|
36
|
+
return new _Column(options);
|
|
37
|
+
}
|
|
38
|
+
autoIncrement() {
|
|
39
|
+
this.definition.autoIncrement = true;
|
|
40
|
+
return this;
|
|
41
|
+
}
|
|
42
|
+
primaryKey() {
|
|
43
|
+
this.definition.primaryKey = true;
|
|
44
|
+
return this;
|
|
45
|
+
}
|
|
46
|
+
notNull() {
|
|
47
|
+
this.definition.notNull = true;
|
|
48
|
+
return this;
|
|
49
|
+
}
|
|
50
|
+
unique() {
|
|
51
|
+
this.definition.unique = true;
|
|
52
|
+
return this;
|
|
53
|
+
}
|
|
54
|
+
comment(value) {
|
|
55
|
+
this.definition.comment = value;
|
|
56
|
+
return this;
|
|
57
|
+
}
|
|
58
|
+
default(value) {
|
|
59
|
+
this.definition.default = value;
|
|
60
|
+
return this;
|
|
61
|
+
}
|
|
62
|
+
dialect(dialect) {
|
|
63
|
+
this.definition.dialect = dialect;
|
|
64
|
+
return this;
|
|
65
|
+
}
|
|
66
|
+
toQuery() {
|
|
67
|
+
if (!this.definition.dialect) {
|
|
68
|
+
throw new Error("No DB Dialect defined");
|
|
69
|
+
}
|
|
70
|
+
const correctType = ColumnTypeMapping[this.type][this.definition.dialect];
|
|
71
|
+
let sql = correctType + (this.length ? `(${this.length})` : "");
|
|
72
|
+
if (this.definition.primaryKey) {
|
|
73
|
+
sql += " PRIMARY KEY";
|
|
74
|
+
}
|
|
75
|
+
if (this.definition.autoIncrement || this.type === AcceptedColumnTypes.SERIAL) {
|
|
76
|
+
const isPrimaryKey = !!this.definition.primaryKey;
|
|
77
|
+
if (this.definition.dialect === Dialect.POSTGRES) {
|
|
78
|
+
sql = `SERIAL${isPrimaryKey ? " PRIMARY KEY" : ""}`;
|
|
79
|
+
} else {
|
|
80
|
+
if (this.type !== AcceptedColumnTypes.SERIAL) {
|
|
81
|
+
sql += " AUTOINCREMENT";
|
|
82
|
+
} else {
|
|
83
|
+
const sqls = ["INTEGER", "PRIMARY KEY", "AUTOINCREMENT"];
|
|
84
|
+
if (!isPrimaryKey) sqls.splice(1, 1);
|
|
85
|
+
sql = sqls.join(" ");
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
if (this.definition.notNull) {
|
|
90
|
+
sql += " NOT NULL";
|
|
91
|
+
}
|
|
92
|
+
if (this.definition.unique) {
|
|
93
|
+
sql += " UNIQUE";
|
|
94
|
+
}
|
|
95
|
+
if (this.definition.default !== void 0) {
|
|
96
|
+
const value = this.definition.default;
|
|
97
|
+
const isString = typeof this.definition.default === "string";
|
|
98
|
+
const finalValue = isString ? `'${value}'` : value;
|
|
99
|
+
sql += ` DEFAULT ${finalValue}`;
|
|
100
|
+
}
|
|
101
|
+
return { query: sql, params: [] };
|
|
102
|
+
}
|
|
103
|
+
toString() {
|
|
104
|
+
return this.toQuery().query;
|
|
105
|
+
}
|
|
106
|
+
infer() {
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
export {
|
|
112
|
+
Column
|
|
113
|
+
};
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Dialect
|
|
3
|
+
} from "./chunk-GLOHF5CP.js";
|
|
4
|
+
|
|
5
|
+
// src/database/wrapper.ts
|
|
6
|
+
import { SQL } from "bun";
|
|
7
|
+
import { Database as Sqlite } from "bun:sqlite";
|
|
8
|
+
var DatabasePsql = class {
|
|
9
|
+
dialect;
|
|
10
|
+
options;
|
|
11
|
+
client;
|
|
12
|
+
status;
|
|
13
|
+
constructor(options) {
|
|
14
|
+
this.dialect = Dialect.POSTGRES;
|
|
15
|
+
this.options = options;
|
|
16
|
+
this.status = "connecting";
|
|
17
|
+
this.client = new SQL({
|
|
18
|
+
...options,
|
|
19
|
+
onconnect: () => {
|
|
20
|
+
this.status = "connected";
|
|
21
|
+
},
|
|
22
|
+
onclose: () => {
|
|
23
|
+
this.status = "disconnected";
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
this.connect();
|
|
27
|
+
}
|
|
28
|
+
async connect() {
|
|
29
|
+
await this.client.connect();
|
|
30
|
+
return this;
|
|
31
|
+
}
|
|
32
|
+
async disconnect() {
|
|
33
|
+
await this.client.close();
|
|
34
|
+
return this;
|
|
35
|
+
}
|
|
36
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
37
|
+
async exec(sql, values) {
|
|
38
|
+
if (!values) {
|
|
39
|
+
return this.client.unsafe(sql);
|
|
40
|
+
}
|
|
41
|
+
return this.client.unsafe(sql, values);
|
|
42
|
+
}
|
|
43
|
+
async transaction(fn) {
|
|
44
|
+
try {
|
|
45
|
+
await this.exec("BEGIN");
|
|
46
|
+
const result = await fn();
|
|
47
|
+
await this.exec("COMMIT");
|
|
48
|
+
return result;
|
|
49
|
+
} catch (err) {
|
|
50
|
+
await this.exec("ROLLBACK");
|
|
51
|
+
throw err;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
var DatabaseSqlite = class {
|
|
56
|
+
dialect;
|
|
57
|
+
options;
|
|
58
|
+
client;
|
|
59
|
+
status;
|
|
60
|
+
constructor(options) {
|
|
61
|
+
this.dialect = Dialect.SQLITE;
|
|
62
|
+
this.options = options;
|
|
63
|
+
this.status = "connecting";
|
|
64
|
+
this.client = new Sqlite(options.filename);
|
|
65
|
+
this.status = "connected";
|
|
66
|
+
}
|
|
67
|
+
async connect() {
|
|
68
|
+
this.client = new Sqlite(this.options.filename);
|
|
69
|
+
this.status = "connected";
|
|
70
|
+
return this;
|
|
71
|
+
}
|
|
72
|
+
async disconnect() {
|
|
73
|
+
this.client.close();
|
|
74
|
+
this.status = "disconnected";
|
|
75
|
+
return this;
|
|
76
|
+
}
|
|
77
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
78
|
+
async exec(sql, params) {
|
|
79
|
+
const query = this.client.prepare(sql, params);
|
|
80
|
+
return query.all();
|
|
81
|
+
}
|
|
82
|
+
async transaction(fn) {
|
|
83
|
+
try {
|
|
84
|
+
await this.exec("BEGIN");
|
|
85
|
+
const result = await fn();
|
|
86
|
+
await this.exec("COMMIT");
|
|
87
|
+
return result;
|
|
88
|
+
} catch (err) {
|
|
89
|
+
await this.exec("ROLLBACK");
|
|
90
|
+
throw err;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
export {
|
|
96
|
+
DatabasePsql,
|
|
97
|
+
DatabaseSqlite
|
|
98
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Dialect
|
|
3
|
+
} from "./chunk-GLOHF5CP.js";
|
|
4
|
+
|
|
5
|
+
// src/database/column.ts
|
|
6
|
+
async function addColumn(tableName, columnName, column) {
|
|
7
|
+
await this.client.exec(
|
|
8
|
+
`ALTER TABLE ${tableName} ADD COLUMN ${columnName} ${column.toString()};`
|
|
9
|
+
);
|
|
10
|
+
if (!this.tables[tableName]) return this;
|
|
11
|
+
this.tables[tableName].columns[columnName] = column;
|
|
12
|
+
return this;
|
|
13
|
+
}
|
|
14
|
+
async function renameColumn(tableName, oldName, newName) {
|
|
15
|
+
if (this.dialect === Dialect.SQLITE) {
|
|
16
|
+
throw new Error("SQLite does not support RENAME COLUMN natively.");
|
|
17
|
+
}
|
|
18
|
+
await this.client.exec(
|
|
19
|
+
`ALTER TABLE ${tableName} RENAME COLUMN ${oldName} TO ${newName};`
|
|
20
|
+
);
|
|
21
|
+
if (!this.tables[tableName]) return this;
|
|
22
|
+
this.tables[tableName].columns[newName] = this.tables[tableName].columns[oldName];
|
|
23
|
+
delete this.tables[tableName].columns[oldName];
|
|
24
|
+
return this;
|
|
25
|
+
}
|
|
26
|
+
async function dropColumn(tableName, columnName) {
|
|
27
|
+
if (this.dialect === Dialect.SQLITE) {
|
|
28
|
+
throw new Error("SQLite does not support DROP COLUMN natively.");
|
|
29
|
+
}
|
|
30
|
+
await this.client.exec(`ALTER TABLE ${tableName} DROP COLUMN ${columnName};`);
|
|
31
|
+
if (!this.tables[tableName]) return this;
|
|
32
|
+
delete this.tables[tableName].columns[columnName];
|
|
33
|
+
return this;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export {
|
|
37
|
+
addColumn,
|
|
38
|
+
renameColumn,
|
|
39
|
+
dropColumn
|
|
40
|
+
};
|