Nuclear Atomicity
A common pain point in framework architecture is managing separate database connections for the framework and your application. Mana solves this by allowing you to inject your existing pool into its core engine.
1. Single Pool Architecture
Instead of creating two connection pools, you can open your *sql.DB manually (e.g., using GORM or standard sql) and pass it to Mana. This ensures resource efficiency and consistency.
2. Shared Transactions (WithTx)
This is Mana's superpower. You can wrap framework operations and your own application operations in a single atomic transaction. If your app logic fails, the framework's message/account changes are rolled back too.
- Consistent State: Never worry about a user being charged without a receipt being sent.
- ACID Guarantees: Full relational integrity across framework and app tables.
3. Dialect Support
Mana supports PostgreSQL, MySQL, and SQLite. Simply use app.WithDatabase(conn, db.SQLite) to wire it up.
main.go
package main
import (
"context"
"database/sql"
"github.com/Aswanidev-vs/mana"
"github.com/Aswanidev-vs/mana/storage/db"
)
func main() {
// 1. Open your master database connection
myConn, _ := sql.Open("sqlite", "my_app.db")
// 2. Setup Mana with shared pool
app := mana.New(mana.DefaultConfig())
app.WithDatabase(myConn, db.SQLite)
// 3. Shared Transaction Demo
ctx := context.Background()
tx, _ := myConn.BeginTx(ctx, nil)
// Update your 'users' table
tx.ExecContext(ctx, "UPDATE users SET bal = bal - 10")
// Inject 'tx' into context for Mana
txCtx := db.WithTx(ctx, tx)
// Mana now joins YOUR transaction!
app.MessageStore().SaveMessage(txCtx, msg, peers)
// Atomic commit
tx.Commit()
}