{"id":22350950,"url":"https://github.com/johnae/relativity","last_synced_at":"2025-03-26T11:45:14.115Z","repository":{"id":136753638,"uuid":"64300516","full_name":"johnae/relativity","owner":"johnae","description":"Relativity is Arel for Moonscript/Lua","archived":false,"fork":false,"pushed_at":"2017-07-07T13:50:01.000Z","size":112,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-01-31T13:12:51.228Z","etag":null,"topics":["arel","lua","moonscript","relational-algebra"],"latest_commit_sha":null,"homepage":null,"language":"MoonScript","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/johnae.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":"2016-07-27T10:43:55.000Z","updated_at":"2022-05-14T18:47:10.000Z","dependencies_parsed_at":null,"dependency_job_id":"8b3d1fa7-8e15-4b04-b32a-932c44825fdb","html_url":"https://github.com/johnae/relativity","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/johnae%2Frelativity","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnae%2Frelativity/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnae%2Frelativity/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnae%2Frelativity/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/johnae","download_url":"https://codeload.github.com/johnae/relativity/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245650205,"owners_count":20650098,"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":["arel","lua","moonscript","relational-algebra"],"created_at":"2024-12-04T12:11:54.341Z","updated_at":"2025-03-26T11:45:14.086Z","avatar_url":"https://github.com/johnae.png","language":"MoonScript","readme":"[![CircleCI](https://circleci.com/gh/johnae/relativity.svg?style=svg)](https://circleci.com/gh/johnae/relativity)\n\n# Relativity\n\nhttps://github.com/johnae/relativity\n\nCurrently I'd say this is a bit experimental and while quite extensive I have yet to actually use it the way I thought I might. Hopefully someone finds it\ninteresting.\n\n## Description\n\nFirst off - this is a bit __raw__ and may need a bit of redesign (perhaps more Luaisms in places if possible). It should be usable however.\n\nRelativity is sort of [arel](https://github.com/rails/arel) but for [MoonScript](http://moonscript.org) and [Lua](https://www.lua.org). As far as I know there is nothing like it (other than this) for Lua/MoonScript. This project owes alot to Rubys Arel and also to the nodejs project called [rel](https://github.com/yang/rel). It also shares some caveats with that project, namely:\n\n* No database connections, it only builds queries.\n* Where Ruby can do funky stuff, Lua sometimes can. When possible\n  Lua-isms are used, otherwise it's a method/function (well - it probably is anyway behind the scenes).\n\nThe point of this (as with arel) is to ease the generation of complex SQL queries. This does NOT adapt to different RDBMS systems (yet at least). I only care about Postgres. Shouldn't be that difficult to extend though.\n\nThis could be used to create an ORM just like Arel is the ActiveRecord enabler in many ways. I might do something like this later.\n\n## Lua compatibility\n\nTo be honest, I'm only sure that this works properly with [LuaJIT 2.x+](http://luajit.org/). It should work with other Lua implementations too however - but I haven't tried. The CircleCI tests run on LuaJIT. The reason is that I'm only interested in LuaJIT (and OpenResty). Please test and help out if you feel like it.\n\n## Performance\n\nQuery generation hasn't been benchmarked __at all__. I don't know whether there's a bottleneck, memory issue or something else hiding. I think there may be performance gains in increasing the amount of local use - a well known optimization for Lua. I'll hold off on any such optimizations until it's clear that they'd help.\n\n## Classes\n\nThis library is using my take on a class implementation for MoonScript: [Classy](https://github.com/johnae/classy).\n\n## Usage\n\nSee spec/relativity/integration_spec.moon for more examples.\n\n```moonscript\n    users = Relativity.table 'users'\n    users\\project(Relativity.star)\\to_sql!\n```\n\nGenerates\n\n```sql\n    SELECT * FROM \"users\"\n```\n\n### More advanced queries\n```moonscript\n    users\\where(users'name'\\eq'Einstein')\\to_sql!\n```\n\nGenerates\n```sql\n    SELECT * FROM \"users\"\n    WHERE \"users\".\"name\" = 'Einstein'\n```\n\nThe selection in SQL contains what you want from the database, this is called\na __projection__.\n\n```moonscript\n    users\\project users'id' -- =\u003e SELECT \"users\".\"id\" FROM \"users\"\n```\n\nJoins look like this:\n\n```moonscript\n    users\\join(photos)\\on users'id'\\eq photos'user_id'\n    -- =\u003e SELECT * FROM \"users\" INNER JOIN \"photos\" ON \"users\".\"id\" = \"photos\".\"user_id\"\n```\n\nNote that some of the above is taking advantage of MoonScript allowing to skip the parentheses in certain instances. Eg. this:\n\n```moonscript\nusers'id'\\eq photos'user_id'\n```\n\nCan also be written like:\n\n```moonscript\nusers('id')\\eq(photos('user_id'))\n```\n\nIt doesn't matter but I just figured I'd point out that these are function calls.\n\n\nLimit and offset are called __take__ and __skip__:\n\n```moonscript\n    users\\take 5 -- =\u003e SELECT * FROM \"users\" LIMIT 5\n    users\\skip 4 -- =\u003e SELECT * FROM \"users\" OFFSET 4\n```\n\nGROUP BY is called __group__:\n\n```moonscript\n    users\\group users'name' -- =\u003e SELECT * FROM \"users\" GROUP BY \"users\".\"name\"\n```\n\nAll operators are chainable:\n\n```moonscript\n    users\\where(users'name'\\eq'ricky')\\project users'id'\n    -- =\u003e SELECT \"users\".\"id\" FROM \"users\" WHERE \"users\".\"name\" = 'ricky'\n```\n\n```moonscript\n    users\\where(users'name'\\eq'linus')\\where users'age'\\lt 25\n```\n\nMultiple arguments can be given too:\n\n```moonscript\n    users\\where users'name'\\eq'linus', users'age'\\lt 25\n```\n\nOR works like this:\n\n```moonscript\n    users\\where users'name'\\eq'linus'\\Or users'age'\\lt 25\n```\n\nUnfortunately 'or' is a reserved keyword in MoonScript/Lua and cannot be used. For now I've resorted to title case for these. It's ugly i.m.o. Therefore I've (for now) also added LPeg:ish operators. If you don't know LPeg, you can read more about it here: http://www.inf.puc-rio.br/~roberto/lpeg/.\n\nSo OR can also be written like this:\n\n```moonscript\n    users\\where users'name'\\eq'linus' + users'age'\\lt 25\n```\n\nAS works in a similar fashion but is lowercased since it isn't reserved:\n\n```moonscript\n    users\\project users'id'\\as 'user_id' -- =\u003e SELECT \"users\".\"id\" AS \"user_id\" FROM \"users\"\n```\n\nAND has the same problem as OR and must be written in title case or, as above, using an LPeg:ish operator - like this:\n\n```moonscript\n    users\\where users'name'\\eq'linus' * users'age'\\lt 25\n```\n\nAnd is less often used since it's assumed in a where.\n\nThere's also Not which is a reserved keyword, but that has been made into a getter which can be used lowercase. For now both\nof the below do the same thing:\n\nUsing title case:\n\n```moonscript\nusers\\where users'id'\\eq(10).not\n```\n\nOr lpeg:ish\n\n```moonscript\nusers\\where -users'id'\\eq 10\n```\n\nBoth generate this:\n\n```SQL\nSELECT FROM \"users\"\nWHERE NOT (\"users\".\"id\" = 10)\n```\n\n\nSince I mostly care about Postgres, more advanced queries (Postgres specific) are possible, such as:\n\n```moonscript\nRelativity = require 'relativity'\nNodes = Relativity.Nodes\nusers = Relativity.table 'users'\nothers = Relativity.table 'others'\n\nany = Relativity.func 'ANY'\ncoalesce = Relativity.func 'COALESCE'\narray_agg = Relativity.func 'array_agg'\njson_build_object = Relativity.func 'json_build_object'\nto_json = Relativity.func 'to_json'\n\njson_select = Relativity.select!\njson_select\\from others\njson_object = json_build_object 'id', others'id', 'name', others'name'\njson_select\\project array_agg(json_object)\\as 'list'\njson_select\\where others'id'\\eq any users'things'\njson_select = Relativity.alias json_select, 'things'\n\nthings = to_json(Relativity.table'things''list')\\as 'things'\nuser_employer = coalesce(users'employer', 'none')\\as 'employer'\n\nu = users\\project users.star, user_employer, things\nu\\join(json_select, Nodes.InnerJoinLateral)\\on true\nu\\where users'name'\\like '%berg%'\n```\n\nGenerates (via calling \\to_sql! on the relation of course):\n\n```SQL\nSELECT \"users\".*,\n       COALESCE(\"users\".\"employer\", 'none') AS \"employer\",\n       to_json(\"things\".\"list\") AS \"things\"\nFROM \"users\"\nINNER JOIN LATERAL (\n  SELECT array_agg(json_build_object('id', \"others\".\"id\", 'name', \"others\".\"name\")) AS \"list\"\n  FROM \"others\"\n  WHERE \"others\".\"id\" = ANY(\"users\".\"things\")\n) \"things\" ON 't'\nWHERE \"users\".\"name\" LIKE '%berg%'\n```\n\n\n## Development\n\nRunning the tests requires busted https://github.com/Olivine-Labs/busted and luassert https://github.com/Olivine-Labs/luassert.\nSince luassert comes with busted, only busted needs to be installed really. It also requires that moonscript is installed.\n\nOn Ubuntu you might go about it like this:\n\n```shell\nsudo apt-get install luarocks luajit\nsudo luarocks install busted\nsudo luarocks install moonscript\n```\n\nTo run the specs, run `busted spec`.\n\n\n## Contributing\n\nI appreciate all feedback and help. If there's a problem, create an issue or pull request. Thanks!\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohnae%2Frelativity","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjohnae%2Frelativity","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohnae%2Frelativity/lists"}