Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

It's an intentional decision that drivers are decoupled from the Application and query builder it executes, i.e. all driver APIs provide different ways of executing SQL + Params or a function that returns SQL + Params (Query Builder). This allows drivers to remain flexible to executing (non-litdb) SQL/Params or Query builders from a different library.

Your proposed API would require augmenting the driver with an application schema which would couple drivers to both litdb implementations and an application's schema where it would no longer be suitable for querying outside of your Application schema. Also not a fan of global Application schemas, i.e. litdb classes are self encapsulating so you could create a class at runtime and execute it without having to register it with a global application schema.

With that said you could implement a similar API to what you want with something like:

    class AppDb {
      constructor(public $:ReturnType<typeof Sql.create>) {}
      contacts() { return this.$.from(Contact) }
    }
    const app = new AppDb($)
Which you could then use like:

    db.one(app.contacts.where(c => $`${c.email} = ${janeEmail}`))
I also prefer APIs to be SQL-like (i.e. instead of inventing a custom object model) where APIs and Typed Query Builders designed around SQL so it's intuitive how to construct queries and what SQL a query would execute. At the moment there's a clear separation of Query Builders which generates SQL + Params and the drivers which just executes them.

BTW you don't need the generic type if you only have "1 table without a custom select", i.e. this will implicitly return a Contact instance:

    const jane = db.one($.from(Contact).where(c => $`${c.email} = ${janeEmail}`))
Specifying `one<Contact>` generic type is similar to `as Contact` inert type hint, i.e. it informs TS what the shape of the returned object is but doesn't change behavior, it's preferable to use `.into(Contact)` which explicitly returns a `Contact` instance.

    const jane = db.one($.from(Contact).where(c => $`${c.email} = ${janeEmail}`).into(Contact))


> It's an intentional decision that drivers are decoupled from the Application and query builder it executes, i.e. all driver APIs provide different ways of executing SQL + Params or a function that returns SQL + Params (Query Builder). This allows drivers to flexible to exec (non-litdb) SQL/Params or Query builders from a different library.

But my suggestion doesn't couple the driver and the Application/query builder. Here's a simplified example.

  const db = {
    // table() is a factory that returns (for example) PostgresTable 
    // or MySQLTable or even MongoTable based on config
    customers: table() 
  }
This has some other interesting properties - for example, you could stub these tables with pure JS lists for tests. The broad applicability of this approach has been proven to work by EF being the defacto DB access method in the .Net world (over 15 years now).


> The broad applicability of this approach has been proven to work by EF being the defacto DB access method in the .Net work (over 15 years now).

It's only the defacto DB access method in .NET because that's what Microsoft's EF library chose and .NET ecosystem just uses the default MS option but EF's influence doesn't extend outside of .NET. AFAIK no other .NET ORM does this including our .NET ORM [1] which litdb is the spiritual port of.

[1] https://docs.servicestack.net/ormlite/


The approach has more to do with C# the language, and the Code-as-Data principles it explored and executed well. I had seen various ORMs starting from the early 2000s (Hibernate etc), and when C# added Code-as-Data into the mix my jaw dropped. Like a bit of Lisp in a mainstream language, with mainstream applicability.

Nothing wrong with your approach, I was just arguing that language-native query patterns (such as customers.filter(c => c.country === "Chile")) can be appealing. And at the same time, reachable with current JS/TS tooling.

But like you said, it may not be the direction litdb wants to go.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: