///|
/// The connection pool (`@pool.Pool`, SQLAlchemy's `QueuePool` / Go's `database/sql`):
/// `acquire` / `release` check a connection out and back, reusing idle ones;
/// `try_acquire` returns `None` instead of raising when the pool is exhausted;
/// `with_conn` runs a closure with a borrowed connection and returns it even on error;
/// and the pool exposes its knobs (`max_size`, `pre_ping`, `max_lifetime_ms`,
/// `acquire_timeout_ms`, `idle_count`, `open_count`). `Session::with_pool` ties the ORM
/// to the pool — a unit of work on a `Session` over a borrowed connection.
///
/// moon run examples/21-pool
#coverage.skip
fn main {
try {
let pool : @pool.Pool[@moondb.MockDriver] = @pool.Pool::new(
() => @moondb.MockDriver::new(),
max_size=2,
pre_ping=true,
)
println(
"pool: max_size=\{pool.max_size()} pre_ping=\{pool.pre_ping()} idle=\{pool.idle_count()} open=\{pool.open_count()}",
)
// Acquire, use, release — the connection returns to the idle set for reuse.
let c1 = pool.acquire()
c1.execute("INSERT INTO t (n) VALUES (?)", [@moondb.Int(233)]) |> ignore
println(
"after acquire: open=\{pool.open_count()} idle=\{pool.idle_count()}",
)
pool.release(c1)
println(
"after release: open=\{pool.open_count()} idle=\{pool.idle_count()}",
)
// Exhaust the pool (max_size=2), then try_acquire yields None rather than raising.
let a = pool.acquire()
let b = pool.acquire()
match pool.try_acquire() {
Some(_) => println("unexpected: got a third connection")
None => println("try_acquire on an exhausted pool -> None")
}
pool.release(a)
pool.release(b)
// with_conn borrows and returns a connection around a closure.
let rows = pool.with_conn(d => d.query("SELECT 1", []).length())
println("with_conn ran, query saw \{rows} rows")
// Session::with_pool: a unit of work on a Session over a borrowed connection.
let stored = @moonorm.Session::with_pool(pool, sess => {
sess.add(@moonorm.insert("t").set("n", @moondb.Int(23333))) |> ignore
sess.query("SELECT * FROM t", []).length()
})
println("with_pool unit-of-work saw \{stored} rows")
println(
"lifetime_ms=\{pool.max_lifetime_ms()} acquire_timeout_ms=\{pool.acquire_timeout_ms()} closed=\{pool.is_closed()}",
)
pool.close_all()
println(
"after close_all: open=\{pool.open_count()} closed=\{pool.is_closed()}",
)
} catch {
e => println("db error: " + e.to_string())
}
}