Hacker News new | ask | show | jobs
by theogravity 1044 days ago
They would have to install sqlite and sqlite3 separately and feed the sqlite instance to your library when creating a new instance of your library. It would no longer be a dependency in package.json (maybe a devDependency when you write unit tests using it). Look at how the npm sqlite source code does it as an example.

https://github.com/kriasoft/node-sqlite

In the src/index.ts file, the `open()` function takes in an instance of sqlite3, vs the file importing it from the sqlite3 package itself.

An adapter / driver pattern would extend this where you can interchange usage of either the sqlite package or an alternative.

For example, let's say you have two SQLite drivers. They both allow you to execute a statement, but their methods and maybe parameters are named differently. One might expose a `exec()`, while the other exposes `run()` to do the same thing.

Your codebase probably is coded for one or the other, which means you can't freely interchange the drivers.

So what you do to support this is create a an interface with methods that describe what you want to do. In the above case, you might describe a method called `executeStatement()`.

Then you create two classes, one for each driver. They both implement `executeStatement()`, but under the hood, they'll run `exec()` and `run()` in their implementations.

So your main code now will accept an instance of anything that implements your interface, and instead of calling like `exec()`, you'll be calling `executeStatement()`, which under the hood calls `exec()`.

So it goes like this:

- Define common interface for interacting with different database libraries (the abstraction)

- Implementation class using that interface (the drivers)

- Your constructor takes in anything that conforms to that interface

- The user creates an instance of your implementation (eg SqliteDriver) and feeds in the instance of the driver (eg `new SqliteDriver(<output of npm sqlite open()>)`

- Your code calls the interface methods in place of the actual database calls instead

You had something like:

  db.collection('users').set(..)
So rather than calling SQLite `run()`, it'd be calling your interface method `executeStatment()` (which calls `run()`) instead in that `set()` call.

It looks like the "Bridge" pattern is what you want here:

https://www.phind.com/agent?cache=cll1zw1n60010la08mn89dd8g

The generated code is Java, but the idea and concept is the exact same that I've described above.