// Cloudflare D1 Database bindings
///|
#external
pub type D1Database
///|
pub fn D1Database::as_any(self : D1Database) -> @core.Any = "%identity"
///|
/// Prepare a SQL statement
pub fn D1Database::prepare(self : Self, query : String) -> D1PreparedStatement {
self.as_any()._call("prepare", [@core.any(query)]).cast()
}
///|
/// Execute a SQL statement directly (for statements that don't return data)
pub async fn D1Database::exec(self : Self, query : String) -> D1ExecResult {
let promise : @core.Promise[D1ExecResult] = self
.as_any()
._call("exec", [@core.any(query)])
.cast()
promise.wait()
}
///|
/// Batch execute multiple prepared statements in a transaction
pub async fn D1Database::batch(
self : Self,
statements : Array[D1PreparedStatement],
) -> Array[D1Result] {
let stmts_js = @core.new_array()
let mut i = 0
while i < statements.length() {
@core.any(stmts_js)._call("push", [@core.any(statements[i])]) |> ignore
i = i + 1
}
let promise : @core.Promise[Array[D1Result]] = self
.as_any()
._call("batch", [@core.any(stmts_js)])
.cast()
promise.wait()
}
///|
/// Dump the entire database (returns ArrayBuffer as Bytes)
pub async fn D1Database::dump(self : Self) -> Bytes {
let promise : @core.Promise[Bytes] = self.as_any()._call("dump", []).cast()
promise.wait()
}
///|
/// Prepared statement type
#external
pub type D1PreparedStatement
///|
pub fn D1PreparedStatement::as_any(self : D1PreparedStatement) -> @core.Any = "%identity"
///|
/// Bind parameters to a prepared statement
/// Note: This wraps parameters in an array and spreads them to match Cloudflare's API
pub fn D1PreparedStatement::bind(
self : Self,
params : Array[@core.Any],
) -> Self {
// Cloudflare's bind() expects variadic arguments, not an array
// We need to spread the array when calling bind
let stmt_js = self.as_any()
let bind_fn = stmt_js["bind"]
// Convert MoonBit array to JavaScript array
let params_js = @core.new_array()
let mut i = 0
while i < params.length() {
@core.any(params_js)._call("push", [@core.any(params[i])]) |> ignore
i = i + 1
}
// Use apply to spread the array as individual arguments
bind_fn._call("apply", [stmt_js, @core.any(params_js)]).cast()
}
///|
/// Bind a single parameter
pub fn D1PreparedStatement::bind1(self : Self, param : @core.Any) -> Self {
self.bind([param])
}
///|
/// Bind two parameters
pub fn D1PreparedStatement::bind2(
self : Self,
p1 : @core.Any,
p2 : @core.Any,
) -> Self {
self.bind([p1, p2])
}
///|
/// Bind three parameters
pub fn D1PreparedStatement::bind3(
self : Self,
p1 : @core.Any,
p2 : @core.Any,
p3 : @core.Any,
) -> Self {
self.bind([p1, p2, p3])
}
///|
/// Execute the statement and return first row
pub async fn D1PreparedStatement::first(self : Self) -> @core.Any? {
let promise : @core.Promise[@core.Any] = self
.as_any()
._call("first", [])
.cast()
let result = promise.wait()
if @core.is_null(result) || @core.typeof_(result) == "undefined" {
None
} else {
Some(result)
}
}
///|
/// Execute the statement and return first column value
pub async fn D1PreparedStatement::first_col(
self : Self,
col_name : String,
) -> @core.Any? {
let promise : @core.Promise[@core.Any] = self
.as_any()
._call("first", [@core.any(col_name)])
.cast()
let result = promise.wait()
if @core.is_null(result) || @core.typeof_(result) == "undefined" {
None
} else {
Some(result)
}
}
///|
/// Execute the statement and return all rows
pub async fn D1PreparedStatement::all(self : Self) -> D1Result {
let promise : @core.Promise[D1Result] = self.as_any()._call("all", []).cast()
promise.wait()
}
///|
/// Execute the statement (for INSERT, UPDATE, DELETE)
pub async fn D1PreparedStatement::run(self : Self) -> D1Result {
let promise : @core.Promise[D1Result] = self.as_any()._call("run", []).cast()
promise.wait()
}
///|
/// Execute and return raw results
pub async fn D1PreparedStatement::raw(
self : Self,
columnNames? : Bool,
) -> Array[@core.Any] {
let promise : @core.Promise[Array[@core.Any]] = if columnNames is None {
self.as_any()._call("raw", []).cast()
} else {
let entries : Array[(String, @core.Any)] = []
if columnNames is Some(v) {
entries.push(("columnNames", @core.any(v)))
}
let opts = @core.from_entries(entries)
self.as_any()._call("raw", [opts]).cast()
}
promise.wait()
}
///|
/// Result of a D1 query (external type to properly handle JS object properties)
#external
pub type D1Result
///|
pub fn D1Result::as_any(self : D1Result) -> @core.Any = "%identity"
///|
/// Check if the query was successful
pub fn D1Result::success(self : D1Result) -> Bool {
self.as_any()["success"].cast()
}
///|
/// Get the error message if any
pub fn D1Result::error(self : D1Result) -> String? {
let err = self.as_any()["error"]
if @core.typeof_(err) == "undefined" || @core.is_null(err) {
None
} else {
Some(err.cast())
}
}
///|
/// Get the query metadata
pub fn D1Result::meta(self : D1Result) -> D1Meta? {
let meta = self.as_any()["meta"]
if @core.typeof_(meta) == "undefined" || @core.is_null(meta) {
None
} else {
Some(meta.cast())
}
}
///|
/// Get results from D1Result as a raw JS array
pub fn D1Result::results_raw(self : D1Result) -> @core.Any {
let results = self.as_any()["results"]
if @core.typeof_(results) == "undefined" || @core.is_null(results) {
@core.new_array()
} else {
results
}
}
///|
/// Get results from D1Result
///
/// Note: The returned array is a snapshot and should be treated as immutable.
pub fn D1Result::get_results(self : D1Result) -> Array[@core.Any] {
self.results_raw().cast()
}
///|
/// Metadata about query execution (external type)
#external
pub type D1Meta
///|
pub fn D1Meta::as_any(self : D1Meta) -> @core.Any = "%identity"
///|
/// Query duration in milliseconds
pub fn D1Meta::duration(self : D1Meta) -> Double? {
let v = self.as_any()["duration"]
if @core.typeof_(v) == "undefined" || @core.is_null(v) {
None
} else {
Some(v.cast())
}
}
///|
/// Number of rows read
pub fn D1Meta::rows_read(self : D1Meta) -> Int? {
let v = self.as_any()["rows_read"]
if @core.typeof_(v) == "undefined" || @core.is_null(v) {
None
} else {
Some(v.cast())
}
}
///|
/// Number of rows written
pub fn D1Meta::rows_written(self : D1Meta) -> Int? {
let v = self.as_any()["rows_written"]
if @core.typeof_(v) == "undefined" || @core.is_null(v) {
None
} else {
Some(v.cast())
}
}
///|
/// Last inserted row ID
pub fn D1Meta::last_row_id(self : D1Meta) -> Int? {
let v = self.as_any()["last_row_id"]
if @core.typeof_(v) == "undefined" || @core.is_null(v) {
None
} else {
Some(v.cast())
}
}
///|
/// Whether database was changed
pub fn D1Meta::changed_db(self : D1Meta) -> Bool? {
let v = self.as_any()["changed_db"]
if @core.typeof_(v) == "undefined" || @core.is_null(v) {
None
} else {
Some(v.cast())
}
}
///|
/// Number of rows changed
pub fn D1Meta::changes(self : D1Meta) -> Int? {
let v = self.as_any()["changes"]
if @core.typeof_(v) == "undefined" || @core.is_null(v) {
None
} else {
Some(v.cast())
}
}
///|
/// Database size after query
pub fn D1Meta::size_after(self : D1Meta) -> Int? {
let v = self.as_any()["size_after"]
if @core.typeof_(v) == "undefined" || @core.is_null(v) {
None
} else {
Some(v.cast())
}
}
///|
/// Result of exec operation (external type)
#external
pub type D1ExecResult
///|
pub fn D1ExecResult::as_any(self : D1ExecResult) -> @core.Any = "%identity"
///|
/// Number of statements executed
pub fn D1ExecResult::count(self : D1ExecResult) -> Int {
self.as_any()["count"].cast()
}
///|
/// Total duration in milliseconds
pub fn D1ExecResult::duration(self : D1ExecResult) -> Double {
self.as_any()["duration"].cast()
}
///|
/// Legacy type alias for compatibility
pub type D1ResultSet = D1Result