@type32/tauri-sqlite-orm 0.1.18-7 → 0.1.18-9

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 CHANGED
@@ -16,159 +16,3 @@ bun add @type32/tauri-sqlite-orm @tauri-apps/plugin-sql
16
16
  ```
17
17
 
18
18
  Make sure the SQL plugin is registered on the Rust side (see Tauri docs).
19
-
20
- ### Quick Start
21
-
22
- Here’s a quick example to get you started:
23
-
24
- ```typescript
25
- // src/db/schema.ts
26
- import { sqliteTable, text, integer } from "@type32/tauri-sqlite-orm";
27
-
28
- export const users = sqliteTable("users", {
29
- id: integer("id").primaryKey().autoincrement(),
30
- name: text("name").notNull(),
31
- email: text("email").unique(),
32
- });
33
-
34
- export const posts = sqliteTable("posts", {
35
- id: integer("id").primaryKey(),
36
- content: text("content"),
37
- authorId: integer("author_id").references(() => users.id),
38
- });
39
-
40
- // src/db/index.ts
41
- import { TauriORM } from "@type32/tauri-sqlite-orm";
42
- import Database from "@tauri-apps/plugin-sql";
43
- import * as schema from "./schema";
44
-
45
- // Load the database
46
- const dbInstance = await Database.load("sqlite:app.db");
47
-
48
- // Create the ORM instance
49
- export const db = new TauriORM(dbInstance, schema);
50
-
51
- // Migrate the database if the schema has changed
52
- await db.migrateIfDirty();
53
-
54
- // Now you can use the ORM to interact with your database
55
- const newUser = await db
56
- .insert(schema.users)
57
- .values({ name: "John Doe", email: "john.doe@example.com" });
58
- const allUsers = await db.select(schema.users).execute();
59
- ```
60
-
61
- ### Documentation
62
-
63
- - [Getting Started](docs/getting-started.md)
64
- - [Schema and Types](docs/schema-and-types.md)
65
- - [CRUD Operations (SELECT)](docs/queries-select.md)
66
- - [CRUD Operations (INSERT)](docs/crud-insert.md)
67
- - [CRUD Operations (UPDATE)](docs/crud-update.md)
68
- - [CRUD Operations (DELETE)](docs/crud-delete.md)
69
- - [Migrations](docs/migrations.md)
70
- - [Transactions](docs/transactions.md)
71
- - [Relations](docs/relations.md)
72
-
73
- ### Schema Definition
74
-
75
- Define your tables and columns using a chainable, Drizzle-style API.
76
-
77
- ```typescript
78
- import { sqliteTable, text, integer, boolean } from "@type32/tauri-sqlite-orm";
79
-
80
- export const users = sqliteTable("users", {
81
- id: integer("id").primaryKey().autoincrement(),
82
- name: text("name").notNull(),
83
- email: text("email").unique(),
84
- isActive: boolean("is_active").default(true),
85
- createdAt: integer("created_at", { mode: "timestamp" }).$defaultFn(
86
- () => new Date()
87
- ),
88
- });
89
- ```
90
-
91
- ### CRUD Operations
92
-
93
- Perform `CREATE`, `READ`, `UPDATE`, and `DELETE` operations using a type-safe query builder.
94
-
95
- **SELECT**
96
-
97
- ```typescript
98
- import { eq, and } from "@type32/tauri-sqlite-orm";
99
-
100
- // Select all users
101
- const allUsers = await db.select(users).execute();
102
-
103
- // Select specific columns
104
- const userNames = await db.select(users, ["name"]).execute();
105
-
106
- // Use WHERE conditions
107
- const activeUsers = await db
108
- .select(users)
109
- .where(eq(users.isActive, true))
110
- .execute();
111
- ```
112
-
113
- **INSERT**
114
-
115
- ```typescript
116
- // Insert a single user
117
- const newUser = await db
118
- .insert(users)
119
- .values({ name: "Jane Doe", email: "jane.doe@example.com" });
120
-
121
- // Insert multiple users
122
- await db.insert(users).values([
123
- { name: "Alice", email: "alice@example.com" },
124
- { name: "Bob", email: "bob@example.com" },
125
- ]);
126
- ```
127
-
128
- **UPDATE**
129
-
130
- ```typescript
131
- import { eq } from "@type32/tauri-sqlite-orm";
132
-
133
- // Update a user's email
134
- await db
135
- .update(users)
136
- .set({ email: "new.email@example.com" })
137
- .where(eq(users._.columns.id, 1));
138
- ```
139
-
140
- **DELETE**
141
-
142
- ```typescript
143
- import { eq } from "@type32/tauri-sqlite-orm";
144
-
145
- // Delete a user
146
- await db.delete(users).where(eq(users._.columns.id, 1));
147
- ```
148
-
149
- ### Migrations
150
-
151
- The ORM includes a simple migration system that automatically detects schema changes and applies them to the database.
152
-
153
- ```typescript
154
- // This will check if the schema has changed and run migrations if it has
155
- await db.migrateIfDirty();
156
-
157
- // You can also run migrations manually
158
- await db.migrate();
159
- ```
160
-
161
- ### Transactions
162
-
163
- Run multiple database operations within a transaction to ensure atomicity.
164
-
165
- ```typescript
166
- await db.transaction(async (tx) => {
167
- await tx.insert(users).values({ name: "From Transaction" });
168
- await tx.delete(users).where(eq(users._.columns.id, 1));
169
- });
170
- ```
171
-
172
- ### License
173
-
174
- MIT
package/dist/index.d.mts CHANGED
@@ -28,6 +28,7 @@ declare class SQLiteColumn<TName extends string = string, TType extends ColumnDa
28
28
  notNull: TNotNull;
29
29
  hasDefault: THasDefault;
30
30
  autoincrement: TAutoincrement;
31
+ table: AnyTable;
31
32
  };
32
33
  constructor(name: TName, type: TType, options?: ColumnOptions<ColumnValueTypes<TType, TMode>>, mode?: TMode);
33
34
  notNull(): SQLiteColumn<TName, TType, TMode, true, THasDefault, TAutoincrement>;
@@ -72,6 +73,9 @@ declare class Table<TColumns extends Record<string, AnySQLiteColumn>, TTableName
72
73
  constructor(name: TTableName, columns: TColumns);
73
74
  }
74
75
  declare const sqliteTable: <TTableName extends string, TColumns extends Record<string, AnySQLiteColumn>>(tableName: TTableName, columns: TColumns) => Table<TColumns, TTableName>;
76
+ declare const getTableColumns: <T extends AnyTable>(table: T) => Record<string, AnySQLiteColumn>;
77
+ declare const alias: <T extends AnyTable>(table: T, alias: string) => Table<T["_"]["columns"], T["_"]["name"]>;
78
+
75
79
  type SQLCondition = {
76
80
  sql: string;
77
81
  params: any[];
@@ -112,31 +116,57 @@ declare class BaseQueryBuilder {
112
116
  protected query: string;
113
117
  protected params: any[];
114
118
  constructor(db: Database);
119
+ build(): {
120
+ sql: string;
121
+ params: any[];
122
+ };
123
+ }
124
+ type SelectedFields = Record<string, AnySQLiteColumn | {
125
+ sql: string;
126
+ params: any[];
127
+ }>;
128
+ declare class SelectQueryBuilder<TTable extends AnyTable, TSelection extends SelectedFields, TResult = InferSelectModel<TTable>> extends BaseQueryBuilder {
129
+ private selection;
130
+ private isDistinct;
131
+ private groupByColumns;
132
+ private havingCondition;
133
+ private joinClauses;
134
+ private fromTable;
135
+ private orderByClauses;
136
+ private limitCount;
137
+ private offsetCount;
138
+ private whereCondition;
139
+ constructor(db: Database, table: TTable, selection: TSelection | undefined);
115
140
  where(condition: SQLCondition): this;
141
+ leftJoin(table: AnyTable, on: SQLCondition): this;
142
+ innerJoin(table: AnyTable, on: SQLCondition): this;
143
+ rightJoin(table: AnyTable, on: SQLCondition): this;
144
+ fullJoin(table: AnyTable, on: SQLCondition): this;
145
+ distinct(): this;
146
+ groupBy(...columns: AnySQLiteColumn[]): this;
147
+ having(condition: SQLCondition): this;
116
148
  orderBy(column: AnySQLiteColumn | {
117
149
  sql: string;
118
150
  params: any[];
119
151
  }, direction?: "ASC" | "DESC"): this;
120
152
  limit(count: number): this;
121
153
  offset(count: number): this;
154
+ private buildSelectQuery;
122
155
  build(): {
123
156
  sql: string;
124
157
  params: any[];
125
158
  };
159
+ execute(): Promise<TResult[]>;
160
+ all(): Promise<TResult[]>;
161
+ get(): Promise<TResult | undefined>;
126
162
  }
127
- declare class SelectQueryBuilder<TTable extends AnyTable, TSelectedColumns extends (keyof TTable["_"]["columns"])[] | undefined = undefined> extends BaseQueryBuilder {
128
- private table;
129
- private columns?;
130
- private isDistinct;
131
- private groupByColumns;
132
- private havingCondition;
133
- constructor(db: Database, table: TTable, columns?: TSelectedColumns | undefined);
134
- distinct(): this;
135
- groupBy(...columns: AnySQLiteColumn[]): this;
136
- having(condition: SQLCondition): this;
137
- execute(): Promise<TSelectedColumns extends (keyof TTable["_"]["columns"])[] ? Pick<InferSelectModel<TTable>, TSelectedColumns[number]>[] : InferSelectModel<TTable>[]>;
138
- all(): Promise<TSelectedColumns extends (keyof TTable["_"]["columns"])[] ? Pick<InferSelectModel<TTable>, TSelectedColumns[number]>[] : InferSelectModel<TTable>[]>;
139
- get(): Promise<TSelectedColumns extends (keyof TTable["_"]["columns"])[] ? Pick<InferSelectModel<TTable>, TSelectedColumns[number]> | undefined : InferSelectModel<TTable> | undefined>;
163
+ declare class SelectBuilder<TSelection extends SelectedFields | undefined = undefined> {
164
+ private db;
165
+ private selection;
166
+ constructor(db: Database, selection: TSelection);
167
+ from<TTable extends AnyTable>(table: TTable): SelectQueryBuilder<TTable, TSelection extends SelectedFields ? TSelection : {}, TSelection extends SelectedFields ? {
168
+ [K in keyof TSelection]: any;
169
+ } : InferSelectModel<TTable>>;
140
170
  }
141
171
  declare class InsertQueryBuilder<T extends AnyTable> extends BaseQueryBuilder {
142
172
  private table;
@@ -147,7 +177,7 @@ declare class InsertQueryBuilder<T extends AnyTable> extends BaseQueryBuilder {
147
177
  private updateSet;
148
178
  constructor(db: Database, table: T);
149
179
  values(data: InferInsertModel<T> | InferInsertModel<T>[]): this;
150
- returning(...columns: (keyof T["_"]["columns"])[]): this;
180
+ returning(...columns: (AnySQLiteColumn | keyof T["_"]["columns"])[]): this;
151
181
  onConflictDoNothing(target?: AnySQLiteColumn | AnySQLiteColumn[]): this;
152
182
  onConflictDoUpdate(config: {
153
183
  target: AnySQLiteColumn | AnySQLiteColumn[];
@@ -164,7 +194,7 @@ declare class UpdateQueryBuilder<T extends AnyTable> extends BaseQueryBuilder {
164
194
  private returningColumns;
165
195
  constructor(db: Database, table: T);
166
196
  set(data: Partial<InferInsertModel<T>>): this;
167
- returning(...columns: (keyof T["_"]["columns"])[]): this;
197
+ returning(...columns: (AnySQLiteColumn | keyof T["_"]["columns"])[]): this;
168
198
  private buildUpdateClause;
169
199
  execute(): Promise<T extends AnyTable ? (InferSelectModel<T> & Record<string, any>)[] : never>;
170
200
  returningAll(): Promise<InferSelectModel<T>[]>;
@@ -173,7 +203,7 @@ declare class DeleteQueryBuilder<T extends AnyTable> extends BaseQueryBuilder {
173
203
  private table;
174
204
  private returningColumns;
175
205
  constructor(db: Database, table: T);
176
- returning(...columns: (keyof T["_"]["columns"])[]): this;
206
+ returning(...columns: (AnySQLiteColumn | keyof T["_"]["columns"])[]): this;
177
207
  execute(): Promise<T extends AnyTable ? (InferSelectModel<T> & Record<string, any>)[] : never>;
178
208
  returningAll(): Promise<InferSelectModel<T>[]>;
179
209
  }
@@ -185,19 +215,23 @@ declare class WithQueryBuilder {
185
215
  sql: string;
186
216
  params: any[];
187
217
  }): this;
188
- select<T extends AnyTable, C extends (keyof T["_"]["columns"])[] | undefined = undefined>(table: T, columns?: C): SelectQueryBuilder<T, C>;
218
+ select<TTable extends AnyTable, TSelection extends SelectedFields | undefined = undefined>(table: TTable, selection?: TSelection): SelectQueryBuilder<TTable, TSelection extends SelectedFields ? TSelection : {}, TSelection extends SelectedFields ? {
219
+ [K in keyof TSelection]: any;
220
+ } : InferSelectModel<TTable>>;
189
221
  insert<T extends AnyTable>(table: T): InsertQueryBuilder<T>;
190
222
  update<T extends AnyTable>(table: T): UpdateQueryBuilder<T>;
191
223
  delete<T extends AnyTable>(table: T): DeleteQueryBuilder<T>;
192
224
  private applyWithClause;
193
225
  }
226
+
194
227
  declare class TauriORM {
195
228
  private db;
196
229
  private tables;
197
- constructor(db: Database, schema?: Record<string, AnyTable> | undefined);
230
+ constructor(db: Database, schema?: Record<string, AnyTable | Record<string, Relation>> | undefined);
198
231
  private buildColumnDefinition;
199
232
  migrate(): Promise<void>;
200
- select<T extends AnyTable, C extends (keyof T["_"]["columns"])[] | undefined = undefined>(table: T, columns?: C): SelectQueryBuilder<T, C>;
233
+ select(): SelectBuilder<undefined>;
234
+ select<TSelection extends SelectedFields>(selection: TSelection): SelectBuilder<TSelection>;
201
235
  insert<T extends AnyTable>(table: T): InsertQueryBuilder<T>;
202
236
  update<T extends AnyTable>(table: T): UpdateQueryBuilder<T>;
203
237
  delete<T extends AnyTable>(table: T): DeleteQueryBuilder<T>;
@@ -222,11 +256,30 @@ declare class TauriORM {
222
256
  }>;
223
257
  migrateIfDirty(): Promise<boolean>;
224
258
  }
225
- declare const relations: <T extends AnyTable, R extends Record<string, any>>(table: T, relationsCallback: (helpers: {
226
- one: any;
227
- many: any;
228
- }) => R) => R;
229
- declare const getTableColumns: <T extends AnyTable>(table: T) => Record<string, AnySQLiteColumn>;
230
- declare const alias: <T extends AnyTable>(table: T, alias: string) => Table<T["_"]["columns"], T["_"]["name"]>;
259
+ declare class Relation<T extends AnyTable = AnyTable> {
260
+ foreignTable: T;
261
+ constructor(foreignTable: T);
262
+ }
263
+ declare class OneRelation<T extends AnyTable = AnyTable> extends Relation<T> {
264
+ config?: {
265
+ fields: AnySQLiteColumn[];
266
+ references: AnySQLiteColumn[];
267
+ } | undefined;
268
+ constructor(foreignTable: T, config?: {
269
+ fields: AnySQLiteColumn[];
270
+ references: AnySQLiteColumn[];
271
+ } | undefined);
272
+ }
273
+ declare class ManyRelation<T extends AnyTable = AnyTable> extends Relation<T> {
274
+ constructor(foreignTable: T);
275
+ }
276
+ type RelationsBuilder = {
277
+ one: <U extends AnyTable>(table: U, config?: {
278
+ fields: AnySQLiteColumn[];
279
+ references: AnySQLiteColumn[];
280
+ }) => OneRelation<U>;
281
+ many: <U extends AnyTable>(table: U) => ManyRelation<U>;
282
+ };
283
+ declare const relations: <T extends AnyTable, R extends Record<string, Relation>>(_table: T, relationsCallback: (helpers: RelationsBuilder) => R) => R;
231
284
 
232
- export { type AnySQLiteColumn, type AnyTable, type ColumnDataType, type ColumnOptions, DeleteQueryBuilder, type InferInsertModel, type InferSelectModel, InsertQueryBuilder, type Mode, type SQLCondition, SQLiteColumn, SelectQueryBuilder, Table, TauriORM, UpdateQueryBuilder, WithQueryBuilder, alias, and, asc, avg, blob, boolean, count, countDistinct, desc, eq, getTableColumns, gt, gte, inArray, integer, isNotNull, isNull, like, lt, lte, max, min, not, or, real, relations, sql, sqliteTable, sum, text };
285
+ export { type AnySQLiteColumn, type AnyTable, BaseQueryBuilder, type ColumnDataType, type ColumnOptions, DeleteQueryBuilder, type InferInsertModel, type InferSelectModel, InsertQueryBuilder, ManyRelation, type Mode, OneRelation, Relation, type SQLCondition, SQLiteColumn, SelectBuilder, SelectQueryBuilder, type SelectedFields, Table, TauriORM, UpdateQueryBuilder, WithQueryBuilder, alias, and, asc, avg, blob, boolean, count, countDistinct, desc, eq, getTableColumns, gt, gte, inArray, integer, isNotNull, isNull, like, lt, lte, max, min, not, or, real, relations, sql, sqliteTable, sum, text };
package/dist/index.d.ts CHANGED
@@ -28,6 +28,7 @@ declare class SQLiteColumn<TName extends string = string, TType extends ColumnDa
28
28
  notNull: TNotNull;
29
29
  hasDefault: THasDefault;
30
30
  autoincrement: TAutoincrement;
31
+ table: AnyTable;
31
32
  };
32
33
  constructor(name: TName, type: TType, options?: ColumnOptions<ColumnValueTypes<TType, TMode>>, mode?: TMode);
33
34
  notNull(): SQLiteColumn<TName, TType, TMode, true, THasDefault, TAutoincrement>;
@@ -72,6 +73,9 @@ declare class Table<TColumns extends Record<string, AnySQLiteColumn>, TTableName
72
73
  constructor(name: TTableName, columns: TColumns);
73
74
  }
74
75
  declare const sqliteTable: <TTableName extends string, TColumns extends Record<string, AnySQLiteColumn>>(tableName: TTableName, columns: TColumns) => Table<TColumns, TTableName>;
76
+ declare const getTableColumns: <T extends AnyTable>(table: T) => Record<string, AnySQLiteColumn>;
77
+ declare const alias: <T extends AnyTable>(table: T, alias: string) => Table<T["_"]["columns"], T["_"]["name"]>;
78
+
75
79
  type SQLCondition = {
76
80
  sql: string;
77
81
  params: any[];
@@ -112,31 +116,57 @@ declare class BaseQueryBuilder {
112
116
  protected query: string;
113
117
  protected params: any[];
114
118
  constructor(db: Database);
119
+ build(): {
120
+ sql: string;
121
+ params: any[];
122
+ };
123
+ }
124
+ type SelectedFields = Record<string, AnySQLiteColumn | {
125
+ sql: string;
126
+ params: any[];
127
+ }>;
128
+ declare class SelectQueryBuilder<TTable extends AnyTable, TSelection extends SelectedFields, TResult = InferSelectModel<TTable>> extends BaseQueryBuilder {
129
+ private selection;
130
+ private isDistinct;
131
+ private groupByColumns;
132
+ private havingCondition;
133
+ private joinClauses;
134
+ private fromTable;
135
+ private orderByClauses;
136
+ private limitCount;
137
+ private offsetCount;
138
+ private whereCondition;
139
+ constructor(db: Database, table: TTable, selection: TSelection | undefined);
115
140
  where(condition: SQLCondition): this;
141
+ leftJoin(table: AnyTable, on: SQLCondition): this;
142
+ innerJoin(table: AnyTable, on: SQLCondition): this;
143
+ rightJoin(table: AnyTable, on: SQLCondition): this;
144
+ fullJoin(table: AnyTable, on: SQLCondition): this;
145
+ distinct(): this;
146
+ groupBy(...columns: AnySQLiteColumn[]): this;
147
+ having(condition: SQLCondition): this;
116
148
  orderBy(column: AnySQLiteColumn | {
117
149
  sql: string;
118
150
  params: any[];
119
151
  }, direction?: "ASC" | "DESC"): this;
120
152
  limit(count: number): this;
121
153
  offset(count: number): this;
154
+ private buildSelectQuery;
122
155
  build(): {
123
156
  sql: string;
124
157
  params: any[];
125
158
  };
159
+ execute(): Promise<TResult[]>;
160
+ all(): Promise<TResult[]>;
161
+ get(): Promise<TResult | undefined>;
126
162
  }
127
- declare class SelectQueryBuilder<TTable extends AnyTable, TSelectedColumns extends (keyof TTable["_"]["columns"])[] | undefined = undefined> extends BaseQueryBuilder {
128
- private table;
129
- private columns?;
130
- private isDistinct;
131
- private groupByColumns;
132
- private havingCondition;
133
- constructor(db: Database, table: TTable, columns?: TSelectedColumns | undefined);
134
- distinct(): this;
135
- groupBy(...columns: AnySQLiteColumn[]): this;
136
- having(condition: SQLCondition): this;
137
- execute(): Promise<TSelectedColumns extends (keyof TTable["_"]["columns"])[] ? Pick<InferSelectModel<TTable>, TSelectedColumns[number]>[] : InferSelectModel<TTable>[]>;
138
- all(): Promise<TSelectedColumns extends (keyof TTable["_"]["columns"])[] ? Pick<InferSelectModel<TTable>, TSelectedColumns[number]>[] : InferSelectModel<TTable>[]>;
139
- get(): Promise<TSelectedColumns extends (keyof TTable["_"]["columns"])[] ? Pick<InferSelectModel<TTable>, TSelectedColumns[number]> | undefined : InferSelectModel<TTable> | undefined>;
163
+ declare class SelectBuilder<TSelection extends SelectedFields | undefined = undefined> {
164
+ private db;
165
+ private selection;
166
+ constructor(db: Database, selection: TSelection);
167
+ from<TTable extends AnyTable>(table: TTable): SelectQueryBuilder<TTable, TSelection extends SelectedFields ? TSelection : {}, TSelection extends SelectedFields ? {
168
+ [K in keyof TSelection]: any;
169
+ } : InferSelectModel<TTable>>;
140
170
  }
141
171
  declare class InsertQueryBuilder<T extends AnyTable> extends BaseQueryBuilder {
142
172
  private table;
@@ -147,7 +177,7 @@ declare class InsertQueryBuilder<T extends AnyTable> extends BaseQueryBuilder {
147
177
  private updateSet;
148
178
  constructor(db: Database, table: T);
149
179
  values(data: InferInsertModel<T> | InferInsertModel<T>[]): this;
150
- returning(...columns: (keyof T["_"]["columns"])[]): this;
180
+ returning(...columns: (AnySQLiteColumn | keyof T["_"]["columns"])[]): this;
151
181
  onConflictDoNothing(target?: AnySQLiteColumn | AnySQLiteColumn[]): this;
152
182
  onConflictDoUpdate(config: {
153
183
  target: AnySQLiteColumn | AnySQLiteColumn[];
@@ -164,7 +194,7 @@ declare class UpdateQueryBuilder<T extends AnyTable> extends BaseQueryBuilder {
164
194
  private returningColumns;
165
195
  constructor(db: Database, table: T);
166
196
  set(data: Partial<InferInsertModel<T>>): this;
167
- returning(...columns: (keyof T["_"]["columns"])[]): this;
197
+ returning(...columns: (AnySQLiteColumn | keyof T["_"]["columns"])[]): this;
168
198
  private buildUpdateClause;
169
199
  execute(): Promise<T extends AnyTable ? (InferSelectModel<T> & Record<string, any>)[] : never>;
170
200
  returningAll(): Promise<InferSelectModel<T>[]>;
@@ -173,7 +203,7 @@ declare class DeleteQueryBuilder<T extends AnyTable> extends BaseQueryBuilder {
173
203
  private table;
174
204
  private returningColumns;
175
205
  constructor(db: Database, table: T);
176
- returning(...columns: (keyof T["_"]["columns"])[]): this;
206
+ returning(...columns: (AnySQLiteColumn | keyof T["_"]["columns"])[]): this;
177
207
  execute(): Promise<T extends AnyTable ? (InferSelectModel<T> & Record<string, any>)[] : never>;
178
208
  returningAll(): Promise<InferSelectModel<T>[]>;
179
209
  }
@@ -185,19 +215,23 @@ declare class WithQueryBuilder {
185
215
  sql: string;
186
216
  params: any[];
187
217
  }): this;
188
- select<T extends AnyTable, C extends (keyof T["_"]["columns"])[] | undefined = undefined>(table: T, columns?: C): SelectQueryBuilder<T, C>;
218
+ select<TTable extends AnyTable, TSelection extends SelectedFields | undefined = undefined>(table: TTable, selection?: TSelection): SelectQueryBuilder<TTable, TSelection extends SelectedFields ? TSelection : {}, TSelection extends SelectedFields ? {
219
+ [K in keyof TSelection]: any;
220
+ } : InferSelectModel<TTable>>;
189
221
  insert<T extends AnyTable>(table: T): InsertQueryBuilder<T>;
190
222
  update<T extends AnyTable>(table: T): UpdateQueryBuilder<T>;
191
223
  delete<T extends AnyTable>(table: T): DeleteQueryBuilder<T>;
192
224
  private applyWithClause;
193
225
  }
226
+
194
227
  declare class TauriORM {
195
228
  private db;
196
229
  private tables;
197
- constructor(db: Database, schema?: Record<string, AnyTable> | undefined);
230
+ constructor(db: Database, schema?: Record<string, AnyTable | Record<string, Relation>> | undefined);
198
231
  private buildColumnDefinition;
199
232
  migrate(): Promise<void>;
200
- select<T extends AnyTable, C extends (keyof T["_"]["columns"])[] | undefined = undefined>(table: T, columns?: C): SelectQueryBuilder<T, C>;
233
+ select(): SelectBuilder<undefined>;
234
+ select<TSelection extends SelectedFields>(selection: TSelection): SelectBuilder<TSelection>;
201
235
  insert<T extends AnyTable>(table: T): InsertQueryBuilder<T>;
202
236
  update<T extends AnyTable>(table: T): UpdateQueryBuilder<T>;
203
237
  delete<T extends AnyTable>(table: T): DeleteQueryBuilder<T>;
@@ -222,11 +256,30 @@ declare class TauriORM {
222
256
  }>;
223
257
  migrateIfDirty(): Promise<boolean>;
224
258
  }
225
- declare const relations: <T extends AnyTable, R extends Record<string, any>>(table: T, relationsCallback: (helpers: {
226
- one: any;
227
- many: any;
228
- }) => R) => R;
229
- declare const getTableColumns: <T extends AnyTable>(table: T) => Record<string, AnySQLiteColumn>;
230
- declare const alias: <T extends AnyTable>(table: T, alias: string) => Table<T["_"]["columns"], T["_"]["name"]>;
259
+ declare class Relation<T extends AnyTable = AnyTable> {
260
+ foreignTable: T;
261
+ constructor(foreignTable: T);
262
+ }
263
+ declare class OneRelation<T extends AnyTable = AnyTable> extends Relation<T> {
264
+ config?: {
265
+ fields: AnySQLiteColumn[];
266
+ references: AnySQLiteColumn[];
267
+ } | undefined;
268
+ constructor(foreignTable: T, config?: {
269
+ fields: AnySQLiteColumn[];
270
+ references: AnySQLiteColumn[];
271
+ } | undefined);
272
+ }
273
+ declare class ManyRelation<T extends AnyTable = AnyTable> extends Relation<T> {
274
+ constructor(foreignTable: T);
275
+ }
276
+ type RelationsBuilder = {
277
+ one: <U extends AnyTable>(table: U, config?: {
278
+ fields: AnySQLiteColumn[];
279
+ references: AnySQLiteColumn[];
280
+ }) => OneRelation<U>;
281
+ many: <U extends AnyTable>(table: U) => ManyRelation<U>;
282
+ };
283
+ declare const relations: <T extends AnyTable, R extends Record<string, Relation>>(_table: T, relationsCallback: (helpers: RelationsBuilder) => R) => R;
231
284
 
232
- export { type AnySQLiteColumn, type AnyTable, type ColumnDataType, type ColumnOptions, DeleteQueryBuilder, type InferInsertModel, type InferSelectModel, InsertQueryBuilder, type Mode, type SQLCondition, SQLiteColumn, SelectQueryBuilder, Table, TauriORM, UpdateQueryBuilder, WithQueryBuilder, alias, and, asc, avg, blob, boolean, count, countDistinct, desc, eq, getTableColumns, gt, gte, inArray, integer, isNotNull, isNull, like, lt, lte, max, min, not, or, real, relations, sql, sqliteTable, sum, text };
285
+ export { type AnySQLiteColumn, type AnyTable, BaseQueryBuilder, type ColumnDataType, type ColumnOptions, DeleteQueryBuilder, type InferInsertModel, type InferSelectModel, InsertQueryBuilder, ManyRelation, type Mode, OneRelation, Relation, type SQLCondition, SQLiteColumn, SelectBuilder, SelectQueryBuilder, type SelectedFields, Table, TauriORM, UpdateQueryBuilder, WithQueryBuilder, alias, and, asc, avg, blob, boolean, count, countDistinct, desc, eq, getTableColumns, gt, gte, inArray, integer, isNotNull, isNull, like, lt, lte, max, min, not, or, real, relations, sql, sqliteTable, sum, text };
package/dist/index.js CHANGED
@@ -20,9 +20,14 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
+ BaseQueryBuilder: () => BaseQueryBuilder,
23
24
  DeleteQueryBuilder: () => DeleteQueryBuilder,
24
25
  InsertQueryBuilder: () => InsertQueryBuilder,
26
+ ManyRelation: () => ManyRelation,
27
+ OneRelation: () => OneRelation,
28
+ Relation: () => Relation,
25
29
  SQLiteColumn: () => SQLiteColumn,
30
+ SelectBuilder: () => SelectBuilder,
26
31
  SelectQueryBuilder: () => SelectQueryBuilder,
27
32
  Table: () => Table,
28
33
  TauriORM: () => TauriORM,
@@ -61,7 +66,7 @@ __export(index_exports, {
61
66
  });
62
67
  module.exports = __toCommonJS(index_exports);
63
68
 
64
- // src/orm.ts
69
+ // src/schema.ts
65
70
  var SQLiteColumn = class _SQLiteColumn {
66
71
  constructor(name, type, options = {}, mode) {
67
72
  this.type = type;
@@ -72,7 +77,8 @@ var SQLiteColumn = class _SQLiteColumn {
72
77
  mode: mode || "default",
73
78
  notNull: options.notNull ?? false,
74
79
  hasDefault: options.default !== void 0 || options.$defaultFn !== void 0,
75
- autoincrement: options.autoincrement ?? false
80
+ autoincrement: options.autoincrement ?? false,
81
+ table: void 0
76
82
  };
77
83
  }
78
84
  _;
@@ -165,8 +171,20 @@ var Table = class {
165
171
  }
166
172
  };
167
173
  var sqliteTable = (tableName, columns) => {
168
- return new Table(tableName, columns);
174
+ const table = new Table(tableName, columns);
175
+ for (const col of Object.values(columns)) {
176
+ col._.table = table;
177
+ }
178
+ return table;
179
+ };
180
+ var getTableColumns = (table) => {
181
+ return table._.columns;
169
182
  };
183
+ var alias = (table, alias2) => {
184
+ return table;
185
+ };
186
+
187
+ // src/query-builder.ts
170
188
  var eq = (column, value) => ({
171
189
  sql: `${column._.name} = ?`,
172
190
  params: [value]
@@ -273,28 +291,6 @@ var BaseQueryBuilder = class {
273
291
  }
274
292
  query = "";
275
293
  params = [];
276
- where(condition) {
277
- this.query += ` WHERE ${condition.sql}`;
278
- this.params.push(...condition.params);
279
- return this;
280
- }
281
- orderBy(column, direction = "ASC") {
282
- if ("sql" in column) {
283
- this.query += ` ORDER BY ${column.sql} ${direction}`;
284
- this.params.push(...column.params);
285
- } else {
286
- this.query += ` ORDER BY ${column._.name} ${direction}`;
287
- }
288
- return this;
289
- }
290
- limit(count2) {
291
- this.query += ` LIMIT ${count2}`;
292
- return this;
293
- }
294
- offset(count2) {
295
- this.query += ` OFFSET ${count2}`;
296
- return this;
297
- }
298
294
  build() {
299
295
  return {
300
296
  sql: this.query,
@@ -303,35 +299,134 @@ var BaseQueryBuilder = class {
303
299
  }
304
300
  };
305
301
  var SelectQueryBuilder = class extends BaseQueryBuilder {
306
- constructor(db, table, columns) {
302
+ constructor(db, table, selection) {
307
303
  super(db);
308
- this.table = table;
309
- this.columns = columns;
310
- const columnNames = columns ? columns.map((c) => table._.columns[c]._.name) : ["*"];
311
- this.query = `SELECT ${columnNames.join(", ")} FROM ${table._.name}`;
304
+ this.selection = selection;
305
+ this.fromTable = table;
306
+ this.query = "";
307
+ this.params = [];
312
308
  }
313
309
  isDistinct = false;
314
310
  groupByColumns = [];
315
- havingCondition = null;
311
+ havingCondition;
312
+ joinClauses = [];
313
+ fromTable;
314
+ orderByClauses = [];
315
+ limitCount;
316
+ offsetCount;
317
+ whereCondition;
318
+ where(condition) {
319
+ this.whereCondition = condition;
320
+ return this;
321
+ }
322
+ leftJoin(table, on) {
323
+ this.joinClauses.push({ type: "LEFT JOIN", table, on });
324
+ return this;
325
+ }
326
+ innerJoin(table, on) {
327
+ this.joinClauses.push({ type: "INNER JOIN", table, on });
328
+ return this;
329
+ }
330
+ rightJoin(table, on) {
331
+ this.joinClauses.push({ type: "RIGHT JOIN", table, on });
332
+ return this;
333
+ }
334
+ fullJoin(table, on) {
335
+ this.joinClauses.push({ type: "FULL JOIN", table, on });
336
+ return this;
337
+ }
316
338
  distinct() {
317
339
  this.isDistinct = true;
318
- this.query = this.query.replace("SELECT", "SELECT DISTINCT");
319
340
  return this;
320
341
  }
321
342
  groupBy(...columns) {
322
343
  this.groupByColumns.push(...columns);
323
- const columnNames = columns.map((col) => col._.name).join(", ");
324
- this.query += ` GROUP BY ${columnNames}`;
325
344
  return this;
326
345
  }
327
346
  having(condition) {
328
347
  this.havingCondition = condition;
329
- this.query += ` HAVING ${condition.sql}`;
330
- this.params.push(...condition.params);
331
348
  return this;
332
349
  }
350
+ orderBy(column, direction = "ASC") {
351
+ if ("sql" in column) {
352
+ this.orderByClauses.push({
353
+ sql: `${column.sql} ${direction}`,
354
+ params: column.params
355
+ });
356
+ } else {
357
+ this.orderByClauses.push({
358
+ sql: `${column._.name} ${direction}`,
359
+ params: []
360
+ });
361
+ }
362
+ return this;
363
+ }
364
+ limit(count2) {
365
+ this.limitCount = count2;
366
+ return this;
367
+ }
368
+ offset(count2) {
369
+ this.offsetCount = count2;
370
+ return this;
371
+ }
372
+ buildSelectQuery() {
373
+ const selectionEntries = this.selection ? Object.entries(this.selection) : [];
374
+ let columnsClause;
375
+ const selectParams = [];
376
+ if (selectionEntries.length === 0) {
377
+ columnsClause = "*";
378
+ } else {
379
+ columnsClause = selectionEntries.map(([alias2, col]) => {
380
+ if (col instanceof SQLiteColumn) {
381
+ return `${col._.table._.name}.${col._.name} AS "${alias2}"`;
382
+ } else {
383
+ selectParams.push(...col.params);
384
+ return `(${col.sql}) AS "${alias2}"`;
385
+ }
386
+ }).join(", ");
387
+ }
388
+ let query = `SELECT ${this.isDistinct ? "DISTINCT " : ""}${columnsClause} FROM ${this.fromTable._.name}`;
389
+ const queryParams = [...selectParams];
390
+ if (this.joinClauses.length > 0) {
391
+ const joins = this.joinClauses.map((j) => {
392
+ queryParams.push(...j.on.params);
393
+ return `${j.type} ${j.table._.name} ON ${j.on.sql}`;
394
+ });
395
+ query += ` ${joins.join(" ")}`;
396
+ }
397
+ if (this.whereCondition) {
398
+ query += ` WHERE ${this.whereCondition.sql}`;
399
+ queryParams.push(...this.whereCondition.params);
400
+ }
401
+ if (this.groupByColumns.length > 0) {
402
+ const columnNames = this.groupByColumns.map((c) => c._.name).join(", ");
403
+ query += ` GROUP BY ${columnNames}`;
404
+ }
405
+ if (this.havingCondition) {
406
+ query += ` HAVING ${this.havingCondition.sql}`;
407
+ queryParams.push(...this.havingCondition.params);
408
+ }
409
+ if (this.orderByClauses.length > 0) {
410
+ const orderBySql = this.orderByClauses.map((c) => c.sql).join(", ");
411
+ query += ` ORDER BY ${orderBySql}`;
412
+ queryParams.push(...this.orderByClauses.flatMap((c) => c.params));
413
+ }
414
+ if (this.limitCount !== void 0) {
415
+ query += ` LIMIT ${this.limitCount}`;
416
+ }
417
+ if (this.offsetCount !== void 0) {
418
+ query += ` OFFSET ${this.offsetCount}`;
419
+ }
420
+ return {
421
+ sql: query,
422
+ params: queryParams
423
+ };
424
+ }
425
+ build() {
426
+ return this.buildSelectQuery();
427
+ }
333
428
  async execute() {
334
- const { sql: sql2, params } = this.build();
429
+ const { sql: sql2, params } = this.buildSelectQuery();
335
430
  return this.db.select(sql2, params);
336
431
  }
337
432
  async all() {
@@ -343,6 +438,19 @@ var SelectQueryBuilder = class extends BaseQueryBuilder {
343
438
  return result[0];
344
439
  }
345
440
  };
441
+ var SelectBuilder = class {
442
+ constructor(db, selection) {
443
+ this.db = db;
444
+ this.selection = selection;
445
+ }
446
+ from(table) {
447
+ return new SelectQueryBuilder(
448
+ this.db,
449
+ table,
450
+ this.selection
451
+ );
452
+ }
453
+ };
346
454
  var InsertQueryBuilder = class extends BaseQueryBuilder {
347
455
  constructor(db, table) {
348
456
  super(db);
@@ -360,7 +468,13 @@ var InsertQueryBuilder = class extends BaseQueryBuilder {
360
468
  return this;
361
469
  }
362
470
  returning(...columns) {
363
- this.returningColumns = columns;
471
+ for (const col of columns) {
472
+ if (typeof col === "string") {
473
+ this.returningColumns.push(this.table._.columns[col]);
474
+ } else {
475
+ this.returningColumns.push(col);
476
+ }
477
+ }
364
478
  return this;
365
479
  }
366
480
  onConflictDoNothing(target) {
@@ -445,7 +559,7 @@ var InsertQueryBuilder = class extends BaseQueryBuilder {
445
559
  params.push(...setValues);
446
560
  }
447
561
  if (this.returningColumns.length > 0) {
448
- const returningNames = this.returningColumns.map((col) => this.table._.columns[col]._.name).join(", ");
562
+ const returningNames = this.returningColumns.map((col) => col._.name).join(", ");
449
563
  const queryWithReturning = `${finalQuery} RETURNING ${returningNames}`;
450
564
  const rows = await this.db.select(queryWithReturning, params);
451
565
  results = results.concat(rows);
@@ -480,7 +594,13 @@ var UpdateQueryBuilder = class extends BaseQueryBuilder {
480
594
  return this;
481
595
  }
482
596
  returning(...columns) {
483
- this.returningColumns = columns;
597
+ for (const col of columns) {
598
+ if (typeof col === "string") {
599
+ this.returningColumns.push(this.table._.columns[col]);
600
+ } else {
601
+ this.returningColumns.push(col);
602
+ }
603
+ }
484
604
  return this;
485
605
  }
486
606
  buildUpdateClause() {
@@ -521,7 +641,7 @@ var UpdateQueryBuilder = class extends BaseQueryBuilder {
521
641
  async execute() {
522
642
  const { sql: updateSql, params } = this.buildUpdateClause();
523
643
  if (this.returningColumns.length > 0) {
524
- const returningNames = this.returningColumns.map((col) => this.table._.columns[col]._.name).join(", ");
644
+ const returningNames = this.returningColumns.map((col) => col._.name).join(", ");
525
645
  const sqlWithReturning = `${updateSql} RETURNING ${returningNames}`;
526
646
  return this.db.select(sqlWithReturning, params);
527
647
  } else {
@@ -544,13 +664,19 @@ var DeleteQueryBuilder = class extends BaseQueryBuilder {
544
664
  }
545
665
  returningColumns = [];
546
666
  returning(...columns) {
547
- this.returningColumns = columns;
667
+ for (const col of columns) {
668
+ if (typeof col === "string") {
669
+ this.returningColumns.push(this.table._.columns[col]);
670
+ } else {
671
+ this.returningColumns.push(col);
672
+ }
673
+ }
548
674
  return this;
549
675
  }
550
676
  async execute() {
551
677
  const { sql: sql2, params } = this.build();
552
678
  if (this.returningColumns.length > 0) {
553
- const returningNames = this.returningColumns.map((col) => this.table._.columns[col]._.name).join(", ");
679
+ const returningNames = this.returningColumns.map((col) => col._.name).join(", ");
554
680
  const sqlWithReturning = `${sql2} RETURNING ${returningNames}`;
555
681
  return this.db.select(sqlWithReturning, params);
556
682
  } else {
@@ -574,8 +700,12 @@ var WithQueryBuilder = class {
574
700
  this.ctes.push({ alias: alias2, query: query.sql, params: query.params });
575
701
  return this;
576
702
  }
577
- select(table, columns) {
578
- const builder = new SelectQueryBuilder(this.db, table, columns);
703
+ select(table, selection) {
704
+ const builder = new SelectQueryBuilder(
705
+ this.db,
706
+ table,
707
+ selection
708
+ );
579
709
  this.applyWithClause(builder);
580
710
  return builder;
581
711
  }
@@ -605,12 +735,16 @@ var WithQueryBuilder = class {
605
735
  }
606
736
  }
607
737
  };
738
+
739
+ // src/orm.ts
608
740
  var TauriORM = class {
609
741
  constructor(db, schema = void 0) {
610
742
  this.db = db;
611
743
  if (schema) {
612
744
  for (const table of Object.values(schema)) {
613
- this.tables.set(table._.name, table);
745
+ if (table instanceof Table) {
746
+ this.tables.set(table._.name, table);
747
+ }
614
748
  }
615
749
  }
616
750
  }
@@ -657,8 +791,8 @@ var TauriORM = class {
657
791
  }
658
792
  }
659
793
  }
660
- select(table, columns) {
661
- return new SelectQueryBuilder(this.db, table, columns);
794
+ select(selection) {
795
+ return new SelectBuilder(this.db, selection);
662
796
  }
663
797
  insert(table) {
664
798
  return new InsertQueryBuilder(this.db, table);
@@ -755,31 +889,42 @@ var TauriORM = class {
755
889
  return false;
756
890
  }
757
891
  };
758
- var relations = (table, relationsCallback) => {
759
- return relationsCallback({
760
- one: (table2, config) => ({
761
- table: table2,
762
- type: "one",
763
- foreignKey: config.fields[0],
764
- localKey: config.references[0]
765
- }),
766
- many: (table2) => ({
767
- table: table2,
768
- type: "many"
769
- })
770
- });
892
+ var Relation = class {
893
+ constructor(foreignTable) {
894
+ this.foreignTable = foreignTable;
895
+ }
771
896
  };
772
- var getTableColumns = (table) => {
773
- return table._.columns;
897
+ var OneRelation = class extends Relation {
898
+ constructor(foreignTable, config) {
899
+ super(foreignTable);
900
+ this.config = config;
901
+ }
774
902
  };
775
- var alias = (table, alias2) => {
776
- return table;
903
+ var ManyRelation = class extends Relation {
904
+ constructor(foreignTable) {
905
+ super(foreignTable);
906
+ }
907
+ };
908
+ var relations = (_table, relationsCallback) => {
909
+ return relationsCallback({
910
+ one: (table, config) => {
911
+ return new OneRelation(table, config);
912
+ },
913
+ many: (table) => {
914
+ return new ManyRelation(table);
915
+ }
916
+ });
777
917
  };
778
918
  // Annotate the CommonJS export names for ESM import in node:
779
919
  0 && (module.exports = {
920
+ BaseQueryBuilder,
780
921
  DeleteQueryBuilder,
781
922
  InsertQueryBuilder,
923
+ ManyRelation,
924
+ OneRelation,
925
+ Relation,
782
926
  SQLiteColumn,
927
+ SelectBuilder,
783
928
  SelectQueryBuilder,
784
929
  Table,
785
930
  TauriORM,
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- // src/orm.ts
1
+ // src/schema.ts
2
2
  var SQLiteColumn = class _SQLiteColumn {
3
3
  constructor(name, type, options = {}, mode) {
4
4
  this.type = type;
@@ -9,7 +9,8 @@ var SQLiteColumn = class _SQLiteColumn {
9
9
  mode: mode || "default",
10
10
  notNull: options.notNull ?? false,
11
11
  hasDefault: options.default !== void 0 || options.$defaultFn !== void 0,
12
- autoincrement: options.autoincrement ?? false
12
+ autoincrement: options.autoincrement ?? false,
13
+ table: void 0
13
14
  };
14
15
  }
15
16
  _;
@@ -102,8 +103,20 @@ var Table = class {
102
103
  }
103
104
  };
104
105
  var sqliteTable = (tableName, columns) => {
105
- return new Table(tableName, columns);
106
+ const table = new Table(tableName, columns);
107
+ for (const col of Object.values(columns)) {
108
+ col._.table = table;
109
+ }
110
+ return table;
111
+ };
112
+ var getTableColumns = (table) => {
113
+ return table._.columns;
106
114
  };
115
+ var alias = (table, alias2) => {
116
+ return table;
117
+ };
118
+
119
+ // src/query-builder.ts
107
120
  var eq = (column, value) => ({
108
121
  sql: `${column._.name} = ?`,
109
122
  params: [value]
@@ -210,28 +223,6 @@ var BaseQueryBuilder = class {
210
223
  }
211
224
  query = "";
212
225
  params = [];
213
- where(condition) {
214
- this.query += ` WHERE ${condition.sql}`;
215
- this.params.push(...condition.params);
216
- return this;
217
- }
218
- orderBy(column, direction = "ASC") {
219
- if ("sql" in column) {
220
- this.query += ` ORDER BY ${column.sql} ${direction}`;
221
- this.params.push(...column.params);
222
- } else {
223
- this.query += ` ORDER BY ${column._.name} ${direction}`;
224
- }
225
- return this;
226
- }
227
- limit(count2) {
228
- this.query += ` LIMIT ${count2}`;
229
- return this;
230
- }
231
- offset(count2) {
232
- this.query += ` OFFSET ${count2}`;
233
- return this;
234
- }
235
226
  build() {
236
227
  return {
237
228
  sql: this.query,
@@ -240,35 +231,134 @@ var BaseQueryBuilder = class {
240
231
  }
241
232
  };
242
233
  var SelectQueryBuilder = class extends BaseQueryBuilder {
243
- constructor(db, table, columns) {
234
+ constructor(db, table, selection) {
244
235
  super(db);
245
- this.table = table;
246
- this.columns = columns;
247
- const columnNames = columns ? columns.map((c) => table._.columns[c]._.name) : ["*"];
248
- this.query = `SELECT ${columnNames.join(", ")} FROM ${table._.name}`;
236
+ this.selection = selection;
237
+ this.fromTable = table;
238
+ this.query = "";
239
+ this.params = [];
249
240
  }
250
241
  isDistinct = false;
251
242
  groupByColumns = [];
252
- havingCondition = null;
243
+ havingCondition;
244
+ joinClauses = [];
245
+ fromTable;
246
+ orderByClauses = [];
247
+ limitCount;
248
+ offsetCount;
249
+ whereCondition;
250
+ where(condition) {
251
+ this.whereCondition = condition;
252
+ return this;
253
+ }
254
+ leftJoin(table, on) {
255
+ this.joinClauses.push({ type: "LEFT JOIN", table, on });
256
+ return this;
257
+ }
258
+ innerJoin(table, on) {
259
+ this.joinClauses.push({ type: "INNER JOIN", table, on });
260
+ return this;
261
+ }
262
+ rightJoin(table, on) {
263
+ this.joinClauses.push({ type: "RIGHT JOIN", table, on });
264
+ return this;
265
+ }
266
+ fullJoin(table, on) {
267
+ this.joinClauses.push({ type: "FULL JOIN", table, on });
268
+ return this;
269
+ }
253
270
  distinct() {
254
271
  this.isDistinct = true;
255
- this.query = this.query.replace("SELECT", "SELECT DISTINCT");
256
272
  return this;
257
273
  }
258
274
  groupBy(...columns) {
259
275
  this.groupByColumns.push(...columns);
260
- const columnNames = columns.map((col) => col._.name).join(", ");
261
- this.query += ` GROUP BY ${columnNames}`;
262
276
  return this;
263
277
  }
264
278
  having(condition) {
265
279
  this.havingCondition = condition;
266
- this.query += ` HAVING ${condition.sql}`;
267
- this.params.push(...condition.params);
268
280
  return this;
269
281
  }
282
+ orderBy(column, direction = "ASC") {
283
+ if ("sql" in column) {
284
+ this.orderByClauses.push({
285
+ sql: `${column.sql} ${direction}`,
286
+ params: column.params
287
+ });
288
+ } else {
289
+ this.orderByClauses.push({
290
+ sql: `${column._.name} ${direction}`,
291
+ params: []
292
+ });
293
+ }
294
+ return this;
295
+ }
296
+ limit(count2) {
297
+ this.limitCount = count2;
298
+ return this;
299
+ }
300
+ offset(count2) {
301
+ this.offsetCount = count2;
302
+ return this;
303
+ }
304
+ buildSelectQuery() {
305
+ const selectionEntries = this.selection ? Object.entries(this.selection) : [];
306
+ let columnsClause;
307
+ const selectParams = [];
308
+ if (selectionEntries.length === 0) {
309
+ columnsClause = "*";
310
+ } else {
311
+ columnsClause = selectionEntries.map(([alias2, col]) => {
312
+ if (col instanceof SQLiteColumn) {
313
+ return `${col._.table._.name}.${col._.name} AS "${alias2}"`;
314
+ } else {
315
+ selectParams.push(...col.params);
316
+ return `(${col.sql}) AS "${alias2}"`;
317
+ }
318
+ }).join(", ");
319
+ }
320
+ let query = `SELECT ${this.isDistinct ? "DISTINCT " : ""}${columnsClause} FROM ${this.fromTable._.name}`;
321
+ const queryParams = [...selectParams];
322
+ if (this.joinClauses.length > 0) {
323
+ const joins = this.joinClauses.map((j) => {
324
+ queryParams.push(...j.on.params);
325
+ return `${j.type} ${j.table._.name} ON ${j.on.sql}`;
326
+ });
327
+ query += ` ${joins.join(" ")}`;
328
+ }
329
+ if (this.whereCondition) {
330
+ query += ` WHERE ${this.whereCondition.sql}`;
331
+ queryParams.push(...this.whereCondition.params);
332
+ }
333
+ if (this.groupByColumns.length > 0) {
334
+ const columnNames = this.groupByColumns.map((c) => c._.name).join(", ");
335
+ query += ` GROUP BY ${columnNames}`;
336
+ }
337
+ if (this.havingCondition) {
338
+ query += ` HAVING ${this.havingCondition.sql}`;
339
+ queryParams.push(...this.havingCondition.params);
340
+ }
341
+ if (this.orderByClauses.length > 0) {
342
+ const orderBySql = this.orderByClauses.map((c) => c.sql).join(", ");
343
+ query += ` ORDER BY ${orderBySql}`;
344
+ queryParams.push(...this.orderByClauses.flatMap((c) => c.params));
345
+ }
346
+ if (this.limitCount !== void 0) {
347
+ query += ` LIMIT ${this.limitCount}`;
348
+ }
349
+ if (this.offsetCount !== void 0) {
350
+ query += ` OFFSET ${this.offsetCount}`;
351
+ }
352
+ return {
353
+ sql: query,
354
+ params: queryParams
355
+ };
356
+ }
357
+ build() {
358
+ return this.buildSelectQuery();
359
+ }
270
360
  async execute() {
271
- const { sql: sql2, params } = this.build();
361
+ const { sql: sql2, params } = this.buildSelectQuery();
272
362
  return this.db.select(sql2, params);
273
363
  }
274
364
  async all() {
@@ -280,6 +370,19 @@ var SelectQueryBuilder = class extends BaseQueryBuilder {
280
370
  return result[0];
281
371
  }
282
372
  };
373
+ var SelectBuilder = class {
374
+ constructor(db, selection) {
375
+ this.db = db;
376
+ this.selection = selection;
377
+ }
378
+ from(table) {
379
+ return new SelectQueryBuilder(
380
+ this.db,
381
+ table,
382
+ this.selection
383
+ );
384
+ }
385
+ };
283
386
  var InsertQueryBuilder = class extends BaseQueryBuilder {
284
387
  constructor(db, table) {
285
388
  super(db);
@@ -297,7 +400,13 @@ var InsertQueryBuilder = class extends BaseQueryBuilder {
297
400
  return this;
298
401
  }
299
402
  returning(...columns) {
300
- this.returningColumns = columns;
403
+ for (const col of columns) {
404
+ if (typeof col === "string") {
405
+ this.returningColumns.push(this.table._.columns[col]);
406
+ } else {
407
+ this.returningColumns.push(col);
408
+ }
409
+ }
301
410
  return this;
302
411
  }
303
412
  onConflictDoNothing(target) {
@@ -382,7 +491,7 @@ var InsertQueryBuilder = class extends BaseQueryBuilder {
382
491
  params.push(...setValues);
383
492
  }
384
493
  if (this.returningColumns.length > 0) {
385
- const returningNames = this.returningColumns.map((col) => this.table._.columns[col]._.name).join(", ");
494
+ const returningNames = this.returningColumns.map((col) => col._.name).join(", ");
386
495
  const queryWithReturning = `${finalQuery} RETURNING ${returningNames}`;
387
496
  const rows = await this.db.select(queryWithReturning, params);
388
497
  results = results.concat(rows);
@@ -417,7 +526,13 @@ var UpdateQueryBuilder = class extends BaseQueryBuilder {
417
526
  return this;
418
527
  }
419
528
  returning(...columns) {
420
- this.returningColumns = columns;
529
+ for (const col of columns) {
530
+ if (typeof col === "string") {
531
+ this.returningColumns.push(this.table._.columns[col]);
532
+ } else {
533
+ this.returningColumns.push(col);
534
+ }
535
+ }
421
536
  return this;
422
537
  }
423
538
  buildUpdateClause() {
@@ -458,7 +573,7 @@ var UpdateQueryBuilder = class extends BaseQueryBuilder {
458
573
  async execute() {
459
574
  const { sql: updateSql, params } = this.buildUpdateClause();
460
575
  if (this.returningColumns.length > 0) {
461
- const returningNames = this.returningColumns.map((col) => this.table._.columns[col]._.name).join(", ");
576
+ const returningNames = this.returningColumns.map((col) => col._.name).join(", ");
462
577
  const sqlWithReturning = `${updateSql} RETURNING ${returningNames}`;
463
578
  return this.db.select(sqlWithReturning, params);
464
579
  } else {
@@ -481,13 +596,19 @@ var DeleteQueryBuilder = class extends BaseQueryBuilder {
481
596
  }
482
597
  returningColumns = [];
483
598
  returning(...columns) {
484
- this.returningColumns = columns;
599
+ for (const col of columns) {
600
+ if (typeof col === "string") {
601
+ this.returningColumns.push(this.table._.columns[col]);
602
+ } else {
603
+ this.returningColumns.push(col);
604
+ }
605
+ }
485
606
  return this;
486
607
  }
487
608
  async execute() {
488
609
  const { sql: sql2, params } = this.build();
489
610
  if (this.returningColumns.length > 0) {
490
- const returningNames = this.returningColumns.map((col) => this.table._.columns[col]._.name).join(", ");
611
+ const returningNames = this.returningColumns.map((col) => col._.name).join(", ");
491
612
  const sqlWithReturning = `${sql2} RETURNING ${returningNames}`;
492
613
  return this.db.select(sqlWithReturning, params);
493
614
  } else {
@@ -511,8 +632,12 @@ var WithQueryBuilder = class {
511
632
  this.ctes.push({ alias: alias2, query: query.sql, params: query.params });
512
633
  return this;
513
634
  }
514
- select(table, columns) {
515
- const builder = new SelectQueryBuilder(this.db, table, columns);
635
+ select(table, selection) {
636
+ const builder = new SelectQueryBuilder(
637
+ this.db,
638
+ table,
639
+ selection
640
+ );
516
641
  this.applyWithClause(builder);
517
642
  return builder;
518
643
  }
@@ -542,12 +667,16 @@ var WithQueryBuilder = class {
542
667
  }
543
668
  }
544
669
  };
670
+
671
+ // src/orm.ts
545
672
  var TauriORM = class {
546
673
  constructor(db, schema = void 0) {
547
674
  this.db = db;
548
675
  if (schema) {
549
676
  for (const table of Object.values(schema)) {
550
- this.tables.set(table._.name, table);
677
+ if (table instanceof Table) {
678
+ this.tables.set(table._.name, table);
679
+ }
551
680
  }
552
681
  }
553
682
  }
@@ -594,8 +723,8 @@ var TauriORM = class {
594
723
  }
595
724
  }
596
725
  }
597
- select(table, columns) {
598
- return new SelectQueryBuilder(this.db, table, columns);
726
+ select(selection) {
727
+ return new SelectBuilder(this.db, selection);
599
728
  }
600
729
  insert(table) {
601
730
  return new InsertQueryBuilder(this.db, table);
@@ -692,30 +821,41 @@ var TauriORM = class {
692
821
  return false;
693
822
  }
694
823
  };
695
- var relations = (table, relationsCallback) => {
696
- return relationsCallback({
697
- one: (table2, config) => ({
698
- table: table2,
699
- type: "one",
700
- foreignKey: config.fields[0],
701
- localKey: config.references[0]
702
- }),
703
- many: (table2) => ({
704
- table: table2,
705
- type: "many"
706
- })
707
- });
824
+ var Relation = class {
825
+ constructor(foreignTable) {
826
+ this.foreignTable = foreignTable;
827
+ }
708
828
  };
709
- var getTableColumns = (table) => {
710
- return table._.columns;
829
+ var OneRelation = class extends Relation {
830
+ constructor(foreignTable, config) {
831
+ super(foreignTable);
832
+ this.config = config;
833
+ }
711
834
  };
712
- var alias = (table, alias2) => {
713
- return table;
835
+ var ManyRelation = class extends Relation {
836
+ constructor(foreignTable) {
837
+ super(foreignTable);
838
+ }
839
+ };
840
+ var relations = (_table, relationsCallback) => {
841
+ return relationsCallback({
842
+ one: (table, config) => {
843
+ return new OneRelation(table, config);
844
+ },
845
+ many: (table) => {
846
+ return new ManyRelation(table);
847
+ }
848
+ });
714
849
  };
715
850
  export {
851
+ BaseQueryBuilder,
716
852
  DeleteQueryBuilder,
717
853
  InsertQueryBuilder,
854
+ ManyRelation,
855
+ OneRelation,
856
+ Relation,
718
857
  SQLiteColumn,
858
+ SelectBuilder,
719
859
  SelectQueryBuilder,
720
860
  Table,
721
861
  TauriORM,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@type32/tauri-sqlite-orm",
3
- "version": "0.1.18-7",
3
+ "version": "0.1.18-9",
4
4
  "description": "A Drizzle-like ORM for Tauri v2's SQL JS API plugin.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",