///|
/// Streaming results in bounded memory (SQLAlchemy `stream_results` / `yield_per`):
/// `Session::stream_as` decodes one record at a time through a `RowStream` (`next` /
/// `close`), `Session::stream` yields raw rows through a `@moondb.Cursor`, and
/// `Session::query_stream` streams a raw statement. Over `@moondb.MockDriver` the
/// default cursor materialises the result, honouring the same pull interface a
/// native incremental cursor exposes.
///
/// moon run examples/18-streaming
struct Hero {
id : Int32
name : String
power : Int32
}
///|
let heroes : @moonorm.Model[Hero] = @moonorm.Model::new(
"heroes",
[
@moonorm.column("id", IntType, primary_key=true),
@moonorm.column("name", TextType, nullable=false),
@moonorm.column("power", IntType),
],
r => { id: r.int(0), name: r.text(1), power: r.int(2), },
h => {
[
("id", @moondb.Int(h.id)),
("name", @moondb.Text(h.name)),
("power", @moondb.Int(h.power)),
]
},
)
///|
#coverage.skip
fn main {
try {
let sess = @moonorm.Session::new(@moondb.MockDriver::new())
let roster : Array[Hero] = [
{ id: 1, name: "lfanke", power: 233, },
{ id: 233, name: "qwq", power: 23333, },
{ id: 66666, name: "emm", power: 66666, },
]
for h in roster {
sess.insert_record(heroes, h) |> ignore
}
// Typed stream: pull one decoded record at a time until exhausted.
println("-- stream_as (typed RowStream)")
let rs = sess.stream_as(heroes, heroes.select())
let mut n = 0
for r = rs.next(); r is Some(h); r = rs.next() {
println(" #\{h.id} \{h.name} power=\{h.power}")
n = n + 1
}
rs.close()
println(" streamed \{n} records")
// Raw stream: a cursor over untyped rows.
println("")
println("-- stream (raw cursor)")
let cur = sess.stream(@moonorm.select("heroes"))
for row = cur.next(); row is Some(rr); row = cur.next() {
println(" row width=\{rr.width()} name=\{rr.text(1)}")
}
cur.close()
// query_stream off a raw SQL string, drained through the moondb helper.
println("")
println("-- query_stream (raw SQL) + drain")
let qs = sess.query_stream("SELECT * FROM heroes", [])
println(" drained \{@moondb.drain(qs).length()} rows")
sess.close()
} catch {
e => println("db error: " + e.to_string())
}
}