{"id":13646774,"url":"https://github.com/KMahoney/squee","last_synced_at":"2025-04-21T21:31:25.168Z","repository":{"id":66851572,"uuid":"242522602","full_name":"KMahoney/squee","owner":"KMahoney","description":"A Typed, Composable Database Query Language","archived":false,"fork":false,"pushed_at":"2021-03-13T15:12:50.000Z","size":96,"stargazers_count":104,"open_issues_count":0,"forks_count":1,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-08-02T01:26:24.618Z","etag":null,"topics":["database","experimental","language"],"latest_commit_sha":null,"homepage":null,"language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/KMahoney.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-02-23T13:32:04.000Z","updated_at":"2024-02-02T16:04:43.000Z","dependencies_parsed_at":"2023-02-21T05:00:35.515Z","dependency_job_id":null,"html_url":"https://github.com/KMahoney/squee","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/KMahoney%2Fsquee","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KMahoney%2Fsquee/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KMahoney%2Fsquee/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KMahoney%2Fsquee/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/KMahoney","download_url":"https://codeload.github.com/KMahoney/squee/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223880273,"owners_count":17219094,"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":["database","experimental","language"],"created_at":"2024-08-02T01:03:05.493Z","updated_at":"2024-11-09T20:30:33.169Z","avatar_url":"https://github.com/KMahoney.png","language":"Haskell","funding_links":[],"categories":["Haskell"],"sub_categories":[],"readme":"# Squee: A Typed, Composable Database Query Language\n\n**Squee** is an experimental language that breaks relational queries down in to *composable* functions that can be fully inferred with a few extensions to Hindley Milner. It compiles to SQL and so can be used with relational databases.\n\n**WARNING**: Squee is **EXPERIMENTAL** and **INCOMPLETE**. Don't use this for anything important!\n\n## Docs\n\n* [The Language in Detail](docs/language.md)\n* [The Command Line](docs/cli.md)\n\n## Rationale\n\nAs much as I love languages with a good type system, integrating types with relational querying is often a weak point. It can be complicated, clunky, and result in poor error messages.\n\nSquee's type system has been designed to handle relational concepts and give good, understandable error messages (WIP - error messages are currently terrible).\n\nUnlike SQL, Squee breaks queries down in to composable parts so you can define and re-use joins, maps and filters across your code.\n\n## Some Quick Examples\n\nGiven a PostgreSQL database with the following definition:\n\n```sql\nCREATE TABLE example (a int not null, b text not null);\nINSERT INTO example VALUES (1, 'example1'), (2, 'example2');\n\nCREATE TABLE join_example (a int not null, c text not null);\nINSERT INTO join_example VALUES (1, 'join_example1'), (2, 'join_example2');\n```\n\nSquee will introspect the database and make tables available:\n\n```\nSQUEE\u003e example\n\n: [{a: ~int4, b: ~text}]\n\n| a | b        |\n+---+----------+\n| 1 | example1 |\n| 2 | example2 |\n\nSQUEE\u003e join_example\n\n: [{a: ~int4, c: ~text}]\n\n| a | c             |\n+---+---------------+\n| 1 | join_example1 |\n| 2 | join_example2 |\n```\n\nQueries can be built out of `map`, `filter`, `order`, `natjoin`, `join` and `aggregate`:\n\n* `map : ({α} → {β}) → [{α}] → [{β}]`\n* `filter : ({α} → ~bool) → [{α}] → [{α}]`\n* `order : (Comparable β) ⇒ ({α} → β) → [{α}] → [{α}]`\n* `natjoin : ({γ} = {α} ⋈ {β}) ⇒ [{α}] → [{β}] → [{γ}]`\n* `join : ({α} → {β} → ~bool) → ({α} → {β} → {γ}) → [{α}] → [{β}] → [{γ}]`\n* `aggregate : ({β} = Agg {γ}) ⇒ ({α} → {β}) → [{α}] → [{γ}]`\n\nThe types are explained in the [language docs](docs/language.md).\n\nThe filter function can be abstracted and used in multiple queries:\n\n```\nSQUEE\u003e example | filter (\\t -\u003e t.a = 1)\n\n: [{a: ~int4, b: ~text}]\n\n| a | b        |\n+---+----------+\n| 1 | example1 |\n\nSQUEE\u003e def filterA1 := filter (\\t -\u003e t.a = 1)\n\nfilterA1 : [{a: ~int4, ..α}] → [{a: ~int4, ..α}]\n\nSQUEE\u003e filterA1 example\n\n: [{a: ~int4, b: ~text}]\n\n| a | b        |\n+---+----------+\n| 1 | example1 |\n\nSQUEE\u003e filterA1 join_example\n\n: [{a: ~int4, c: ~text}]\n\n| a | c             |\n+---+---------------+\n| 1 | join_example1 |\n```\n\nas well as the natjoin function:\n\n```\nSQUEE\u003e example | natjoin join_example\n\n: [{a: ~int4, b: ~text, c: ~text}]\n\n| a | b        | c             |\n+---+----------+---------------+\n| 1 | example1 | join_example1 |\n| 2 | example2 | join_example2 |\n\nSQUEE\u003e def joinExample := natjoin join_example\n\njoinExample : ({β} = {a: ~int4, c: ~text} ⋈ {α}) ⇒ [{α}] → [{β}]\n\nSQUEE\u003e example | filterA1 | joinExample\n\n: [{a: ~int4, b: ~text, c: ~text}]\n\n| a | b        | c             |\n+---+----------+---------------+\n| 1 | example1 | join_example1 |\n```\n\nThe queries can be exported to other languages.\n\nGiven the file `example.squee`:\n```\nexport exportedExample := example\nexport filteredExportedExample a := example | filter (\\t -\u003e t.a = a)\n```\n\nThe command `squee generate sql-prepare example.squee` will generate:\n\n```sql\nPREPARE exportedExample AS\n  SELECT \"a\",\"b\" FROM \"example\" AS _t;\n\nPREPARE filteredExportedExample AS\n  SELECT \"a\",\"b\" FROM \"example\" AS _t WHERE (\"a\") = ($1);\n```\n\nSince Squee is fully type inferred, it can also generate templates for languages that require type annotations:\n\n`squee generate hs-postgresql-simple example.squee`:\n\n```haskell\nexportedExample :: Connection -\u003e IO [(Int, String)]\nexportedExample connection = do\n  query_ connection \"SELECT \\\"a\\\",\\\"b\\\" FROM \\\"example\\\" AS _t\"\n\nfilteredExportedExample :: Connection -\u003e Int -\u003e IO [(Int, String)]\nfilteredExportedExample connection a = do\n  query connection \"SELECT \\\"a\\\",\\\"b\\\" FROM \\\"example\\\" AS _t WHERE (\\\"a\\\") = (?)\" (Only a)\n```\n\n## Installation\n\nRequirements:\n\n- [Stack](https://docs.haskellstack.org/en/stable/README/#how-to-install)\n- PostgreSQL development libraries (e.g. on Debian/Ubuntu: `apt install libpq-dev`)\n- ncurses development libraries (e.g. on Debian/Ubuntu: `apt install libtinfo-dev`)\n\nClone the repo, and then `stack install`.\n\n## Notes and Limitations\n\n* Squee doesn't currently handle nulls or nullable fields.\n* Rows have a flat namespace, as opposed to SQL's qualified field names i.e. `table.column`. A row cannot have duplicate field names because there's no way to disambiguate them.\n* Very few SQL operators/functions are currently available.\n* Only natural and inner joins are currently available. Left/right joins require null handling.\n* The error reporting is currently poor, but quality error reporting is a long-term goal of the project.\n\n## Interesting Links\n\n* [The Links Programming Language](https://links-lang.org/)\n* [The Ur/Web Programming Language](http://impredicative.com/ur/)\n* [LINQ](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/linq/)\n\n* [Generalizing Hindley-Milner Type Inference Algorithms](https://www.researchgate.net/publication/2528716_Generalizing_Hindley-Milner_Type_Inference_Algorithms)\n* [Row-based Effect Types for Database Integration](http://homepages.inf.ed.ac.uk/slindley/papers/corelinks.pdf)\n\nIf you know of any similar projects not listed here, please let me know!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FKMahoney%2Fsquee","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FKMahoney%2Fsquee","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FKMahoney%2Fsquee/lists"}