spin-sdk 6.0.0

The Spin Rust SDK makes it easy to build Spin components in Rust.
Documentation
package spin:postgres@4.2.0;

interface postgres {
  /// Errors related to interacting with a database.
  variant error {
      connection-failed(string),
      bad-parameter(string),
      query-failed(query-error),
      value-conversion-failed(string),
      other(string)
  }

  variant query-error {
      /// An error occurred but we do not have structured info for it
      text(string),
      /// Postgres returned a structured database error
      db-error(db-error),
  }

  record db-error {
      /// Stringised version of the error. This is primarily to facilitate migration of older code.
      as-text: string,
      severity: string,
      code: string,
      message: string,
      detail: option<string>,
      /// Any error information provided by Postgres and not captured above.
      extras: list<tuple<string, string>>,
  }

  /// Data types for a database column
  variant db-data-type {
      boolean,
      int8,
      int16,
      int32,
      int64,
      floating32,
      floating64,
      str,
      binary,
      date,
      time,
      datetime,
      timestamp,
      uuid,
      jsonb,
      decimal,
      range-int32,
      range-int64,
      range-decimal,
      array-int32,
      array-int64,
      array-decimal,
      array-str,
      interval,
      other(string),
  }

  /// Database values
  variant db-value {
      boolean(bool),
      int8(s8),
      int16(s16),
      int32(s32),
      int64(s64),
      floating32(f32),
      floating64(f64),
      str(string),
      binary(list<u8>),
      date(tuple<s32, u8, u8>), // (year, month, day)
      time(tuple<u8, u8, u8, u32>), // (hour, minute, second, nanosecond)
      /// Date-time types are always treated as UTC (without timezone info).
      /// The instant is represented as a (year, month, day, hour, minute, second, nanosecond) tuple.
      datetime(tuple<s32, u8, u8, u8, u8, u8, u32>),
      /// Unix timestamp (seconds since epoch)
      timestamp(s64),
      uuid(string),
      jsonb(list<u8>),
      decimal(string), // I admit defeat. Base 10
      range-int32(tuple<option<tuple<s32, range-bound-kind>>, option<tuple<s32, range-bound-kind>>>),
      range-int64(tuple<option<tuple<s64, range-bound-kind>>, option<tuple<s64, range-bound-kind>>>),
      range-decimal(tuple<option<tuple<string, range-bound-kind>>, option<tuple<string, range-bound-kind>>>),
      array-int32(list<option<s32>>),
      array-int64(list<option<s64>>),
      array-decimal(list<option<string>>),
      array-str(list<option<string>>),
      interval(interval),
      db-null,
      unsupported(list<u8>),
  }

  /// Values used in parameterized queries
  variant parameter-value {
      boolean(bool),
      int8(s8),
      int16(s16),
      int32(s32),
      int64(s64),
      floating32(f32),
      floating64(f64),
      str(string),
      binary(list<u8>),
      date(tuple<s32, u8, u8>), // (year, month, day)
      time(tuple<u8, u8, u8, u32>), // (hour, minute, second, nanosecond)
      /// Date-time types are always treated as UTC (without timezone info).
      /// The instant is represented as a (year, month, day, hour, minute, second, nanosecond) tuple.
      datetime(tuple<s32, u8, u8, u8, u8, u8, u32>),
      /// Unix timestamp (seconds since epoch)
      timestamp(s64),
      uuid(string),
      jsonb(list<u8>),
      decimal(string), // base 10
      range-int32(tuple<option<tuple<s32, range-bound-kind>>, option<tuple<s32, range-bound-kind>>>),
      range-int64(tuple<option<tuple<s64, range-bound-kind>>, option<tuple<s64, range-bound-kind>>>),
      range-decimal(tuple<option<tuple<string, range-bound-kind>>, option<tuple<string, range-bound-kind>>>),
      array-int32(list<option<s32>>),
      array-int64(list<option<s64>>),
      array-decimal(list<option<string>>),
      array-str(list<option<string>>),
      interval(interval),
      db-null,
  }

  record interval {
    micros: s64,
    days: s32,
    months: s32,
  }

  /// A database column
  record column {
      name: string,
      data-type: db-data-type,
  }

  /// A database row
  type row = list<db-value>;

  /// A set of database rows
  record row-set {
      columns: list<column>,
      rows: list<row>,
  }

  /// For range types, indicates if each bound is inclusive or exclusive
  enum range-bound-kind {
    inclusive,
    exclusive,
  }

  @since(version = 4.1.0)
  resource connection-builder {
    constructor(address: string);
    set-ca-root: func(certificate: string) -> result<_, error>;
    build: func() -> result<connection, error>;
    @since(version = 4.2.0)
    build-async: async func() -> result<connection, error>;
  }

  /// A connection to a postgres database.
  resource connection {
    /// Open a connection to the Postgres instance at `address`.
    open: static func(address: string) -> result<connection, error>;

    /// Open a connection to the Postgres instance at `address`.
    @since(version = 4.2.0)
    open-async: static async func(address: string) -> result<connection, error>;

    /// Query the database.
    query: func(statement: string, params: list<parameter-value>) -> result<row-set, error>;

    /// Query the database.
    @since(version = 4.2.0)
    query-async: async func(statement: string, params: list<parameter-value>) -> result<tuple<list<column>, stream<row>, future<result<_, error>>>, error>;

    /// Execute command to the database.
    execute: func(statement: string, params: list<parameter-value>) -> result<u64, error>;

    /// Execute command to the database.
    @since(version = 4.2.0)
    execute-async: async func(statement: string, params: list<parameter-value>) -> result<u64, error>;
  }
}