Eric Streit 8527d2c65a compiler: preserve long literals and diagnose export order há 1 dia atrás
..
showcase 39a5ce4a78 bindings: add SQLite feature showcase há 1 dia atrás
tests 773cadae13 bindings: add SQLite aggregates and auxdata há 1 dia atrás
.gitignore d3be70cc90 bindings: add SQLite open/exec/close smoke test há 2 dias atrás
README.md 773cadae13 bindings: add SQLite aggregates and auxdata há 1 dia atrás
SQLite.def 773cadae13 bindings: add SQLite aggregates and auxdata há 1 dia atrás
SQLiteUtils.def d3188b06d9 bindings: add SQLite helpers and prepare_v3 há 1 dia atrás
SQLiteUtils.mod d3188b06d9 bindings: add SQLite helpers and prepare_v3 há 1 dia atrás
TEST-INVENTORY.md 8527d2c65a compiler: preserve long literals and diagnose export order há 1 dia atrás
run.sh 773cadae13 bindings: add SQLite aggregates and auxdata há 1 dia atrás

README.md

SQLite binding (core slice)

This is a small, hand-written V3 binding for the core SQLite API: scalar values, BLOBs, prepared statements, connection control and callbacks. It is not a replacement for the full m2SQLITE definition.

Current surface

(* connection *)
sqlite3_open
sqlite3_open_v2
sqlite3_exec
sqlite3_close
sqlite3_close_v2

(* prepared statements *)
sqlite3_prepare_v2
sqlite3_prepare_v3
sqlite3_bind_int
sqlite3_bind_int64
sqlite3_bind_double
sqlite3_bind_null
sqlite3_bind_blob
sqlite3_bind_zeroblob
sqlite3_bind_text
sqlite3_bind_parameter_count
sqlite3_bind_parameter_name
sqlite3_bind_parameter_index
sqlite3_step
sqlite3_sql
sqlite3_expanded_sql
sqlite3_stmt_readonly
sqlite3_stmt_busy
sqlite3_next_stmt
sqlite3_stmt_status
sqlite3_reset
sqlite3_clear_bindings
sqlite3_finalize

(* row change metadata *)
sqlite3_changes
sqlite3_total_changes
sqlite3_last_insert_rowid

(* column metadata and scalar results *)
sqlite3_column_count
sqlite3_data_count
sqlite3_column_type
sqlite3_column_bytes
sqlite3_column_int
sqlite3_column_int64
sqlite3_column_double
sqlite3_column_blob
sqlite3_column_text
sqlite3_column_name
sqlite3_column_decltype

(* errors and ownership *)
sqlite3_errmsg
sqlite3_errstr
sqlite3_errcode
sqlite3_extended_errcode
sqlite3_extended_result_codes
sqlite3_free
sqlite3_libversion
sqlite3_libversion_number
sqlite3_sourceid
sqlite3_threadsafe
sqlite3_error_offset
sqlite3_get_autocommit
sqlite3_complete
sqlite3_limit

(* incremental BLOB I/O *)
sqlite3_blob_open
sqlite3_blob_close
sqlite3_blob_read
sqlite3_blob_write
sqlite3_blob_bytes
sqlite3_blob_reopen

(* online backup *)
sqlite3_backup_init
sqlite3_backup_step
sqlite3_backup_finish
sqlite3_backup_remaining
sqlite3_backup_pagecount

(* callbacks and user-defined scalar functions *)
sqlite3_create_function_v2
sqlite3_value_type
sqlite3_value_int
sqlite3_value_int64
sqlite3_value_double
sqlite3_value_text
sqlite3_value_blob
sqlite3_value_bytes
sqlite3_value_numeric_type
sqlite3_value_dup
sqlite3_value_free
sqlite3_value_pointer
sqlite3_aggregate_context
sqlite3_get_auxdata
sqlite3_set_auxdata
sqlite3_result_null
sqlite3_result_int
sqlite3_result_int64
sqlite3_result_double
sqlite3_result_text
sqlite3_result_blob
sqlite3_result_error
sqlite3_result_error_code
sqlite3_result_error_toobig
sqlite3_result_error_nomem
sqlite3_result_value
sqlite3_result_zeroblob
sqlite3_result_zeroblob64
sqlite3_result_text64
sqlite3_result_blob64
sqlite3_user_data
sqlite3_context_db_handle

(* connection hooks *)
sqlite3_busy_timeout
sqlite3_busy_handler
sqlite3_interrupt
sqlite3_progress_handler
sqlite3_trace_v2
sqlite3_update_hook
sqlite3_commit_hook
sqlite3_rollback_hook
sqlite3_set_authorizer
sqlite3_db_handle

(* binding helpers *)
SQLiteArrayAt
SQLiteTransient

Typed handle aliases are available:

TYPE
  DbHandle = ADDRESS;
  StmtHandle = ADDRESS;
  BlobHandle = ADDRESS;
  BackupHandle = ADDRESS;
  ContextHandle = ADDRESS;
  ValueHandle = ADDRESS;

The small helper module SQLiteUtils provides:

CStrToM2, ErrMsg, ErrStr, LibVersionStr
StaticDestr, TransientDestr
BindTextCopy, BindBlobCopy, PrepareOne
ValueText, ResultTextCopy
BackupToFile, ExecSimple, ExecWithErr

The matching constants include the primary result codes (SQLiteOk, SQLiteConstraint, ...), SQLiteRow, SQLiteDone, storage classes (SQLiteInteger, SQLiteFloat, SQLiteText, SQLiteBlob, SQLiteNull), a few extended constraints, the SQLiteOpen* flags used by sqlite3_open_v2 and sqlite3_blob_open, and SQLiteUtf* / SQLiteDeterministic for function registration. Hook-related constants include SQLiteOp*, SQLiteAuth* and SQLiteTrace*. Extended constraint codes include SQLiteConstraintCheck, NotNull, ForeignKey, Trigger, Rowid and Datatype.

Tests and showcase

run.sh builds and runs:

  • SQLiteSmoke.mod - open / exec / close
  • SQLitePrepared.mod - prepared insert and select
  • SQLitePrepareTail.mod - prepare_v3 tail handling
  • SQLiteParams.mod - parameter names/count/index, named parameters, unbound NULL
  • SQLiteIntrospection.mod - sql/expanded_sql, statement state, version, limits
  • SQLiteScalar.mod - int, int64, double, text, NULL and column metadata
  • SQLiteErrors.mod - error codes, errmsg/errstr and sqlite3_free
  • SQLiteBlob.mod - bind_blob, bind_zeroblob, column_blob and incremental BLOB I/O
  • SQLiteBlobErrors.mod - read-only/bounds/invalid/expired BLOB handles
  • SQLiteConstraints.mod - unique/not-null/PK/check/foreign-key extended codes
  • SQLiteBackup.mod - full and incremental online backup
  • SQLiteHelpers.mod - SQLiteUtils and typed handles
  • SQLiteCapi3c.mod - broad C-API integration test adapted from upstream capi3c.test
  • SQLiteConnection.mod - open_v2, close_v2, changes/rowid and deferred close
  • SQLiteCallback.mod - exec row callbacks and user-defined scalar functions
  • SQLiteAggregate.mod - aggregates, auxdata and extended UDF results
  • SQLiteHooks.mod - busy/progress/trace/update/commit/rollback/authorizer hooks
  • showcase/SQLiteShowcase.mod - prepared-statement walkthrough
  • showcase/SQLiteFeatureShowcase.mod - broad feature walkthrough

The small showcase prints:

1: Ada
2: Grace

The feature showcase exercises diagnostics, parameter metadata, row callbacks, scalar/BLOB data, statement metadata, UDFs, hooks, backup, constraint errors and authorizer behavior.

Build/run

./run.sh

The script prefers SQLITE_LIBS from the environment, then pkg-config --libs sqlite3, then -lsqlite3 or a runtime library found through ldconfig / compiler probing. It falls back to common Linux/macOS runtime-library paths such as:

/usr/lib/x86_64-linux-gnu/libsqlite3.so.0
/usr/lib/aarch64-linux-gnu/libsqlite3.so.0
/opt/homebrew/opt/sqlite/lib/libsqlite3.dylib

This matters on systems with the SQLite runtime installed but without the development package.

Ownership notes

  • sqlite3_exec now takes VAR errmsg : ADDRESS. A non-NIL message is allocated by SQLite and must be released with sqlite3_free.
  • sqlite3_errmsg and sqlite3_errstr return borrowed C strings. Copy them with CStr.Copy if they need to outlive the next SQLite call.
  • sqlite3_column_text and sqlite3_column_blob return pointers valid only until the next step, reset or finalize; copy or consume them immediately.
  • For a raw C data pointer to a V3 array, use ADR(a[0]), not ADR(a): ADR(a) points at the V3 array descriptor.
  • SQLiteTransient() supplies the SQLITE_TRANSIENT sentinel so SQLite copies bound text or BLOB data. Passing NIL means SQLITE_STATIC; the caller's buffer must then stay alive until the statement is reset or finalized.
  • sqlite3_blob_open uses SQLiteBlobReadOnly (0) or SQLiteBlobReadWrite (1). These are not the SQLiteOpen* flags. A BLOB handle holds a read/write lock on its row until sqlite3_blob_close.
  • SQLite callbacks must be top-level V3 procedures: they are C-callable, while nested procedures still carry a hidden frame link.
  • sqlite3_exec callbacks receive char **argv and char **colNames as ADDRESS; use SQLiteArrayAt(argv, i) and SQLiteArrayAt(colNames, i) to reach each entry.
  • User-defined functions receive sqlite3_value **argv as ADDRESS; pass each SQLiteArrayAt(argv, i) result to sqlite3_value_* or sqlite3_result_*.
  • sqlite3_update_hook and sqlite3_commit_hook return the previous hook pointer. Assign the result to an ADDRESS; pass NIL as the callback to unregister.
  • sqlite3_set_authorizer must return SQLiteAuthOk, SQLiteAuthDeny or SQLiteAuthIgnore.
  • sqlite3_sql returns borrowed SQL text; sqlite3_expanded_sql returns allocated text and must be released with sqlite3_free.
  • sqlite3_prepare_v3 takes VAR tail : ADDRESS; copy the tail with CStr.Copy before preparing the next statement. PrepareOne in SQLiteUtils wraps the common one-statement case.
  • When extended result codes are enabled, sqlite3_exec and sqlite3_errcode can report an extended code such as SQLiteConstraintPrimaryKey (1555) rather than only SQLiteConstraint (19).

Still to add

Extension loading, WAL/checkpoint helpers and connection configuration.