{"id":15724301,"url":"https://github.com/cedlemo/ocaml-sqlite3-notes","last_synced_at":"2025-03-13T00:31:25.884Z","repository":{"id":144939695,"uuid":"162493846","full_name":"cedlemo/ocaml-sqlite3-notes","owner":"cedlemo","description":"OCaml Sqlite3 tutorial","archived":false,"fork":false,"pushed_at":"2019-03-16T18:34:36.000Z","size":618,"stargazers_count":7,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-26T18:11:40.417Z","etag":null,"topics":["ocaml","ocaml-sqlite","sqlite3","tutorial"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cedlemo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2018-12-19T21:42:09.000Z","updated_at":"2024-06-08T17:05:44.000Z","dependencies_parsed_at":"2023-04-04T21:02:25.266Z","dependency_job_id":null,"html_url":"https://github.com/cedlemo/ocaml-sqlite3-notes","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/cedlemo%2Focaml-sqlite3-notes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cedlemo%2Focaml-sqlite3-notes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cedlemo%2Focaml-sqlite3-notes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cedlemo%2Focaml-sqlite3-notes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cedlemo","download_url":"https://codeload.github.com/cedlemo/ocaml-sqlite3-notes/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243318767,"owners_count":20272136,"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":["ocaml","ocaml-sqlite","sqlite3","tutorial"],"created_at":"2024-10-03T22:16:03.436Z","updated_at":"2025-03-13T00:31:25.856Z","avatar_url":"https://github.com/cedlemo.png","language":null,"readme":"# OCaml SQLite notes\n\n* [Installation](#installation)\n* [basic usage](#basic-usage)\n  * [Create a database](#create-a-database)\n  * [Create a table](#create-a-table)\n  * [Handle basic error on request](#handle-basic-error-on-request)\n  * [Query a database](#query-a-database)\n* [User defined functions](#user-defined-functions)\n* [Statements](#statements)\n* [sqlexpr](#sqlexpr)\n* [orm](#orm)\n\n## Installation\n\n```\nopam install sqlite3\n```\n\n* Use it in a file:\n\n```ocaml\nopen Sqlite3\n```\n\n* Use it in utop:\n\n```ocaml\n#require \"sqlite3\"\n#open Sqlite3\n```\n\n## Basic usage\nCreate a database, a table and do a basic query. The full code can be found in\n*samples/sample_1.ml*.\n\n### Create a database\n```ocaml\nlet mydb = db_open \"test.db\"\n```\n\n### Create a table\n\n* the table structure\n```\n_________________________________\n[Contacts                        ]\n----------------------------------\n| contact_id INTEGER PRIMARY KEY |\n| first_name TEXT NOT NULL       |\n| last_name  TEXT NOT NULL       |\n| email      TEST NOT NULL UNIQUE|\n| phone      TEST NOT NULL UNIQUE|\n|________________________________|\n```\n\n* the query to create the table\n\n```ocaml\nlet create_table_sql = \"CREATE TABLE contacts ( \\\n                          contact_id INTEGER PRIMARY KEY, \\\n                          first_name TEXT NOT NULL, \\\n                          last_name TEXT NOT NULL, \\\n                          email text NOT NULL UNIQUE, \\\n                          phone text NOT NULL UNIQUE \\\n                        );\"\n\nlet db = db_open \"test.db\"\n\nlet () =\n  match exec db create_table_sql with\n  | Rc.OK -\u003e print_endline \"Ok\"\n  | r -\u003e prerr_endline (Rc.to_string r); prerr_endline (errmsg db)\n```\n\nWith the command line client of sqlite, we can verify the good execution of our\ncode with:\n\n```\nsqlite3 test.db\nsqlite\u003e SELECT name FROM sqlite_master WHERE type='table';\ncontacts\nsqlite\u003e PRAGMA table_info(contacts);\n0|contact_id|INTEGER|0||1\n1|first_name|TEXT|1||0\n2|last_name|TEXT|1||0\n3|email|text|1||0\n4|phone|text|1||0\n```\n\n### Handle basic error request\n\nWhen opening a database with the *ocaml-sqlite3* lib, the function\n`Sqlite3.db_open` returns a `Sqlite3.db` database handle. This handle stores the\nerror code of the last operation.\n\nThe `Sqlite3.exec` function returns a [`Sqlite3.Rc.t` type](http://mmottl.github.io/sqlite3-ocaml/api/sqlite3/Sqlite3/Rc/index.html#type-t). In this variant there is one particular tag : *OK*\nthat is returned when the query is successful. All the other cases can be considered\nlike an error. A string corresponding to this type can be obtained with the\nfunction `val to_string : Rc.t ‑\u003e string`, it can be useful to display the kind\nof error you are facing.\n\nFurthermore, when you have one of this error, its possible to ask for an error\nmessage from the database handle with the function: `Sqlite3.errmsg`.\n\nIn the *sample_2*, there is a query on a database that does not exits.\n\n```ocaml\n(** Build with ocamlbuild -pkg sqlite3 sample_2.native or use make sample_2 *)\n\nopen Sqlite3\n\nlet mydb = db_open \"test.db\"\n\nlet create_table_sql = \"SELECT first_name FROM bad_table_name;\"\n\nlet db = db_open \"test.db\"\n\nlet () =\n  match exec db create_table_sql with\n  | Rc.OK -\u003e print_endline \"Ok\"\n  | r -\u003e prerr_endline (Rc.to_string r); prerr_endline (errmsg db)\n```\n\nWhen executed, this sample display the following information:\n\n```\nERROR\nno such table: bad_table_name\n```\n\n### Query a database\n\nIn the following example (*samples/sample_3.ml*), there will be multiples queries.\n\n```\n(** Build with ocamlbuild -pkg sqlite3 sample_3.native or use make sample_3 *)\n\nopen Sqlite3\n\nlet db = db_open \"test.db\"\n\nlet gracefully_exist error message =\n  let () = prerr_endline (Rc.to_string error) in\n  let () = prerr_endline (errmsg db) in\n  let () = prerr_endline message in\n  let _closed = db_close db in\n  let () = prerr_endline \"Exiting ...\" in\n  exit 1\n\nlet create_contacts_table () =\n  let create_table_sql = \"CREATE TABLE contacts ( \\\n                          contact_id INTEGER PRIMARY KEY, \\\n                          first_name TEXT NOT NULL, \\\n                          last_name TEXT NOT NULL, \\\n                          email text NOT NULL UNIQUE, \\\n                          phone text NOT NULL UNIQUE \\\n                          );\"\n  in match exec db create_table_sql with\n  | Rc.OK -\u003e ()\n  | r -\u003e\n    let message = \"Unable to create table contacts.\" in\n    gracefully_exist r message\n\n(* Query that should returns a result if a table contacts exists *)\nlet check_table_sql =\n  \"SELECT COUNT(name) FROM sqlite_master WHERE type='table' AND name='contacts'\"\n\n(* Callback that checks if there is already a table contacts and if not creates\n   it *)\nlet check_table_cb row = match row.(0) with\n  | Some a -\u003e\n    if a = \"0\" then begin\n      let () = print_endline \"Creating the table Contacts\" in\n      create_contacts_table ()\n    end else print_endline \"The table Contacts already exists\"\n  | None -\u003e ()\n\nlet ensure_table_contacts_exists () =\n  match exec_no_headers db ~cb:check_table_cb check_table_sql with\n  | Rc.OK -\u003e ()\n  | r -\u003e\n    let message =  \"Unable to check if the table Contacts exists.\" in\n    gracefully_exist r message\n\n(* Lets add some data in our table *)\nlet data = [\n  (\"NULL\", \"Jean\", \"Pignon\", \"jean@pignon.fr\", \"123456789\");\n  (\"NULL\", \"Marcelle\", \"Michue\", \"marcelle@michue.fr\", \"987654321\");\n]\n\nlet clean_table () =\n  let sql = \"DELETE FROM Contacts\" in\n  match exec db sql with\n  | Rc.OK -\u003e ()\n  | r -\u003e\n    let message =  \"Unable to clean the table Contacts.\" in\n    gracefully_exist r message\n\nlet add_data () =\n  let rec _add = function\n    | [] -\u003e print_endline \"Insertion finished\"\n    | (id, fn, ln, mail, phone) :: t -\u003e\n      let sql =\n        Printf.sprintf \"INSERT INTO Contacts VALUES(%s,'%s','%s','%s','%s')\"\n          id fn ln mail phone\n      in\n      let () = begin match exec db sql with\n        | Rc.OK -\u003e\n          let id = Sqlite3.last_insert_rowid db in\n          Printf.printf \"Row inserted with id %Ld\\n\" id\n        | r -\u003e prerr_endline (Rc.to_string r); prerr_endline (errmsg db)\n      end\n      in _add t\n  in _add data\n\nlet () =\n  let () = ensure_table_contacts_exists () in\n  let () = clean_table () in\n  add_data ()\n```\n\n## User defined functions\n\n## Statements\n\n## sqlexpr\n## sequoia\n\n## More usage examples\n\nMore examples can be found in [README_sqlite3_tutorial](README_sqlite3_tutorial.md)\n\n## Using the orm module\nhttps://github.com/mirage/orm\n\n\n## References\n\n* https://stackoverflow.com/questions/82875/how-to-list-the-tables-in-a-sqlite-database-file-that-was-opened-with-attach\n* https://www.tutorialspoint.com/sqlite\n* http://www.sqlitetutorial.net/\n* https://mmottl.github.io/sqlite3-ocaml/\n* http://mmottl.github.io/sqlite3-ocaml/api/sqlite3/Sqlite3/index.html\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcedlemo%2Focaml-sqlite3-notes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcedlemo%2Focaml-sqlite3-notes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcedlemo%2Focaml-sqlite3-notes/lists"}