{"id":24367806,"url":"https://github.com/piisalie/sql_capsule","last_synced_at":"2025-04-10T16:05:48.159Z","repository":{"id":56896727,"uuid":"46829443","full_name":"piisalie/sql_capsule","owner":"piisalie","description":"Less ORM, more SQL","archived":false,"fork":false,"pushed_at":"2015-11-26T12:43:12.000Z","size":45,"stargazers_count":27,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-24T13:51:17.542Z","etag":null,"topics":["database","orm","ruby","sql","wrapper"],"latest_commit_sha":null,"homepage":"","language":"Ruby","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/piisalie.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-11-25T01:24:01.000Z","updated_at":"2024-01-22T13:43:22.000Z","dependencies_parsed_at":"2022-08-21T00:50:57.394Z","dependency_job_id":null,"html_url":"https://github.com/piisalie/sql_capsule","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/piisalie%2Fsql_capsule","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/piisalie%2Fsql_capsule/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/piisalie%2Fsql_capsule/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/piisalie%2Fsql_capsule/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/piisalie","download_url":"https://codeload.github.com/piisalie/sql_capsule/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248250744,"owners_count":21072682,"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","orm","ruby","sql","wrapper"],"created_at":"2025-01-19T02:55:12.177Z","updated_at":"2025-04-10T16:05:48.137Z","avatar_url":"https://github.com/piisalie.png","language":"Ruby","readme":"# SQLCapsule\n\nSQLCapsule is the culmination of many of my thoughts and concerns surrounding ORMs and how\nwe use Ruby to interact with databases. The goal is to be a small and easy to understand\ntool to help you talk to your database without the baggage of a using a full fledged ORM.\nSQLCapsule is reminiscent of the repository pattern (though you may use it however you like)\nand works by registering and naming SQL queries for later use.\n\nSQLCapsule aims to provide helpful errors, and to assist you along the way to building\nan application specific PostgreSQL interaction layer.\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem 'sql_capsule'\n```\n\nAnd then execute:\n\n    $ bundle\n\nOr install it yourself as:\n\n    $ gem install sql_capsule\n\n## Usage\n\nInitialize a wrapper using a PG connection object:\n```ruby\nuser_database = SQLCapsule.wrap(pg_connection)\n```\n\nOnce you have a wrapper you can register bits of SQL. The method\nsignature is: `query_name, raw_sql, *arguments`\n\n```ruby\nquery = \"SELECT * FROM users_table WHERE id = $1;\"\nuser_database.register(:find_user, query, :id)\n```\n\nIf you try and register a SQL statement using `$1` without defining an\nargument name it will raise an error.\n\n```ruby\nuser_database.register :find_user, \"SELECT * FROM users WHERE id = $1;\"\n  # SQLCapsule::Query::ArgumentCountMismatchError: Argument count mismatch\n  # 0 arguments provided for\n  # SQL: SELECT * FROM users WHERE id = $1;\n  # Args:[]\n```\n\nLikewise, if you try and register an argument without defining\nits use within the SQL it will also raise an error.\n\n```ruby\nuser_database.register :find_user, \"SELECT * FROM users;\", :id\n  # SQLCapsule::Query::ArgumentCountMismatchError: Argument count mismatch\n  # 1 arguments provided for\n  # SQL: SELECT * FROM users;\n  # Args:[:id]\n```\n\nArguments are used in order, so if you register `:id, :name` then `$1` will\ncorrespond with `:id` and `$2` will correspond with `:name`. SQLCapsule does\nnot attempt to verify your numbering. :-)\n\nIt is also possible to register a query with a block to handle the resulting rows:\n\n```ruby\nquery = \"SELECT * FROM users_table WHERE id = $1;\", :id\nuser_database.register(:find_user, query, :id) { |row| row.merge('preprocessed' =\u003e true) }\nuser_database.run(:find_user, id: 1) =\u003e [ { 'name' =\u003e 'John', 'age' =\u003e 20, 'id' =\u003e 3, 'preprocessed' =\u003e true} ]\n```\n\nAny registered query can be called like:\n```ruby\nuser_database.run :find_user, id: 3  # =\u003e [ { 'name' =\u003e 'John', 'age' =\u003e 20, 'id' =\u003e 3 } ]\n```\n\nOr with a block:\n```ruby\nuser_database.run(:find_user, id: 3) { |user| user.merge('loaded' =\u003e true) }\n  # =\u003e [ { 'name' =\u003e 'John', 'age' =\u003e 20, 'id' =\u003e 3, 'loaded' =\u003e true } ]\n```\n\nRun checks for required keywords when called and will throw an error if missing one:\n```ruby\nuser_database.run :find_user\n  # =\u003e SQLCapsule::QueryGroup::MissingKeywordArgumentError: Missing query argument: id\n```\n\nThe result of a query will return in the form of an array of hashes, where each item in\nthe array corresponds to result row, and key/value pairs in the hash correspond with\ncolumn/value pairs in a resulting row.\n\n```ruby\nuser_database.register :find_adult_users, \"SELECT * FROM users WHERE age \u003e= 18;\"\nuser_database.run :find_adult_users  # =\u003e [ { 'name' =\u003e 'John', 'age' =\u003e 20 }, { 'name' =\u003e  'Anne', 'age' =\u003e  23 } ]\n```\n\n### Complex Queries\n\nOne thing about SQL and relational databases is that returning tables with identical\ncolumn names is a perfectly normal and sane thing to do. SQLCapsule enforces the use\nof `AS` to alias column names and will raise an error when duplicate column names result\nfrom a query (like a join)\n\n```ruby\nquery = 'SELECT * FROM widgets LEFT JOIN orders on widgets.id=orders.widget_id;'\nwidget_database.register :join_widgets, query\nwidget_database.run :join_widgets\n  # SQLCapsule::Wrapper::DuplicateColumnNamesError: Error duplicate column names in resulting table: [\"name\", \"price\", \"id\", \"widget_id\", \"amount\", \"id\"]\n  # This usually happens when using a `JOIN` with a `SELECT *`\n  # You may need use `AS` to name your columns.\n  # QUERY: SELECT * FROM widgets LEFT JOIN orders on widgets.id=orders.widget_id;\n```\n\n## Development\n\nAfter checking out the repo, run `bin/setup` to install dependencies / setup the testing database. Then, run `rake test` to run the tests.\n\nYou can also run `bin/console` for an interactive prompt that will allow you to experiment. Once in the console `@wrapper` is already setup for use and includes a registered query:\n`@wrapper.run :all_widgets`\n\nTo install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).\n\n## Contributing\n\nBug reports and pull requests are welcome on GitHub at https://github.com/piisalie/sql_capsule. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](contributor-covenant.org) code of conduct.\n\n\n## License\n\nThe gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpiisalie%2Fsql_capsule","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpiisalie%2Fsql_capsule","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpiisalie%2Fsql_capsule/lists"}