{"id":13699301,"url":"https://github.com/bvinc/go-sqlite-lite","last_synced_at":"2025-04-05T17:07:30.157Z","repository":{"id":55649845,"uuid":"143873375","full_name":"bvinc/go-sqlite-lite","owner":"bvinc","description":"SQLite driver for the Go programming language","archived":false,"fork":false,"pushed_at":"2020-12-15T12:02:54.000Z","size":7968,"stargazers_count":329,"open_issues_count":8,"forks_count":35,"subscribers_count":13,"default_branch":"master","last_synced_at":"2025-03-29T16:06:49.846Z","etag":null,"topics":["go","golang","sqlite","sqlite3"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bvinc.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}},"created_at":"2018-08-07T12:56:58.000Z","updated_at":"2025-03-13T08:09:16.000Z","dependencies_parsed_at":"2022-08-15T05:31:14.949Z","dependency_job_id":null,"html_url":"https://github.com/bvinc/go-sqlite-lite","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bvinc%2Fgo-sqlite-lite","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bvinc%2Fgo-sqlite-lite/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bvinc%2Fgo-sqlite-lite/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bvinc%2Fgo-sqlite-lite/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bvinc","download_url":"https://codeload.github.com/bvinc/go-sqlite-lite/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247369952,"owners_count":20927928,"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":["go","golang","sqlite","sqlite3"],"created_at":"2024-08-02T20:00:30.048Z","updated_at":"2025-04-05T17:07:30.124Z","avatar_url":"https://github.com/bvinc.png","language":"C","readme":"[![GoDoc](https://godoc.org/github.com/bvinc/go-sqlite-lite/sqlite3?status.svg)](https://godoc.org/github.com/bvinc/go-sqlite-lite/sqlite3)\n[![Build Status](https://travis-ci.com/bvinc/go-sqlite-lite.svg?branch=master)](https://travis-ci.com/bvinc/go-sqlite-lite)\n[![Build status](https://ci.appveyor.com/api/projects/status/xk6fpk23wb5ppdhx?svg=true)](https://ci.appveyor.com/project/bvinc/go-sqlite-lite)\n[![Coverage Status](https://coveralls.io/repos/github/bvinc/go-sqlite-lite/badge.svg?branch=master)](https://coveralls.io/github/bvinc/go-sqlite-lite?branch=master)\n[![Go Report Card](https://goreportcard.com/badge/github.com/bvinc/go-sqlite-lite)](https://goreportcard.com/report/github.com/bvinc/go-sqlite-lite)\n\n# go-sqlite-lite\n\ngo-sqlite-lite is a SQLite driver for the Go programming language.  It is designed with the following goals in mind.\n\n* **Lightweight** - Most methods should be little more than a small wrapper around SQLite C functions.\n* **Performance** - Where possible, methods should be available to allow for the highest performance possible.\n* **Understandable** - You should always know what SQLite functions are being called and in what order.\n* **Unsurprising** - Connections, PRAGMAs, transactions, bindings, and stepping should work out of the box exactly as you would expect with SQLite.\n* **Debuggable** - When you encounter a SQLite error, the SQLite documentation should be relevant and relatable to the Go code.\n* **Ergonomic** - Where it makes sense, convenient compound methods should exist to make tasks easy and to conform to Go standard interfaces.\n\nMost database drivers include a layer to work nicely with the Go `database/sql` interface, which introduces connection pooling and behavior differences from pure SQLite.  This driver does not include a `database/sql` interface.\n\n## Releases\n\n* 2019-05-01 **v0.6.1** - Bug fixes, authorizer callback support\n* 2019-05-01 **v0.6.0** - SQLite version 3.28.0\n* 2019-02-05 **v0.5.0** - SQLite version 3.26.0\n* 2018-10-30 **v0.4.2** - Better error messages from SQLite\n* 2018-10-11 **v0.4.1** - Fixed an issue with new go 1.11 modules\n* 2018-09-29 **v0.4.0** - SQLite version 3.25.2.  Add support for the Session extension\n* 2018-09-16 **v0.3.1** - Forgot to update sqlite3.h\n* 2018-09-16 **v0.3.0** - SQLite version 3.25.0\n* 2018-09-14 **v0.2.0** - Proper error and NULL handling on Column* methods.  Empty blobs and empty strings are now distinct from NULL in all cases.  A nil byte slice is interpreted as NULL for binding purposes as well as Column* methods.\n* 2018-09-01 **v0.1.2** - Added Column methods to Stmt, and WithTx methods to Conn\n* 2018-08-25 **v0.1.1** - Fixed linking on some Linux systems\n* 2018-08-21 **v0.1.0** - SQLite version 3.24.0\n\n## Getting started\n\n```go\nimport \"github.com/bvinc/go-sqlite-lite/sqlite3\"\n```\n\n### Acquiring a connection\n```go\nconn, err := sqlite3.Open(\"mydatabase.db\")\nif err != nil {\n\t...\n}\ndefer conn.Close()\n\n// It's always a good idea to set a busy timeout\nconn.BusyTimeout(5 * time.Second)\n```\n\n### Executing SQL\n```go\nerr = conn.Exec(`CREATE TABLE student(name TEXT, age INTEGER)`)\nif err != nil {\n\t...\n}\n// Exec can optionally bind parameters\nerr = conn.Exec(`INSERT INTO student VALUES (?, ?)`, \"Bob\", 18)\nif err != nil {\n\t...\n}\n```\n\n### Using Prepared Statements\n```go\nstmt, err := conn.Prepare(`INSERT INTO student VALUES (?, ?)`)\nif err != nil {\n\t...\n}\ndefer stmt.Close()\n\n// Bind the arguments\nerr = stmt.Bind(\"Bill\", 18)\nif err != nil {\n\t...\n}\n// Step the statement\nhasRow, err := stmt.Step()\nif err != nil {\n\t...\n}\n// Reset the statement\nerr = stmt.Reset()\nif err != nil {\n\t...\n}\n```\n\n### Using Prepared Statements Conveniently\n```go\nstmt, err := conn.Prepare(`INSERT INTO student VALUES (?, ?)`)\nif err != nil {\n\t...\n}\ndefer stmt.Close()\n\n// Exec binds arguments, steps the statement to completion, and always resets the statement\nerr = stmt.Exec(\"John\", 19)\nif err != nil {\n\t...\n}\n```\n\n### Using Queries Conveniently\n```go\n// Prepare can prepare a statement and optionally also bind arguments\nstmt, err := conn.Prepare(`SELECT name, age FROM student WHERE age = ?`, 18)\nif err != nil {\n\t...\n}\ndefer stmt.Close()\n\nfor {\n\thasRow, err := stmt.Step()\n\tif err != nil {\n\t\t...\n\t}\n\tif !hasRow {\n\t\t// The query is finished\n\t\tbreak\n\t}\n\n\t// Use Scan to access column data from a row\n\tvar name string\n\tvar age int\n\terr = stmt.Scan(\u0026name, \u0026age)\n\tif err != nil {\n\t\t...\n\t}\n\tfmt.Println(\"name:\", name, \"age:\", age)\n}\n// Remember to Reset the statement if you would like to Bind new arguments and reuse the prepared statement\n```\n\n### Getting columns that might be NULL\nScan can be convenient to use, but it doesn't handle NULL values.  To get full control of column values, there are column methods for each type.\n```go\nname, ok, err := stmt.ColumnText(0)\nif err != nil {\n\t// Either the column index was out of range, or SQLite failed to allocate memory\n\t...\n}\nif !ok {\n\t// The column was NULL\n}\n\nage, ok, err := stmt.ColumnInt(1)\nif err != nil {\n\t// Can only fail if the column index is out of range\n\t...\n}\nif !ok {\n\t// The column was NULL\n}\n```\n\n`ColumnBlob` returns a nil slice in the case of NULL.\n```go\nblob, err := stmt.ColumnBlob(i)\nif err != nil {\n\t// Either the column index was out of range, or SQLite failed to allocate memory\n\t...\n}\nif blob == nil {\n\t// The column was NULL\n}\n```\n\n\n\n### Using Transactions\n```go\n// Equivalent to conn.Exec(\"BEGIN\")\nerr := conn.Begin()\nif err != nil {\n\t...\n}\n\n// Do some work\n...\n\n// Equivalent to conn.Exec(\"COMMIT\")\nerr = conn.Commit()\nif err != nil {\n\t...\n}\n```\n\n### Using Transactions Conveniently\n\nWith error handling in Go, it can be pretty inconvenient to ensure that a transaction is rolled back in the case of an error.  The `WithTx` method is provided, which accepts a function of work to do inside of a transaction.  `WithTx` will begin the transaction and call the function.  If the function returns an error, the transaction will be rolled back.  If the function succeeds, the transaction will be committed.  `WithTx` can be a little awkward to use, but it's necessary.  For example:\n\n```go\nerr := conn.WithTx(func() error {\n\treturn insertStudents(conn)\n})\nif err != nil {\n\t...\n}\n\nfunc insertStudents(conn *sqlite3.Conn) error {\n\t...\n}\n```\n\n## Advanced Features\n* Binding parameters to statements using SQLite named parameters.\n* SQLite Blob Incremental IO API.\n* SQLite Online Backup API.\n* SQLite Session extension.\n* Supports setting a custom busy handler\n* Supports callback hooks on commit, rollback, and update.\n* Supports setting compile-Time authorization callbacks.\n* If shared cache mode is enabled and one statement receives a `SQLITE_LOCKED` error, the SQLite [unlock_notify](https://sqlite.org/unlock_notify.html) extension is used to transparently block and try again when the conflicting statement finishes.\n* Compiled with SQLite support for JSON1, RTREE, FTS5, GEOPOLY, STAT4, and SOUNDEX.\n* Compiled with SQLite support for OFFSET/LIMIT on UPDATE and DELETE statements.\n* RawString and RawBytes can be used to reduce copying between Go and SQLite.  Please use with caution.\n\n## Credit\nThis project began as a fork of https://github.com/mxk/go-sqlite/\n\n## FAQ\n\n* **Why is there no `database/sql` interface?**\n\nIf a `database/sql` interface is required, please use https://github.com/mattn/go-sqlite3 .  In my experience, using a `database/sql` interface with SQLite is painful.  Connection pooling causes unnecessary overhead and weirdness.  Transactions using `Exec(\"BEGIN\")` don't work as expected.  Your connection does not correspond to SQLite's concept of a connection.  PRAGMA commands do not work as expected.  When you hit SQLite errors, such as locking or busy errors, it's difficult to discover why since you don't know which connection received which SQL and in what order.\n\n* **What are the differences between this driver and the mxk/go-sqlite driver?**\n\nThis driver was forked from `mxk/go-sqlite-driver`.  It hadn't been maintained in years and used an ancient version of SQLite.  A large number of features were removed, reworked, and renamed.  A lot of smartness and state was removed.  It is now much easier to upgrade to newer versions of SQLite since the `codec` feature was removed.  The behavior of methods now lines up closely with the behavior of SQLite's C API.\n\n* **What are the differences between this driver and the crawshaw/sqlite driver?**\n\nThe crawshaw driver is pretty well thought out and solves a lot of the same problems as this\ndriver.  There are a few places where our philosophies differ.  The crawshaw driver defaults (when flags of 0 are given) to SQLite shared cache mode and WAL mode.  The default WAL synchronous mode is changed.  Prepared statements are transparently cached.  Connection pools are provided.  I would be opposed to making most of these changes to this driver.  I would like this driver to provide a default, light, and unsurprising SQLite experience.\n\n* **Are finalizers provided to automatically close connections and statements?**\n\nNo finalizers are used in this driver.  You are responsible for closing connections and statements.  While I mostly agree with finalizers for cleaning up most accidental resource leaks, in this case, finalizers may fix errors such as locking errors while debugging only to find that the code works unreliably in production.  Removing finalizers makes the behavior consistent.\n\n* **Is it thread safe?**\n\ngo-sqlite-lite is as thread safe as SQLite.  SQLite with this driver is compiled with `-DSQLITE_THREADSAFE=2` which is **Multi-thread** mode.  In this mode, SQLite can be safely used by multiple threads provided that no single database connection is used simultaneously in two or more threads.  This applies to goroutines.  A single database connection should not be used simultaneously between two goroutines.\n\nIt is safe to use separate connection instances concurrently, even if they are accessing the same database file. For example:\n```go\n// ERROR (without any extra synchronization)\nc, _ := sqlite3.Open(\"sqlite.db\")\ngo use(c)\ngo use(c)\n```\n```go\n// OK\nc1, _ := sqlite3.Open(\"sqlite.db\")\nc2, _ := sqlite3.Open(\"sqlite.db\")\ngo use(c1)\ngo use(c2)\n```\n\nConsult the SQLite documentation for more information.\n\nhttps://www.sqlite.org/threadsafe.html\n\n* **How do I pool connections for handling HTTP requests?**\n\nOpening new connections is cheap and connection pooling is generally unnecessary for SQLite.  I would recommend that you open a new connection for each request that you're handling.  This ensures that each request is handled separately and the normal rules of SQLite database/table locking apply.\n\nIf you've decided that pooling connections provides you with an advantage, it would be outside the scope of this package and something that you would need to implement and ensure works as needed.\n\n## License\nThis project is licensed under the BSD license.\n\n","funding_links":[],"categories":["C"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbvinc%2Fgo-sqlite-lite","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbvinc%2Fgo-sqlite-lite","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbvinc%2Fgo-sqlite-lite/lists"}