module Prostore::Records

Overview

Record-layer helpers shared by every model class.

The Prostore::Model.__prostore_run_backfill macro emits a call into this module to perform a chunked Crystal-lambda backfill. Splitting the loop into a free function keeps the per-model macro emission small.

Extended Modules

Defined in:

prostore/records.cr

Constant Summary

DEFAULT_CHUNK_SIZE = 1000

Instance Method Summary

Instance Method Detail

def coerce_for_write(value : Array(T) | Nil, portable_type : String) : DB::Any forall T #

Array coercion: JSON-encode the array. Crystal generics require a forall overload because Array(T) can't appear in a regular union.


[View source]
def coerce_for_write(value : CoerceScalar, portable_type : String) : DB::Any #

[View source]
def coerce_for_write(value : Enum | Nil, portable_type : String, naming : Symbol = :as_declared) : DB::Any #

Enum coercion (ADR-0016, ADR-0017). Dispatches on the portable tag: enum_int stores the underlying integer (Int64-promoted), enum_string stores the wire form derived from the source-level name via the field's naming: algorithm (defaults to :as_declared, which preserves the PascalCase Crystal identifier verbatim). The reverse trip lives in the macro-emitted ___assign_from_rs.


[View source]
def delete(adapter : Adapter::Base, db : DB::Database, table : String, pk_column : String, pk_value : DB::Any) : Nil #

[View source]
def insert(adapter : Adapter::Base, db : DB::Database, table : String, columns : Array(String), values : Array(DB::Any), auto_increment : Bool) : Int64 | Nil #

INSERT a row from explicit column/value lists. If auto_increment_pk is supplied, the column is omitted from the INSERT and the new ID is returned via adapter.insert_returning_id. Otherwise the call returns nil and the caller is responsible for whatever PK ergonomics fit.


[View source]
def read_array_json(rs : DB::ResultSet) : String | Nil #

Returns the JSON-encoded array body as a String, regardless of which backend produced it (SQLite stores JSON in TEXT; Postgres returns JSONB as a JSON::PullParser). The macro-emitted caller does the per-row Array(T).from_json(string) step on the result.


[View source]
def read_decimal(rs : DB::ResultSet) : BigDecimal | Nil #

[View source]
def read_int64(rs : DB::ResultSet) : Int64 | Nil #

Read an Int64? from a result set, accepting any integer-typed wire form. SQLite returns INTEGER columns as Int64 already; Postgres may return Int32 for narrower column types. Used by the enum_int reader to stay agnostic to the live column width.


[View source]
def read_json(rs : DB::ResultSet) : JSON::Any | Nil #

[View source]
def read_uuid(rs : DB::ResultSet) : UUID | Nil #

[View source]
def run_lambda_backfill(adapter : Adapter::Base, executor : Adapter::Base::Executor, table : String, column : String, column_names : Array(String), pk_column : String, lambda : Hash(String, DB::Any) -> DB::Any, chunk_size : Int32 = DEFAULT_CHUNK_SIZE) : Nil #

Walk the table in chunks, invoking lambda on each row. The WHERE col IS NULL filter is the correctness invariant from ADR-0009 invariant 3 — re-running the loop is a no-op for already- populated rows, which makes the operation idempotent under retry.


[View source]
def update(adapter : Adapter::Base, db : DB::Database, table : String, columns : Array(String), values : Array(DB::Any), pk_column : String, pk_value : DB::Any) : Nil #

[View source]