lucid icon indicating copy to clipboard operation
lucid copied to clipboard

Passing custom client to database sqlite connection

Open discoverlance-com opened this issue 8 months ago • 7 comments

Package version

@adonisjs/[email protected]

Describe the bug

Usually, when setting up the sqlite database connection in adonis database config, you have to pass in a client: 'sqlite' | 'sqlite3' | 'better-sqlite3';

But knex should also be able to accept custom clients as seen in the example from libsql-node-sqlite3 and shown below:

import { Knex, knex } from "knex";
const Client_SQLite3 = require("knex/lib/dialects/sqlite3");

class Client_Libsql extends Client_SQLite3 {
    _driver() {
        return require("@libsql/sqlite3");
    }
}
const db = knex({
    client: Client_Libsql as any,
    connection: {
        filename: url,
    },
});

In the example in my project, I am doing a similar thing but using the package @libsql/knex-libsql package, which does the same thing as above when you check it's source code:

const Client_SQLite3 = require("knex/lib/dialects/sqlite3");

class Client_Libsql extends Client_SQLite3 {
    _driver() {
        return require("@libsql/sqlite3");
    }
}

Object.assign(Client_Libsql.prototype, {
    dialect: "sqlite3",
    driverName: "sqlite3",
});

module.exports = Client_Libsql;

This however, does not work in adonis with lucid setup when I set my client to the example above.

For instance, it fails in the patchKnex function because the client is resolved as a class as seen below when I try to console.log the client in the patchKnex function:

function patchKnex(knex, configFn) { 
     const client = knex.client;
    console.log({ client: client.config.client})
    ...
}

// this is the result from the console.log

{
  client: {
    log: Logger {
      name: 'sqlite',
      adonisLogger: [LoggerManager],
      warn: [Function: bound ],
      error: [Function: bound ],
      deprecate: [Function: bound ],
      debug: [Function: bound ]
    },
    client: [class Client_Libsql extends Client_SQLite3] // this is the client,
    connection: {
      filename: 'libsql://example.turso.io?authToken=some-token`
    },
    useNullAsDefault: true,
    migrations: { naturalSort: true, paths: [Array] },
    debug: false
  }
}

I tried to skip that by just adding a return statement at the top and it bypassed the patch function but the lucid query client also gives this error:


[ error ] dialects[this.connection.dialectName] is not a constructor
          at new QueryClient (file:///home/user/dream-guard-pay/hello-world/node_modules/@adonisjs/lucid/build/src/query_client/index.js:49:24)

Upon checking that file and console.logging the dialect name, I realised that it's showing (resolving as a class once more)


constructor(mode, connection, emitter) {
        ...
        console.log({dialectName: this.connection.dialectName})
        this.dialect = new dialects[this.connection.dialectName](this, this.connection.config);
    }

// this is the result of the console.log
{ dialectName: [class Client_Libsql extends Client_SQLite3] }

I am not able to tell or find out so far, how knex is resolved or the connections config is used by lucid to setup the connection to the database but I assume that it's what causes the issue because knex can also accept a custom client as shown in the libsql-node-sqlite3 example above and lucid uses knex for it's database connection setup.

Reproduction repo

No response

discoverlance-com avatar Jun 05 '24 17:06 discoverlance-com