@stacksjs/database 0.58.73 → 0.59.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.
@@ -0,0 +1,18 @@
1
+ interface Options {
2
+ notNull?: boolean;
3
+ default?: any;
4
+ primaryKey?: boolean;
5
+ autoIncrement?: boolean;
6
+ }
7
+ type ColumnType = 'integer' | 'varchar' | 'timestamp';
8
+ export declare class Column {
9
+ name: string;
10
+ type: ColumnType;
11
+ options: Options;
12
+ constructor(name: string, type: ColumnType, options?: Options);
13
+ notNullable(): this;
14
+ defaultTo(value: any): this;
15
+ primary(): this;
16
+ autoIncrement(): this;
17
+ }
18
+ export {};
@@ -0,0 +1,19 @@
1
+ import { Kysely } from 'kysely';
2
+ import type { ColumnType, Generated } from 'kysely';
3
+ export * from './schema';
4
+ export * from './migrations';
5
+ export * from './types';
6
+ export * from './utils';
7
+ export interface UsersTable {
8
+ id: Generated<number>;
9
+ name: string;
10
+ email: string;
11
+ password: string;
12
+ created_at: ColumnType<Date, string | undefined, never>;
13
+ deleted_at: ColumnType<Date, string | undefined, never>;
14
+ }
15
+ export interface Database {
16
+ users: UsersTable;
17
+ }
18
+ export declare const db: Kysely<Database>;
19
+ export declare const dbDialect: any;
@@ -0,0 +1,6 @@
1
+ export interface MigrationOptions {
2
+ name: string;
3
+ up: string;
4
+ down: string;
5
+ }
6
+ export declare function generateMigrationFile(options: MigrationOptions): void;
@@ -0,0 +1,4 @@
1
+ import { Table } from './table';
2
+ export declare class Schema {
3
+ static createTable(tableName: string, callback: (table: Table) => void): Promise<void>;
4
+ }
@@ -0,0 +1,8 @@
1
+ import { Column } from './column';
2
+ export declare class Table {
3
+ private columns;
4
+ increments(name: string): Column;
5
+ string(name: string, varchar?: number): Column;
6
+ timestamps(): void;
7
+ execute(): void;
8
+ }
@@ -0,0 +1 @@
1
+ export { Kysely as Migration } from 'kysely';
@@ -0,0 +1 @@
1
+ export declare const now: import("kysely").RawBuilder<unknown>;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@stacksjs/database",
3
3
  "type": "module",
4
- "version": "0.58.73",
4
+ "version": "0.59.1",
5
5
  "description": "The Stacks database integration.",
6
6
  "author": "Chris Breuer",
7
7
  "license": "MIT",
@@ -71,7 +71,7 @@
71
71
  "kysely-bun-worker": "^0.5.7"
72
72
  },
73
73
  "optionalDependencies": {
74
- "mysql2": "^3.9.1"
74
+ "mysql2": "^3.9.2"
75
75
  },
76
76
  "devDependencies": {
77
77
  "@stacksjs/development": "latest"
package/src/column.ts ADDED
@@ -0,0 +1,32 @@
1
+ interface Options {
2
+ notNull?: boolean
3
+ default?: any
4
+ primaryKey?: boolean
5
+ autoIncrement?: boolean
6
+ }
7
+
8
+ type ColumnType = 'integer' | 'varchar' | 'timestamp'
9
+
10
+ export class Column {
11
+ constructor(public name: string, public type: ColumnType, public options: Options = {}) {}
12
+
13
+ notNullable(): this {
14
+ this.options.notNull = true
15
+ return this
16
+ }
17
+
18
+ defaultTo(value: any): this {
19
+ this.options.default = value
20
+ return this
21
+ }
22
+
23
+ primary(): this {
24
+ this.options.primaryKey = true
25
+ return this
26
+ }
27
+
28
+ autoIncrement(): this {
29
+ this.options.autoIncrement = true
30
+ return this
31
+ }
32
+ }
package/src/index.ts CHANGED
@@ -1,10 +1,14 @@
1
- // export * from './migrations'
2
1
  // export * from './seeder''
3
2
  import { Kysely, MysqlDialect } from 'kysely'
4
3
  import { createPool } from 'mysql2'
5
4
  import type { ColumnType, Generated } from 'kysely'
6
5
  import { BunWorkerDialect } from './kysely-bun-worker'
7
6
 
7
+ export * from './schema'
8
+ export * from './migrations'
9
+ export * from './types'
10
+ export * from './utils'
11
+
8
12
  // const driver = config.database.default
9
13
  const driver = 'mysql'
10
14
 
package/src/schema.ts ADDED
@@ -0,0 +1,11 @@
1
+ import { Table } from './table'
2
+
3
+ export class Schema {
4
+ static async createTable(tableName: string, callback: (table: Table) => void): Promise<void> {
5
+ const table = new Table()
6
+ callback(table)
7
+ table.execute() // Simulate the execution of the table creation
8
+ // eslint-disable-next-line no-console
9
+ console.log(`Table "${tableName}" created.`)
10
+ }
11
+ }
package/src/table.ts ADDED
@@ -0,0 +1,29 @@
1
+ import { Column } from './column'
2
+
3
+ export class Table {
4
+ private columns: Column[] = []
5
+
6
+ increments(name: string): Column {
7
+ const column = new Column(name, 'integer', { primaryKey: true, autoIncrement: true })
8
+ this.columns.push(column)
9
+ return column
10
+ }
11
+
12
+ string(name: string, varchar: number = 255): Column {
13
+ const column = new Column(name, `varchar(${varchar})`)
14
+ this.columns.push(column)
15
+ return column
16
+ }
17
+
18
+ timestamps(): void {
19
+ this.columns.push(new Column('created_at', 'timestamp'))
20
+ this.columns.push(new Column('updated_at', 'timestamp'))
21
+ }
22
+
23
+ // Method to simulate the execution of the schema definition
24
+ execute(): void {
25
+ // eslint-disable-next-line no-console
26
+ console.log(`Creating table with columns: ${this.columns.map(col => col.name).join(', ')}`)
27
+ // Here you would normally execute the SQL commands to create the table and columns in the database
28
+ }
29
+ }
package/src/types.ts ADDED
@@ -0,0 +1 @@
1
+ export { Kysely as Migration } from 'kysely'
package/src/utils.ts ADDED
@@ -0,0 +1,3 @@
1
+ import { sql } from 'kysely'
2
+
3
+ export const now = sql`now()`
package/dist/index.js DELETED
@@ -1,200 +0,0 @@
1
- // @bun
2
- // src/index.ts
3
- import {Kysely, MysqlDialect} from "kysely";
4
- import {createPool} from "mysql2";
5
-
6
- // src/kysely-bun-worker/index.ts
7
- import {SqliteAdapter, SqliteIntrospector, SqliteQueryCompiler} from "kysely";
8
-
9
- // src/kysely-bun-worker/driver.ts
10
- import {CompiledQuery} from "kysely";
11
-
12
- // ../../../../node_modules/mitt/dist/mitt.mjs
13
- function mitt_default(n) {
14
- return { all: n = n || new Map, on: function(t, e) {
15
- var i = n.get(t);
16
- i ? i.push(e) : n.set(t, [e]);
17
- }, off: function(t, e) {
18
- var i = n.get(t);
19
- i && (e ? i.splice(i.indexOf(e) >>> 0, 1) : n.set(t, []));
20
- }, emit: function(t, e) {
21
- var i = n.get(t);
22
- i && i.slice().map(function(n2) {
23
- n2(e);
24
- }), (i = n.get("*")) && i.slice().map(function(n2) {
25
- n2(t, e);
26
- });
27
- } };
28
- }
29
-
30
- // src/kysely-bun-worker/mitt.ts
31
- function mittOnce(all) {
32
- const emitter = mitt_default(all);
33
- return {
34
- ...emitter,
35
- once(type, handler) {
36
- const fn = (arg) => {
37
- emitter.off(type, fn);
38
- handler(arg);
39
- };
40
- emitter.on(type, fn);
41
- }
42
- };
43
- }
44
-
45
- // src/kysely-bun-worker/driver.ts
46
- class BunWorkerDriver {
47
- config;
48
- worker;
49
- connection;
50
- connectionMutex = new ConnectionMutex;
51
- mitt;
52
- constructor(config) {
53
- this.config = config;
54
- }
55
- async init() {
56
- this.worker = this.config?.worker ?? new Worker(new URL("../src/kysely-bun-worker/worker", import.meta.url), { type: "module" });
57
- this.mitt = mittOnce();
58
- this.worker.onmessage = ({ data: { data, err, type } }) => {
59
- this.mitt?.emit(type, { data, err });
60
- };
61
- const msg = {
62
- type: "init",
63
- url: this.config?.url ?? ":memory:",
64
- cache: this.config?.cacheStatment ?? false
65
- };
66
- this.worker.postMessage(msg);
67
- await new Promise((resolve, reject) => {
68
- this.mitt?.once("init", ({ err }) => {
69
- err ? reject(err) : resolve();
70
- });
71
- });
72
- this.connection = new BunWorkerConnection(this.worker, this.mitt);
73
- await this.config?.onCreateConnection?.(this.connection);
74
- }
75
- async acquireConnection() {
76
- await this.connectionMutex.lock();
77
- return this.connection;
78
- }
79
- async beginTransaction(connection) {
80
- await connection.executeQuery(CompiledQuery.raw("begin"));
81
- }
82
- async commitTransaction(connection) {
83
- await connection.executeQuery(CompiledQuery.raw("commit"));
84
- }
85
- async rollbackTransaction(connection) {
86
- await connection.executeQuery(CompiledQuery.raw("rollback"));
87
- }
88
- async releaseConnection() {
89
- this.connectionMutex.unlock();
90
- }
91
- async destroy() {
92
- if (!this.worker)
93
- return;
94
- this.worker.postMessage({
95
- type: "close"
96
- });
97
- return new Promise((resolve, reject) => {
98
- this.mitt?.once("close", ({ err }) => {
99
- if (err) {
100
- reject(err);
101
- } else {
102
- this.worker?.terminate();
103
- this.mitt?.all.clear();
104
- this.mitt = undefined;
105
- resolve();
106
- }
107
- });
108
- });
109
- }
110
- }
111
-
112
- class ConnectionMutex {
113
- promise;
114
- resolve;
115
- async lock() {
116
- while (this.promise)
117
- await this.promise;
118
- this.promise = new Promise((resolve) => {
119
- this.resolve = resolve;
120
- });
121
- }
122
- unlock() {
123
- const resolve = this.resolve;
124
- this.promise = undefined;
125
- this.resolve = undefined;
126
- resolve?.();
127
- }
128
- }
129
-
130
- class BunWorkerConnection {
131
- worker;
132
- mitt;
133
- constructor(worker, mitt2) {
134
- this.worker = worker;
135
- this.mitt = mitt2;
136
- }
137
- streamQuery() {
138
- throw new Error("Sqlite driver doesn\'t support streaming");
139
- }
140
- async executeQuery(compiledQuery) {
141
- const { parameters, sql, query } = compiledQuery;
142
- const mode = query.kind === "SelectQueryNode" ? "query" : query.kind === "RawNode" ? "raw" : "exec";
143
- const msg = { type: "run", mode, sql, parameters };
144
- this.worker.postMessage(msg);
145
- return new Promise((resolve, reject) => {
146
- if (!this.mitt)
147
- reject("kysely instance has been destroyed");
148
- this.mitt.once("run", ({ data, err }) => {
149
- !err && data ? resolve(data) : reject(err);
150
- });
151
- });
152
- }
153
- }
154
-
155
- // src/kysely-bun-worker/index.ts
156
- class BunWorkerDialect {
157
- #config;
158
- constructor(config) {
159
- this.#config = config;
160
- }
161
- createDriver() {
162
- return new BunWorkerDriver(this.#config);
163
- }
164
- createQueryCompiler() {
165
- return new SqliteQueryCompiler;
166
- }
167
- createAdapter() {
168
- return new SqliteAdapter;
169
- }
170
- createIntrospector(db) {
171
- return new SqliteIntrospector(db);
172
- }
173
- }
174
-
175
- // src/index.ts
176
- var driver2 = "mysql";
177
- var dialect;
178
- if (driver2 === "sqlite") {
179
- dialect = new BunWorkerDialect({
180
- url: "stacks.sqlite"
181
- });
182
- } else {
183
- dialect = new MysqlDialect({
184
- pool: createPool({
185
- database: "stacks",
186
- host: "127.0.0.1",
187
- user: "root",
188
- password: "",
189
- port: 3306
190
- })
191
- });
192
- }
193
- var db = new Kysely({
194
- dialect
195
- });
196
- var dbDialect = dialect;
197
- export {
198
- dbDialect,
199
- db
200
- };
@@ -1,144 +0,0 @@
1
- /* eslint-disable eslint-comments/no-unlimited-disable */
2
- /* eslint-disable */
3
- import type { DatabaseConnection, Driver, QueryResult } from 'kysely'
4
- import { CompiledQuery } from 'kysely'
5
- import type { EmitterOnce } from './mitt'
6
- import MittOnce from './mitt'
7
- import type { EventWithError, MainMsg, WorkerMsg } from './type'
8
- import type { BunWorkerDialectConfig } from '.'
9
-
10
- export class BunWorkerDriver implements Driver {
11
- private config?: BunWorkerDialectConfig
12
- private worker?: Worker
13
- private connection?: DatabaseConnection
14
- private connectionMutex = new ConnectionMutex()
15
- private mitt?: EmitterOnce<EventWithError>
16
- constructor(config?: BunWorkerDialectConfig) {
17
- this.config = config
18
- }
19
-
20
- async init(): Promise<void> {
21
- this.worker = this.config?.worker ?? new Worker(
22
- new URL('../src/kysely-bun-worker/worker', import.meta.url),
23
- { type: 'module' },
24
- )
25
- this.mitt = MittOnce<EventWithError>()
26
- this.worker.onmessage = ({ data: { data, err, type } }: MessageEvent<WorkerMsg>) => {
27
- this.mitt?.emit(type, { data, err })
28
- }
29
- const msg: MainMsg = {
30
- type: 'init',
31
- url: this.config?.url ?? ':memory:',
32
- cache: this.config?.cacheStatment ?? false,
33
- }
34
- this.worker.postMessage(msg)
35
- await new Promise<void>((resolve, reject) => {
36
- this.mitt?.once('init', ({ err }) => {
37
- err ? reject(err) : resolve()
38
- })
39
- })
40
- this.connection = new BunWorkerConnection(this.worker, this.mitt)
41
-
42
- await this.config?.onCreateConnection?.(this.connection)
43
- }
44
-
45
- async acquireConnection(): Promise<DatabaseConnection> {
46
- // SQLite only has one single connection. We use a mutex here to wait
47
- // until the single connection has been released.
48
- await this.connectionMutex.lock()
49
- return this.connection!
50
- }
51
-
52
- async beginTransaction(connection: DatabaseConnection): Promise<void> {
53
- await connection.executeQuery(CompiledQuery.raw('begin'))
54
- }
55
-
56
- async commitTransaction(connection: DatabaseConnection): Promise<void> {
57
- await connection.executeQuery(CompiledQuery.raw('commit'))
58
- }
59
-
60
- async rollbackTransaction(connection: DatabaseConnection): Promise<void> {
61
- await connection.executeQuery(CompiledQuery.raw('rollback'))
62
- }
63
-
64
- async releaseConnection(): Promise<void> {
65
- this.connectionMutex.unlock()
66
- }
67
-
68
- async destroy(): Promise<void> {
69
- if (!this.worker)
70
- return
71
-
72
- this.worker.postMessage({
73
- type: 'close',
74
- })
75
- return new Promise<void>((resolve, reject) => {
76
- this.mitt?.once('close', ({ err }) => {
77
- if (err) {
78
- reject(err)
79
- }
80
- else {
81
- this.worker?.terminate()
82
- this.mitt?.all.clear()
83
- this.mitt = undefined
84
- resolve()
85
- }
86
- })
87
- })
88
- }
89
- }
90
-
91
- class ConnectionMutex {
92
- private promise?: Promise<void>
93
- private resolve?: () => void
94
-
95
- async lock(): Promise<void> {
96
- while (this.promise)
97
- await this.promise
98
-
99
- this.promise = new Promise((resolve) => {
100
- this.resolve = resolve
101
- })
102
- }
103
-
104
- unlock(): void {
105
- const resolve = this.resolve
106
-
107
- this.promise = undefined
108
- this.resolve = undefined
109
-
110
- resolve?.()
111
- }
112
- }
113
-
114
- class BunWorkerConnection implements DatabaseConnection {
115
- readonly worker: Worker
116
- readonly mitt?: EmitterOnce<EventWithError>
117
- constructor(worker: Worker, mitt?: EmitterOnce<EventWithError>) {
118
- this.worker = worker
119
- this.mitt = mitt
120
- }
121
-
122
- streamQuery<R>(): AsyncIterableIterator<QueryResult<R>> {
123
- throw new Error('Sqlite driver doesn\'t support streaming')
124
- }
125
-
126
- async executeQuery<R>(compiledQuery: CompiledQuery<unknown>): Promise<QueryResult<R>> {
127
- const { parameters, sql, query } = compiledQuery
128
- const mode = query.kind === 'SelectQueryNode'
129
- ? 'query'
130
- : query.kind === 'RawNode'
131
- ? 'raw'
132
- : 'exec'
133
- const msg: MainMsg = { type: 'run', mode, sql, parameters }
134
- this.worker.postMessage(msg)
135
- return new Promise((resolve, reject) => {
136
- if (!this.mitt)
137
- reject('kysely instance has been destroyed')
138
-
139
- this.mitt!.once('run', ({ data, err }) => {
140
- (!err && data) ? resolve(data) : reject(err)
141
- })
142
- })
143
- }
144
- }
@@ -1,46 +0,0 @@
1
- import type { DatabaseConnection, DatabaseIntrospector, Dialect, DialectAdapter, Driver, Kysely, QueryCompiler } from 'kysely'
2
- import { SqliteAdapter, SqliteIntrospector, SqliteQueryCompiler } from 'kysely'
3
- import { BunWorkerDriver } from './driver'
4
- import type { Promisable } from './type'
5
-
6
- export interface BunWorkerDialectConfig {
7
- /**
8
- * db file path
9
- *
10
- * @default ':memory:'
11
- */
12
- url?: string
13
- onCreateConnection?: (connection: DatabaseConnection) => Promisable<void>
14
- /**
15
- * use bun:sqlite's built-in statment cache
16
- * @see https://bun.sh/docs/api/sqlite#query
17
- */
18
- cacheStatment?: boolean
19
- /**
20
- * custom worker, default is a worker that use bun:sqlite
21
- */
22
- worker?: Worker
23
- }
24
-
25
- export class BunWorkerDialect implements Dialect {
26
- #config?: BunWorkerDialectConfig
27
- constructor(config?: BunWorkerDialectConfig) {
28
- this.#config = config
29
- }
30
-
31
- createDriver(): Driver {
32
- return new BunWorkerDriver(this.#config)
33
- }
34
-
35
- createQueryCompiler(): QueryCompiler {
36
- return new SqliteQueryCompiler()
37
- }
38
-
39
- createAdapter(): DialectAdapter {
40
- return new SqliteAdapter()
41
- }
42
-
43
- createIntrospector(db: Kysely<any>): DatabaseIntrospector {
44
- return new SqliteIntrospector(db)
45
- }
46
- }
@@ -1,24 +0,0 @@
1
- import type { Emitter, EventHandlerMap, EventType, Handler } from 'mitt'
2
- import mitt from 'mitt'
3
-
4
- export interface EmitterOnce<Events extends Record<EventType, unknown>> extends Emitter<Events> {
5
- once: <Key extends keyof Events>(type: Key, handler: Handler<Events[Key]>) => void
6
- }
7
-
8
- export default function mittOnce<Events extends Record<EventType, unknown>>(
9
- all?: EventHandlerMap<Events>,
10
- ): EmitterOnce<Events> {
11
- const emitter = mitt<Events>(all)
12
-
13
- return {
14
- ...emitter,
15
-
16
- once<Key extends keyof Events>(type: Key, handler: Handler<Events[Key]>) {
17
- const fn = (arg: Events[Key]) => {
18
- emitter.off(type, fn)
19
- handler(arg)
20
- }
21
- emitter.on(type, fn)
22
- },
23
- }
24
- }
@@ -1,40 +0,0 @@
1
- import type { QueryResult } from 'kysely'
2
-
3
- export type Promisable<T> = T | Promise<T>
4
-
5
- export type RunMode = 'exec' | 'query' | 'raw'
6
-
7
- export type MainMsg =
8
- | {
9
- type: 'run'
10
- mode: RunMode
11
- sql: string
12
- parameters?: readonly unknown[]
13
- }
14
- | {
15
- type: 'close'
16
- }
17
- | {
18
- type: 'init'
19
- url: string
20
- cache: boolean
21
- }
22
-
23
- export type WorkerMsg = {
24
- [K in keyof Events]: {
25
- type: K
26
- data: Events[K]
27
- err: unknown
28
- }
29
- }[keyof Events]
30
- interface Events {
31
- run: QueryResult<any> | null
32
- init: null
33
- close: null
34
- }
35
- export type EventWithError = {
36
- [K in keyof Events]: {
37
- data: Events[K]
38
- err: unknown
39
- }
40
- }
@@ -1,52 +0,0 @@
1
- import Database from 'bun:sqlite'
2
- import type { QueryResult } from 'kysely'
3
- import type { MainMsg, RunMode, WorkerMsg } from './type'
4
-
5
- let db: Database
6
- let cache: boolean
7
- function run(mode: RunMode, sql: string, parameters?: readonly unknown[]): QueryResult<any> {
8
- const stmt = db[cache ? 'query' : 'prepare'](sql)
9
-
10
- let rows: unknown[] = []
11
- if (mode !== 'exec')
12
-
13
- rows = stmt.all(parameters as any)
14
-
15
- if (mode === 'query')
16
- return { rows }
17
-
18
- stmt.run(parameters as any)
19
- return {
20
- rows,
21
- // @ts-expect-error get insert id
22
- insertId: db.query('SELECT last_insert_rowid() as i').get().i,
23
- // @ts-expect-error get changes
24
- numAffectedRows: db.query('SELECT changes() as c').get().c,
25
- }
26
- }
27
-
28
- onmessage = ({ data }: MessageEvent<MainMsg>) => {
29
- const ret: WorkerMsg = {
30
- type: data.type,
31
- data: null,
32
- err: null,
33
- }
34
- try {
35
- switch (data.type) {
36
- case 'run':
37
- ret.data = run(data.mode, data.sql, data.parameters)
38
- break
39
- case 'close':
40
- db.close()
41
- break
42
- case 'init':
43
- db = new Database(data.url, { create: true })
44
- cache = data.cache
45
- break
46
- }
47
- }
48
- catch (error) {
49
- ret.err = error
50
- }
51
- postMessage(ret)
52
- }
@@ -1,7 +1,7 @@
1
- // import { storage } from '@stacksjs/storage'
2
1
  import { path as p } from '@stacksjs/path'
3
2
  import { log } from '@stacksjs/cli'
4
3
 
4
+ // import { storage } from '@stacksjs/storage'
5
5
  // import type { Model, SchemaOptions } from '@stacksjs/types'
6
6
  // import { titleCase } from '@stacksjs/strings'
7
7
 
File without changes