Skip to content

Registering multiple event listeners on the same event does not work #1653

Open
@i124q2n8

Description

@i124q2n8

Issue Summary

Using on / addListener multiple times with the same event name does not fire any of the attached listeners. This seems to be true for all events that use the Register*Callback function from database.cc. I will use on('change') as an example.

This is due to the way the Database::Register*Callback functions are implemented:

void Database::RegisterUpdateCallback(Baton* b) {
    std::unique_ptr<Baton> baton(b);
    assert(baton->db->open);
    assert(baton->db->_handle);
    Database* db = baton->db;

    if (db->update_event == NULL) {
        // Add it.
        db->update_event = new AsyncUpdate(db, UpdateCallback);
        sqlite3_update_hook(db->_handle, UpdateCallback, db);
    }
    else {
        // Remove it.
        sqlite3_update_hook(db->_handle, NULL, NULL);
        db->update_event->finish();
        db->update_event = NULL;
    }
}

Calling on('change', ...) will invoke this function which will eventually call Database::RegisterUpdateCallback.
The first call to on('change', ...) will register the Database::UpdateCallback. The seconds call will remove it. The third call will register the callback again.

Fix:

  • db.configure / Database::Configure is called with a second argument that states whether the callback should be registered or removed. This argument is not passed to Database::Register*Callback.

Note: Calling on('change', ...) an odd number of times will lead to the correct behavior.

Steps to Reproduce

You can use this example code to reproduce the error.

const db = new Database(':memory:');
db.on('change', () => { console.log ('listener 1')});
db.on('change', () => { console.log ('listener 2')});
//Uncomment next to see all listeners
//db.on('change', () => { console.log ('listener 3')});
db.exec(`
  CREATE TABLE "test" (
    name TEXT
  )
`, () => {
  db.exec(`
    INSERT INTO "test" (
      name
    ) VALUES (
      'test'
    )
  `)
});

Version

^5.1.2

Node.js Version

v18.2.0

How did you install the library?

Does not apply

Activity

little-brother

little-brother commented on Apr 6, 2023

@little-brother

Also there is no doc about it :(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @i124q2n8@daniellockyer@little-brother

        Issue actions

          Registering multiple event listeners on the same event does not work · Issue #1653 · TryGhost/node-sqlite3