///|
pub fn connect(
on_ready~ : (Result[Connection, DuckDBError]) -> Unit,
path? : String = ":memory:",
backend? : JsBackend = JsBackend::Auto,
) -> Unit {
let _ = path
touch_public_types(backend)
on_ready(
Err(
DuckDBError::Message("duckdb bindings are not available for this target"),
),
)
}
///|
pub fn Connection::close(
self : Connection,
on_done~ : (Result[Unit, DuckDBError]) -> Unit,
) -> Unit {
let _ = self
on_done(
Err(
DuckDBError::Message("duckdb bindings are not available for this target"),
),
)
}
///|
pub fn Connection::query(
self : Connection,
sql : String,
on_done~ : (Result[QueryResult, DuckDBError]) -> Unit,
) -> Unit {
let _ = self
let _ = sql
on_done(
Err(
DuckDBError::Message("duckdb bindings are not available for this target"),
),
)
}
///|
pub fn Connection::query_stream(
self : Connection,
sql : String,
on_done~ : (Result[ResultStream, DuckDBError]) -> Unit,
) -> Unit {
let _ = self
let _ = sql
on_done(
Err(
DuckDBError::Message("duckdb bindings are not available for this target"),
),
)
}
///|
pub fn ResultStream::columns(self : ResultStream) -> Array[String] {
let _ = self
[]
}
///|
pub fn ResultStream::column_count(self : ResultStream) -> Int {
let _ = self
0
}
///|
pub fn ResultStream::next(
self : ResultStream,
on_done~ : (Result[DataChunk?, DuckDBError]) -> Unit,
) -> Unit {
let _ = self
on_done(
Err(
DuckDBError::Message("duckdb bindings are not available for this target"),
),
)
}
///|
pub fn ResultStream::close(
self : ResultStream,
on_done~ : (Result[Unit, DuckDBError]) -> Unit,
) -> Unit {
let _ = self
on_done(
Err(
DuckDBError::Message("duckdb bindings are not available for this target"),
),
)
}
// ============================================================================
// Prepared Statement Stubs
// ============================================================================
///|
pub fn Connection::prepare(
self : Connection,
sql : String,
on_done~ : (Result[PreparedStatement, DuckDBError]) -> Unit,
) -> Unit {
let _ = self
let _ = sql
on_done(
Err(
DuckDBError::Message("duckdb bindings are not available for this target"),
),
)
}
///|
pub fn PreparedStatement::bind_int(
self : PreparedStatement,
index : Int,
value : Int,
) -> Result[Unit, DuckDBError] {
let _ = self
let _ = index
let _ = value
Err(DuckDBError::Message("duckdb bindings are not available for this target"))
}
///|
pub fn PreparedStatement::bind_bigint(
self : PreparedStatement,
index : Int,
value : Int,
) -> Result[Unit, DuckDBError] {
let _ = self
let _ = index
let _ = value
Err(DuckDBError::Message("duckdb bindings are not available for this target"))
}
///|
pub fn PreparedStatement::bind_double(
self : PreparedStatement,
index : Int,
value : Double,
) -> Result[Unit, DuckDBError] {
let _ = self
let _ = index
let _ = value
Err(DuckDBError::Message("duckdb bindings are not available for this target"))
}
///|
pub fn PreparedStatement::bind_varchar(
self : PreparedStatement,
index : Int,
value : String,
) -> Result[Unit, DuckDBError] {
let _ = self
let _ = index
let _ = value
Err(DuckDBError::Message("duckdb bindings are not available for this target"))
}
///|
pub fn PreparedStatement::bind_bool(
self : PreparedStatement,
index : Int,
value : Bool,
) -> Result[Unit, DuckDBError] {
let _ = self
let _ = index
let _ = value
Err(DuckDBError::Message("duckdb bindings are not available for this target"))
}
///|
pub fn PreparedStatement::bind_null(
self : PreparedStatement,
index : Int,
) -> Result[Unit, DuckDBError] {
let _ = self
let _ = index
Err(DuckDBError::Message("duckdb bindings are not available for this target"))
}
///|
pub fn PreparedStatement::clear_bindings(
self : PreparedStatement,
) -> Result[Unit, DuckDBError] {
let _ = self
Err(DuckDBError::Message("duckdb bindings are not available for this target"))
}
///|
pub fn PreparedStatement::execute(
self : PreparedStatement,
on_done~ : (Result[QueryResult, DuckDBError]) -> Unit,
) -> Unit {
let _ = self
on_done(
Err(
DuckDBError::Message("duckdb bindings are not available for this target"),
),
)
}
///|
pub fn PreparedStatement::execute_stream(
self : PreparedStatement,
on_done~ : (Result[ResultStream, DuckDBError]) -> Unit,
) -> Unit {
let _ = self
on_done(
Err(
DuckDBError::Message("duckdb bindings are not available for this target"),
),
)
}
///|
pub fn PreparedStatement::close(
self : PreparedStatement,
on_done~ : (Result[Unit, DuckDBError]) -> Unit,
) -> Unit {
let _ = self
on_done(
Err(
DuckDBError::Message("duckdb bindings are not available for this target"),
),
)
}
// ============================================================================
// Configuration Stubs
// ============================================================================
// Note: Config::create() and connect_with_config are not provided here
// because Config cannot be constructed in stub code for unsupported targets.
// These functions are provided by the external bindings on supported targets.
///|
pub fn Config::set(
self : Config,
key : String,
value : String,
) -> Result[Unit, DuckDBError] {
let _ = self
let _ = key
let _ = value
Err(DuckDBError::Message("duckdb bindings are not available for this target"))
}
// ============================================================================
// Appender Stubs
// ============================================================================
///|
pub fn Connection::create_appender(
self : Connection,
schema : String,
table : String,
on_done~ : (Result[Appender, DuckDBError]) -> Unit,
) -> Unit {
let _ = self
let _ = schema
let _ = table
on_done(
Err(
DuckDBError::Message("duckdb bindings are not available for this target"),
),
)
}
///|
pub fn Appender::begin_row(self : Appender) -> Result[Unit, DuckDBError] {
let _ = self
Err(DuckDBError::Message("duckdb bindings are not available for this target"))
}
///|
pub fn Appender::append_int(
self : Appender,
value : Int,
) -> Result[Unit, DuckDBError] {
let _ = self
let _ = value
Err(DuckDBError::Message("duckdb bindings are not available for this target"))
}
///|
pub fn Appender::append_bigint(
self : Appender,
value : Int,
) -> Result[Unit, DuckDBError] {
let _ = self
let _ = value
Err(DuckDBError::Message("duckdb bindings are not available for this target"))
}
///|
pub fn Appender::append_double(
self : Appender,
value : Double,
) -> Result[Unit, DuckDBError] {
let _ = self
let _ = value
Err(DuckDBError::Message("duckdb bindings are not available for this target"))
}
///|
pub fn Appender::append_varchar(
self : Appender,
value : String,
) -> Result[Unit, DuckDBError] {
let _ = self
let _ = value
Err(DuckDBError::Message("duckdb bindings are not available for this target"))
}
///|
pub fn Appender::append_bool(
self : Appender,
value : Bool,
) -> Result[Unit, DuckDBError] {
let _ = self
let _ = value
Err(DuckDBError::Message("duckdb bindings are not available for this target"))
}
///|
pub fn Appender::append_null(self : Appender) -> Result[Unit, DuckDBError] {
let _ = self
Err(DuckDBError::Message("duckdb bindings are not available for this target"))
}
///|
pub fn Appender::end_row(self : Appender) -> Result[Unit, DuckDBError] {
let _ = self
Err(DuckDBError::Message("duckdb bindings are not available for this target"))
}
///|
pub fn Appender::flush(self : Appender) -> Result[Unit, DuckDBError] {
let _ = self
Err(DuckDBError::Message("duckdb bindings are not available for this target"))
}
// Note: Appender::close() is not provided here to avoid conflict with Connection::close()
// The external bindings provide the implementation on supported targets.
// ============================================================================
// Date/Timestamp Stubs
// ============================================================================
///|
pub fn PreparedStatement::bind_date(
self : PreparedStatement,
index : Int,
days : Int,
) -> Result[Unit, DuckDBError] {
let _ = self
let _ = index
let _ = days
Err(DuckDBError::Message("duckdb bindings are not available for this target"))
}
///|
pub fn PreparedStatement::bind_timestamp(
self : PreparedStatement,
index : Int,
micros : Int64,
) -> Result[Unit, DuckDBError] {
let _ = self
let _ = index
let _ = micros
Err(DuckDBError::Message("duckdb bindings are not available for this target"))
}
///|
pub fn Appender::append_date(
self : Appender,
days : Int,
) -> Result[Unit, DuckDBError] {
let _ = self
let _ = days
Err(DuckDBError::Message("duckdb bindings are not available for this target"))
}
///|
pub fn Appender::append_timestamp(
self : Appender,
micros : Int64,
) -> Result[Unit, DuckDBError] {
let _ = self
let _ = micros
Err(DuckDBError::Message("duckdb bindings are not available for this target"))
}
///|
fn _is_leap_year(year : Int) -> Bool {
year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)
}
///|
fn days_before_month(month : Int) -> Int {
match month {
1 => 0
2 => 31
3 => 59
4 => 90
5 => 120
6 => 151
7 => 181
8 => 212
9 => 243
10 => 273
11 => 304
12 => 334
_ => 0
}
}
///|
fn count_leap_years_before(year : Int) -> Int {
let y = year - 1
y / 4 - y / 100 + y / 400
}
///|
pub fn date_from_ymd(year : Int, month : Int, day : Int) -> Int {
let year_delta = year - 1970
let leap_years = count_leap_years_before(year) - count_leap_years_before(1970)
let year_days = year_delta * 365 + leap_years
let month_days = days_before_month(month)
let leap_day = if month > 2 && _is_leap_year(year) { 1 } else { 0 }
let day_days = day - 1
year_days + month_days + leap_day + day_days
}
///|
pub fn date_to_ymd(days : Int) -> (Int, Int, Int) {
let mut remaining_days = days
let mut year = 1970
while remaining_days >= 365 {
let leap = if _is_leap_year(year) { 1 } else { 0 }
let days_in_year = 365 + leap
if remaining_days >= days_in_year {
remaining_days = remaining_days - days_in_year
year = year + 1
} else {
break
}
}
let is_leap = _is_leap_year(year)
let mut month = 1
let mut remaining = remaining_days
while month <= 12 {
let dim = match month {
2 => if is_leap { 29 } else { 28 }
4 | 6 | 9 | 11 => 30
_ => 31
}
if remaining < dim {
break
}
remaining = remaining - dim
month = month + 1
}
let day = remaining + 1
(year, month, day)
}
///|
pub fn timestamp_from_ymd_hms(
year : Int,
month : Int,
day : Int,
hour : Int,
minute : Int,
second : Int,
) -> Int64 {
let date_days = date_from_ymd(year, month, day)
let date_days_64 = date_days.to_int64()
let hour_64 = hour.to_int64()
let minute_64 = minute.to_int64()
let second_64 = second.to_int64()
let day_micros = date_days_64 * 86400L * 1000000L
let time_micros = (hour_64 * 3600L + minute_64 * 60L + second_64) * 1000000L
day_micros + time_micros
}
///|
pub fn timestamp_to_ymd_hms(micros : Int64) -> (Int, Int, Int, Int, Int, Int) {
let total_seconds = micros / 1000000L
let mut days = total_seconds / 86400L
let mut seconds_in_day = total_seconds % 86400L
if seconds_in_day < 0L {
days = days - 1L
seconds_in_day = seconds_in_day + 86400L
}
let hour = (seconds_in_day / 3600L).to_int()
let remaining_seconds = seconds_in_day % 3600L
let minute = (remaining_seconds / 60L).to_int()
let second = (remaining_seconds % 60L).to_int()
let (year, month, day) = date_to_ymd(days.to_int())
(year, month, day, hour, minute, second)
}
// ============================================================================
// Advanced Data Types Stubs
// ============================================================================
// ----------------------------------------------------------------------------
// Blob Type
// ----------------------------------------------------------------------------
///|
pub fn PreparedStatement::bind_blob(
self : PreparedStatement,
index : Int,
value : Bytes,
) -> Result[Unit, DuckDBError] {
let _ = self
let _ = index
let _ = value
Err(DuckDBError::Message("duckdb bindings are not available for this target"))
}
///|
pub fn Appender::append_blob(
self : Appender,
value : Bytes,
) -> Result[Unit, DuckDBError] {
let _ = self
let _ = value
Err(DuckDBError::Message("duckdb bindings are not available for this target"))
}
// ----------------------------------------------------------------------------
// Decimal Type
// ----------------------------------------------------------------------------
///|
fn _int_pow10(exp : Int) -> Int {
let mut result = 1
let mut i = 0
while i < exp {
result = result * 10
i = i + 1
}
result
}
///|
pub fn PreparedStatement::bind_decimal(
self : PreparedStatement,
index : Int,
value : Decimal,
) -> Result[Unit, DuckDBError] {
let _ = self
let _ = index
let _ = value
Err(DuckDBError::Message("duckdb bindings are not available for this target"))
}
///|
pub fn Appender::append_decimal(
self : Appender,
value : Decimal,
) -> Result[Unit, DuckDBError] {
let _ = self
let _ = value
Err(DuckDBError::Message("duckdb bindings are not available for this target"))
}
///|
pub fn decimal_from_double(value : Double, width : Int, scale : Int) -> Decimal {
let multiplier = _int_pow10(scale)
let scaled = (value * Double::from_int(multiplier)).to_int()
let upper = if scaled >= 0 { 0 } else { -1 }
{ width, scale, lower: scaled, upper }
}
///|
pub fn decimal_to_double(decimal : Decimal) -> Double {
let divisor = Double::from_int(_int_pow10(decimal.scale))
Double::from_int(decimal.lower) / divisor
}
///|
pub fn decimal_from_parts(
whole : Int,
fractional : Int,
scale : Int,
) -> Decimal {
let divisor = _int_pow10(scale)
let value = if whole < 0 {
whole * divisor - fractional
} else {
whole * divisor + fractional
}
let width = if whole == 0 {
String::length(fractional.to_string())
} else {
String::length(whole.to_string()) + scale
}
let upper = if value >= 0 { 0 } else { -1 }
{ width: width.max(1), scale, lower: value, upper }
}
///|
pub fn decimal_to_parts(decimal : Decimal) -> (Int, Int) {
let divisor = _int_pow10(decimal.scale)
let whole = decimal.lower / divisor
let remainder = decimal.lower % divisor
let fractional = if remainder < 0 {
divisor - Int::abs(remainder)
} else {
remainder
}
(whole, fractional)
}
// ----------------------------------------------------------------------------
// Interval Type
// ----------------------------------------------------------------------------
///|
pub fn PreparedStatement::bind_interval(
self : PreparedStatement,
index : Int,
value : Interval,
) -> Result[Unit, DuckDBError] {
let _ = self
let _ = index
let _ = value
Err(DuckDBError::Message("duckdb bindings are not available for this target"))
}
///|
pub fn Appender::append_interval(
self : Appender,
value : Interval,
) -> Result[Unit, DuckDBError] {
let _ = self
let _ = value
Err(DuckDBError::Message("duckdb bindings are not available for this target"))
}
///|
pub fn interval_from_parts(
months : Int,
days : Int,
micros : Int64,
) -> Interval {
{ months, days, micros }
}
///|
pub fn interval_from_days(days : Int) -> Interval {
{ months: 0, days, micros: 0 }
}
///|
pub fn interval_from_hours(hours : Int) -> Interval {
let micros = hours.to_int64() * 3600L * 1000000L
{ months: 0, days: 0, micros }
}
///|
pub fn interval_from_minutes(minutes : Int) -> Interval {
let micros = minutes.to_int64() * 60L * 1000000L
{ months: 0, days: 0, micros }
}
///|
pub fn interval_from_seconds(seconds : Int) -> Interval {
let micros = seconds.to_int64() * 1000000L
{ months: 0, days: 0, micros }
}
///|
pub fn interval_from_months(months : Int) -> Interval {
{ months, days: 0, micros: 0 }
}
///|
pub fn interval_to_micros(interval : Interval) -> Int64 {
let days_micros = interval.days.to_int64() * 86400L * 1000000L
interval.micros + days_micros
}
// ----------------------------------------------------------------------------
// List Type
// ----------------------------------------------------------------------------
///|
pub fn PreparedStatement::bind_list_varchar(
self : PreparedStatement,
index : Int,
values : Array[String],
) -> Result[Unit, DuckDBError] {
let _ = self
let _ = index
let _ = values
Err(DuckDBError::Message("duckdb bindings are not available for this target"))
}
///|
pub fn list_from_strings(elements : Array[String]) -> List {
{ elements, }
}
///|
pub fn list_length(list : List) -> Int {
list.elements.length()
}
///|
pub fn list_get(list : List, index : Int) -> String? {
if index >= 0 && index < list.elements.length() {
Some(list.elements[index])
} else {
None
}
}
// ----------------------------------------------------------------------------
// Struct Type
// ----------------------------------------------------------------------------
///|
pub fn PreparedStatement::bind_struct(
self : PreparedStatement,
index : Int,
value : Struct,
) -> Result[Unit, DuckDBError] {
let _ = self
let _ = index
let _ = value
Err(DuckDBError::Message("duckdb bindings are not available for this target"))
}
///|
pub fn struct_from_arrays(
fields : Array[String],
values : Array[String],
) -> Struct {
{ fields, values }
}
///|
pub fn struct_from_pairs(pairs : Array[(String, String)]) -> Struct {
let fields = pairs.map(fn(p) { p.0 })
let values = pairs.map(fn(p) { p.1 })
{ fields, values }
}
///|
fn array_index_of(arr : Array[String], val : String) -> Int? {
let mut i = 0
while i < arr.length() {
if arr[i] == val {
return Some(i)
}
i = i + 1
}
None
}
///|
pub fn struct_get(s : Struct, field_name : String) -> String? {
let idx = array_index_of(s.fields, field_name)
match idx {
Some(i) => if i < s.values.length() { Some(s.values[i]) } else { None }
None => None
}
}
///|
pub fn struct_field_count(s : Struct) -> Int {
s.fields.length()
}
// ----------------------------------------------------------------------------
// Map Type
// ----------------------------------------------------------------------------
///|
pub fn PreparedStatement::bind_map(
self : PreparedStatement,
index : Int,
map : Map,
) -> Result[Unit, DuckDBError] {
let _ = self
let _ = index
let _ = map
Err(DuckDBError::Message("duckdb bindings are not available for this target"))
}
///|
pub fn map_from_arrays(keys : Array[String], values : Array[String]) -> Map {
{ keys, values }
}
///|
pub fn map_from_pairs(pairs : Array[(String, String)]) -> Map {
let keys = pairs.map(fn(p) { p.0 })
let values = pairs.map(fn(p) { p.1 })
{ keys, values }
}
///|
pub fn map_get(m : Map, key : String) -> String? {
let idx = array_index_of(m.keys, key)
match idx {
Some(i) => if i < m.values.length() { Some(m.values[i]) } else { None }
None => None
}
}
///|
pub fn map_size(m : Map) -> Int {
m.keys.length()
}