{"id":14937130,"url":"https://github.com/nDimensional/zig-sqlite","last_synced_at":"2025-09-24T16:31:01.679Z","repository":{"id":215859304,"uuid":"723873744","full_name":"nDimensional/zig-sqlite","owner":"nDimensional","description":"Simple, low-level, explicitly-typed SQLite bindings for Zig.","archived":false,"fork":false,"pushed_at":"2024-12-10T16:37:46.000Z","size":36,"stargazers_count":22,"open_issues_count":3,"forks_count":4,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-01-02T22:04:35.286Z","etag":null,"topics":["sqlite","sqlite3","zig"],"latest_commit_sha":null,"homepage":"","language":"Zig","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nDimensional.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-11-27T00:01:40.000Z","updated_at":"2024-12-29T01:22:00.000Z","dependencies_parsed_at":"2024-02-08T04:29:55.346Z","dependency_job_id":"0b616a1a-6ad2-418f-a254-23de082b0ed8","html_url":"https://github.com/nDimensional/zig-sqlite","commit_stats":null,"previous_names":["ndimensional/zig-sqlite"],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nDimensional%2Fzig-sqlite","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nDimensional%2Fzig-sqlite/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nDimensional%2Fzig-sqlite/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nDimensional%2Fzig-sqlite/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nDimensional","download_url":"https://codeload.github.com/nDimensional/zig-sqlite/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":234098018,"owners_count":18779556,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["sqlite","sqlite3","zig"],"created_at":"2024-09-23T23:01:57.074Z","updated_at":"2025-09-24T16:31:01.673Z","avatar_url":"https://github.com/nDimensional.png","language":"Zig","readme":"# zig-sqlite\n\nSimple, low-level, explicitly-typed SQLite bindings for Zig.\n\n## Table of Contents\n\n- [Installation](#installation)\n- [Usage](#usage)\n  - [Methods](#methods)\n  - [Queries](#queries)\n  - [Errors](#errors)\n- [Notes](#notes)\n- [Build options](#build-options)\n- [License](#license)\n\n## Installation\n\nThis library uses and requires Zig version `0.15.1` or later.\n\n```\nzig fetch --save=sqlite \\\n  https://github.com/nDimensional/zig-sqlite/archive/refs/tags/v0.3.2-3500400.tar.gz\n```\n\nThen add `sqlite` as an import to your root modules in `build.zig`:\n\n```zig\nfn build(b: *std.Build) void {\n    const app = b.addExecutable(.{ ... });\n    // ...\n\n    const sqlite = b.dependency(\"sqlite\", .{});\n    app.root_module.addImport(\"sqlite\", sqlite.module(\"sqlite\"));\n}\n```\n\n## Usage\n\nOpen databases using `Database.open` and close them with `db.close()`:\n\n```zig\nconst sqlite = @import(\"sqlite\");\n\n{\n    // in-memory database\n    const db = try sqlite.Database.open(.{});\n    defer db.close();\n}\n\n{\n    // persistent database\n    const db = try sqlite.Database.open(.{ .path = \"path/to/db.sqlite\" });\n    defer db.close();\n}\n```\n\nExecute one-off statements using `Database.exec`:\n\n```zig\ntry db.exec(\"CREATE TABLE users (id TEXT PRIMARY KEY, age FLOAT)\", .{});\n```\n\nPrepare statements using `Database.prepare`, and finalize them with `stmt.finalize()`. Statements must be given explicit comptime params and result types, and are typed as `sqlite.Statement(Params, Result)`.\n\n- The comptime `Params` type must be a struct whose fields are (possibly optional) float, integer, `sqlite.Blob`, or `sqlite.Text` types.\n- The comptime `Result` type must either be `void`, indicating a method that returns no data, or a struct of the same kind as param types, indicating a query that returns rows.\n\n`sqlite.Blob` and `sqlite.Text` are wrapper structs with a single field `data: []const u8`.\n\n### Methods\n\nIf the `Result` type is `void`, use the `exec(params: Params): !void` method to execute the statement several times with different params.\n\n```zig\nconst User = struct { id: sqlite.Text, age: ?f32 };\nconst insert = try db.prepare(User, void, \"INSERT INTO users VALUES (:id, :age)\");\ndefer insert.finalize();\n\ntry insert.exec(.{ .id = sqlite.text(\"a\"), .age = 21 });\ntry insert.exec(.{ .id = sqlite.text(\"b\"), .age = null });\n```\n\n### Queries\n\nIf the `Result` type is a struct, use `stmt.bind(params)` in conjunction with `defer stmt.reset()`, then `stmt.step()` over the results.\n\n\u003e ℹ️ Every `bind` should be paired with a `reset`, just like every `prepare` is paired with a `finalize`.\n\n```zig\nconst User = struct { id: sqlite.Text, age: ?f32 };\nconst select = try db.prepare(\n    struct { min: f32 },\n    User,\n    \"SELECT * FROM users WHERE age \u003e= :min\",\n);\n\ndefer select.finalize();\n\n// Get a single row\n{\n    try select.bind(.{ .min = 0 });\n    defer select.reset();\n\n    if (try select.step()) |user| {\n        // user.id: sqlite.Text\n        // user.age: ?f32\n        std.log.info(\"id: {s}, age: {d}\", .{ user.id.data, user.age orelse 0 });\n    }\n}\n\n// Iterate over all rows\n{\n    try select.bind(.{ .min = 0 });\n    defer select.reset();\n\n    while (try select.step()) |user| {\n        std.log.info(\"id: {s}, age: {d}\", .{ user.id.data, user.age orelse 0 });\n    }\n}\n\n// Iterate again, with different params\n{\n    try select.bind(.{ .min = 21 });\n    defer select.reset();\n\n    while (try select.step()) |user| {\n        std.log.info(\"id: {s}, age: {d}\", .{ user.id.data, user.age orelse 0 });\n    }\n}\n```\n\nText and blob values must not be retained across steps. **You are responsible for copying them.**\n\n### Errors\n\nThe basic sqlite errors (`SQLITE_ERROR`, `SQLITE_BUSY`, `SQLITE_CANTOPEN`, etc) are exported as a `sqlite.Error` error union. If an error has been thrown, you can access a detailed error message with `db.errmsg(): ?[*:0]const u8`.\n\n## Notes\n\nCrafting sensible Zig bindings for SQLite involves making tradeoffs between following the Zig philosophy (\"deallocation must succeed\") and matching the SQLite API, in which closing databases or finalizing statements may return error codes.\n\nThis library takes the following approach:\n\n- `Database.close` calls `sqlite3_close_v2` and panics if it returns an error code.\n- `Statement.finalize` calls `sqlite3_finalize` and panics if it returns an error code.\n- `Statement.step` automatically calls `sqlite3_reset` if `sqlite3_step` returns an error code.\n  - In SQLite, `sqlite3_reset` returns the error code from the most recent call to `sqlite3_step`. This is handled gracefully.\n- `Statement.reset` calls both `sqlite3_reset` and `sqlite3_clear_bindings`, and panics if either return an error code.\n\nThese should only result in panic through gross misuse or in extremely unusual situations, e.g. `sqlite3_reset` failing internally. All \"normal\" errors are faithfully surfaced as Zig errors.\n\n## Build options\n\n```zig\nstruct {\n    SQLITE_ENABLE_COLUMN_METADATA: bool = false,\n    SQLITE_ENABLE_DBSTAT_VTAB:     bool = false,\n    SQLITE_ENABLE_FTS3:            bool = false,\n    SQLITE_ENABLE_FTS4:            bool = false,\n    SQLITE_ENABLE_FTS5:            bool = false,\n    SQLITE_ENABLE_GEOPOLY:         bool = false,\n    SQLITE_ENABLE_ICU:             bool = false,\n    SQLITE_ENABLE_MATH_FUNCTIONS:  bool = false,\n    SQLITE_ENABLE_RBU:             bool = false,\n    SQLITE_ENABLE_RTREE:           bool = false,\n    SQLITE_ENABLE_STAT4:           bool = false,\n    SQLITE_OMIT_DECLTYPE:          bool = false,\n    SQLITE_OMIT_JSON:              bool = false,\n    SQLITE_USE_URI:                bool = false,\n}\n```\n\nSet these by passing e.g. `-DSQLITE_ENABLE_RTREE` in the CLI, or by setting `.SQLITE_ENABLE_RTREE = true` in the `args` parameter to `std.Build.dependency`. For example:\n\n```zig\npub fn build(b: *std.Build) !void {\n    // ...\n\n    const sqlite = b.dependency(\"sqlite\", .{ .SQLITE_ENABLE_RTREE = true });\n}\n```\n\n## License\n\nMIT © nDimensional Studios\n","funding_links":[],"categories":["Data \u0026 Science"],"sub_categories":["Database"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FnDimensional%2Fzig-sqlite","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FnDimensional%2Fzig-sqlite","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FnDimensional%2Fzig-sqlite/lists"}