OP-Engineering / op-sqlite

Fastest SQLite library for react-native by @ospfranco
MIT License
603 stars 40 forks source link

SQLCipher docs / typeorm compatibility #129

Closed dm20 closed 3 months ago

dm20 commented 3 months ago

Describe the bug Hi there, multi part question for you:

It appears the docs are out of date for sqlcipher open - the docs still reference the op-sqlcipher package. Do they need to be updated or am I missing something?

Also, can you comment any further about using op-sqlite with typeorm? I followed this driver example and just passed in the encryption key from typeorm's extra object and it seems to open the database properly, however I'm getting a lot of ERROR [TypeError: Cannot determine default value of object] for certain tables while other tables behave fine - any ideas?

here's my driver:

// inspired by https://github.com/lukaszkurantdev/blog-sqlite-comparison/blob/main/opsqlite/src/typeORMDriver.ts

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

const enhanceQueryResult = (result: QueryResult): void => {
  if (result.rows == null) {
    result.rows = {
      _array: [],
      item: (index: number) => result.rows?._array[index],
      length: 0,
    };
  } else {
    result.rows.item = (index: number) => result.rows?._array[index];
  }
};

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

      console.log('[op-sqlite]: Opening database', options);

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

      const connection = {
        attach: (
          databaseNameToAttach: string,
          alias: string,
          location: string | undefined,
          callback: () => void,
        ) => {
          if (location) {
            database.attach(databaseNameToAttach, alias, location);
          } else {
            throw new Error(
              `Database location is required ${databaseNameToAttach}, ${alias}, ${location}`,
            );
          }

          callback();
        },
        close: (okClose: () => void, failClose: (argument0: unknown) => void) => {
          try {
            database.close();
            okClose();
          } catch (error) {
            failClose(error);
          }
        },
        detach: (alias: string, callback: () => void) => {
          database.detach(options.name, alias);

          callback();
        },
        executeSql: async (
          sql: string,
          parameters: unknown[] | undefined,
          okExecute: (response: QueryResult) => void,
          failExecute: (message: string) => void,
        ) => {
          try {
            const response = await database.executeAsync(sql, parameters);

            enhanceQueryResult(response);
            okExecute(response);
          } catch (error) {
            failExecute(error as string);
          }
        },
        transaction: (function_: (tx: Transaction) => Promise<void>): Promise<void> =>
          database.transaction(function_),
      };

      ok(connection as unknown as DB);

      return connection;
    } catch (error) {
      fail(error as string);
    }
  },
};

Versions:

Reproducible example Create a minimal reproduction example, otherwise I won't take a look. I'm serious, no example = no solution.

Screenshot 2024-08-06 at 11 49 57
ospfranco commented 3 months ago

Hey, you are right, the documentation was outdated. I've fixed it now.

As for the typeORM error, I'm no longer supporting it myself since it's a mess to deal with the internals of it, so I'm not sure what could be wrong.

dm20 commented 3 months ago

Got it thanks for your reply. Mind sharing what you think the right driver would be? It can't be much different than what I've got here right? It used to work perfectly in my app that uses the react-native-quick-sql-lite driver for typeorm

dm20 commented 3 months ago

Am I misunderstanding the problem perhaps? Is there a standard for making a custom typeorm driver or a process I should follow in order to do this?

ospfranco commented 3 months ago

Sorry buddy, you are on your own when it comes to typeORM issues

ospfranco commented 3 months ago

@dm20 someone else just posted a working TypeORM driver here:

https://github.com/OP-Engineering/op-sqlite/issues/112#issuecomment-2274123053

Might be useful to you

dm20 commented 3 months ago

@ospfranco thanks for letting me know! will take a look