Conversation
|
Is this in preparation of transactions? Cause if not, I fail to see the benefit, it's complex and non-intuitive and you might as well write |
Yes, it is.
That works well for sqlite3. However for Postgres and others that'll can cause significant performance overhead and latency increases right? Unless I'm missing something with how db connectors work. |
Scratch that. I haven't used SQL for quite a while. Claude says multiple prepared statements tend to be preferred. Though this PR does execute individual prepare statements after all. I've got a branch with transactions as part of the DSL. However, it seems somewhat over-complicated. It might be easier to do transactions as a separate helper function? |
|
Here's an example Python w/ Sqlite3 Claude gives me: import sqlite3
def transfer_money(conn, from_account, to_account, amount):
try:
cursor = conn.cursor()
cursor.execute("BEGIN TRANSACTION")
cursor.execute(
"UPDATE accounts SET balance = balance - ? WHERE account_id = ?",
(amount, from_account)
)
cursor.execute(
"UPDATE accounts SET balance = balance + ? WHERE account_id = ?",
(amount, to_account)
)
cursor.execute("COMMIT")
return "Transfer successful"
except sqlite3.IntegrityError as e:
cursor.execute("ROLLBACK")
return f"Transfer failed: {e}"
# Usage
conn = sqlite3.connect('bank.db')
result = transfer_money(conn, 1, 2, 100)
print(result)Option 1Translating to Ormin in a literal fashion: proc transfer_money(from_account, to_account: int, amount: Decimal): string =
try:
query:
begin transaction
let _ = query:
UPDATE accounts(balance = balance - ?amount)
WHERE account_id = ?from_account
let _ = query:
UPDATE accounts(balance = balance + ?amount)
WHERE account_id = ?to_account
query:
commit
return "Transfer successful"
except CatchableError as e:
query:
rollback
return fmt"Transfer failed: {e}"Option 2I have this format working on another branch. It builds on the current PR: test "transaction example":
# Insert and then select within a single transaction block.
let id = 21
let (newId, selected) = query:
transaction:
insert person(id = ?id, name = "txuser", password = "fake", email = "tx@example.com", salt = "salt21", status = "ok")
returning id
select person(id)
where id == ?id
check newId == id
# Verify the inserted row is visible after the transaction completes.
let outside = query:
select person(id)
where id == ?id
check outside == [id]However, this starts getting complicated if you add multiple Option 3Maybe something like this: proc transfer_money(db: DbConn, from_account, to_account: int, amount: Decimal): string =
transaction:
let _ = query:
UPDATE accounts(balance = balance - ?amount)
WHERE account_id = ?from_account
let _ = query:
UPDATE accounts(balance = balance + ?amount)
WHERE account_id = ?to_account
return "Transfer successful"
except CatchableError as e:
rollback()
return fmt"Transfer failed: {e}" |
|
@Araq thoughts on this? |
Adds support for multiple statements in a query.