-
Notifications
You must be signed in to change notification settings - Fork 21
Multi-queries #72
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Multi-queries #72
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.