{"id":16788574,"url":"https://github.com/mna/xpgsql","last_synced_at":"2026-05-11T16:37:39.604Z","repository":{"id":145702250,"uuid":"292652474","full_name":"mna/xpgsql","owner":"mna","description":"Lua module providing a straightforward API to the luapgsql library. (mirror)","archived":false,"fork":false,"pushed_at":"2022-11-12T02:27:07.000Z","size":36,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-17T00:41:28.659Z","etag":null,"topics":["lua","mirror","postgresql"],"latest_commit_sha":null,"homepage":"","language":"Lua","has_issues":false,"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/mna.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","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},"funding":{"github":["mna"],"custom":["https://www.buymeacoffee.com/mna"]}},"created_at":"2020-09-03T18:43:39.000Z","updated_at":"2022-09-08T18:14:01.000Z","dependencies_parsed_at":"2023-04-07T23:47:20.989Z","dependency_job_id":null,"html_url":"https://github.com/mna/xpgsql","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/mna/xpgsql","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mna%2Fxpgsql","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mna%2Fxpgsql/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mna%2Fxpgsql/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mna%2Fxpgsql/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mna","download_url":"https://codeload.github.com/mna/xpgsql/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mna%2Fxpgsql/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32903759,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-10T13:40:02.631Z","status":"online","status_checked_at":"2026-05-11T02:00:05.975Z","response_time":120,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["lua","mirror","postgresql"],"created_at":"2024-10-13T08:18:20.332Z","updated_at":"2026-05-11T16:37:39.596Z","avatar_url":"https://github.com/mna.png","language":"Lua","funding_links":["https://github.com/sponsors/mna","https://www.buymeacoffee.com/mna"],"categories":[],"sub_categories":[],"readme":"# xpgsql\n\nA pure Lua module that provides a more straightforward API to work with the [luapgsql] Lua library (also works with [cqueues-pgsql]).\n\n* Canonical repository: https://git.sr.ht/~mna/xpgsql\n* Issue tracker: https://todo.sr.ht/~mna/xpgsql\n\n## Install\n\nVia Luarocks:\n\n```\n$ luarocks install xpgsql\n```\n\nOr simply copy the single xpgsql.lua file in your project or your `LUA_PATH`.\n\n## API\n\nAssuming `local xpgsql = require 'xpgsql'`. You can check out the tests for actual examples of using the API.\n\n### `xpgsql.transform_error`\n\nIf set, the `transform_error` field is called with all error values and its\nreturn value(s) is returned instead of the base values. Can be useful to\ncollect the different values in a structured object and return that object\ninstead.\n\nMay be called with up to 4 values:\n1. the error message\n2. the error status code (a number)\n3. the string version of the status (e.g. 'PGRES_FATAL_ERROR')\n4. the SQL state code (e.g. 42P01, see https://www.postgresql.org/docs/current/errcodes-appendix.html)\n\n### `xpgsql.connect(connstr)`\n\nConnects to the database specified by the connection string.  It may be an\nempty string if the required settings are set in environment variables. If\nno connection string is provided, an empty string is used.\n\nReturns the connection object on success, or nil, an error message and the\nstatus code.\n\n### `xpgsql.model(res, newf)`\n\nReturns a table filled with the values of the first row of res, keyed by\nthe field names. Returns nil if res has no row. If newf is provided,\ncalls it with the generated table so that it can make further\ninitialization and returns the return value(s) of newf.\n\n### `xpgsql.models(res, newf)`\n\nReturns an array of models for each row in res. Works the same as\nxpgsql.model, except for multiple rows, and if res contains no row, returns\nan empty array instead of nil.\n\n### `Connection:format_array(t)`\n\nFormats array t so that it can be used in a SQL statement as\ne.g. IN (...) or ANY (...). It returns a string that can safely\nbe inserted in the SQL statement, with each value comma-separated\nand each string value properly escaped. If the array contains\nvalues other than strings and numbers, it raises an error.\n\n### `Connection:tx(f, ...)`\n\nExecutes f inside a transaction, passing the Connection as first argument\nand any extra arguments passed to this function as subsequent arguments. On\nexit, the transaction is committed if f executed without error, otherwise it\nis rollbacked. The Connection.transaction field is set to true before calling\nf, and is reset to its old value before returning.\n\nReturns the return values of f on success, or nil and an error message on\nerror. As a special-case, to allow asserting on the call, it returns true if\nf succeeded and did not return anything (it can still return nil\nexplicitly and Connection:tx will then return nil).\n\n### `Connection:ensuretx(f, ...)`\n\nSimilar to Connection:tx, ensuretx starts a transaction only if Connection\nis not already inside one, and calls f with the Connection as first argument\nand any extra arguments passed to this function as subsequent arguments.\nIf a transaction was started, it is closed after the call to f with a commit\nif f succeeded, or a rollback if it raised an error. If a transaction was\nnot started (if Connection was already in a transaction before the call to\nensuretx), the transaction is not terminated after the call to f.\n\nReturns the return values of f on success, or nil and an error message on\nerror. As a special-case, to allow asserting on the call, it returns true if\nf succeeded and did not return anything (it can still return nil explicitly\nand Connection:ensuretx will then return nil).\n\n### `Connection:with(close, f, ...)`\n\nCalls f with the Connection as first argument and any extra arguments passed\nto this function as subsequent arguments. If close is true, the connection\nis closed after the call to f.\n\nReturns the return values of f on success, or nil and an error message on\nerror. As a special-case, to allow asserting on the call, it returns true if\nf succeeded and did not return anything (it can still return nil explicitly\nand Connection:with will then return nil).\n\n### `Connection:query(stmt, ...)`\n\nExecutes a query statement and returns the result if it succeeds, or nil, an\nerror message and the status code (number). If the error is not related to the\nconnection, then it also returns the string version of the status (e.g. `PGRES_FATAL_ERROR`)\nand the SQL state code (e.g. 42P01, see https://www.postgresql.org/docs/current/errcodes-appendix.html).\n\nNote that INSERT .. RETURNING must use Connection:query as it returns\nvalues. The statement may contain $1, $2, etc. placeholders, they will be\nreplaced by the extra arguments provided to the method.\n\n### `Connection:exec(stmt, ...)`\n\nExecutes a non-query statement and returns the result if it succeeds, or\nnil, an error message and the status code (number). If the error is not\nrelated to the connection, then it also returns the string version of the\nstatus (e.g. `PGRES_FATAL_ERROR`) and the SQL state code (e.g. 42P01, see\nhttps://www.postgresql.org/docs/current/errcodes-appendix.html).\n\nNote that INSERT..RETURNING must use Connection:query as it returns values.\nThe statement may contain $1, $2, etc. placeholders, they will be replaced\nby the extra arguments provided to the method.\n\n### `Connection:get(stmt, ...)`\n\nCombines a call to `:query` with a call to `.model` to return the first row\ndecoded into a table with column names as keys. If the last parameter\nafter the statement is a function, it is used as the 'newf' argument to\nthe call to `.model`, to provide further initialization of the row's table.\nReturns the resulting table, or nil if the query did not return any row.\nIt returns nil along with any error in case of failure, as returned by\n`:query`.\n\n### `Connection:select(stmt, ...)`\n\nCombines a call to `:query` with a call to `.models` to return an array of rows\neach decoded into a table with column names as keys. If the last parameter\nafter the statement is a function, it is used as the 'newf' argument to\nthe call to `.models`, to provide further initialization of each row's table.\nReturns the resulting array (which is empty if the query returned no row),\nor nil and any error as returned by `:query`.\n\n### `Connection:close()`\n\nCloses the connection and frees resources associated with it.\n\n## Development\n\nClone the project and install the required development dependencies:\n\n* luapgsql (runtime dependency)\n* luaunit (unit test runner)\n* luacov (recommended, test coverage)\n\nIf like me you prefer to keep your dependencies locally, per-project, then I recommend using my [llrocks] wrapper of the `luarocks` cli, which by default uses a local `lua_modules/` tree.\n\n```\n$ llrocks install ...\n```\n\nTo run tests, first make sure a postgres database is reachable with\nan empty connection string (e.g. via environment variables) and make\nsure it is ok to create tables and change data in that database.\n\nYou can use the provided docker-compose file to run a dockerized postgresql\ninstance. Just generate a random password for root:\n\n```\n$ openssl rand -base64 32 | tr -d '/' \u003e .root_pwd\n\n# if on SELinux-based OS\n$ chcon -Rt svirt_sandbox_file_t .root_pwd\n```\n\nAnd create a local `.pgpass` file for it, and setup the required env vars, e.g.:\n\n```\n# .pgpass file:\nlocalhost:5432:postgres:postgres:[the-password-from-.root_pwd]\n\n# environment variables, e.g. in .envrc if you use direnv:\nexport PGPASSFILE=`pwd`/.pgpass\nexport PGHOST=localhost\nexport PGPORT=5432\nexport PGCONNECT_TIMEOUT=10\nexport PGUSER=postgres\nexport PGDATABASE=postgres\n```\n\nThen bring the instance up by running:\n\n```\n$ docker-compose up -d\n```\n\nThen:\n\n```\n$ llrocks run test/main.lua\n```\n\nTo view code coverage:\n\n```\n$ llrocks cover test/main.lua\n```\n\n## License\n\nThe [BSD 3-clause][bsd] license.\n\n[bsd]: http://opensource.org/licenses/BSD-3-Clause\n[llrocks]: https://git.sr.ht/~mna/llrocks\n[luapgsql]: https://github.com/arcapos/luapgsql\n[cqueues-pgsql]: https://github.com/daurnimator/cqueues-pgsql\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmna%2Fxpgsql","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmna%2Fxpgsql","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmna%2Fxpgsql/lists"}