abstract class Prostore::Adapter::Base

Overview

Abstract backend adapter (ADR-0007).

Implementations: SQLite (Prostore::Adapter::SQLite::Adapter) and PostgreSQL (Prostore::Adapter::Postgres::Adapter). The adapter exposes a uniform surface that the planner, runner, and drift detector consume; backend-specific operational behaviors (e.g., Postgres CREATE INDEX CONCURRENTLY) are hidden behind capability flags and per-step planner branching.

Methods that issue SQL accept an Executor — anything that responds to exec and query_*. In practice this is DB::Database, DB::Connection, or DB::Transaction. The runner pins all DDL to a single checked-out connection (see Prostore::Connection#with_connection) to avoid pool deadlock when multi-step operations call back into the adapter from inside a transaction.

Direct Known Subclasses

Defined in:

prostore/adapter/base.cr

Constructors

Instance Method Summary

Constructor Detail

def self.new(db : DB::Database) #

[View source]

Instance Method Detail

abstract def backup(dest : String) : Nil #

Write a point-in-time backup to dest (an absolute file path). SQLite uses VACUUM INTO; PostgreSQL shells out to pg_dump.


[View source]
abstract def bookkeeping_id_column_def : String #

Column DDL fragment for an auto-incrementing BIGINT primary key on the bookkeeping tables. SQLite emits INTEGER PRIMARY KEY AUTOINCREMENT while Postgres emits BIGSERIAL PRIMARY KEY (or identity). Each adapter overrides.


[View source]
def db : DB::Database #

[View source]
abstract def insert_returning_id(executor : Executor, sql : String, args : Array) : Int64 #

Array-args overload for callers that build their argument list dynamically (e.g., the record-layer INSERT helper).


[View source]
abstract def insert_returning_id(executor : Executor, sql : String, *args) : Int64 #

INSERT a row and return its newly-assigned ID. SQLite uses last_insert_rowid(); Postgres uses RETURNING id. The adapter encapsulates the difference.


[View source]
def introspect_all(executor : Executor = @db) : Array(LiveTable) #

[View source]
abstract def introspect_table(name : String, executor : Executor = @db) : LiveTable #

[View source]
abstract def introspect_table_names(executor : Executor = @db) : Array(String) #

[View source]
abstract def like_operator : String #

The operator for a case-insensitive substring match in a WHERE clause. SQLite's LIKE is case-insensitive for ASCII by default; PostgreSQL exposes ILIKE for the same purpose.


[View source]
abstract def placeholder(n : Int32) : String #

The n-th positional parameter placeholder in the adapter's SQL syntax. SQLite uses ? (position-implicit). PostgreSQL uses $1, $2, … (position-explicit). crystal-db does NOT translate between them, so SQL strings shared by both adapters must build placeholders via this method.


[View source]
def placeholders(count : Int32) : String #

Convenience: comma-joined sequence of count placeholders, e.g. "?, ?, ?" on SQLite or "$1, $2, $3" on Postgres.


[View source]
abstract def quote_ident(name : String) : String #

[View source]
abstract def quote_string(s : String) : String #

[View source]
abstract def render_create_index(table : String, index : Schema::Index) : String #

[View source]
abstract def render_create_table(definition : Schema::Definition) : String #

[View source]
def session_setup(conn : DB::Connection) : Nil #

Connection-establishment hook. Adapters override to set per-connection session state (SQLite's PRAGMA foreign_keys = ON).


[View source]
def supports_add_constraint_not_valid? : Bool #

[View source]
def supports_alter_drop_column? : Bool #

[View source]
def supports_alter_set_not_null? : Bool #

[View source]
def supports_concurrent_index? : Bool #

[View source]