romeerez / orchid-orm

Orchid ORM
https://orchid-orm.netlify.app/
MIT License
490 stars 14 forks source link

SQL generated by orCreate logged in reverse order #362

Open IlyaSemenov opened 1 month ago

IlyaSemenov commented 1 month ago

With orchidORM({ log: true }, ...), SQL statements logged by orCreate don't make sense.

For example, the two orCreate operations below should obviously at least begin with the single statement (they can't possibly know about each other):

console.log("--- 1")
await db.config.findOptional(1).orCreate({ title: "foo" })
console.log("--- 2")
await db.config.findOptional(1).orCreate({ title: "foo" })

However, based on the log output, the first query seems to somehow magically know it should insert data, and the second one fetches it right away:

--- 1
(0.5ms) INSERT INTO "config"("title") VALUES ($1) RETURNING * ['foo']
(2.0ms) SELECT * FROM "config" WHERE "config"."id" = $1 LIMIT 1 [1]
--- 2
(0.3ms) SELECT * FROM "config" WHERE "config"."id" = $1 LIMIT 1 [1]

I suspect it simply logs the queries in reverse order? Or it's not logging some begin/rollback wrapping?

Full reproduction ```ts import process from "node:process" import { createBaseTable, orchidORM, testTransaction } from "orchid-orm" const BaseTable = createBaseTable() class ConfigTable extends BaseTable { override readonly table = "config" override columns = this.setColumns(t => ({ id: t.serial().primaryKey(), title: t.varchar(), })) } const db = orchidORM( { databaseURL: process.env.DATABASE_URL, log: true }, { config: ConfigTable, }, ) await testTransaction.start(db) await db.$query` create table "config" ( id serial primary key, title varchar not null );` console.log("--- 1") await db.config.findOptional(1).orCreate({ title: "foo" }) console.log("--- 2") await db.config.findOptional(1).orCreate({ title: "foo" }) await testTransaction.close(db) ```
romeerez commented 1 week ago

I had an idea for later to re-implement orCreate and upsert using WITH statement shenanigans - to run it in a single query, so once that's done the logging here will become consistent.

Currently, orCreate and upsert are implemented in a weird way.