{"id":13409021,"url":"https://github.com/exoscale/vinyl","last_synced_at":"2026-02-21T03:32:01.636Z","repository":{"id":37795238,"uuid":"365275250","full_name":"exoscale/vinyl","owner":"exoscale","description":"A Clojure facade for the FoundationDB record-layer","archived":false,"fork":false,"pushed_at":"2025-11-19T16:01:19.000Z","size":161,"stargazers_count":15,"open_issues_count":2,"forks_count":1,"subscribers_count":19,"default_branch":"master","last_synced_at":"2025-11-19T18:04:01.998Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/exoscale.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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2021-05-07T15:22:02.000Z","updated_at":"2025-11-09T15:02:25.000Z","dependencies_parsed_at":"2024-03-18T14:53:21.971Z","dependency_job_id":"079bc40a-4cc6-49cb-9ee6-1f66ce310219","html_url":"https://github.com/exoscale/vinyl","commit_stats":null,"previous_names":[],"tags_count":26,"template":false,"template_full_name":null,"purl":"pkg:github/exoscale/vinyl","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/exoscale%2Fvinyl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/exoscale%2Fvinyl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/exoscale%2Fvinyl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/exoscale%2Fvinyl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/exoscale","download_url":"https://codeload.github.com/exoscale/vinyl/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/exoscale%2Fvinyl/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29672704,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-21T03:11:15.450Z","status":"ssl_error","status_checked_at":"2026-02-21T03:10:34.920Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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-07-30T20:00:57.375Z","updated_at":"2026-02-21T03:32:01.616Z","avatar_url":"https://github.com/exoscale.png","language":"Clojure","funding_links":[],"categories":["Bindings"],"sub_categories":[],"readme":"vinyl: a record store for Clojure\n=================================\n\nVinyl provides a facade for [FoundationDB](https://www.foundationdb.org/)'s\n[record-layer](https://foundationdb.github.io/fdb-record-layer/).\n\nThe intent of the record layer is to provide a protobuf based storage\nengine for indexed records stored in FoundationDB.\n\n## Search queries\n\nQueries in vinyl can be supplied using the following functions:\n\n- `exoscale.vinyl.store/list-query`\n- `exoscale.vinyl.store/execute-query`\n\nA typical query will be executed this way:\n\n``` clojure\n@(store/list-query vinyl-store [:RecordType [:= :field \"value\"]])\n```\n\nBoth `list-query` and `execute-query` accept different arities:\n\n``` clojure\n(list-query store query)\n(list-query store query opts)\n(list-query store query opts values)\n\n(execute-query store query)\n(execute-query store query opts)\n(execute-query store query opts values)\n```\n\nThe `query` argument can either be an instance of `RecordQuery` or a vector,\nin which case a `RecordQuery` will be built from the vector. See\n[Query language](#query-language) for a reference.\n\nThe additional `opts` argument allows supplying options to perform modifications\non the results *inside* the transaction in which the query is executed. See\n[Record cursors](#record-cursors) for details on what can be supplied there.\n\nThe additional `values` argument is a map of bindings to be applied to a\nprepared query where applicable.\n\n## Query language\n\nThe data representation for queries takes the following shape:\n\n``` clojure\n[:RecordType optional-filter]\n```\n\n#### Select all queries\n\nTo select all fields you can provide a single member vector containing\nthe record type:\n\n``` clojure\n[:RecordType] ;; for instance: @(store/list-query store [:RecordType])\n```\n\n#### Field equality\n\nField equality is supported in two ways, if the comparand is anything but\na vector it will be treated as a fixed value:\n\n``` clojure\n@(store/list-query store [:RecordType [:= :id 1234]])\n@(store/list-query store [:RecordType [:= :name \"jane\"]])\n```\n\nIf the comparand is provided as a keyword, a prepared query is built and the\ncorresponding keyword is expected to be found in the query's evaluation context:\n\n``` clojure\n(def my-query (query/build-query :RecordType [:= :user-name :name]))\n@(store/list-query store my-query {} {:name \"jane\"})\n@(store/list-query store my-query {} {:name \"unknown\"})\n```\n\n#### Field set membership\n\nA field can be checked for membership in a set:\n\n``` clojure\n@(store/list-query store [:RecordType [:in :id [10 20 30]]])\n```\n\nPrepared queries are also supported for membership tests:\n\n``` clojure\n(def my-query (query/build-query :RecordType [:= :in :user-name :names]))\n@(store/list-query store my-query {} {:names [\"jane\" \"unknown\"]})\n```\n\n#### Field inequality, null value check, and non null value checks\n\nFields can be checked for values that do not match a fixed comparand. Prepared\nqueries are currently unsupported for the comparand of inequality tests:\n\n``` clojure\n@(store/list-query store [:RecordType [:not= :id 1234]])\n@(store/list-query store [:RecordType [:some? :email]])\n@(store/list-query store [:RecordType [:nil? :purge_date]])\n```\n\n#### Range comparisons\n\nFor values supporting comparisons, range operations are supported:\n\n``` clojure\n@(store/list-query store [:RecordType [:\u003e :id 100]])\n@(store/list-query store [:RecordType [:\u003c :id 100]])\n@(store/list-query store [:RecordType [:\u003e= :id 100]])\n@(store/list-query store [:RecordType [:\u003c= :id 100]])\n```\n\nFor string fields, prefix searches are supported:\n\n``` clojure\n@(store/list-query store [:RecordType [:starts-with? :path \"/usr/local/\"]])\n```\n\n#### Boolean operations\n\nFilters can be composed with boolean operations `:not`, `:or`, `:and`:\n\n``` clojure\n@(store/list-query store [:Rec [:and [:not [:= :id 1]]\n                                     [:or [:\u003e :id 100] [:\u003c :id 50]]]])\n```\n\n#### Nested field matches\n\nSince the FDB record layer supports storing records which contain nested values,\nThere needs to be support for matching those in queries.\n\nSuppose you have the following protobuf definition:\n\n``` protocol-buffer\nmessage Info {\n  string path = 1;\n}\n\nmessage Top {\n   int64 id = 1;\n   Info info = 2;\n}\n```\n\nYou can apply any field query to fields in info by using `:nested`:\n\n``` clojure\n@(store/list-query store [:Top [:nested :info [:starts-with? :path \"/\"]]])\n```\n\n#### Enums\n\nProto3 enum must start at ordinal 0.\nInternally, FDB record layer does not make the difference between\n0 and null and thus 0 will be serialized as null.\n\nWhen defining an enum, you must add a dummy entry that you must never use.\n\n``` protocol-buffer\n enum Payment {\n    INVALID = 0; # This value must not be used\n    PREPAID = 1;\n    POSTPAID = 2;\n }\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fexoscale%2Fvinyl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fexoscale%2Fvinyl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fexoscale%2Fvinyl/lists"}