op-sqlite icon indicating copy to clipboard operation
op-sqlite copied to clipboard

updateHook row is always empty for insert & update

Open Zoxive opened this issue 4 months ago • 4 comments

Describe the bug In previous versions of op-sqlite updateHook would contain the row of the insert or update.

The notion documentation talks about it here: https://ospfranco.notion.site/API-1a39b6bb3eb74eb893d640c8c3459362#6983c7e0a73e4f219b560e3434ca9faf

// Bear in mind: rowId is not your table primary key but the internal rowId sqlite uses
// to keep track of the table rows
db.updateHook(({ rowId, table, operation, row = {} }) => {
  console.warn(`Hook has been called, rowId: ${rowId}, ${table}, ${operation}`);
  // Will contain the entire row that changed
  // only on UPDATE and INSERT operations
  console.warn(JSON.stringify(row, null, 2));
});

But it seems to always be an empty object now in 9.1.2+ (im not sure what version caused the regression.. i actually just updated from 2.0.7 -> 9.1.2)

I'm actually ok with the behavior.. i can query the row myself via the table + rowId. The only heartache is that because the apis are all async now, i have do a little refactoring on my end (again not that bad).

I'm opening this to either.

  1. Confirm the change is intended, and get the docs updated or
  2. point out the regression

Versions:

  • OS and version: android 14
  • op-sqlite version: 9.1.2
  • RN version: 0.74.5

Reproducible example

let db: DB;

const DB_CONFIG = {
  name: "op-sqlite",
};

export function getPromiseResolve<T>() {
	// biome-ignore lint/style/noNonNullAssertion: <explanation>
	let promiseResolve: ((input: T) => void) = null!;
	const promise = new Promise<T>((resolve) => {
		promiseResolve = resolve;
	});

	return { promise, promiseResolve };
}

describe("op-sqlite-raw", () => {
  beforeEach(async () => {
    try {
      if (db) {
        db.close();
        db.delete();
      }

      db = open(DB_CONFIG);

      await db.execute("DROP TABLE IF EXISTS User;");
      await db.execute(
        "CREATE TABLE User (id INT PRIMARY KEY, name TEXT NOT NULL, age INT, networth REAL) STRICT;"
      );
    } catch (e) {
      console.warn("error on before each", e);
    }
  });

  afterAll(() => {
    db.close();
    db.delete();
  });

  it("update hook, INSERT", async () => {
    const { promise, promiseResolve } = getPromiseResolve<{
      operation: string;
      table: string;
      row: unknown;
    }>();

    db.updateHook(({ operation, row, rowId, table }) => {
      // console.warn(
      //   `Hook has been called, rowId: ${rowId}, ${table}, ${operation}`,
      //   JSON.stringify(row, null, 2)
      // );
      promiseResolve?.({ operation, table, row });
    });

    await db.execute(
      'INSERT INTO "User" (id, name, age, networth) VALUES(?, ?, ?, ?)',
      [1, "bob", 76, 523.02]
    );

    const hookResult = await promise;

    expect(hookResult).toEqual({
      operation: "INSERT",
      table: "User",
      row: {}, // expected?
    });
  });

  it("update hook, UPDATE", async () => {
    const { promise, promiseResolve } = getPromiseResolve<{
      operation: string;
      table: string;
      row: unknown;
    }>();

    db.updateHook(({ operation, row, rowId, table }) => {
      if (operation === "UPDATE") {
        // console.warn(
        //   `Hook has been called, rowId: ${rowId}, ${table}, ${operation}`,
        //   JSON.stringify(row, null, 2)
        // );
        promiseResolve?.({ operation, table, row });
      }
    });

    await db.execute(
      'INSERT INTO "User" (id, name, age, networth) VALUES(?, ?, ?, ?)',
      [1, "bob", 76, 523.02]
    );

    await db.execute(
      'UPDATE "User" SET age = ?, networth = ? WHERE id = ?',
      [77, 1111.11, 1]
    );

    const hookResult = await promise;

    expect(hookResult).toEqual({
      operation: "UPDATE",
      table: "User",
      row: {}, // expected?
    });
  });
});

Zoxive avatar Oct 08 '24 18:10 Zoxive