diff --git a/.gitignore b/.gitignore index c22a4cd..2b6fc86 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ node_modules BunORM*.tgz yarn-error.log +*.sqlite \ No newline at end of file diff --git a/README.md b/README.md index 75fbf3e..19319b6 100644 --- a/README.md +++ b/README.md @@ -130,8 +130,8 @@ Please! Please! Please! Please! Please use the dev branch when making changes an - [ ] Cleaning up the messy shit i call "code" - [ ] Adding support for multiple relation types (one-to-many, one-to-one, etc.) - [ ] Support relations both ways if one is set -- [ ] `db.tables.[table].save` should return the saved entity - [ ] Bulk actions for everything +- [x] `db.tables.[table].save` should return the saved or updated entity

diff --git a/src/example/README.md b/src/example/README.md index b3470a1..d19a116 100644 --- a/src/example/README.md +++ b/src/example/README.md @@ -179,12 +179,19 @@ db.tables[TableName].create({ // Save a row in the database // Parameter can be a object containing the data or the result of the create function db.tables[TableName].save({ - name: "admin", + username: "admin", +}); + +// Call save with id parameter to update +// It also makes all properties partial/optional +db.tables[TableName].save({ + id: 1, + username: "newAdmin", }); // Delete a row from the database based on the parameters db.tables.users.delete({ - username: "admin", + username: "newAdmin", }); ``` diff --git a/src/example/example.ts b/src/example/example.ts index e70f862..407264f 100644 --- a/src/example/example.ts +++ b/src/example/example.ts @@ -91,6 +91,11 @@ const onlyUsernameAdmins = db.tables.users.find({ // everything except username and the default attributes (id, createdAt, updatedAt and functions) will be undefined onlyUsernameAdmins[0].username; +db.tables.users.save({ + id: 1, + username: "newAdmin", +}); + db.tables.users.delete({ - username: "admin", + username: "newAdmin", }); diff --git a/src/index.ts b/src/index.ts index 11f8318..5115db7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -166,7 +166,11 @@ type Or = A extends TA ? true : B extends TB ? true : false; interface _TableFunctions { create: (cols: _Columns) => AddTableFx>; - save: (cols: { id?: number } & _Columns) => void; + save: ( + cols: + | _Columns + | ({ id: number } & Partial<_Columns>) + ) => AddTableFx>>[]; delete: (opts: Partial<_Columns>) => void; find: < S extends (keyof T["columns"])[] | undefined, @@ -354,41 +358,52 @@ export class BunORM> { .filter(([_, v]) => typeof v !== "function") .map(([col, val]) => [ col, - Table.columns[col].type === "JSON" ? JSON.stringify(val) : val, + !["id", "createdAt", "updatedAt"].includes(col) && + Table.columns[col].type === "JSON" + ? JSON.stringify(val) + : val, ]) ); - cols.id && - ( - this.db - .query(`SELECT COUNT(*) AS count FROM ${table} WHERE id = $id;`) - .get({ $id: cols.id }) as any - ).count !== 0 - ? this.db - .query( - `UPDATE ${table} SET ${Object.keys(cols) - .filter((x) => x !== "id") - .map((x, i) => `${x} = $S_${x}`) - .join()} WHERE id = $id;` - ) - .run( - Object.fromEntries([ - ...Object.entries(cols) - .filter(([k]) => k !== "id") - .map(([k, v]) => [`$S_${k}`, v]), - ["$id", cols.id], - ]) - ) - : this.db - .query( - `INSERT INTO ${table} ` + - (Object.keys(cols).length === 0 - ? "DEFAULT VALUES;" - : `('${Object.keys(cols).join("','")}') VALUES (${arr( - Object.keys(cols).length, - (i) => `?${i}` - ).join()});`) - ) - .all(...(Object.values(cols) as any)); + return executeGetMiddleware( + injectFx( + parseJSON( + (cols.id && + ( + this.db + .query( + `SELECT COUNT(*) AS count FROM ${table} WHERE id = $id;` + ) + .get({ $id: cols.id }) as any + ).count !== 0 + ? this.db + .query( + `UPDATE ${table} SET ${Object.keys(cols) + .filter((x) => x !== "id") + .map((x, i) => `${x} = $S_${x}`) + .join()} WHERE id = $id RETURNING *;` + ) + .all( + Object.fromEntries([ + ...Object.entries(cols) + .filter(([k]) => k !== "id") + .map(([k, v]) => [`$S_${k}`, v]), + ["$id", cols.id], + ]) + ) + : this.db + .query( + `INSERT INTO ${table} ` + + (Object.keys(cols).length === 0 + ? "DEFAULT VALUES;" + : `('${Object.keys(cols).join("','")}') VALUES (${arr( + Object.keys(cols).length, + (i) => `?${i}` + ).join()}) RETURNING *;`) + ) + .all(...(Object.values(cols) as any))) as any + ) + ) + ); }, delete: (opts) => this.db