{"id":22619099,"url":"https://github.com/caneroj1/sqlite-simple-errors","last_synced_at":"2025-04-11T14:32:45.121Z","repository":{"id":56878781,"uuid":"70420977","full_name":"caneroj1/sqlite-simple-errors","owner":"caneroj1","description":"Light wrapper around errors from sqlite-simple to make working with constraint errors a bit easier.","archived":false,"fork":false,"pushed_at":"2020-06-18T17:11:55.000Z","size":23,"stargazers_count":5,"open_issues_count":3,"forks_count":4,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-04-24T22:21:47.506Z","etag":null,"topics":["error-handling","haskell","sqlite"],"latest_commit_sha":null,"homepage":null,"language":"Haskell","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/caneroj1.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":"2016-10-09T18:00:49.000Z","updated_at":"2023-03-29T11:34:47.000Z","dependencies_parsed_at":"2022-08-20T11:40:34.231Z","dependency_job_id":null,"html_url":"https://github.com/caneroj1/sqlite-simple-errors","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/caneroj1%2Fsqlite-simple-errors","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/caneroj1%2Fsqlite-simple-errors/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/caneroj1%2Fsqlite-simple-errors/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/caneroj1%2Fsqlite-simple-errors/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/caneroj1","download_url":"https://codeload.github.com/caneroj1/sqlite-simple-errors/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248419650,"owners_count":21100214,"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":["error-handling","haskell","sqlite"],"created_at":"2024-12-08T21:13:46.902Z","updated_at":"2025-04-11T14:32:45.097Z","avatar_url":"https://github.com/caneroj1.png","language":"Haskell","readme":"# sqlite-simple-errors\n\u003ca href=\"https://hackage.haskell.org/package/sqlite-simple-errors\"\u003eHackage\u003c/a\u003e\n\u003cbr\u003e\n[![Build Status](https://travis-ci.org/caneroj1/sqlite-simple-errors.svg?branch=master)](https://travis-ci.org/caneroj1/sqlite-simple-errors)\n\u003cbr\u003e\nLight wrapper around errors from sqlite-simple to make working with constraint errors a bit easier.\n\nThe wrapper function, ```runDBAction``` allows you to run your database code and get the errors returned to you:\n\n```haskell\ntype DatabaseResponse a = Either SQLiteResponse a\nrunDBAction :: IO a -\u003e IO (DatabaseResponse a)\n```\n\n```SQLiteResponse``` encapsulates the different error types that can be thrown by sqlite-simple, as well as providing a new error type for constraint violations that is more immediately actionable:\n\n```haskell\ndata Constraint = NotNull\n                | ForeignKey\n                | Unique\n                | Check\n  deriving (Show, Eq)\n\ndata SQLiteResponse = SQLConstraintError Constraint Text\n                    | SQLFormatError FormatError\n                    | SQLResultError ResultError\n                    | SQLOtherError  SQLError\n  deriving (Show, Eq, Typeable)\n```\n\n## Usage\nLet's use sqlite-simple to create our ```People``` table.\n\n```haskell\ncreatePeopleTableSQL :: Query\ncreatePeopleTableSQL =\n  \"CREATE TABLE if not exists People (name varchar(50) NOT NULL UNIQUE        \\\n  \\                                  ,age  int         CHECK(age \u003e 0)         \\\n  \\                                  ,id   integer     PRIMARY KEY NOT NULL); \"\n```\n\n### Not Null Constraint\nIf we try to insert a record into our database where we provide a ```NULL``` value on a column that is ```NOT NULL```:\n\n```haskell\nresult \u003c- runDBAction $ execute conn \"INSERT INTO People (name, age) VALUES (?, ?)\" ( (Nothing, 10) :: (Maybe Text, Int) )\n```\n\nwhere ```result``` is ```Left $ SQLConstraintError NotNull \"People.name\"```.\n\nThe typical error you would get from ```sqlite-simple``` would be a ```SQLError``` whose error context is ```\"SQLite3 returned ErrorConstraint while attempting to perform step: NOT NULL constraint failed: People.name\"```.\n\n### Unique Constraint\nIf we try to insert a record into our database that violates a ```UNIQUE``` constraint:\n\n```haskell\n_      \u003c- runDBAction $ execute conn \"INSERT INTO People (name, age) VALUES (?, ?)\" ( (\"Joe\", 10) :: (Text, Int) )\nresult \u003c- runDBAction $ execute conn \"INSERT INTO People (name, age) VALUES (?, ?)\" ( (\"Joe\", 10) :: (Text, Int) )\n```\n\nwhere ```result``` is ```Left $ SQLConstraintError Unique \"People.name\"```.\n\nThe typical error you would get from ```sqlite-simple``` would be a ```SQLError``` whose error context is ```\"SQLite3 returned ErrorConstraint while attempting to perform step: UNIQUE constraint failed: People.name\"```.\n\n### Check Constraint\nIf we try to insert a record that violates some condition we've specified through ```CHECK```:\n\n```haskell\nresult \u003c- runDBAction $ execute conn \"INSERT INTO People (name, age) VALUES (?, ?)\" ( (\"Joe\", 0) :: (Text, Int) )\n```\n\nwhere ```result``` is ```Left $ SQLConstraintError Check \"People\"```.\n\nThe typical error you would get from ```sqlite-simple``` would be a ```SQLError``` whose error context is ```\"SQLite3 returned ErrorConstraint while attempting to perform step: CHECK constraint failed: People\"```.\n\n### Foreign Key Constraint\nLet's make a new table where we can have a foreign key.\n\n```haskell\ncreateJobsTableSQL :: Query\ncreateJobsTableSQL =\n  \"CREATE TABLE if not exists Jobs (title varchar(50)                              \\\n  \\                                ,person_id int          NOT NULL                \\\n  \\                                ,FOREIGN KEY(person_id) REFERENCES People(id)); \"\n```\n\nIf we try to insert a record into this table without a corresponding entry in the People table:\n\n```haskell\nresult \u003c- runDBAction $ execute conn \"INSERT INTO Jobs (title, person_id) VALUES (?, ?)\" ((\"coder\", -1) :: (Text, Int))\n```\n\nwhere ```result``` is ```Left $ SQLConstraintError ForeignKey \"\"```.\n\nThe typical error you would get from ```sqlite-simple``` would be a ```SQLError``` whose error context is ```\"SQLite3 returned ErrorConstraint while attempting to perform step: FOREIGN KEY constraint failed\"```.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcaneroj1%2Fsqlite-simple-errors","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcaneroj1%2Fsqlite-simple-errors","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcaneroj1%2Fsqlite-simple-errors/lists"}