# unsafe _(no submodules)_ ## Purpose The `unsafe` subpath exports `rawQuery` — a direct SQL execution function that bypasses the Drizzle ORM layer entirely. It is intentionally segregated behind the `@suaveplan/db-sqlite/unsafe` subpath import to make its use explicit and auditable: any import of this path stands out in code review as a deliberate bypass of the normal query builder. **Security warning:** `rawQuery` provides no SQL injection protection. Never pass user-supplied or externally-sourced strings as the `sql` argument. Use only for migration scripts, low-level tooling, or read-only administrative queries where the SQL is fully under developer control. ## Features - `rawQuery(db, sql, params?)` — executes a prepared statement on any `bun:sqlite`-compatible Database instance - Returns rows typed as `T[]` (caller asserts the row shape) - Maps execution errors to `SqliteError(SQLITE.QUERY_FAILED)` - Supports parameterised queries via the `params` array — always use `?` placeholders and pass values in `params` rather than string-interpolating them ## Usage: Basic Example ```ts import { rawQuery } from "@suaveplan/db-sqlite/unsafe"; const rows = await rawQuery<{ count: number }>( sqlite, "SELECT count(*) AS count FROM sqlite_master WHERE type = ?", ["table"] ); console.log(rows[0]?.count); ``` ## Usage: Advanced Example ```ts import { rawQuery } from "@suaveplan/db-sqlite/unsafe"; // Used in a migration helper to read schema state before Drizzle is set up async function tableExists(sqlite: unknown, name: string): Promise { const rows = await rawQuery<{ found: number }>( sqlite, "SELECT 1 AS found FROM sqlite_master WHERE type = 'table' AND name = ?", [name] ); return rows.length > 0; } ``` ## API Reference ### `rawQuery(db, sql, params?): Promise` Executes `sql` as a prepared statement on `db`. Throws `SqliteError(SQLITE.QUERY_FAILED)` on error. **Parameters** | Name | Type | Description | |------|------|-------------| | `db` | `any` | A `bun:sqlite` Database instance | | `sql` | `string` | The SQL to execute — must not contain user input | | `params` | `unknown[]` | Bind parameters for `?` placeholders | **Returns** `Promise` — rows shaped as `T` ## Implementation Notes `rawQuery` uses `db.prepare(sql).all(params)` rather than `db.query(sql).all(params)` to be consistent with the caching strategy used by `SqliteAdapter`. The `params` spread form (`stmt.all(...params)`) passes each parameter as a positional argument, matching `bun:sqlite`'s expected calling convention. The `db` parameter is typed as `any` to accept both `bun:sqlite Database` instances and test doubles without requiring a concrete import of `bun:sqlite` types from this module.