{"id":16064404,"url":"https://github.com/ashercn97/funsies","last_synced_at":"2025-03-18T05:30:38.775Z","repository":{"id":257812620,"uuid":"867729991","full_name":"ashercn97/funsies","owner":"ashercn97","description":"A fun ORM for the Gleam language! DEPRECATED. CHECK OUT https://github.com/ashercn97/ormlette","archived":false,"fork":false,"pushed_at":"2024-10-13T21:23:47.000Z","size":72,"stargazers_count":13,"open_issues_count":2,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-16T17:12:53.092Z","etag":null,"topics":["database","db","dsl","gleam","gleam-lang","object-relational-mapping","orm","postgres","postgresql","query-builder","querydsl","sql"],"latest_commit_sha":null,"homepage":"https://hexdocs.pm/funsies/index.html","language":"Gleam","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ashercn97.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2024-10-04T15:55:03.000Z","updated_at":"2025-03-14T14:51:27.000Z","dependencies_parsed_at":null,"dependency_job_id":"2f5ecf53-cd7b-492e-aa51-cd86d5d7efcd","html_url":"https://github.com/ashercn97/funsies","commit_stats":{"total_commits":22,"total_committers":1,"mean_commits":22.0,"dds":0.0,"last_synced_commit":"d3542868544618a98353c510f71fcf4062f0f952"},"previous_names":["ashercn97/funsies"],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ashercn97%2Ffunsies","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ashercn97%2Ffunsies/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ashercn97%2Ffunsies/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ashercn97%2Ffunsies/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ashercn97","download_url":"https://codeload.github.com/ashercn97/funsies/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244164580,"owners_count":20408955,"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","db","dsl","gleam","gleam-lang","object-relational-mapping","orm","postgres","postgresql","query-builder","querydsl","sql"],"created_at":"2024-10-09T05:07:10.641Z","updated_at":"2025-03-18T05:30:38.769Z","avatar_url":"https://github.com/ashercn97.png","language":"Gleam","readme":"# Funsies\n\n\u003e[!IMPORTANT]\n\u003eTHIS IS DEPRECATED. Check out [ormlette!](https://github.com/ashercn97/ormlette)\n\n\n\u003e A fun, friendly, and type-safe in-betweensies-ORM for Gleam! Compose type-safe SQL queries, generate decoders and types from schemas, and with a fun CLI!\n\nFull type-safety derived from your schema.\n\n## About\n\nFunsies is a fully type-safe in-betweensies-ORM (?) for Gleam. Obviously, there are other database tools for Gleam. But, I found that most of them felt too barebones for my taste. So, I built the library of my dreams.\n\nFunsies comes with a DSL for schema creation (these schemas are used throughout the rest of the package), a DSL for building queries (with an innovative, stack-based approach), and a CLI for generating boilerplate code from your schemas. All in one, simple package.\n\nThe schema allows for type checking, meaning the following will always be true:\n\n- You will not create a query asking for a column of type X to be equal to a value of type Y.\n- You will not insert values in the wrong order, or with the wrong types.\n- It will be pretty tough to make invalid queries.\n\n## Installation\n\n```bash\ngleam add funsies\n```\n\n## Usage\n\n\u003e THIS PART OF THE DOCS IS IN PROGRESSSSSSS\n\nTo define a schema, create a `schema` folder in your `src` directory. Then, create a `{name}.gleam` file in there, where `{name}` is the name of the schema you're creating. For example, I'd create a `user.gleam` file with the following inside of it:\n\n```gleam\npub fn user() {\n  schema.create_table(\"user\")\n  |\u003e schema.add_serial_column(\"id\")\n  |\u003e schema.add_string_column(\"name\", 255)\n  |\u003e schema.add_bool_column(\"is_active\")\n}\n```\n\nThis is where the magic happens! This schema is the brains of your application. It tells Funsies how to create queries, type-check them, and generate pitch-perfect decoders. All with this little, **reusable** definition.\n\nTo create the necessary types and decoders, run the following command:\n\n```bash\ngleam run -m funsies\n```\n\nAnd thats it! You will now have decoders and types for your schema, as well as an `insert` command that is type-safe and ensures you are passing the correct values in the correct order. The decoders are used from the postgres driver to decode the results of your queries into the generated types. That way, you get easy-to-work-with and type-safe data.\n\n\u003e The ORM/query builder is a work in progress. Below is what we CURRENTLY have.\n\nTo create a query, you can use the `yummy` DSL.\n\nFor example:\n\n```gleam\nimport funsies/query/yummy as y\nimport schema/users\nimport gleam/io.{debug}\n\npub fn main() {\n  let table = users.users()\n\n  let query =y.new(table)\n  |\u003e y.select()\n  |\u003e y.where(\n    y.wb(table)\n    |\u003e y.equals(\"name\", \"Alice\")\n    |\u003e y.not()\n    |\u003e y.equals(\"id\", 4)\n    |\u003e y.and()\n    |\u003e y.equals(\"id\", 5)\n    |\u003e y.or()\n  )\n  |\u003e y.to_sql()\n\n  case query {\n    Ok(sql) =\u003e debug(sql)\n    Error(_) =\u003e debug(\"Error!\")\n  }\n}\n```\n\nThis might look a bit weird at first. Don't worry! It is natural. Instead of usual composition of functions, we use a stack-based DSL. This allows for a neater, more readable syntax. This yummy query would look like this in a more traditional DSL:\n\n```gleam\ny.or(y.and(y.not(y.equals(\"name\", \"Alice\")), y.equals(\"id\", 4)), y.equals(\"id\", 5))\n```\n\nNow, you might see the issue with this \"traditional\" syntax. It is HARD. TO. READ! Why have an ugly syntax in such a beautiful language?\n\nSo, we use the stack-based DSL. It may take a bit of getting used to, but it's worth it!\n\nThere are other benefits to our DSL. For example, we have full type-safety. This is because we use the types directly in the DSL to build the query. This means that if you try to add a `String` where a `Bool` is expected, the type-checker will catch it. By expected I mean the type of the column that you are referencing (EVEN THOUGH YOU ARE JUST PASSING A STRING! Magic of the schema :D)\n\nThis could look like:\n\n```gleam\n|\u003e y.equals(\"name\", 1) // Error, 1 is not a string. It knows that the name value of the column is a string, so it can't be compared to an int.\n|\u003e y.equals(\"is_active\", \"true\") // Error, \"true\" is not a bool\n```\n\nThis will be propogated throughout, and you will get an `Error` value for the query instead of an `Ok` value.\n\nWhile you can still make invalid queries with the yummy DSL, you will not be able to make some common errors (i.e. passing the wrong type of value). This is because funsies checks the schema, sees that the column named \"name\" is a `String` column, and also sees that you are trying to pass an `Int` to an `equals`. Thus, it will return an error! Pretty cool if I do say so myself 🤓\n\nYou can also insert values!\n\nSince you have a Schema, Funsies can generate type-safe insert functions for you! All you have to do is import `insert` from the `funs` (the folder with all the outputs from the codegen).\n\n```gleam\nimport funs/insert\nimport funsies/query/yummy as y\nimport schema/users\nimport gleam/io.{debug}\nimport funs/users.{}\n\npub fn main() {\n  let table = users.users()\n\n  let query = y.new(table)\n  |\u003e y.insert(users.UsersRow(\"John\", True)) // This is type-safe!\n  |\u003e y.to_insert_sql()\n\n  case query {\n    Ok(sql) =\u003e debug(sql)\n    Error(_) =\u003e debug(\"Error!\")\n  }\n}\n```\n\nThe reason it has to be generated is because of we want full type-safety + good code completeion and help.\n\n## Why do you say `in-betweensies-ORM`?\n\nI don't think `funsies` is a full-on ORM. I took a lot of inspiration from Ecto in the Phoenix/Elixir ecosystem. I think that it is a lot less bare-bones than some existing alternatives, but not as feature-rich (or heavy and difficult to learn) as a typical, traditional ORM.\n\nI'm not sure what to call it! `in-betweensies-ORM`? `micro-ORM`? `mini-ORM`?\n\n## Contributing\n\nContributions in ANY way are super duper duper appreciated and encouraged! Leaving an issue, starring, or downloading and giving feedback are all amazing.\n\n## Docs\n\nDocs are **in progress**.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fashercn97%2Ffunsies","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fashercn97%2Ffunsies","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fashercn97%2Ffunsies/lists"}