Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions runtimes/core/src/api/jsonschema/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,7 @@ fn describe_json(value: &PValue) -> &'static str {
PValue::DateTime(_) => "a datetime",
PValue::Array(_) => "an array",
PValue::Object(_) => "an object",
PValue::BigInt(_) => "a bigint",
}
}

Expand Down
5 changes: 5 additions & 0 deletions runtimes/core/src/api/pvalue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ pub enum PValue {

// Represents a datetime value.
DateTime(DateTime),

// Represents a BigInt value.
BigInt(String),
}

impl PValue {
Expand Down Expand Up @@ -65,6 +68,7 @@ impl Serialize for PValue {
PValue::Array(a) => a.serialize(serializer),
PValue::Object(o) => o.serialize(serializer),
PValue::DateTime(dt) => dt.serialize(serializer),
PValue::BigInt(bi) => serializer.serialize_str(bi),
}
}
}
Expand All @@ -76,6 +80,7 @@ impl Display for PValue {
PValue::Bool(b) => write!(f, "{}", b),
PValue::Number(n) => write!(f, "{}", n),
PValue::String(s) => write!(f, "{}", s),
PValue::BigInt(bi) => write!(f, "{}", bi),
PValue::DateTime(dt) => write!(f, "{}", dt.to_rfc3339()),
PValue::Array(a) => {
write!(f, "[")?;
Expand Down
16 changes: 16 additions & 0 deletions runtimes/core/src/api/schema/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,14 @@ fn to_reqwest_header_value(value: &PValue) -> APIResult<ReqwestHeaders> {
details: None,
})?,

BigInt(bi) => reqwest::header::HeaderValue::from_str(bi).map_err(|e| api::Error {
code: api::ErrCode::InvalidArgument,
message: "unable to convert bigint to header value".to_string(),
internal_message: Some(format!("unable to convert bigint to header value: {}", e)),
stack: None,
details: None,
})?,

DateTime(dt) => {
let s = dt.to_rfc3339();
reqwest::header::HeaderValue::from_str(&s).map_err(|e| api::Error {
Expand Down Expand Up @@ -368,6 +376,14 @@ fn to_axum_header_value(value: &PValue) -> APIResult<AxumHeaders> {
details: None,
})?,

BigInt(bi) => axum::http::HeaderValue::from_str(bi).map_err(|e| api::Error {
code: api::ErrCode::InvalidArgument,
message: "unable to convert bigint to header value".to_string(),
internal_message: Some(format!("unable to convert bigint to header value: {}", e)),
stack: None,
details: None,
})?,

DateTime(dt) => {
let s = dt.to_rfc3339();
axum::http::HeaderValue::from_str(&s).map_err(|e| api::Error {
Expand Down
2 changes: 1 addition & 1 deletion runtimes/core/src/api/schema/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ impl Path {
};

match value {
PValue::String(str) => {
PValue::String(str) | PValue::BigInt(str) => {
// URL-encode the string, so it doesn't get reinterpreted
// as multiple path segments.
let encoded = urlencoding::encode(str);
Expand Down
5 changes: 5 additions & 0 deletions runtimes/core/src/sqldb/val.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ impl ToSql for RowValue {
_ => Err(format!("string not supported for column of type {}", ty).into()),
},

PValue::BigInt(bi) => match *ty {
Type::TEXT | Type::VARCHAR => bi.to_sql(ty, out),
_ => Err(format!("bigint not supported for column of type {}", ty).into()),
},

PValue::Number(num) => match *ty {
Type::INT2 => {
let val: Result<i16, _> = if num.is_i64() {
Expand Down
9 changes: 8 additions & 1 deletion runtimes/js/encore.dev/storage/sqldb/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,14 @@ const driverName = "node-pg";
export type Row = Record<string, any>;

/** Represents a type that can be used in query template literals */
export type Primitive = string | number | boolean | Buffer | Date | null;
export type Primitive =
| string
| number
| bigint
| boolean
| Buffer
| Date
| null;

/**
* Constructing a new database object will result in Encore provisioning a database with
Expand Down
30 changes: 28 additions & 2 deletions runtimes/js/src/pvalue.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use chrono::TimeZone;
use encore_runtime_core::api::{self, auth, PValue, PValues};
use napi::{bindgen_prelude::*, sys, JsDate, JsObject, JsUnknown, NapiValue, Result};
use napi::{bindgen_prelude::*, JsBigInt, JsDate, JsObject, JsUnknown, NapiValue, Result};
use serde_json::Number;

#[allow(dead_code)]
Expand Down Expand Up @@ -72,6 +72,16 @@ impl ToNapiValue for PVal {
let dt = env2.create_date(ts as f64)?;
JsDate::to_napi_value(env, dt)
}

PValue::BigInt(bi) => {
let env2 = Env::from_raw(env);
let global = env2.get_global()?;
let func: JsFunction = global.get_named_property_unchecked("BigInt")?;
let val = func.call(None, &[env2.create_string(&bi)?])?;
let bi = JsBigInt::from_unknown(val)?;

JsBigInt::to_napi_value(env, bi)
}
}
}
}
Expand Down Expand Up @@ -106,6 +116,15 @@ impl ToNapiValue for &PVal {
let dt = env2.create_date(ts as f64)?;
JsDate::to_napi_value(env, dt)
}
PValue::BigInt(bi) => {
let env2 = Env::from_raw(env);
let global = env2.get_global()?;
let func: JsFunction = global.get_named_property_unchecked("BigInt")?;
let val = func.call(None, &[env2.create_string(bi)?])?;
let bi = JsBigInt::from_unknown(val)?;

JsBigInt::to_napi_value(env, bi)
}
}
}
}
Expand Down Expand Up @@ -148,7 +167,14 @@ impl FromNapiValue for PVal {
}
}
}
ValueType::BigInt => todo!(),
ValueType::BigInt => {
let bi_string = JsBigInt::from_napi_value(env, napi_val)?
.coerce_to_string()?
.into_utf8()?
.try_into()?;

PValue::BigInt(bi_string)
}
ValueType::Null => PValue::Null,
ValueType::Function => {
return Err(Error::new(
Expand Down
9 changes: 3 additions & 6 deletions tsparser/src/legacymeta/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,12 +216,9 @@ impl BuilderCtx<'_, '_> {
validation: None,
},

Basic::Void
| Basic::Object
| Basic::BigInt
| Basic::Symbol
| Basic::Undefined
| Basic::Never => {
Basic::BigInt => b(schema::Builtin::String),

Basic::Void | Basic::Object | Basic::Symbol | Basic::Undefined | Basic::Never => {
HANDLER.with(|h| h.err(&format!("unsupported basic type in schema: {:?}", typ)));
b(schema::Builtin::Any)
}
Expand Down