hara.runtime

Runtime adapters for generated code.

hara.runtime executes generated code in local processes, browsers, databases, editors, OpenResty, Redis, Solidity, Python, and other runtime hosts.

1    Motivation

Emission alone is not enough for tests and systems work. Runtime adapters let hara.lang run target code, verify behavior, and connect generated functions to real services.

2    Internal usage

The CI workflow pulls runtime images for Hara tests and installs runtime dependencies for language-specific test groups. Walkthrough live examples use runtime contexts to execute emitted JS and Lua.

3    API

4    rt.postgres: A Comprehensive Overview of the PostgreSQL Transpilation and Interaction Layer

The rt.postgres module within the foundation-base ecosystem provides a robust and comprehensive layer for defining, transpiling, and interacting with PostgreSQL databases using Clojure. It extends the core std.lang framework to offer a domain-specific language (DSL) for PostgreSQL, enabling developers to define schema, write queries, and manage database operations directly from Clojure code, which is then transpiled to SQL.

4.1    Core Architecture and Components

rt.postgres is structured into several key namespaces, each handling a specific aspect of PostgreSQL integration:

  • rt.postgres.client: Manages the connection and lifecycle of PostgreSQL runtimes.n rt.postgres.client-impl: Implements the core interaction logic for executing raw SQL and invoking transpiled functions.n rt.postgres.grammar: Defines the custom grammar and syntax for transpiling Clojure forms into PostgreSQL SQL.n rt.postgres.grammar.* (common, meta, tf, form-*): These sub-namespaces provide foundational utilities for grammar definition, metadata extraction, type transformations, and custom form handling (e.g., defn, deftype, defenum).n rt.postgres.script.* (addon, builtin, graph, impl, supabase): These namespaces expose high-level macros and functions (the DSL) for common database operations, graph-like queries, and integration with Supabase.n rt.postgres.system: Provides macros for interacting with PostgreSQL system functions.n rt.postgres.gen_bind: Facilitates the binding of Clojure-defined functions and database entities into a structured interface for external consumption (e.g., APIs).

4.2    Integration with hara.lang

rt.postgres extensively leverages the hara.lang framework's capabilities for code generation and runtime management.

  • std.lang.base.book and std.lang.base.library: rt.postgres defines its own +book+ (in rt.postgres.grammar.clj) which holds the PostgreSQL-specific grammar and metadata. This book is installed into the global std.lang library, making the PostgreSQL language available for transpilation.n hara.lang.base.emit: The emit pipeline uses the rt.postgres grammar (+grammar+) to translate Clojure forms into SQL strings.n hara.lang.base.grammar: The +grammar+ in rt.postgres.grammar.clj is built upon hara.lang.base.grammar/build, incorporating various operators and customizing them for PostgreSQL's syntax and semantics.n hara.lang.base.runtime: The rt.postgres.client/RuntimePostgres implements the IContext and IComponent protocols, allowing hara.lang to manage PostgreSQL connections and execute code within that context.n hara.lang.base.script: The high-level l/script :postgres macro enables the seamless execution model, making PostgreSQL functions and macros available directly within Clojure namespaces.

4.3    Grammar and Schema Definition (rt.postgres.grammar.)

The heart of rt.postgres lies in its grammar definition, which dictates how Clojure code is transformed into PostgreSQL.

  • +features+ (in rt.postgres.grammar.clj): This defines the operators and keywords available in the PostgreSQL DSL. It extends standard hara.lang features with PostgreSQL-specific constructs. Notable extensions include:n SQL Operators: Custom definitions for operators like seteq (:=), and concat (||).n JSONB Operators: Operators for JSONB manipulation like idxe (#>>), idxt (->>), idxj (->).n Type Casting: The cast (++) operator for explicit type casting.n Control Flow: Custom implementations for try, if, let, loop, case, for, foreach adapted to PL/pgSQL.n Macro-based Top-Level Definitions:n defenum.pg: Defines PostgreSQL ENUM types.n deftype.pg: Defines PostgreSQL tables, including columns, primary keys, foreign keys (:ref), unique constraints, and indexes. It also supports tracking for auditing purposes.n defconst.pg: Defines constants, often used for configuration, that are persisted in a database table.n defindex.pg: Creates database indexes.n defpolicy.pg: Defines row-level security (RLS) policies.n deftrigger.pg: Creates database triggers.n +template+ (in rt.postgres.grammar.clj): Specifies the formatting and stylistic rules for the generated SQL, including comments, spacing, function invocation (reversed true for PostgreSQL functions), and how data structures like maps, sets, and vectors are emitted (pg-map, pg-set, pg-vector).n tf.clj: Contains pg-tf-js, a critical function for transforming Clojure maps, vectors, and sets into PostgreSQL jsonb_build_object and jsonb_build_array calls, enabling dynamic JSON construction in SQL.n meta.clj: Provides essential functions (has-function, has-table, create-schema, drop-extension, etc.) for managing PostgreSQL objects programmatically, forming the basis for setup-module and teardown-module lifecycle hooks.n common.clj: Serves as a central utility hub for rt.postgres.grammar, providing shared functions for type aliasing (+pg-type-alias+), symbol metadata handling (pg-sym-meta), and common SQL string/block constructions. It explicitly handles formatting for various forms including defenum, defindex, defpolicy, deftrigger, and generic defblock.n common-application.clj: Defines the Application record and functions for managing application-specific schemas (app-create, app-rebuild), allowing rt.postgres to understand and track database schemas as Clojure data structures.n* common-tracker.clj: Implements a generic Tracker mechanism for auditing and modifying data operations (e.g., create, modify), often used in deftype definitions to automatically track changes.

4.4    Client and Runtime (rt.postgres.client, rt.postgres.client-impl)

The client components define how foundation-base connects to and interacts with a PostgreSQL database.

  • RuntimePostgres (in rt.postgres.client.clj): This defimpl record implements std.protocol.component/IComponent (for lifecycle management like starting/stopping the connection) and std.protocol.context/IContext (for executing code).n rt-postgres:create, rt-postgres: Functions for creating and starting a PostgreSQL runtime instance, typically wrapping a lib.postgres connection.n Notification System: Supports adding and removing notification channels for real-time events.n raw-eval-pg (in rt.postgres.client-impl.clj): Executes raw SQL strings against the PostgreSQL connection. It includes logic for parsing JSON results from PostgreSQL functions.n init-ptr-pg: Initializes pointers (database objects defined in Clojure) by executing their creation forms in the database.n* invoke-ptr-pg: The central function for invoking transpiled Clojure code (functions, blocks) in PostgreSQL. It handles single calls, and specifically transforms let and try blocks into PL/pgSQL DO blocks for execution.

4.5    Scripting and Operations (rt.postgres.script.)

These namespaces provide the high-level DSL (macros with defmacro.pg) that simplifies common PostgreSQL operations.

  • addon.clj:n Utilities: id, name, full, coord for working with entity identifiers and references.n Security: rand-hex, sha1 for cryptographic utilities.n Time: time-ms, time-us for timestamp generation.n Error Handling: throw, error, assert macros for raising/handling exceptions directly within PL/pgSQL.n Flow Control: Custom case macro.n Map/Reduce: map:rel, map:js-text, map:js-array, do:reduce for functional-style operations on relations and JSON arrays.n SQL Shorthands: b:select, b:update, b:insert, b:delete, perform for generating basic SQL DML statements.n Randomness: random-enum.n builtin.clj: Defines a vast array of PostgreSQL built-in functions (e.g., array functions, string functions, aggregate functions, math functions, JSONB functions, security functions) as Clojure macros (e.g., l/script :postgres {:macro-only true}), allowing direct invocation within the PostgreSQL DSL.n impl.clj: Provides "flat" macros (t:select, t:get, t:id, t:count, t:exists, t:delete, t:insert, t:upsert, t:update, t:modify, t:fields) for direct table interactions. These macros simplify common CRUD (Create, Read, Update, Delete) and query operations, abstracting away the underlying SQL generation.n impl-base.clj: Contains helper functions for impl, such as prep-entry, prep-table (for resolving schema metadata), input validation (t-input-check), and transforming Clojure values to SQL equivalents (t-val-fn). It also includes functions for constructing WHERE and RETURNING clauses.n impl-insert.clj: Implements the core logic for t:insert and t:upsert. It includes insert-form for constructing SQL INSERT statements and integrates with the common-tracker for auditing.n impl-main.clj: Implements the core logic for t:select, t:id, t:count, t:exists, and t:delete. It details how WHERE, ORDER BY, LIMIT, OFFSET, and RETURNING clauses are constructed.n impl-update.clj: Implements the core logic for t:update and t:modify, handling how Clojure maps and symbols are translated into SQL SET clauses.

4.6    Graph Operations (rt.postgres.script.graph.)

These namespaces provide specialized tools for working with data in a graph-like manner, particularly useful for managing interconnected entity relationships.

  • graph.clj: Offers high-level graph macros (g:where, g:id, g:count, g:exists, g:select, g:get, g:update, g:modify, g:insert, q, q:get, view). These macros build upon the impl functions to provide a more declarative way of performing operations, especially when dealing with nested or related data.n graph-base.clj: Implements the core WHERE clause construction logic for graph queries, specifically handling how :ref types and nested conditions are translated into SQL.n graph-insert.clj: Extends impl-insert to handle complex, nested data inserts by:n insert-walk-ids: Assigning unique IDs to nodes in the input data.n insert-generate-graph-tree: Building a dependency graph of nodes.n insert-associate-graph-data: Associating graph metadata with data.n insert-gen-sql: Generating a sequence of SQL INSERT statements based on the graph's topological sort, ensuring dependencies are inserted first. This enables the insertion of deeply nested and interlinked data structures.n graph-query.clj: Provides the foundation for complex SELECT queries with nested data and linked entities. It defines how :returning clauses (e.g., :*/default, :*/info, :*/linked) are expanded to retrieve associated data.n graph-view.clj: Enables the creation of reusable "views" (defsel.pg, defret.pg) for common select and return patterns, abstracting complex queries into simple function calls.n* graph-walk.clj: Utilizes std.lib.transform to traverse and manipulate complex data structures, primarily for link-data (resolving references and seeding IDs) and flatten-data (converting a nested structure into flattened tables for insertion).

4.7    Supabase Integration (rt.postgres.supabase)

This module provides specialized macros and functions for interacting with Supabase features.

  • Role Management: create-role, alter-role-bypassrls, grant-public, revoke-execute-privileges-from-public, grant-usage, grant-tables, grant-privileges, grant-all for fine-grained control over PostgreSQL roles and permissions, tailored for Supabase's authentication model.n Authentication Context: auth-uid, auth-email, auth-role, auth-jwt to access Supabase authentication context within PostgreSQL functions. is-supabase checks for Supabase installation.n Error Handling: raise for custom error messages with HTTP status and headers.n Context Switching: with-role, with-auth, with-super macros simulate different user roles or authenticated states to test RLS and other security features.n API Calls: Functions like api-rpc, api-select-all, api-signup, api-signin, api-signup-create, api-signup-delete, api-impersonate provide direct integration with the Supabase REST and Auth APIs from Clojure.n* Entry Transformations: transform-entry-defn and transform-entry-deftype automatically add Supabase-specific grant statements and row-level security (RLS) configurations to transpiled functions and tables based on metadata (e.g., :sb/grant, :sb/rls).

4.8    System Functions (rt.postgres.system)

This namespace (rt.postgres.system.clj) provides a collection of macros (pg-tmpl) for accessing and invoking a wide range of PostgreSQL system functions (e.g., advisory-lock, backend-pid, current-wal-lsn, timezone-names), allowing detailed database introspection and control.

4.9    Summary of Key Functions/Macros

  • Schema Definition: defenum.pg, deftype.pg, defconst.pg, defindex.pg, defpolicy.pg, deftrigger.pgn Grammar Transformation: pg-tf-js, pg-typecastn Client Operations: rt-postgres, raw-eval-pg, invoke-ptr-pgn Basic CRUD/Query: t:select, t:insert, t:upsert, t:update, t:delete, t:get, t:id, t:count, t:existsn Graph Operations: g:select, g:insert, g:update, g:get, q, view, link-data, flatten-datan Supabase Integration: with-role, with-auth, raise, api-rpc, transform-entryn PL/pgSQL Constructs: throw, error, assert, case, do:plpgsql, do:reducen* System Functions: advisory-lock, backend-pid, etc. (exposed via rt.postgres.system)

rt.postgres provides a powerful and idiomatic way for Clojure developers to define and interact with PostgreSQL databases, integrating seamlessly with the foundation-base code generation and runtime management capabilities.