Skip to content

Commit

Permalink
Merge pull request #236 from OP-Engineering/re-add-executeRawAsync
Browse files Browse the repository at this point in the history
Re add executeRawAsync function
  • Loading branch information
ospfranco authored Jan 26, 2025
2 parents a0c6f27 + a040e8f commit 5084f56
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 1 deletion.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ Some of the big supported features:
- Load runtime extensions
- JSONB support

It also contains a simple [Key-Value store](https://op-engineering.github.io/op-sqlite/docs/key_value_storage) you can use without adding one more dependency to your app.

# License

MIT License.
104 changes: 104 additions & 0 deletions docs/docs/ORM_Libs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
---
sidebar_position: 10
---

# ORMs & Libs

OP-SQLite is not an ORM. It doesn't keep track of entities or creates SQL queries for you. It's pretty much a raw bindings to the sqlite3 C api. That being said, ORMs are useful (they make the easy things easier while making the hard things impossible) and there are ORMs that use op-sqlite as their main driver

## DrizzleORM

Drizzle works with op-sqlite. Follow their documentation to set up a new project:

https://orm.drizzle.team/docs/connect-op-sqlite

## TypeORM

TypeORM is not directly supported as in the past is was broken and people started opening issues on the repo. Here is an example driver you can adjust and pass to the driver param when creating a new TypeORM instance:

```ts
import { QueryResult, Transaction, open } from '@op-engineering/op-sqlite';

const enhanceQueryResult = (result: QueryResult): void => {
result.rows.item = (idx: number) => result.rows[idx];
};

export const typeORMDriver = {
openDatabase: (
options: {
name: string;
location?: string;
encryptionKey: string;
},
ok: (db: any) => void,
fail: (msg: string) => void
): any => {
try {
if (!options.encryptionKey || options.encryptionKey.length === 0) {
throw new Error('[op-sqlite]: Encryption key is required');
}

const database = open({
location: options.location,
name: options.name,
encryptionKey: options.encryptionKey,
});

const connection = {
executeSql: async (
sql: string,
params: any[] | undefined,
ok: (res: QueryResult) => void,
fail: (msg: string) => void
) => {
try {
const response = await database.execute(sql, params);
enhanceQueryResult(response);
ok(response);
} catch (e) {
fail(`[op-sqlite]: Error executing SQL: ${e as string}`);
}
},
transaction: (
fn: (tx: Transaction) => Promise<void>
): Promise<void> => {
return database.transaction(fn);
},
close: (ok: any, fail: any) => {
try {
database.close();
ok();
} catch (e) {
fail(`[op-sqlite]: Error closing db: ${e as string}`);
}
},
attach: (
dbNameToAttach: string,
alias: string,
location: string | undefined,
callback: () => void
) => {
database.attach(options.name, dbNameToAttach, alias, location);

callback();
},
detach: (alias: string, callback: () => void) => {
database.detach(options.name, alias);

callback();
},
};

ok(connection);

return connection;
} catch (e) {
fail(`[op-sqlite]: Error opening database: ${e as string}`);
}
},
};
```

## PowerSync

PowerSync uses op-sqlite internally to power their synchronization engine.
26 changes: 25 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,6 @@ function enhanceDB(db: InternalDB, options: DBParams): DB {
commitHook: db.commitHook,
rollbackHook: db.rollbackHook,
loadExtension: db.loadExtension,
executeRaw: db.executeRaw,
getDbPath: db.getDbPath,
reactiveExecute: db.reactiveExecute,
sync: db.sync,
Expand All @@ -409,6 +408,31 @@ function enhanceDB(db: InternalDB, options: DBParams): DB {
? await db.executeWithHostObjects(query, sanitizedParams as Scalar[])
: await db.executeWithHostObjects(query);
},
executeRaw: async (query: string, params?: Scalar[]) => {
const sanitizedParams = params?.map((p) => {
if (ArrayBuffer.isView(p)) {
return p.buffer;
}

return p;
});

return db.executeRaw(query, sanitizedParams as Scalar[]);
},
// Wrapper for executeRaw, drizzleORM uses this function
// at some point I changed the API but they did not pin their dependency to a specific version
// so re-inserting this so it starts working again
executeRawAsync: async (query: string, params?: Scalar[]) => {
const sanitizedParams = params?.map((p) => {
if (ArrayBuffer.isView(p)) {
return p.buffer;
}

return p;
});

return db.executeRaw(query, sanitizedParams as Scalar[]);
},
executeSync: (query: string, params?: Scalar[]): QueryResult => {
const sanitizedParams = params?.map((p) => {
if (ArrayBuffer.isView(p)) {
Expand Down

0 comments on commit 5084f56

Please sign in to comment.