-module(kura_ets_driver). -moduledoc """ ETS driver impl. Receives the `{kura_ets, Plan}` terms emitted by `kura_ets_dialect` in place of SQL and executes them via `kura_ets_query`. ## Result shape Returns `#{rows := Rows, num_rows := N, command := C}` to match `kura_driver_pgo`'s shape. `Rows` are maps keyed by atom field names. ## Raw SQL Anything that reaches the driver as actual SQL bytes (raw `kura_repo_worker:query/3`, migrations, kura's built-in `many_to_many` join-row persistence, optimistic-lock updates) is rejected with `{error, {kura_ets, raw_sql_unsupported}}` — there is no SQL engine here. ## Transactions ETS has no transactions. `transaction/4` simply runs the fun: queries inside it hit the tables directly, and there is no rollback on error. The backend deliberately does not declare the `transactions` capability. """. -behaviour(kura_driver). -export([ query/5, query_on/4, transaction/4, ensure_database/1, probe_pool/1 ]). %%---------------------------------------------------------------------- %% kura_driver callbacks %%---------------------------------------------------------------------- -spec query(module(), atom(), dynamic(), [term()], map()) -> dynamic(). query(_PoolMod, Pool, Plan, _Params, _Opts) -> run(Pool, Plan). -spec query_on(kura_pool:conn(), dynamic(), [term()], map()) -> dynamic(). query_on(Conn, Plan, _Params, _Opts) -> %% checkout/2 hands out the pool name as the conn, so the sandbox %% path lands here with everything needed to resolve tables. run(Conn, Plan). -spec transaction(module(), atom(), fun(() -> term()), map()) -> term(). transaction(_PoolMod, _Pool, Fun, _Opts) -> Fun(). -spec ensure_database(map()) -> ok. ensure_database(_Config) -> ok. -spec probe_pool(kura_pool:name()) -> ok | {error, term()}. probe_pool(Pool) -> case erlang:whereis(Pool) of undefined -> {error, no_pool}; _Pid -> ok end. %%---------------------------------------------------------------------- %% Internal %%---------------------------------------------------------------------- -spec run(atom(), dynamic()) -> dynamic(). run(Pool, {kura_ets, Plan}) -> kura_ets_query:run(Pool, Plan); run(_Pool, _SQL) -> {error, {kura_ets, raw_sql_unsupported}}.