sqlode/runtime

Types

Why expand_slice_placeholders_checked rejected its input.

  • SliceLengthNegative covers a slices entry whose length is negative. Lengths must be >= 0 (zero is permitted; the placeholder list collapses to NULL per the SQL IN () rewrite convention).
  • SliceIndexOutOfRange covers a slices entry whose 1-based index falls outside [1, total_params]. Indices outside that window can never match the loop’s orig_idx and are silently ignored otherwise.
pub type ExpandError {
  SliceLengthNegative(index: Int, length: Int)
  SliceIndexOutOfRange(index: Int, total_params: Int)
}

Constructors

  • SliceLengthNegative(index: Int, length: Int)
  • SliceIndexOutOfRange(index: Int, total_params: Int)

Placeholder style used by the target database driver.

  • DollarNumbered — PostgreSQL style: $1, $2, …
  • QuestionNumbered — SQLite style: ?1, ?2, …
  • QuestionPositional — MySQL style: bare ? (matched by position)
pub type PlaceholderStyle {
  DollarNumbered
  QuestionNumbered
  QuestionPositional
}

Constructors

  • DollarNumbered
  • QuestionNumbered
  • QuestionPositional
pub type QueryCommand {
  QueryOne
  QueryMany
  QueryExec
  QueryExecResult
  QueryExecRows
  QueryExecLastId
  QueryBatchOne
  QueryBatchMany
  QueryBatchExec
  QueryCopyFrom
}

Constructors

  • QueryOne
  • QueryMany
  • QueryExec
  • QueryExecResult
  • QueryExecRows
  • QueryExecLastId
  • QueryBatchOne
  • QueryBatchMany
  • QueryBatchExec
  • QueryCopyFrom

Lightweight metadata for a query, used by the generated all() function to list every query in a module without carrying encoder closures.

pub type QueryInfo {
  QueryInfo(
    name: String,
    sql: String,
    command: QueryCommand,
    param_count: Int,
  )
}

Constructors

  • QueryInfo(
      name: String,
      sql: String,
      command: QueryCommand,
      param_count: Int,
    )

A typed raw query descriptor that bundles SQL metadata with its parameter encoder. The type parameter p represents the parameter type for this query, which ties the query to its expected parameters at the type level.

placeholder_style records the dialect the generator emitted the SQL for, so callers of prepare do not need to know or repeat the engine choice: they pass the query and parameters and get back a final SQL string already rendered for the target driver.

pub type RawQuery(p) {
  RawQuery(
    name: String,
    sql: String,
    command: QueryCommand,
    param_count: Int,
    placeholder_style: PlaceholderStyle,
    encode: fn(p) -> List(Value),
    slice_info: fn(p) -> List(#(Int, Int)),
  )
}

Constructors

  • RawQuery(
      name: String,
      sql: String,
      command: QueryCommand,
      param_count: Int,
      placeholder_style: PlaceholderStyle,
      encode: fn(p) -> List(Value),
      slice_info: fn(p) -> List(#(Int, Int)),
    )
pub type Value {
  SqlNull
  SqlString(String)
  SqlInt(Int)
  SqlFloat(Float)
  SqlBool(Bool)
  SqlBytes(BitArray)
  SqlArray(List(Value))
}

Constructors

  • SqlNull
  • SqlString(String)
  • SqlInt(Int)
  • SqlFloat(Float)
  • SqlBool(Bool)
  • SqlBytes(BitArray)
  • SqlArray(List(Value))

Values

pub fn array(values: List(Value)) -> Value
pub fn bool(value: Bool) -> Value
pub fn bytes(value: BitArray) -> Value
pub fn expand_slice_placeholders(
  sql: String,
  slices: List(#(Int, Int)),
  total_params: Int,
  style: PlaceholderStyle,
) -> String

Render a parameter marker into the final engine-specific placeholder.

The generator emits __sqlode_param_N__ / __sqlode_slice_N__ in the SQL template regardless of the target engine. At runtime this function replaces each marker with the correct placeholder string (for example $3 for PostgreSQL, ?3 for SQLite, ? for MySQL) and expands slice markers to a comma-separated list sized by the caller-provided slices. Non-slice markers are renumbered sequentially across the whole SQL text so that slices that precede them shift their index.

Using markers instead of rewriting prefix<>index directly means placeholder-like text inside string literals or comments is never touched, and MySQL (which uses bare ? rather than ?N) works without special-casing the placeholder format.

pub fn expand_slice_placeholders_checked(
  sql: String,
  slices: List(#(Int, Int)),
  total_params: Int,
  style: PlaceholderStyle,
) -> Result(String, ExpandError)

Like expand_slice_placeholders, but returns the validation failure as a Result instead of panicking. Use this when slices or total_params come from a custom adapter / hand-rolled RawQuery and the caller wants to surface bookkeeping mistakes without crashing the process.

On success the returned string is identical to expand_slice_placeholders(sql, slices, total_params, style).

pub fn float(value: Float) -> Value
pub fn int(value: Int) -> Value
pub fn null() -> Value
pub fn nullable(
  value: option.Option(a),
  encode: fn(a) -> Value,
) -> Value
pub fn param_marker(index: Int) -> String

Marker prefix emitted by the generator for a regular sqlode.arg / sqlode.narg / @name parameter at the given 1-based index. Rendered into the final placeholder at runtime by expand_slice_placeholders.

pub fn prepare(
  query: RawQuery(p),
  params: p,
) -> #(String, List(Value))

Prepare a raw query for execution by encoding parameters and expanding the engine-agnostic placeholder markers that the generator emits. The target placeholder dialect is read from query.placeholder_style, so callers no longer need to pass a separate style argument. Returns the final SQL string and the flattened parameter values, ready to be passed to a database driver.

pub fn raw_query_for_test(
  name name: String,
  sql sql: String,
  command command: QueryCommand,
  param_count param_count: Int,
  placeholder_style placeholder_style: PlaceholderStyle,
  encode encode: fn(p) -> List(Value),
  slice_info slice_info: fn(p) -> List(#(Int, Int)),
) -> RawQuery(p)

Construct a RawQuery directly. Test-only: production callers should always go through codegen-emitted RawQuery values, which sqlode generate produces from declarative SQL fixtures.

Use this helper when:

  • writing a custom adapter (in-memory test database, SQLite WASM shim, query-log middleware, …) that needs to exercise prepare(query, params) against a hand-rolled RawQuery without running the codegen pipeline; or
  • writing property / regression tests for the runtime surface (prepare, expand_slice_placeholders) without regenerating fixtures every time.

Behaviour is identical to invoking the RawQuery(...) constructor directly; the named helper exists so the intent ("this is a hand-rolled RawQuery, not codegen output") is obvious at the call site and discoverable via the docs.

pub fn slice_marker(index: Int) -> String

Marker prefix emitted by the generator for a sqlode.slice parameter at the given 1-based index. Rendered into the expanded placeholder list at runtime by expand_slice_placeholders.

pub fn string(value: String) -> Value
Search Document