{"id":18077677,"url":"https://github.com/fukamachi/datafly","last_synced_at":"2025-04-05T20:20:26.168Z","repository":{"id":16082102,"uuid":"18826714","full_name":"fukamachi/datafly","owner":"fukamachi","description":"A lightweight database library for Common Lisp.","archived":false,"fork":false,"pushed_at":"2023-11-17T02:01:03.000Z","size":40,"stargazers_count":101,"open_issues_count":8,"forks_count":6,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-02-11T19:13:18.523Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Common Lisp","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/fukamachi.png","metadata":{"files":{"readme":"README.markdown","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}},"created_at":"2014-04-16T04:22:16.000Z","updated_at":"2025-01-22T21:01:08.000Z","dependencies_parsed_at":"2022-09-11T17:53:50.875Z","dependency_job_id":"b23831d8-eb97-4f9f-a192-e116cbb73641","html_url":"https://github.com/fukamachi/datafly","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/fukamachi%2Fdatafly","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fukamachi%2Fdatafly/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fukamachi%2Fdatafly/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fukamachi%2Fdatafly/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fukamachi","download_url":"https://codeload.github.com/fukamachi/datafly/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247394691,"owners_count":20931993,"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":[],"created_at":"2024-10-31T11:47:17.050Z","updated_at":"2025-04-05T20:20:26.148Z","avatar_url":"https://github.com/fukamachi.png","language":"Common Lisp","readme":"# datafly\n\n[![Build Status](https://travis-ci.org/fukamachi/datafly.svg?branch=master)](https://travis-ci.org/fukamachi/datafly)\n\nDatafly is a lightweight database library for Common Lisp.\n\n## Quickstart\n\nDatafly provides 3 functions which wrap [CL-DBI](https://github.com/fukamachi/cl-dbi) \u0026mdash; `retrieve-one`, `retrieve-all` and `execute`.\n\nThey take a [SxQL](https://github.com/fukamachi/sxql) statement.\n\n```common-lisp\n(use-package :sxql)\n\n(connect-toplevel :sqlite3 :database-name #P\"myapp.db\")\n\n(retrieve-one\n  (select :*\n    (from :user)\n    (where (:= :name \"nitro_idiot\"))))\n;=\u003e (:ID 1 :NAME \"nitro_idiot\" :EMAIL \"nitro_idiot@example.com\" :REGISTERED-AT \"2014-04-14T19:20:13\")\n\n(retrieve-all\n  (select :*\n    (from :user)))\n;=\u003e ((:ID 1 :NAME \"nitro_idiot\" :EMAIL \"nitro_idiot@example.com\" :REGISTERED-AT \"2014-04-14T19:20:13\")\n;    (:ID 2 :NAME \"m2ym\" :EMAIL \"m2ym@example.com\" :REGISTERED-AT \"2014-04-15T01:03:42\"))\n\n(execute\n (insert-into :tweet\n   (set= :id 1\n         :user_id 1\n         :body \"Hi.\"\n         :created_at (princ-to-string *now*))))\n```\n\nIf you specify `:as` option with a class name to retrieval functions, they create instances of the class for each rows.\n\n```common-lisp\n(defstruct user\n  id\n  name\n  email\n  registered-at)\n\n(retrieve-one\n  (select :*\n    (from :user)\n    (where (:= :name \"nitro_idiot\")))\n  :as 'user)\n;=\u003e #S(USER :ID 1 :NAME \"nitro_idiot\" :EMAIL \"nitro_idiot@example.com\" :REGISTERED-AT \"2014-04-14T19:20:13\")\n\n(retrieve-all\n  (select :*\n    (from :user))\n  :as 'user)\n;=\u003e (#S(USER :ID 1 :NAME \"nitro_idiot\" :EMAIL \"nitro_idiot@example.com\" :REGISTERED-AT \"2014-04-14T19:20:13\")\n;    #S(USER :ID 2 :NAME \"m2ym\" :EMAIL \"m2ym@example.com\" :REGISTERED-AT \"2014-04-15T01:03:42\"))\n```\n\nThe structure doesn't require having slots same as an existing table's in a database. It is acceptable even if the names are different. This might be convenient when you'd like to treat a JOINed table result as a structure object.\n\n## Model Definitions\n\nDatafly provides a macro `defmodel` which defines a flavored structure class.\n\n```common-lisp\n(defmodel (user (:inflate registered-at #'datetime-to-timestamp))\n  id\n  name\n  email\n  registered-at)\n\n\n;; Same as the above.\n(syntax:use-syntax :annot)\n\n@model\n(defstruct (user (:inflate registered-at #'datetime-to-timestamp))\n  id\n  name\n  email\n  registered-at)\n```\n\n`(:inflate \u003ccolumns\u003e \u003cinflation-function\u003e)` options mean `inflation-function` will be applied to each `\u003ccolumns\u003e` when creating an instance.\n\n```common-lisp\n(defvar *user*\n  (retrieve-one\n    (select :*\n      (from :user)\n      (where (:= :name \"nitro_idiot\")))\n    :as 'user))\n\n;; Returns a local-time:timestamp.\n(user-registered-at *user*)\n;=\u003e @2014-04-15T04:20:13.000000+09:00\n```\n\n`defmodel` also allows `:has-a` and `:has-many` options.\n\n```common-lisp\n(use-package :sxql)\n\n(defmodel (user (:inflate registered-at #'datetime-to-timestamp)\n                (:has-a config (where (:= :user_id id)))\n                (:has-many (tweets tweet)\n                 (select :*\n                   (from :tweet)\n                   (where (:= :user_id id))\n                   (order-by (:desc :created_at)))))\n  id\n  name\n  email\n  registered-at)\n\n(defvar *user*\n  (retrieve-one\n    (select :*\n      (from :user)\n      (where (:= :name \"nitro_idiot\")))\n    :as 'user))\n\n(user-config *user*)\n;=\u003e #S(CONFIG :ID 4 :USER-ID 1 :TIMEZONE \"JST\" :COUNTRY \"jp\" :LANGUAGE \"ja\")\n\n(user-tweets *user*)\n;=\u003e (#S(TWEET :ID 2 :USER-ID 1 :BODY \"Is it working?\" :CREATED-AT @2014-04-16T11:02:31.000000+09:00)\n;    #S(TWEET :ID 1 :USER-ID 1 :BODY \"Hi.\" :CREATED-AT @2014-04-15T18:58:20.000000+09:00))\n```\n\n## Provided inflation functions\n\n* `tinyint-to-boolean`\n* `datetime-to-timestamp`\n* `unixtime-to-timestamp`\n* `string-to-keyword`\n* `octet-vector-to-string`\n\n## Tips: Getting Association List or Hash Table for each rows\n\n`retrieve-one` and `retrieve-all` return row(s) as a property list or a list of property lists by default.\n\nIf you'd like they were other types, for example \"Association List\" or \"Hash Table\", you can do it by passing `:as` parameter.\n\n```common-lisp\n(retrieve-one\n  (select :*\n    (from :user)\n    (where (:= :name \"nitro_idiot\")))\n  :as 'trivial-types:association-list)\n;=\u003e ((:ID . 1) (:NAME . \"nitro_idiot\") (:EMAIL . \"nitro_idiot@example.com\") (:REGISTERED-AT . \"2014-04-14T19:20:13\"))\n\n(retrieve-one\n  (select :*\n    (from :user)\n    (where (:= :name \"nitro_idiot\")))\n  :as 'hash-table)\n;=\u003e #\u003cHASH-TABLE :TEST EQL :COUNT 4 {1007AE3CD3}\u003e\n```\n\nIf no `:as` parameter is specified, `*default-row-type*` will be used.\n\n```common-lisp\n(let ((*default-row-type* 'hash-table))\n  (retrieve-all\n    (select :*\n      (from :user))))\n;=\u003e (#\u003cHASH-TABLE :TEST EQL :COUNT 4 {100815FA03}\u003e #\u003cHASH-TABLE :TEST EQL :COUNT 4 {100815FE43}\u003e)\n```\n\n## See Also\n\n* [SxQL](https://github.com/fukamachi/sxql)\n* [CL-DBI](https://github.com/fukamachi/cl-dbi)\n* [cl-annot](https://github.com/arielnetworks/cl-annot), [CL-SYNTAX](https://github.com/m2ym/cl-syntax)\n* [function-cache](https://github.com/AccelerationNet/function-cache)\n\n## Author\n\n* Eitaro Fukamachi (e.arrows@gmail.com)\n\n## Copyright\n\nCopyright (c) 2014 Eitaro Fukamachi (e.arrows@gmail.com)\n\n# License\n\nLicensed under the BSD 3-Clause License.\n","funding_links":[],"categories":["Expert Systems"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffukamachi%2Fdatafly","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffukamachi%2Fdatafly","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffukamachi%2Fdatafly/lists"}