{"id":23626304,"url":"https://github.com/yetanalytics/flint","last_synced_at":"2025-04-05T11:09:51.537Z","repository":{"id":42518407,"uuid":"443116919","full_name":"yetanalytics/flint","owner":"yetanalytics","description":"SPARQL DSL library for Clojure(Script)","archived":false,"fork":false,"pushed_at":"2025-01-13T20:40:16.000Z","size":728,"stargazers_count":56,"open_issues_count":0,"forks_count":5,"subscribers_count":8,"default_branch":"main","last_synced_at":"2025-03-29T10:08:21.698Z","etag":null,"topics":["clojure","clojurescript","dsl","rdf","sparql"],"latest_commit_sha":null,"homepage":"https://cljdoc.org/d/com.yetanalytics/flint/","language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yetanalytics.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","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":"2021-12-30T15:42:55.000Z","updated_at":"2025-01-24T13:36:53.000Z","dependencies_parsed_at":"2024-02-09T17:51:47.820Z","dependency_job_id":"f341e94a-c772-46aa-a819-623cf796ee49","html_url":"https://github.com/yetanalytics/flint","commit_stats":{"total_commits":331,"total_committers":2,"mean_commits":165.5,"dds":"0.015105740181268867","last_synced_commit":"ae637f7483d7cffff85abfd81dd2bcb464d1fcea"},"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yetanalytics%2Fflint","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yetanalytics%2Fflint/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yetanalytics%2Fflint/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yetanalytics%2Fflint/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yetanalytics","download_url":"https://codeload.github.com/yetanalytics/flint/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247325693,"owners_count":20920714,"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":["clojure","clojurescript","dsl","rdf","sparql"],"created_at":"2024-12-27T22:52:53.057Z","updated_at":"2025-04-05T11:09:51.520Z","avatar_url":"https://github.com/yetanalytics.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"# flint\n\n\u003cimg src=\"logo/logo.svg\" alt=\"Flint Logo\" width=\"250px\"/\u003e\n\n[![CI](https://github.com/yetanalytics/flint/actions/workflows/test.yml/badge.svg)](https://github.com/yetanalytics/flint/actions/workflows/test.yml)\n[![Clojars Project](https://img.shields.io/clojars/v/com.yetanalytics/flint.svg)](https://clojars.org/com.yetanalytics/flint)\n[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-5e0b73.svg)](CODE_OF_CONDUCT.md)\n\n_The fire i' the flint shows not till it be struck_\n\\- William Shakespeare, _Timon of Athens_, Act I, Scene 1\n\nA Clojure(Script) DSL for creating SPARQL query and update strings.\n\nIf you are using Apache Jena, check out the [flint-jena](https://github.com/yetanalytics/flint-jena) companion library.\n\n## Installation\n\nAdd the following to your `deps.edn` map.\n\n```clojure\ncom.yetanalytics/flint {:mvn/version \"0.3.0\"\n                        :exclusions [org.clojure/clojure\n                                     org.clojure/clojurescript]}\n```\n\nSee [Clojars](https://clojars.org/com.yetanalytics/flint) for installation using Leiningen, Boot, etc; do not forget to adapt `:exclusions` to your method.\n\n## Outline\n\nDocumentation is also available on [cljdoc](https://cljdoc.org/d/com.yetanalytics/flint).\n\n- Queries and Updates\n  - [Queries](doc/query.md)\n  - [Updates](doc/update.md)\n- Clauses and Subforms\n  - [Graph IRIs](doc/graph.md)\n  - [Graph Patterns](doc/where.md)\n  - [Modifiers](doc/modifier.md)\n  - [Prologue](doc/prologue.md)\n- [Expressions](doc/expr.md)\n- [Triples](doc/triple.md)\n- [RDF Terms](doc/axiom.md)\n\n## API\n\nThree functions exist in the Flint API:\n- `format-query`\n- `format-update`\n- `format-updates`\n\nThe first two functions format a single SPARQL query or update, respectively, while the third formats a collection of SPARQL updates into a single update string.\n\nEach function takes in the following keyword arguments:\n\n| Argument       | Description |\n| ---            | --- |\n| `:pretty?`     | If `true`, adds line breaks and indentation to the resulting SPARQL string. Default `false`.\n| `:validate?`   | If `true`, validates that prefixed IRIs are expandable and that certain restrictions on variables and blank nodes are met. Default `true`.\n| `:spec-ed?`    | If `true`, let the exception data map be the spec error data map (i.e. with `::s/problems`) upon conformance failure, instead of Flint's default error map. Spec error data maps can get quite large, hence this is default `false`.\n| `:force-iris?` | If `true`, let all literals be formatted with their datatype IRIs (e.g. `\u003chttp://www.w3.org/2001/XMLSchema#string\u003e` for string literals); if `false` (the default), then string, numeric, and boolean literals will not have such IRIs appended. Language-tagged literals will never have an appended datatype IRI.\n\n## Examples\n\nThe following is a simple query that queries the name of the author who wrote the popular manga series [Attack on Titan](https://en.wikipedia.org/wiki/Attack_on_Titan):\n```clojure\n(def query\n  '{:prefixes {:dc \"\u003chttp://purl.org/dc/elements/1.1/\u003e\"}\n    :select   [?author]\n    :where    [[?aot :dc/title \"Attack on Titan\"]\n               [?aot :dc/creator ?author]]})\n```\nNote that the map needs to be quoted due to the presence of symbols in the map. We can then pass the query to the function `format-query`:\n```clojure\n(require '[com.yetanalytics.flint :as f])\n\n(f/format-query query :pretty? true)\n```\nand it will return a SPARQL string:\n```sparql\nPREFIX dc: \u003chttp://purl.org/dc/elements/1.1/\u003e\nSELECT ?author\nWHERE {\n    ?aot dc:title \"Attack on Titan\" .\n    ?aot dc:creator ?author .\n}\n```\nOne can then pass this query string to a Resource Description Framework (RDF) database and, depending on the data in the system, should return that `?author` is [Hajime Isayama](https://en.wikipedia.org/wiki/Hajime_Isayama).\n\nThe following is a more comprehensive example - a query that looks for the publisher of Attack on Titan, then returns the titles of all the works it published in 2010 or after:\n```clojure\n(def query-2\n  '{:prefixes {:dc  \"\u003chttp://purl.org/dc/elements/1.1/\u003e\"\n               :xsd \"\u003chttp://www.w3.org/2001/XMLSchema#\u003e\"}\n    :select   [?title]\n    :from     [\"\u003chttp://my-anime-rdf-graph.com\u003e\"]\n    :where    [[:union [{_b1 {:dc/title     #{{:en \"Attack on Titan\"}}\n                              :dc/publisher #{?publisher}}}]\n                       [{_b2 {:dc/title     #{{:jp \"進撃の巨人\"}}\n                              :dc/publisher #{?publisher}}}]]\n               {?work {:dc/publisher #{?publisher}\n                       :dc/title     #{?title}\n                       :dc/date      #{?date}}}\n               [:filter (\u003c= #inst \"2010-01-01T00:00:00Z\" ?date)]]})\n```\nwhich demonstrates several additional features, such as an alternate triple syntax using maps instead of vectors, blank nodes, language tags, and the `:union`, `:filter` and `:from` clauses. When passed to `format-query`, it is translated to:\n```sparql\nPREFIX dc:  \u003chttp://purl.org/dc/elements/1.1/\u003e\nPREFIX xsd: \u003chttp://www.w3.org/2001/XMLSchema#\u003e\nSELECT ?title\nFROM \u003chttp://my-anime-rdf-graph.com\u003e\nWHERE {\n    {\n        _:b1 dc:title \"Attack on Titan\"@en ;\n             dc:publisher ?publisher .\n    }\n    UNION\n    {\n        _:b2 dc:title \"進撃の巨人\"@jp ;\n             dc:publisher ?publisher .\n    }\n    ?work dc:publisher ?publisher ;\n          dc:title ?title ;\n          dc:date ?date .\n    FILTER (\"2010-01-01T00:00:00Z\"^^xsd:dateTime \u003c= ?date)\n}\n```\n\n## Prior Art\n- Flint is based off of the grammar of [SPARQL 1.1](https://www.w3.org/TR/sparql11-query/).\n- The idea of a SPARQL DSL was inspired by [HoneySQL](https://github.com/seancorfield/honeysql), a DSL for creating SQL queries.\n- [Matsu](https://github.com/boutros/matsu) is a previous SPARQL DSL implementation that uses an expression-based approach to query construction.\n- Flint borrows certain syntactic conventions from the [Datomic](https://docs.datomic.com/on-prem/query/query.html) and [Asami](https://github.com/threatgrid/asami) query and update languages.\n- The map-based triples syntax is based on the normal form used in the [IGraph protocol](https://github.com/ont-app/igraph).\n\n## License\n\nCopyright © 2022-2025 Yet Analytics, Inc.\n\nDistributed under the Apache License version 2.0.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyetanalytics%2Fflint","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyetanalytics%2Fflint","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyetanalytics%2Fflint/lists"}