diff --git a/README.md b/README.md index 1f62eab4..3dde2478 100644 --- a/README.md +++ b/README.md @@ -7,987 +7,78 @@ This project is to provide an ORM in Crystal. [![Build Status](https://img.shields.io/travis/amberframework/granite.svg?maxAge=360)](https://travis-ci.org/amberframework/granite) -## Installation +## Documentation -Add this library to your projects dependencies along with the driver in -your `shard.yml`. This can be used with any framework but was originally -designed to work with the amber framework in mind. This library will work -with kemal or any other framework as well. - -```yaml -dependencies: - granite: - github: amberframework/granite - - # Pick your database - mysql: - github: crystal-lang/crystal-mysql - - sqlite3: - github: crystal-lang/crystal-sqlite3 - - pg: - github: will/crystal-pg - -``` - -Next you will need to create a `config/database.yml` -You can leverage environment variables using `${}` syntax. - -```yaml -mysql: - database: "mysql://username:password@hostname:3306/database_${AMBER_ENV}" -pg: - database: "postgres://username:password@hostname:5432/database" -sqlite: - database: "sqlite3:./config/${DB_NAME}.db" -``` - -Or you can set the `DATABASE_URL` environment variable. This will override the config/database.yml - -## Usage - -Here is an example using Granite Model - -```crystal -require "granite/adapter/mysql" - -class Post < Granite::Base - adapter mysql - field name : String - field body : String - timestamps -end -``` - -```crystal -require "granite/adapter/mysql" - -class Post < Granite::Base - adapter mysql - field name : String - field body : String - timestamps -end - -# There are various ways to instantiate a new object: -namedTuple = Post.new(name: "Name", body: "I am the body") # .new NamedTuple -hash = Post.new({name: "Name", body: "I am the body"}.to_h) # .new Hash -fromJson = Post.from_json(JSON.parse(%({"name": "Name", "body": "I am the body"}))) # .from_json JSON -jsonArray = Array(Post).from_json(JSON.parse(%([{"name": "Post1", "body": "I am the body for post1"},{"name": "Post2", "body": "I am the body for post2"}]))) # .from_json array of JSON - -# Can also use .create to automatically instantiate and save a model -Post.create(name: "First Post", body: "I get saved automatically") # Instantiates and saved the post -``` -**Note: When using `.from_json/.to_json` see [JSON::Serialization](https://crystal-lang.org/api/0.25.1/JSON/Serializable.html) for more details.** - -You can disable the timestamps for SqlLite since TIMESTAMP is not supported for this database: - -```crystal -require "granite/adapter/sqlite" - -class Comment < Granite::Base - adapter sqlite - table_name post_comments - field name : String - field body : String -end -``` - -### id, created_at, updated_at - -The primary key is automatically created for you and if you use `timestamps` they will be -automatically updated for you. - -Here are the MySQL field definitions for id, created_at, updated_at - -```mysql - id BIGINT NOT NULL AUTO_INCREMENT - # Your fields go here - created_at TIMESTAMP - updated_at TIMESTAMP - PRIMARY KEY (id) -``` - -### Custom Primary Key - -For legacy database mappings, you may already have a table and the primary key is not named `id` or `Int64`. - -We have a macro called `primary` to help you out: - -```crystal -class Site < Granite::Base - adapter mysql - primary custom_id : Int32 - field name : String -end -``` - -This will override the default primary key of `id : Int64`. - -#### Natural Keys - -For natural keys, you can set `auto: false` option to disable auto increment insert. - -```crystal -class Site < Granite::Base - adapter mysql - primary code : String, auto: false - field name : String -end -``` - -#### UUIDs - -For databases that utilize UUIDs as the primary key, the `primary` macro can be used again with the `auto: false` option. A `before_create` callback can be added to the model to randomly generate and set a secure UUID on the record before it is saved to the database. - -```crystal -class Book < Granite::Base - require "uuid" - adapter mysql - primary ISBN : String, auto: false - field name : String - - before_create :assign_isbn - - def assign_isbn - @ISBN = UUID.random.to_s - end -end -``` - -### Bulk Insertions - -#### Import - -**Note: Imports do not trigger callbacks automatically. See [Running Callbacks](#running-callbacks).** - -Each model has an `import` class level method to import an array of models in one bulk insert statement. -```Crystal -models = [ - Model.new(id: 1, name: "Fred", age: 14), - Model.new(id: 2, name: "Joe", age: 25), - Model.new(id: 3, name: "John", age: 30), -] - -Model.import(models) -``` - -#### update_on_duplicate - -The `import` method has an optional `update_on_duplicate` + `columns` params that allows you to specify the columns (as an array of strings) that should be updated if primary constraint is violated. -```Crystal -models = [ - Model.new(id: 1, name: "Fred", age: 14), - Model.new(id: 2, name: "Joe", age: 25), - Model.new(id: 3, name: "John", age: 30), -] - -Model.import(models) - -Model.find!(1).name # => Fred - -models = [ - Model.new(id: 1, name: "George", age: 14), -] - -Model.import(models, update_on_duplicate: true, columns: %w(name)) - -Model.find!(1).name # => George -``` - -**NOTE: If using PostgreSQL you must have version 9.5+ to have the on_duplicate_key_update feature.** - -#### ignore_on_duplicate - -The `import` method has an optional `ignore_on_duplicate` param, that takes a boolean, which will skip records if the primary constraint is violated. -```Crystal -models = [ - Model.new(id: 1, name: "Fred", age: 14), - Model.new(id: 2, name: "Joe", age: 25), - Model.new(id: 3, name: "John", age: 30), -] - -Model.import(models) - -Model.find!(1).name # => Fred - -models = [ - Model.new(id: 1, name: "George", age: 14), -] - -Model.import(models, ignore_on_duplicate: true) - -Model.find!(1).name # => Fred -``` - -#### batch_size - -The `import` method has an optional `batch_size` param, that takes an integer. The batch_size determines the number of models to import in each INSERT statement. This defaults to the size of the models array, i.e. only 1 INSERT statement. -```Crystal -models = [ - Model.new(id: 1, name: "Fred", age: 14), - Model.new(id: 2, name: "Joe", age: 25), - Model.new(id: 3, name: "John", age: 30), - Model.new(id: 3, name: "Bill", age: 66), -] - -Model.import(models, batch_size: 2) -# => First SQL INSERT statement imports Fred and Joe -# => Second SQL INSERT statement imports John and Bill -``` - -#### Running Callbacks - -Since the `import` method runs on the class level, callbacks are not triggered automatically, they have to be triggered manually. For example, using the Item class with a UUID primary key: -```Crystal -require "uuid" - -class Item < Granite::Base - adapter mysql - table_name items - - primary item_id : String, auto: false - field item_name : String - - before_create :generate_uuid - - def generate_uuid - @item_id = UUID.random.to_s - end -end -``` - -```Crystal -items = [ - Item.new(item_name: "item1"), - Item.new(item_name: "item2"), - Item.new(item_name: "item3"), - Item.new(item_name: "item4"), -] - -# If we did `Item.import(items)` now, it would fail since the item_id wouldn't get set before saving the record, violating the primary key constraint. - -# Manually run the callback on each model to generate the item_id. -items.each(&.before_create) - -# Each model in the array now has a item_id set, so can be imported. -Item.import(items) - -# This can also be used for a single record. -item = Item.new(item_name: "item5") -item.before_create -item.save -``` - -**Note: Manually running your callbacks is mainly aimed at bulk imports. Running them before a normal `.save`, for example, would run your callbacks twice.** - -### SQL - -To clear all the rows in the database: - -```crystal -Post.clear #truncate the table -``` - -#### Find All - -```crystal -posts = Post.all -if posts - posts.each do |post| - puts post.name - end -end -``` - -#### Find First - -```crystal -post = Post.first -if post - puts post.name -end - -post = Post.first! # raises when no records exist -``` - -#### Find - -```crystal -post = Post.find 1 -if post - puts post.name -end - -post = Post.find! 1 # raises when no records found -``` - -#### Find By - -```crystal -post = Post.find_by(slug: "example_slug") -if post - puts post.name -end - -post = Post.find_by!(slug: "foo") # raises when no records found. -other_post = Post.find_by(slug: "foo", type: "bar") # Also works for multiple arguments. -``` - -#### Create -```crystal -Post.create(name: "Granite Rocks!", body: "Check this out.") # Set attributes and call save -Post.create!(name: "Granite Rocks!", body: "Check this out.") # Set attributes and call save!. Will throw an exception when the save failed -``` - -#### Insert - -```crystal -post = Post.new -post.name = "Granite Rocks!" -post.body = "Check this out." -post.save - -post = Post.new -post.name = "Granite Rocks!" -post.body = "Check this out." -post.save! # raises when save failed -``` - -#### Update - -```crystal -post = Post.find 1 -post.name = "Granite Really Rocks!" -post.save - -post = Post.find 1 -post.update(name: "Granite Really Rocks!") # Assigns attributes and calls save - -post = Post.find 1 -post.update!(name: "Granite Really Rocks!") # Assigns attributes and calls save!. Will throw an exception when the save failed -``` - -#### Delete - -```crystal -post = Post.find 1 -post.destroy -puts "deleted" unless post - -post = Post.find 1 -post.destroy! # raises when delete failed -``` - -### Queries - -The query macro and where clause combine to give you full control over your query. - -#### All - -When using the `all` method, the SQL selected fields will match the -fields specified in the model unless the `query` macro was used to customize -the SELECT. - -Always pass in parameters to avoid SQL Injection. Use a `?` -in your query as placeholder. Checkout the [Crystal DB Driver](https://github.com/crystal-lang/crystal-db) -for documentation of the drivers. - -Here are some examples: - -```crystal -posts = Post.all("WHERE name LIKE ?", ["Joe%"]) -if posts - posts.each do |post| - puts post.name - end -end - -# ORDER BY Example -posts = Post.all("ORDER BY created_at DESC") - -# JOIN Example -posts = Post.all("JOIN comments c ON c.post_id = post.id - WHERE c.name = ? - ORDER BY post.created_at DESC", - ["Joe"]) - -``` - -#### First - -It is common to only want the first result and append a `LIMIT 1` to the query. -This is what the `first` method does. - -For example: - -```crystal -post = Post.first("ORDER BY posts.name DESC") -``` - -This is the same as: - -```crystal -post = Post.all("ORDER BY posts.name DESC LIMIT 1").first -``` - -#### Customizing SELECT - -The `select_statement` macro allows you to customize the entire query, including the SELECT portion. This shouldn't be necessary in most cases, but allows you to craft more complex (i.e. cross-table) queries if needed: - -```crystal -class CustomView < Granite:Base - adapter pg - field articlebody : String - field commentbody : String - - select_statement <<-SQL - SELECT articles.articlebody, comments.commentbody - FROM articles - JOIN comments - ON comments.articleid = articles.id - SQL -end -``` - -You can combine this with an argument to `all` or `first` for maximum flexibility: - -```crystal -results = CustomView.all("WHERE articles.author = ?", ["Noah"]) -``` - -### Relationships - -#### One to Many - -`belongs_to` and `has_many` macros provide a rails like mapping between Objects. - -```crystal -class User < Granite::Base - adapter mysql - - has_many :posts - - field email : String - field name : String - timestamps -end -``` - -This will add a `posts` instance method to the user which returns an array of posts. - -```crystal -class Post < Granite::Base - adapter mysql - - belongs_to :user - - field title : String - timestamps -end -``` - -This will add a `user` and `user=` instance method to the post. - -For example: - -```crystal -user = User.find 1 -user.posts.each do |post| - puts post.title -end - -post = Post.find 1 -puts post.user - -post.user = user -post.save -``` - -In this example, you will need to add a `user_id` and index to your posts table: - -```mysql -CREATE TABLE posts ( - id BIGSERIAL PRIMARY KEY, - user_id BIGINT, - title VARCHAR, - created_at TIMESTAMP, - updated_at TIMESTAMP -); - -CREATE INDEX 'user_id_idx' ON posts (user_id); -``` - -#### Many to Many - -Instead of using a hidden many-to-many table, Granite recommends always creating a model for your join tables. For example, let's say you have many `users` that belong to many `rooms`. We recommend adding a new model called `participants` to represent the many-to-many relationship. - -Then you can use the `belongs_to` and `has_many` relationships going both ways. - -```crystal -class User < Granite::Base - has_many :participants - - field name : String -end - -class Participant < Granite::Base - belongs_to :user - belongs_to :room -end - -class Room < Granite::Base - has_many :participants - - field name : String -end -``` - -The Participant class represents the many-to-many relationship between the Users and Rooms. - -Here is what the database table would look like: - -```mysql -CREATE TABLE participants ( - id BIGSERIAL PRIMARY KEY, - user_id BIGINT, - room_id BIGINT, - created_at TIMESTAMP, - updated_at TIMESTAMP -); - -CREATE INDEX 'user_id_idx' ON TABLE participants (user_id); -CREATE INDEX 'room_id_idx' ON TABLE participants (room_id); -``` - -##### has_many through: - -As a convenience, we provide a `through:` clause to simplify accessing the many-to-many relationship: - -```crystal -class User < Granite::Base - has_many :participants - has_many :rooms, through: participants - - field name : String -end - -class Participant < Granite::Base - belongs_to :user - belongs_to :room -end - -class Room < Granite::Base - has_many :participants - has_many :users, through: participants - - field name : String -end -``` - -This will allow you to find all the rooms that a user is in: - -```crystal -user = User.first -user.rooms.each do |room| - puts room.name -end -``` - -And the reverse, all the users in a room: - -```crystal -room = Room.first -room.users.each do |user| - puts user.name -end -``` - -### Errors - -All database errors are added to the `errors` array used by Granite::Validators with the symbol ':base' - -```crystal -post = Post.new -post.save -post.errors[0].to_s.should eq "ERROR: name cannot be null" -``` - -### Callbacks - -There is support for callbacks on certain events. - -Here is an example: - -```crystal -require "granite/adapter/pg" - -class Post < Granite::Base - adapter pg - - before_save :upcase_title - - field title : String - field content : String - timestamps - - def upcase_title - if title = @title - @title = title.upcase - end - end -end -``` - -You can register callbacks for the following events: - -#### Create - -- before_save -- before_create -- **save** -- after_create -- after_save - -#### Update - -- before_save -- before_update -- **save** -- after_update -- after_save - -#### Destroy - -- before_destroy -- **destroy** -- after_destroy - -### Validation - -Validations can be made on models to ensure that given criteria are met. - -Models that do not pass the validations will not be saved, and will have the errors added to the model's `errors` array. - -For example, asserting that the title on a post is not blank: - -```Crystal -class Post < Granite::Base - adapter mysql - - field title : String - - validate :title, "can't be blank" do |post| - !post.title.to_s.blank? - end -end -``` - -#### Validation Helpers - -A set of common validation macros exist to make validations easier to manage/create. - -**Common** -- `validate_not_nil :field` - Validates that field should not be nil. -- `validate_is_nil :field` - Validates that field should be nil. -- `validate_is_valid_choice :type, ["allowedType1", "allowedType2"]` - Validates that type should be one of a preset option. -- `validate_uniqueness :field` - Validates that the field is unique - -**String** -- `validate_not_blank :field` - Validates that field should not be blank. -- `validate_is_blank :field` - Validates that field should be blank. -- `validate_min_length :field, 5` - Validates that field should be at least 5 long -- `validate_max_length :field, 20` - Validates that field should be at most 20 long - -**Number** -- `validate_greater_than :field, 0` - Validates that field should be greater than 0. -- `validate_greater_than :field, 0, true` - Validates that field should be greater than or equal to 0. -- `validate_less_than :field, 100` - Validates that field should be less than 100. -- `validate_less_than :field, 100, true` - Validates that field should be less than or equal to 100. - -Using the helpers, the previous example could have been written like: - -```Crystal -class Post < Granite::Base - adapter mysql - - field title : String - - validate_not_blank :title -end -``` - -### JSON Support - -A few handy things that come from the `JSON::Serializable` support. See [JSON::Serializable Docs](https://crystal-lang.org/api/0.25.1/JSON/Serializable.html) for more information. - -#### JSON::Field - -Allows for control over the serialization and deserialization of instance variables. - -```Crystal -class Foo < Granite::Base - adapter mysql - table_name foos - - field name : String - field password : String, json_options: {ignore: true} # skip this field in serialization and deserialization - field age : Int32, json_options: {key: "HowOldTheyAre"} # the value of the key in the json object - field todayBirthday : Bool, json_options: {emit_null: true} # emits a null value for nilable property - field isNil : Bool -end -``` - -`foo = Foo.from_json(%({"name": "Granite1", "HowOldTheyAre": 12, "password": "12345"}))` - -```Crystal -# -``` - -`foo.to_json` - -```JSON -{ - "name":"Granite1", - "HowOldTheyAre":12, - "todayBirthday":null -} -``` - -Notice how `isNil` is omitted from the JSON output since it is Nil. If you wish to always show Nil instance variables on a class level you can do: - -```Crystal -@[JSON::Serializable::Options(emit_nulls: true)] -class Foo < Granite::Base - adapter mysql - table_name foos - - field name : String - field age : Int32 -end -``` - -This would be functionally the same as adding `json_options: {emit_null: true}` on each property. - -#### after_initialize - -This method gets called after `from_json` is done parsing the given JSON string. This allows you to set other fields that are not in the JSON directly or that require some more logic. - -```Crystal -class Foo < Granite::Base - adapter mysql - table_name foos - - field name : String - field age : Int32 - field date_added : Time - - def after_initialize - @date_added = Time.utc_now - end -end -``` - -`foo = Foo.from_json(%({"name": "Granite1"}))` - -```Crystal - -``` - -#### JSON::Serializable::Unmapped - -If the JSON::Serializable::Unmapped module is included, unknown properties in the JSON document will be stored in a Hash(String, JSON::Any). On serialization, any keys inside `json_unmapped` will be serialized appended to the current JSON object. - -```Crystal -class Foo < Granite::Base - include JSON::Serializable::Unmapped - - adapter mysql - table_name foos - - field name : String - field age : Int32 -end -``` - -`foo = Foo.from_json(%({"name": "Granite1", "age": 12, "foobar": true}))` - -```Crystal - true}, - @name="Granite1", - @new_record=true, - @updated_at=nil> -``` - -`foo.to_json` - -```JSON -{ - "name": "Granite", - "age": 12, - "foobar": true -} -``` - -#### on_to_json - -Allows doing additional manipulations before returning from `to_json`. - -```Crystal -class Foo < Granite::Base - adapter mysql - table_name foos - - field name : String - field age : Int32 - - def on_to_json(json : JSON::Builder) - json.field("years_young", @age) - end -end -``` - -`foo = Foo.from_json(%({"name": "Granite1", "age": 12}))` - -```Crystal - -``` - -`foo.to_json` - -```JSON -{ - "name": "Granite", - "age": 12, - "years_young": 12 -} -``` - -### Migration - -- `migrator` provides `drop`, `create` and `drop_and_create` methods - -```crystal -class User < Granite::Base - adapter mysql - field name : String -end - -User.migrator.drop_and_create -# => "DROP TABLE IF EXISTS `users`;" -# => "CREATE TABLE `users` (id BIGSERIAL PRIMARY KEY, name VARCHAR(255));" - -User.migrator(table_options: "ENGINE=InnoDB DEFAULT CHARSET=utf8").create -# => "CREATE TABLE ... ENGINE=InnoDB DEFAULT CHARSET=utf8;" -``` +Start by checking out the [Getting Started](docs/getting_started.md) guide to get Granite installed and configured. For additional information visit the [Docs folder](docs/). ## Contributing -1. Fork it ( https://github.com/amberframework/granite/fork ) -2. Create your feature branch (git checkout -b my-new-feature) -3. Commit your changes (git commit -am 'Add some feature') -4. Push to the branch (git push origin my-new-feature) -5. Create a new Pull Request - -## Running tests - -Granite uses Crystal's built in test framework. The tests can be run with `$ crystal spec`. - -The test suite depends on access to a PostgreSQL, MySQL, and SQLite database to ensure the adapters work as intended. - -### Docker setup + 1. Fork it ( https://github.com/amberframework/granite/fork ) + 2. Create your feature branch (git checkout -b my-new-feature) + 3. Commit your changes (git commit -am 'Add some feature') + 4. Push to the branch (git push origin my-new-feature) + 5. Create a new Pull Request -There is a self-contained testing environment provided via the `docker-compose.yml` file in this repository. + ## Running tests -After you have docker installed do the following to run tests: + Granite uses Crystal's built in test framework. The tests can be run with `$ crystal spec`. -#### First run + The test suite depends on access to a PostgreSQL, MySQL, and SQLite database to ensure the adapters work as intended. -``` -$ docker-compose build spec -$ docker-compose run spec -``` + ### Docker setup -#### Subsequent runs + There is a self-contained testing environment provided via the `docker-compose.yml` file in this repository. -``` -$ docker-compose run spec -``` + After you have docker installed do the following to run tests: -#### Cleanup + #### First run -If you're done testing and you'd like to shut down and clean up the docker dependences run the following: + ``` + $ docker-compose build spec + $ docker-compose run spec + ``` -``` -$ docker-compose down -``` + #### Subsequent runs -### Local setup + ``` + $ docker-compose run spec + ``` -If you'd like to test without docker you can do so by following the instructions below: + #### Cleanup -1. Install dependencies with `$ crystal deps` -2. Update .env to use appropriate ENV variables, or create appropriate databases. -3. Setup databases: + If you're done testing and you'd like to shut down and clean up the docker dependences run the following: -#### PostgreSQL + ``` + $ docker-compose down + ``` -```sql -CREATE USER granite WITH PASSWORD 'password'; + ### Local setup -CREATE DATABASE granite_db; + If you'd like to test without docker you can do so by following the instructions below: -GRANT ALL PRIVILEGES ON DATABASE granite_db TO granite; -``` + 1. Install dependencies with `$ crystal deps` + 2. Update .env to use appropriate ENV variables, or create appropriate databases. + 3. Setup databases: -#### MySQL + #### PostgreSQL -```sql -CREATE USER 'granite'@'localhost' IDENTIFIED BY 'password'; + ```sql + CREATE USER granite WITH PASSWORD 'password'; + + CREATE DATABASE granite_db; + + GRANT ALL PRIVILEGES ON DATABASE granite_db TO granite; + ``` -CREATE DATABASE granite_db; + #### MySQL -GRANT ALL PRIVILEGES ON granite_db.* TO 'granite'@'localhost' WITH GRANT OPTION; -``` + ```sql + CREATE USER 'granite'@'localhost' IDENTIFIED BY 'password'; + + CREATE DATABASE granite_db; + + GRANT ALL PRIVILEGES ON granite_db.* TO 'granite'@'localhost' WITH GRANT OPTION; + ``` -4. Export `.env` with `$ source .env` -5. `$ crystal spec` + 4. Export `.env` with `$ source .env` + 5. `$ crystal spec` \ No newline at end of file diff --git a/docs/Granite.html b/docs/Granite.html deleted file mode 100644 index 94a2f7ec..00000000 --- a/docs/Granite.html +++ /dev/null @@ -1,347 +0,0 @@ - - - - - - - - Granite - github.com/Amber-Crystal/granite-orm - - - -
- - - - - - -
- -
-

- - module Granite - -

- - - - - - - - - - - - - - - - - - -

Defined in:

- - - granite/collection.cr - -
- - - granite/settings.cr - -
- - - granite/version.cr - -
- - - - - -

Constant Summary

- -
- -
- VERSION = "0.10.0" -
- - -
- - - - - -

Class Method Summary

- - - - - - - - -
- -
- - - - -

Class Method Detail

- -
-
- - def self.settings - - # -
- -
-
- - [View source] - -
-
- - - - - - - -
- - - diff --git a/docs/Granite/Adapter.html b/docs/Granite/Adapter.html deleted file mode 100644 index f175696b..00000000 --- a/docs/Granite/Adapter.html +++ /dev/null @@ -1,366 +0,0 @@ - - - - - - - - Granite::Adapter - github.com/Amber-Crystal/granite-orm - - - -
- - - - - - -
- -
-

- - module Granite::Adapter - -

- - - - - - - - - - - - - - - - - - -

Defined in:

- - - adapter/base.cr - -
- - - - - - - - - - - - - - -
- -
- - - - - - - - - -
- - - diff --git a/docs/Granite/Adapter/Base.html b/docs/Granite/Adapter/Base.html deleted file mode 100644 index be073a49..00000000 --- a/docs/Granite/Adapter/Base.html +++ /dev/null @@ -1,744 +0,0 @@ - - - - - - - - Granite::Adapter::Base - github.com/Amber-Crystal/granite-orm - - - -
- - - - - - -
- -
-

- - abstract class Granite::Adapter::Base - -

- - - - - - - -

Overview

- -

The Base Adapter specifies the interface that will be used by the model -objects to perform actions against a specific database. Each adapter needs -to implement these methods.

- - - - - - - - - -

Direct Known Subclasses

- - - - - - - -

Defined in:

- - - adapter/base.cr - -
- - - - - -

Constant Summary

- -
- -
- DATABASE_YML = "config/database.yml" -
- - -
- - - -

Constructors

- - - - -

Class Method Summary

-
    - -
  • - .env(url) - -

    class level method so we can test it

    - -
  • - -
- - - -

Instance Method Summary

- - - - - - -
- - - - - - - - - - - - - - - - - - - - - -
- - -

Constructor Detail

- -
-
- - def self.new(adapter : String) - - # -
- -
-
- - [View source] - -
-
- - - - -

Class Method Detail

- -
-
- - def self.env(url) - - # -
- -

class level method so we can test it

- -
-
- - [View source] - -
-
- - - - -

Instance Method Detail

- -
-
- abstract - def clear(table_name) - - # -
- -

remove all rows from a table and reset the counter on the id.

- -
-
- - [View source] - -
-
- -
-
- - def database : DB::Database - - # -
- -
-
- - [View source] - -
-
- -
-
- - def database=(database : DB::Database) - - # -
- -
-
- - [View source] - -
-
- -
-
- abstract - def delete(table_name, primary_name, value) - - # -
- -

This will delete a row from the database.

- -
-
- - [View source] - -
-
- -
-
- abstract - def import(table_name : String, primary_name : String, auto : String, fields, model_array, **options) - - # -
- -

This will insert an array of models as one insert statement

- -
-
- - [View source] - -
-
- -
-
- abstract - def insert(table_name, fields, params, lastval) : Int64 - - # -
- -

This will insert a row in the database and return the id generated.

- -
-
- - [View source] - -
-
- -
-
- - def log(query : String, params = [] of String) : Nil - - # -
- -
-
- - [View source] - -
-
- -
-
- - def open(&block) - - # -
- -
-
- - [View source] - -
-
- -
-
- abstract - def select(table_name, fields, clause = "", params = nil, &block) - - # -
- -

select performs a query against a table. The table_name and fields are -configured using the sql_mapping directive in your model. The clause and -params is the query and params that is passed in via .all() method

- -
-
- - [View source] - -
-
- -
-
- - def settings(adapter : String) - - # -
- -
-
- - [View source] - -
-
- -
-
- abstract - def update(table_name, primary_name, fields, params) - - # -
- -

This will update a row in the database.

- -
-
- - [View source] - -
-
- - - - - -
- - - diff --git a/docs/Granite/Adapter/Base/Schema.html b/docs/Granite/Adapter/Base/Schema.html deleted file mode 100644 index f34713e4..00000000 --- a/docs/Granite/Adapter/Base/Schema.html +++ /dev/null @@ -1,378 +0,0 @@ - - - - - - - - Granite::Adapter::Base::Schema - github.com/Amber-Crystal/granite-orm - - - -
- - - - - - -
- -
-

- - module Granite::Adapter::Base::Schema - -

- - - - - - - - - - - - - - - - - - -

Defined in:

- - - adapter/base.cr - -
- - - - - -

Constant Summary

- -
- -
- TYPES = {"Bool" => "BOOL", "Float32" => "FLOAT", "Float64" => "REAL", "Int32" => "INT", "Int64" => "BIGINT", "String" => "VARCHAR(255)", "Time" => "TIMESTAMP"} -
- - -
- - - - - - - - - - - -
- -
- - - - - - - - - -
- - - diff --git a/docs/Granite/Adapter/Mysql.html b/docs/Granite/Adapter/Mysql.html deleted file mode 100644 index c8521193..00000000 --- a/docs/Granite/Adapter/Mysql.html +++ /dev/null @@ -1,728 +0,0 @@ - - - - - - - - Granite::Adapter::Mysql - github.com/Amber-Crystal/granite-orm - - - -
- - - - - - -
- -
-

- - class Granite::Adapter::Mysql - -

- - - - - - - -

Overview

- -

Mysql implementation of the Adapter

- - - - - - - - - - - - - - -

Defined in:

- - - adapter/mysql.cr - -
- - - - - -

Constant Summary

- -
- -
- QUOTING_CHAR = '`' -
- - -
- - - - - -

Class Method Summary

- - - - -

Instance Method Summary

- - - - - - - - - - - -

Class Method Detail

- -
-
- - def self.schema_type?(key : String) - - # -
- -

converts the crystal class to database type of this adapter

- -
-
- - [View source] - -
-
- - - - -

Instance Method Detail

- -
-
- - def clear(table_name) - - # -
- -

Using TRUNCATE instead of DELETE so the id column resets to 0

- -
-
- - [View source] - -
-
- -
-
- - def delete(table_name, primary_name, value) - - # -
- -

This will delete a row from the database.

- -
-
- - [View source] - -
-
- -
-
- - def import(table_name : String, primary_name : String, auto : String, fields, model_array, **options) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def insert(table_name, fields, params, lastval) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def quote(name : String) : String - - # -
- -

quotes table and column names

- -
-
- - [View source] - -
-
- -
-
- - def select(table_name, fields, clause = "", params = [] of DB::Any, &block) - - # -
- -

select performs a query against a table. The table_name and fields are -configured using the sql_mapping directive in your model. The clause and -params is the query and params that is passed in via .all() method

- -
-
- - [View source] - -
-
- -
-
- - def select_one(table_name, fields, field, id, &block) - - # -
- -

select_one is used by the find method. -it checks id by default, but one can -pass another field.

- -
-
- - [View source] - -
-
- -
-
- - def update(table_name, primary_name, fields, params) - - # -
- -

This will update a row in the database.

- -
-
- - [View source] - -
-
- - - - - -
- - - diff --git a/docs/Granite/Adapter/Mysql/Schema.html b/docs/Granite/Adapter/Mysql/Schema.html deleted file mode 100644 index 06e269b0..00000000 --- a/docs/Granite/Adapter/Mysql/Schema.html +++ /dev/null @@ -1,378 +0,0 @@ - - - - - - - - Granite::Adapter::Mysql::Schema - github.com/Amber-Crystal/granite-orm - - - -
- - - - - - -
- -
-

- - module Granite::Adapter::Mysql::Schema - -

- - - - - - - - - - - - - - - - - - -

Defined in:

- - - adapter/mysql.cr - -
- - - - - -

Constant Summary

- -
- -
- TYPES = {"AUTO_Int32" => "INT NOT NULL AUTO_INCREMENT", "AUTO_Int64" => "BIGINT NOT NULL AUTO_INCREMENT", "created_at" => "TIMESTAMP DEFAULT CURRENT_TIMESTAMP", "updated_at" => "TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP"} -
- - -
- - - - - - - - - - - -
- -
- - - - - - - - - -
- - - diff --git a/docs/Granite/Adapter/Pg.html b/docs/Granite/Adapter/Pg.html deleted file mode 100644 index 5b31303e..00000000 --- a/docs/Granite/Adapter/Pg.html +++ /dev/null @@ -1,726 +0,0 @@ - - - - - - - - Granite::Adapter::Pg - github.com/Amber-Crystal/granite-orm - - - -
- - - - - - -
- -
-

- - class Granite::Adapter::Pg - -

- - - - - - - -

Overview

- -

PostgreSQL implementation of the Adapter

- - - - - - - - - - - - - - -

Defined in:

- - - adapter/pg.cr - -
- - - - - -

Constant Summary

- -
- -
- QUOTING_CHAR = '"' -
- - -
- - - - - -

Class Method Summary

- - - - -

Instance Method Summary

- - - - - - - - - - - -

Class Method Detail

- -
-
- - def self.schema_type?(key : String) - - # -
- -

converts the crystal class to database type of this adapter

- -
-
- - [View source] - -
-
- - - - -

Instance Method Detail

- -
-
- - def clear(table_name) - - # -
- -

remove all rows from a table and reset the counter on the id.

- -
-
- - [View source] - -
-
- -
-
- - def delete(table_name, primary_name, value) - - # -
- -

This will delete a row from the database.

- -
-
- - [View source] - -
-
- -
-
- - def import(table_name : String, primary_name : String, auto : String, fields, model_array, **options) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def insert(table_name, fields, params, lastval) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def quote(name : String) : String - - # -
- -

quotes table and column names

- -
-
- - [View source] - -
-
- -
-
- - def select(table_name, fields, clause = "", params = [] of DB::Any, &block) - - # -
- -

select performs a query against a table. The table_name and fields are -configured using the sql_mapping directive in your model. The clause and -params is the query and params that is passed in via .all() method

- -
-
- - [View source] - -
-
- -
-
- - def select_one(table_name, fields, field, id, &block) - - # -
- -

select_one is used by the find method.

- -
-
- - [View source] - -
-
- -
-
- - def update(table_name, primary_name, fields, params) - - # -
- -

This will update a row in the database.

- -
-
- - [View source] - -
-
- - - - - -
- - - diff --git a/docs/Granite/Adapter/Pg/Schema.html b/docs/Granite/Adapter/Pg/Schema.html deleted file mode 100644 index 656bd368..00000000 --- a/docs/Granite/Adapter/Pg/Schema.html +++ /dev/null @@ -1,378 +0,0 @@ - - - - - - - - Granite::Adapter::Pg::Schema - github.com/Amber-Crystal/granite-orm - - - -
- - - - - - -
- -
-

- - module Granite::Adapter::Pg::Schema - -

- - - - - - - - - - - - - - - - - - -

Defined in:

- - - adapter/pg.cr - -
- - - - - -

Constant Summary

- -
- -
- TYPES = {"AUTO_Int32" => "SERIAL", "AUTO_Int64" => "BIGSERIAL", "created_at" => "TIMESTAMP", "updated_at" => "TIMESTAMP"} -
- - -
- - - - - - - - - - - -
- -
- - - - - - - - - -
- - - diff --git a/docs/Granite/Adapter/Sqlite.html b/docs/Granite/Adapter/Sqlite.html deleted file mode 100644 index 9c8c8391..00000000 --- a/docs/Granite/Adapter/Sqlite.html +++ /dev/null @@ -1,726 +0,0 @@ - - - - - - - - Granite::Adapter::Sqlite - github.com/Amber-Crystal/granite-orm - - - -
- - - - - - -
- -
-

- - class Granite::Adapter::Sqlite - -

- - - - - - - -

Overview

- -

Sqlite implementation of the Adapter

- - - - - - - - - - - - - - -

Defined in:

- - - adapter/sqlite.cr - -
- - - - - -

Constant Summary

- -
- -
- QUOTING_CHAR = '"' -
- - -
- - - - - -

Class Method Summary

- - - - -

Instance Method Summary

- - - - - - - - - - - -

Class Method Detail

- -
-
- - def self.schema_type?(key : String) - - # -
- -

converts the crystal class to database type of this adapter

- -
-
- - [View source] - -
-
- - - - -

Instance Method Detail

- -
-
- - def clear(table_name) - - # -
- -

remove all rows from a table and reset the counter on the id.

- -
-
- - [View source] - -
-
- -
-
- - def delete(table_name, primary_name, value) - - # -
- -

This will delete a row from the database.

- -
-
- - [View source] - -
-
- -
-
- - def import(table_name : String, primary_name : String, auto : String, fields, model_array, **options) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def insert(table_name, fields, params, lastval) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def quote(name : String) : String - - # -
- -

quotes table and column names

- -
-
- - [View source] - -
-
- -
-
- - def select(table_name, fields, clause = "", params = [] of DB::Any, &block) - - # -
- -

select performs a query against a table. The table_name and fields are -configured using the sql_mapping directive in your model. The clause and -params is the query and params that is passed in via .all() method

- -
-
- - [View source] - -
-
- -
-
- - def select_one(table_name, fields, field, id, &block) - - # -
- -

select_one is used by the find method.

- -
-
- - [View source] - -
-
- -
-
- - def update(table_name, primary_name, fields, params) - - # -
- -

This will update a row in the database.

- -
-
- - [View source] - -
-
- - - - - -
- - - diff --git a/docs/Granite/Adapter/Sqlite/Schema.html b/docs/Granite/Adapter/Sqlite/Schema.html deleted file mode 100644 index 81074c67..00000000 --- a/docs/Granite/Adapter/Sqlite/Schema.html +++ /dev/null @@ -1,378 +0,0 @@ - - - - - - - - Granite::Adapter::Sqlite::Schema - github.com/Amber-Crystal/granite-orm - - - -
- - - - - - -
- -
-

- - module Granite::Adapter::Sqlite::Schema - -

- - - - - - - - - - - - - - - - - - -

Defined in:

- - - adapter/sqlite.cr - -
- - - - - -

Constant Summary

- -
- -
- TYPES = {"AUTO_Int32" => "INTEGER NOT NULL", "AUTO_Int64" => "INTEGER NOT NULL", "Int32" => "INTEGER", "Int64" => "INTEGER", "created_at" => "VARCHAR", "updated_at" => "VARCHAR"} -
- - -
- - - - - - - - - - - -
- -
- - - - - - - - - -
- - - diff --git a/docs/Granite/AssociationCollection.html b/docs/Granite/AssociationCollection.html deleted file mode 100644 index ae6cfa65..00000000 --- a/docs/Granite/AssociationCollection.html +++ /dev/null @@ -1,489 +0,0 @@ - - - - - - - - Granite::AssociationCollection(Owner, Target) - github.com/Amber-Crystal/granite-orm - - - -
- - - - - - -
- -
-

- - class Granite::AssociationCollection(Owner, Target) - -

- - - - - - - - - - - - - - - - - - - - -

Defined in:

- - - granite/association_collection.cr - -
- - - - - - -

Constructors

- - - - - - -

Instance Method Summary

- - - - -

Macro Summary

- - - - -
- - - - - - - - - - - - - - - - - - - - - -
- - -

Constructor Detail

- -
-
- - def self.new(owner : Owner, through : Symbol? = nil) - - # -
- -
-
- - [View source] - -
-
- - - - - - -

Instance Method Detail

- -
-
- - def all(clause = "", params = [] of DB::Any) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def find(value) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def find!(value) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def find_by(field : String | Symbol, value) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def find_by!(field : String | Symbol, value) - - # -
- -
-
- - [View source] - -
-
- - - - -

Macro Detail

- -
-
- - macro method_missing(call) - - # -
- -
-
- - [View source] - -
-
- - - -
- - - diff --git a/docs/Granite/Associations.html b/docs/Granite/Associations.html deleted file mode 100644 index 53f9a924..00000000 --- a/docs/Granite/Associations.html +++ /dev/null @@ -1,432 +0,0 @@ - - - - - - - - Granite::Associations - github.com/Amber-Crystal/granite-orm - - - -
- - - - - - -
- -
-

- - module Granite::Associations - -

- - - - - - - - - - - - - - - -

Direct including types

- - - - - -

Defined in:

- - - granite/associations.cr - -
- - - - - - - - - - - - -

Macro Summary

- - - - -
- -
- - - - - - - - -

Macro Detail

- -
-
- - macro belongs_to(model) - - # -
- -

define getter and setter for parent relationship

- -
-
- - [View source] - -
-
- -
-
- - macro belongs_to(model, foreign_key) - - # -
- -

ditto

- -
-
- - [View source] - -
-
- -
-
- - macro belongs_to(method_name, model_name, foreign_key) - - # -
- -

ditto

- -
-
- - [View source] - -
-
- -
-
- - macro has_many(children_table) - - # -
- -
-
- - [View source] - -
-
- -
-
- - macro has_many(children_table, through) - - # -
- -

define getter for related children

- -
-
- - [View source] - -
-
- - - -
- - - diff --git a/docs/Granite/Base.html b/docs/Granite/Base.html deleted file mode 100644 index aa949c2f..00000000 --- a/docs/Granite/Base.html +++ /dev/null @@ -1,562 +0,0 @@ - - - - - - - - Granite::Base - github.com/Amber-Crystal/granite-orm - - - -
- - - - - - -
- -
-

- - class Granite::Base - -

- - - - - - - -

Overview

- -

Granite::Base is the base class for your model objects.

- - - - - -

Included Modules

- - - - -

Extended Modules

- - - - - - - - - -

Defined in:

- - - granite/base.cr - -
- - - - - - -

Constructors

- - - - - - - - -

Macro Summary

- - - - -
- - - - - - - - - - - - - -

Instance methods inherited from module Granite::Validators

- - - - errors - errors, - - - - valid? - valid? - - - - - - - - - - - - - -

Instance methods inherited from module Granite::Transactions

- - - - destroyed? : Bool - destroyed?, - - - - new_record? : Bool - new_record?, - - - - persisted? - persisted? - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Instance methods inherited from module Granite::Callbacks

- - - - abort!(message = "Aborted at #{@_current_callback}.") - abort! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - -

Constructor Detail

- -
-
- - def self.new(args : Hash(Symbol | String, String | JSON::Type)) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def self.new - - # -
- -
-
- - [View source] - -
-
- -
-
- - def self.new - - # -
- -
-
- - [View source] - -
-
- - - - - - - - -

Macro Detail

- -
-
- - macro __process_querying - - # -
- -
-
- - [View source] - -
-
- - - -
- - - diff --git a/docs/Granite/Callbacks.html b/docs/Granite/Callbacks.html deleted file mode 100644 index c8ea2a85..00000000 --- a/docs/Granite/Callbacks.html +++ /dev/null @@ -1,688 +0,0 @@ - - - - - - - - Granite::Callbacks - github.com/Amber-Crystal/granite-orm - - - -
- - - - - - -
- -
-

- - module Granite::Callbacks - -

- - - - - - - - - - - - - - - -

Direct including types

- - - - - -

Defined in:

- - - granite/callbacks.cr - -
- - - - - -

Constant Summary

- -
- -
- CALLBACK_NAMES = [:before_save, :after_save, :before_create, :after_create, :before_update, :after_update, :before_destroy, :after_destroy] of ::Symbol -
- - -
- - - - - - - -

Instance Method Summary

- - - - -

Macro Summary

- - - - -
- -
- - - - - - -

Instance Method Detail

- -
-
- - def abort!(message = "Aborted at #{@_current_callback}.") - - # -
- -
-
- - [View source] - -
-
- - - - -

Macro Detail

- -
-
- - macro __after_create - - # -
- -
-
- - [View source] - -
-
- -
-
- - macro __after_destroy - - # -
- -
-
- - [View source] - -
-
- -
-
- - macro __after_save - - # -
- -
-
- - [View source] - -
-
- -
-
- - macro __after_update - - # -
- -
-
- - [View source] - -
-
- -
-
- - macro __before_create - - # -
- -
-
- - [View source] - -
-
- -
-
- - macro __before_destroy - - # -
- -
-
- - [View source] - -
-
- -
-
- - macro __before_save - - # -
- -
-
- - [View source] - -
-
- -
-
- - macro __before_update - - # -
- -
-
- - [View source] - -
-
- -
-
- - macro after_create(*callbacks) - - # -
- -
-
- - [View source] - -
-
- -
-
- - macro after_destroy(*callbacks) - - # -
- -
-
- - [View source] - -
-
- -
-
- - macro after_save(*callbacks) - - # -
- -
-
- - [View source] - -
-
- -
-
- - macro after_update(*callbacks) - - # -
- -
-
- - [View source] - -
-
- -
-
- - macro before_create(*callbacks) - - # -
- -
-
- - [View source] - -
-
- -
-
- - macro before_destroy(*callbacks) - - # -
- -
-
- - [View source] - -
-
- -
-
- - macro before_save(*callbacks) - - # -
- -
-
- - [View source] - -
-
- -
-
- - macro before_update(*callbacks) - - # -
- -
-
- - [View source] - -
-
- - - -
- - - diff --git a/docs/Granite/Callbacks/Abort.html b/docs/Granite/Callbacks/Abort.html deleted file mode 100644 index 4b25cbba..00000000 --- a/docs/Granite/Callbacks/Abort.html +++ /dev/null @@ -1,328 +0,0 @@ - - - - - - - - Granite::Callbacks::Abort - github.com/Amber-Crystal/granite-orm - - - -
- - - - - - -
- -
-

- - class Granite::Callbacks::Abort - -

- - - - - - - - - - - - - - - - - - - - -

Defined in:

- - - granite/callbacks.cr - -
- - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - -
- - - diff --git a/docs/Granite/Collection.html b/docs/Granite/Collection.html deleted file mode 100644 index 11f2ef63..00000000 --- a/docs/Granite/Collection.html +++ /dev/null @@ -1,405 +0,0 @@ - - - - - - - - Granite::Collection(M) - github.com/Amber-Crystal/granite-orm - - - -
- - - - - - -
- -
-

- - class Granite::Collection(M) - -

- - - - - - - - - - - - - - - - - - - - -

Defined in:

- - - granite/collection.cr - -
- - - - - - -

Constructors

- - - - - - -

Instance Method Summary

- - - - -

Macro Summary

- - - - -
- - - - - - - - - - - - - - - - - - - - - -
- - -

Constructor Detail

- -
-
- - def self.new(loader : -> Array(M)) - - # -
- -
-
- - [View source] - -
-
- - - - - - -

Instance Method Detail

- -
-
- - def loaded? - - # -
- -
-
- - [View source] - -
-
- - - - -

Macro Detail

- -
-
- - macro method_missing(call) - - # -
- -
-
- - [View source] - -
-
- - - -
- - - diff --git a/docs/Granite/Error.html b/docs/Granite/Error.html deleted file mode 100644 index 57d1b33f..00000000 --- a/docs/Granite/Error.html +++ /dev/null @@ -1,460 +0,0 @@ - - - - - - - - Granite::Error - github.com/Amber-Crystal/granite-orm - - - -
- - - - - - -
- -
-

- - class Granite::Error - -

- - - - - - - - - - - - - - - - - - - - -

Defined in:

- - - granite/error.cr - -
- - - - - - -

Constructors

- - - - - - -

Instance Method Summary

- - - - - - -
- - - - - - - - - - - - - - - - - - - - - -
- - -

Constructor Detail

- -
-
- - def self.new(field : String | Symbol, message : String? = "") - - # -
- -
-
- - [View source] - -
-
- - - - - - -

Instance Method Detail

- -
-
- - def field : String | Symbol - - # -
- -
-
- - [View source] - -
-
- -
-
- - def field=(field) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def message : String? - - # -
- -
-
- - [View source] - -
-
- -
-
- - def message=(message) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def to_s - - # -
- -
-
- - [View source] - -
-
- - - - - -
- - - diff --git a/docs/Granite/Fields.html b/docs/Granite/Fields.html deleted file mode 100644 index 39b14c1a..00000000 --- a/docs/Granite/Fields.html +++ /dev/null @@ -1,419 +0,0 @@ - - - - - - - - Granite::Fields - github.com/Amber-Crystal/granite-orm - - - -
- - - - - - -
- -
-

- - module Granite::Fields - -

- - - - - - - - - - - - - - - -

Direct including types

- - - - - -

Defined in:

- - - granite/fields.cr - -
- - - - - -

Constant Summary

- -
- -
- TIME_FORMAT_REGEX = /\d{4,}-\d{2,}-\d{2,}\s\d{2,}:\d{2,}:\d{2,}/ -
- - -
- - - - - - - - - -

Macro Summary

- - - - -
- -
- - - - - - - - -

Macro Detail

- -
-
- - macro __process_fields - - # -
- -
-
- - [View source] - -
-
- -
-
- - macro field(decl, **options) - - # -
- -

specify the fields you want to define and types

- -
-
- - [View source] - -
-
- -
-
- - macro field!(decl, **options) - - # -
- -

specify the raise-on-nil fields you want to define and types

- -
-
- - [View source] - -
-
- -
-
- - macro timestamps - - # -
- -

include created_at and updated_at that will automatically be updated

- -
-
- - [View source] - -
-
- - - -
- - - diff --git a/docs/Granite/Fields/Type.html b/docs/Granite/Fields/Type.html deleted file mode 100644 index 2906d0af..00000000 --- a/docs/Granite/Fields/Type.html +++ /dev/null @@ -1,299 +0,0 @@ - - - - - - - - Granite::Fields::Type - github.com/Amber-Crystal/granite-orm - - - -
- - - - - - -
- -
-

- - alias Granite::Fields::Type - -

- - - - - - - -

Alias Definition

- Array(JSON::Type) | Bool | Float32 | Float64 | Hash(String, JSON::Type) | Int32 | Int64 | Slice(UInt8) | String | Time | Nil - - - - - - - - - - - - -

Defined in:

- - - granite/fields.cr - -
- - - - - - - - - - - - - - -
- -
- - - - - - - - - -
- - - diff --git a/docs/Granite/Migrator.html b/docs/Granite/Migrator.html deleted file mode 100644 index 563d3d90..00000000 --- a/docs/Granite/Migrator.html +++ /dev/null @@ -1,348 +0,0 @@ - - - - - - - - Granite::Migrator - github.com/Amber-Crystal/granite-orm - - - -
- - - - - - -
- -
-

- - module Granite::Migrator - -

- - - - - -

Overview

- -

DB migration tool that prepares a table for the class

- -
class User < Granite::Base
-  adapter mysql
-  field name : String
-end
-
-User.migrator.drop_and_create
-# => "DROP TABLE IF EXISTS `users`;"
-# => "CREATE TABLE `users` (id BIGSERIAL PRIMARY KEY, name VARCHAR(255));"
-
-User.migrator(table_options: "ENGINE=InnoDB DEFAULT CHARSET=utf8").create
-# => "CREATE TABLE ... ENGINE=InnoDB DEFAULT CHARSET=utf8;"
- - - - - - - - - - - -

Direct including types

- - - - - -

Defined in:

- - - granite/migrator.cr - -
- - - - - - - - - - - - -

Macro Summary

- - - - -
- -
- - - - - - - - -

Macro Detail

- -
-
- - macro __process_migrator - - # -
- -
-
- - [View source] - -
-
- - - -
- - - diff --git a/docs/Granite/Migrator/Base.html b/docs/Granite/Migrator/Base.html deleted file mode 100644 index 6ab2588e..00000000 --- a/docs/Granite/Migrator/Base.html +++ /dev/null @@ -1,418 +0,0 @@ - - - - - - - - Granite::Migrator::Base - github.com/Amber-Crystal/granite-orm - - - -
- - - - - - -
- -
-

- - class Granite::Migrator::Base - -

- - - - - - - - - - - - - - - - - - - - -

Defined in:

- - - granite/migrator.cr - -
- - - - - - -

Constructors

- - - - - - -

Instance Method Summary

- - - - - - -
- - - - - - - - - - - - - - - - - - - - - -
- - -

Constructor Detail

- -
-
- - def self.new(klass, table_options = "") - - # -
- -
-
- - [View source] - -
-
- - - - - - -

Instance Method Detail

- -
-
- - def create - - # -
- -
-
- - [View source] - -
-
- -
-
- - def drop - - # -
- -
-
- - [View source] - -
-
- -
-
- - def drop_and_create - - # -
- -
-
- - [View source] - -
-
- - - - - -
- - - diff --git a/docs/Granite/Query.html b/docs/Granite/Query.html deleted file mode 100644 index 89b85e80..00000000 --- a/docs/Granite/Query.html +++ /dev/null @@ -1,296 +0,0 @@ - - - - - - - - Granite::Query - github.com/Amber-Crystal/granite-orm - - - -
- - - - - - -
- -
-

- - module Granite::Query - -

- - - - - - - - - - - - - - - - - - -

Defined in:

- - - query_builder.cr - -
- - - - - - - - - - - - - - -
- -
- - - - - - - - - -
- - - diff --git a/docs/Granite/Query/Assembler.html b/docs/Granite/Query/Assembler.html deleted file mode 100644 index 4dc22e33..00000000 --- a/docs/Granite/Query/Assembler.html +++ /dev/null @@ -1,306 +0,0 @@ - - - - - - - - Granite::Query::Assembler - github.com/Amber-Crystal/granite-orm - - - -
- - - - - - -
- -
-

- - module Granite::Query::Assembler - -

- - - - - -

Overview

- -

Query runner which finalizes a query and runs it. -This will likely require adapter specific subclassing :[.

- - - - - - - - - - - - - - -

Defined in:

- - - granite/query/assemblers/base.cr - -
- - - granite/query/assemblers/postgresql.cr - -
- - - - - - - - - - - - - - -
- -
- - - - - - - - - -
- - - diff --git a/docs/Granite/Query/Assembler/Base.html b/docs/Granite/Query/Assembler/Base.html deleted file mode 100644 index 3fc058ee..00000000 --- a/docs/Granite/Query/Assembler/Base.html +++ /dev/null @@ -1,530 +0,0 @@ - - - - - - - - Granite::Query::Assembler::Base(Model) - github.com/Amber-Crystal/granite-orm - - - -
- - - - - - -
- -
-

- - abstract class Granite::Query::Assembler::Base(Model) - -

- - - - - - - - - - - - - - - -

Direct Known Subclasses

- - - - - - - -

Defined in:

- - - granite/query/assemblers/base.cr - -
- - - - - - -

Constructors

- - - - - - -

Instance Method Summary

- - - - - - -
- - - - - - - - - - - - - - - - - - - - - -
- - -

Constructor Detail

- -
-
- - def self.new(query : Granite::Query::Builder(Model)) - - # -
- -
-
- - [View source] - -
-
- - - - - - -

Instance Method Detail

- -
-
- - def add_aggregate_field(name : String) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def add_parameter(value : DB::Any) : String - - # -
- -
-
- - [View source] - -
-
- -
-
- abstract - def count : Int64 - - # -
- -
-
- - [View source] - -
-
- -
-
- abstract - def delete - - # -
- -
-
- - [View source] - -
-
- -
-
- - def field_list - - # -
- -
-
- - [View source] - -
-
- -
-
- abstract - def first(n : Int32 = 1) : Array(Model) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def numbered_parameters - - # -
- -
-
- - [View source] - -
-
- -
-
- - def table_name - - # -
- -
-
- - [View source] - -
-
- - - - - -
- - - diff --git a/docs/Granite/Query/Assembler/Postgresql.html b/docs/Granite/Query/Assembler/Postgresql.html deleted file mode 100644 index ee836c02..00000000 --- a/docs/Granite/Query/Assembler/Postgresql.html +++ /dev/null @@ -1,607 +0,0 @@ - - - - - - - - Granite::Query::Assembler::Postgresql(Model) - github.com/Amber-Crystal/granite-orm - - - -
- - - - - - -
- -
-

- - class Granite::Query::Assembler::Postgresql(Model) - -

- - - - - - - - - - - - - - - - - - - - -

Defined in:

- - - granite/query/assemblers/postgresql.cr - -
- - - - - - -

Constructors

- - - - - - -

Instance Method Summary

- - - - - - - - - -

Constructor Detail

- -
-
- - def self.new(query : Granite::Query::Builder(Model)) - - # -
- -
-
- - [View source] - -
-
- - - - - - -

Instance Method Detail

- -
-
- - def build_group_by - - # -
- -
-
- - [View source] - -
-
- -
-
- - def build_order(use_default_order = true) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def build_where - - # -
- -
-
- - [View source] - -
-
- -
-
- - def count : Granite::Query::Executor::Value(Model, Int64) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def default_order - - # -
- -
-
- - [View source] - -
-
- -
-
- - def delete - - # -
- -
-
- - [View source] - -
-
- -
-
- - def first(n : Int32 = 1) : Granite::Query::Executor::List(Model) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def log(*stuff) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def select - - # -
- -
-
- - [View source] - -
-
- - - - - -
- - - diff --git a/docs/Granite/Query/Builder.html b/docs/Granite/Query/Builder.html deleted file mode 100644 index 84064684..00000000 --- a/docs/Granite/Query/Builder.html +++ /dev/null @@ -1,753 +0,0 @@ - - - - - - - - Granite::Query::Builder(Model) - github.com/Amber-Crystal/granite-orm - - - -
- - - - - - -
- -
-

- - class Granite::Query::Builder(Model) - -

- - - - - - - -

Overview

- -

Data structure which will allow chaining of query components, -nesting of boolean logic, etc.

- -

Should return self, or another instance of Builder wherever -chaining should be possible.

- -

Current query syntax:

- -
  • where(field: value) => "WHERE field = 'value'"
- -

Hopefully soon:

- -
  • Model.where(field: value).not( Model.where(field2: value2) ) -or
  • Model.where(field: value).not { where(field2: value2) }
- -
  • Model.where(field: value).or( Model.where(field3: value3) ) -or
  • Model.where(field: value).or { whehre(field3: value3) }
- - - - - - - - - - - - - - -

Defined in:

- - - granite/query/builder.cr - -
- - - - - - -

Constructors

- - - - - - -

Instance Method Summary

- - - - - - -
- - - - - - - - - - - - - - - - - - - - - -
- - -

Constructor Detail

- -
-
- - def self.new(boolean_operator = :and) - - # -
- -
-
- - [View source] - -
-
- - - - - - -

Instance Method Detail

- -
-
- - def any? : Bool - - # -
- -
-
- - [View source] - -
-
- -
-
- - def assembler - - # -
- -
-
- - [View source] - -
-
- -
-
- - def count : Granite::Query::Executor::Value(Model, Int64) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def delete - - # -
- -
-
- - [View source] - -
-
- -
-
- - def each(&block) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def first(n : Int32) : Granite::Query::Executor::List(Model) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def first : Model? - - # -
- -
-
- - [View source] - -
-
- -
-
- - def map(&block) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def order - - # -
- -
-
- - [View source] - -
-
- -
-
- - def order(fields : Array(Symbol)) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def order(field : Symbol) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def order_fields - - # -
- -
-
- - [View source] - -
-
- -
-
- - def raw_sql - - # -
- -
-
- - [View source] - -
-
- -
-
- - def reject(&block) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def select - - # -
- -
-
- - [View source] - -
-
- -
-
- - def size - - # -
- -
-
- - [View source] - -
-
- -
-
- - def where - - # -
- -
-
- - [View source] - -
-
- -
-
- - def where_fields - - # -
- -
-
- - [View source] - -
-
- - - - - -
- - - diff --git a/docs/Granite/Query/Builder/FieldData.html b/docs/Granite/Query/Builder/FieldData.html deleted file mode 100644 index 40a3a4b6..00000000 --- a/docs/Granite/Query/Builder/FieldData.html +++ /dev/null @@ -1,299 +0,0 @@ - - - - - - - - Granite::Query::Builder::FieldData - github.com/Amber-Crystal/granite-orm - - - -
- - - - - - -
- -
-

- - alias Granite::Query::Builder::FieldData - -

- - - - - - - -

Alias Definition

- Bool | Float32 | Float64 | Int32 | Int64 | Slice(UInt8) | String | Time | Nil - - - - - - - - - - - - -

Defined in:

- - - granite/query/builder.cr - -
- - - - - - - - - - - - - - -
- -
- - - - - - - - - -
- - - diff --git a/docs/Granite/Query/Builder/FieldName.html b/docs/Granite/Query/Builder/FieldName.html deleted file mode 100644 index 672aa144..00000000 --- a/docs/Granite/Query/Builder/FieldName.html +++ /dev/null @@ -1,299 +0,0 @@ - - - - - - - - Granite::Query::Builder::FieldName - github.com/Amber-Crystal/granite-orm - - - -
- - - - - - -
- -
-

- - alias Granite::Query::Builder::FieldName - -

- - - - - - - -

Alias Definition

- String - - - - - - - - - - - - -

Defined in:

- - - granite/query/builder.cr - -
- - - - - - - - - - - - - - -
- -
- - - - - - - - - -
- - - diff --git a/docs/Granite/Query/Builder/Sort.html b/docs/Granite/Query/Builder/Sort.html deleted file mode 100644 index a73e1ad0..00000000 --- a/docs/Granite/Query/Builder/Sort.html +++ /dev/null @@ -1,403 +0,0 @@ - - - - - - - - Granite::Query::Builder::Sort - github.com/Amber-Crystal/granite-orm - - - -
- - - - - - -
- -
-

- - enum Granite::Query::Builder::Sort - -

- - - - - - - - - - - - - - - - - - -

Defined in:

- - - granite/query/builder.cr - -
- - - - - -

Enum Members

- -
- -
- Ascending = 0 -
- - -
- Descending = 1 -
- - -
- - - - - - - -

Instance Method Summary

- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - -

Instance Method Detail

- -
-
- - def ascending? - - # -
- -
-
- - [View source] - -
-
- -
-
- - def descending? - - # -
- -
-
- - [View source] - -
-
- - - - - -
- - - diff --git a/docs/Granite/Query/BuilderMethods.html b/docs/Granite/Query/BuilderMethods.html deleted file mode 100644 index 45443e5a..00000000 --- a/docs/Granite/Query/BuilderMethods.html +++ /dev/null @@ -1,418 +0,0 @@ - - - - - - - - Granite::Query::BuilderMethods - github.com/Amber-Crystal/granite-orm - - - -
- - - - - - -
- -
-

- - module Granite::Query::BuilderMethods - -

- - - - - -

Overview

- -

DSL to be included into a model -To activate, simply

- -

class Model < Granite::Base - include Query::BuilderMethods -end

- - - - - - - - - - - - - - -

Defined in:

- - - granite/query/builder_methods.cr - -
- - - - - - - - - - -

Instance Method Summary

- - - - - - -
- -
- - - - - - -

Instance Method Detail

- -
-
- - def __builder - - # -
- -
-
- - [View source] - -
-
- -
-
- - def count : Granite::Query::Executor::Value(self, Int64) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def first(n : Int32) : Granite::Query::Executor::List(self) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def first : self? - - # -
- -
-
- - [View source] - -
-
- -
-
- - def where : Builder - - # -
- -
-
- - [View source] - -
-
- - - - - -
- - - diff --git a/docs/Granite/Query/Executor.html b/docs/Granite/Query/Executor.html deleted file mode 100644 index 3633bf86..00000000 --- a/docs/Granite/Query/Executor.html +++ /dev/null @@ -1,306 +0,0 @@ - - - - - - - - Granite::Query::Executor - github.com/Amber-Crystal/granite-orm - - - -
- - - - - - -
- -
-

- - module Granite::Query::Executor - -

- - - - - - - - - - - - - - - - - - -

Defined in:

- - - granite/query/executors/base.cr - -
- - - granite/query/executors/list.cr - -
- - - granite/query/executors/value.cr - -
- - - - - - - - - - - - - - -
- -
- - - - - - - - - -
- - - diff --git a/docs/Granite/Query/Executor/List.html b/docs/Granite/Query/Executor/List.html deleted file mode 100644 index 80fd186d..00000000 --- a/docs/Granite/Query/Executor/List.html +++ /dev/null @@ -1,659 +0,0 @@ - - - - - - - - Granite::Query::Executor::List(Model) - github.com/Amber-Crystal/granite-orm - - - -
- - - - - - -
- -
-

- - class Granite::Query::Executor::List(Model) - -

- - - - - - - - - - - -

Included Modules

- - - - - - - - - - - -

Defined in:

- - - granite/query/executors/list.cr - -
- - - - - - -

Constructors

- - - - - - -

Instance Method Summary

- - - - - - -
- - - -

Instance methods inherited from module Granite::Query::Executor::Shared

- - - - log(*messages) - log, - - - - raw_sql : String - raw_sql - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - -

Constructor Detail

- -
-
- - def self.new(sql : String, args = [] of DB::Any) - - # -
- -
-
- - [View source] - -
-
- - - - - - -

Instance Method Detail

- -
-
- - def [](*args, **options) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def [](*args, **options, &block) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def each(*args, **options) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def each(*args, **options, &block) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def first(*args, **options) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def first(*args, **options, &block) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def first?(*args, **options) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def first?(*args, **options, &block) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def group_by(*args, **options) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def group_by(*args, **options, &block) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def run : Array(Model) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def to_s(*args, **options) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def to_s(*args, **options, &block) - - # -
- -
-
- - [View source] - -
-
- - - - - -
- - - diff --git a/docs/Granite/Query/Executor/Shared.html b/docs/Granite/Query/Executor/Shared.html deleted file mode 100644 index b6cde826..00000000 --- a/docs/Granite/Query/Executor/Shared.html +++ /dev/null @@ -1,355 +0,0 @@ - - - - - - - - Granite::Query::Executor::Shared - github.com/Amber-Crystal/granite-orm - - - -
- - - - - - -
- -
-

- - module Granite::Query::Executor::Shared - -

- - - - - - - - - - - - - - - -

Direct including types

- - - - - -

Defined in:

- - - granite/query/executors/base.cr - -
- - - - - - - - - - -

Instance Method Summary

- - - - - - -
- -
- - - - - - -

Instance Method Detail

- -
-
- - def log(*messages) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def raw_sql : String - - # -
- -
-
- - [View source] - -
-
- - - - - -
- - - diff --git a/docs/Granite/Query/Executor/Value.html b/docs/Granite/Query/Executor/Value.html deleted file mode 100644 index e34a2609..00000000 --- a/docs/Granite/Query/Executor/Value.html +++ /dev/null @@ -1,659 +0,0 @@ - - - - - - - - Granite::Query::Executor::Value(Model, Scalar) - github.com/Amber-Crystal/granite-orm - - - -
- - - - - - -
- -
-

- - class Granite::Query::Executor::Value(Model, Scalar) - -

- - - - - - - - - - - -

Included Modules

- - - - - - - - - - - -

Defined in:

- - - granite/query/executors/value.cr - -
- - - - - - -

Constructors

- - - - - - -

Instance Method Summary

- - - - - - -
- - - -

Instance methods inherited from module Granite::Query::Executor::Shared

- - - - log(*messages) - log, - - - - raw_sql : String - raw_sql - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - -

Constructor Detail

- -
-
- - def self.new(sql : String, args = [] of DB::Any, default : Scalar = nil) - - # -
- -
-
- - [View source] - -
-
- - - - - - -

Instance Method Detail

- -
-
- - def <(*args, **options) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def <(*args, **options, &block) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def <=(*args, **options) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def <=(*args, **options, &block) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def >(*args, **options) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def >(*args, **options, &block) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def >=(*args, **options) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def >=(*args, **options, &block) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def run : Scalar - - # -
- -
-
- - [View source] - -
-
- -
-
- - def to_i(*args, **options) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def to_i(*args, **options, &block) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def to_s(*args, **options) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def to_s(*args, **options, &block) - - # -
- -
-
- - [View source] - -
-
- - - - - -
- - - diff --git a/docs/Granite/Querying.html b/docs/Granite/Querying.html deleted file mode 100644 index 35cf6b3a..00000000 --- a/docs/Granite/Querying.html +++ /dev/null @@ -1,653 +0,0 @@ - - - - - - - - Granite::Querying - github.com/Amber-Crystal/granite-orm - - - -
- - - - - - -
- -
-

- - module Granite::Querying - -

- - - - - - - - - - - - - - - - - - -

Defined in:

- - - granite/querying.cr - -
- - - - - - - - - - -

Instance Method Summary

- - - - - - -
- -
- - - - - - -

Instance Method Detail

- -
-
- - def all(clause = "", params = [] of DB::Any) - - # -
- -

All will return all rows in the database. The clause allows you to specify -a WHERE, JOIN, GROUP BY, ORDER BY and any other SQL92 compatible query to -your table. The result will be a Collection(Model) object which lazy loads -an array of instantiated instances of your Model class. -This allows you to take full advantage of the database -that you are using so you are not restricted or dummied down to support a -DSL. -Lazy load prevent running unnecessary queries from unused variables.

- -
-
- - [View source] - -
-
- -
-
- - def clear - - # -
- -

Clear is used to remove all rows from the table and reset the counter for -the primary key.

- -
-
- - [View source] - -
-
- -
-
- - def count : Int32 - - # -
- -

count returns a count of all the records

- -
-
- - [View source] - -
-
- -
-
- - def exec(clause = "") - - # -
- -
-
- - [View source] - -
-
- -
-
- - def find(value) - - # -
- -

find returns the row with the primary key specified. -it checks by primary by default, but one can pass -another field for comparison

- -
-
- - [View source] - -
-
- -
-
- - def find!(value) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def find_by(field : String | Symbol, value) - - # -
- -

find_by returns the first row found where the field maches the value

- -
-
- - [View source] - -
-
- -
-
- - def find_by!(field : String | Symbol, value) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def find_each(clause = "", params = [] of DB::Any, batch_size limit = 100, offset = 0, &block) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def find_in_batches(clause = "", params = [] of DB::Any, batch_size limit = 100, offset = 0, &block) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def first(clause = "", params = [] of DB::Any) - - # -
- -

First adds a LIMIT 1 clause to the query and returns the first result

- -
-
- - [View source] - -
-
- -
-
- - def first!(clause = "", params = [] of DB::Any) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def query(clause = "", params = [] of DB::Any, &block) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def raw_all(clause = "", params = [] of DB::Any) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def scalar(clause = "", &block) - - # -
- -
-
- - [View source] - -
-
- - - - - -
- - - diff --git a/docs/Granite/Querying/NotFound.html b/docs/Granite/Querying/NotFound.html deleted file mode 100644 index b6dcb5bd..00000000 --- a/docs/Granite/Querying/NotFound.html +++ /dev/null @@ -1,328 +0,0 @@ - - - - - - - - Granite::Querying::NotFound - github.com/Amber-Crystal/granite-orm - - - -
- - - - - - -
- -
-

- - class Granite::Querying::NotFound - -

- - - - - - - - - - - - - - - - - - - - -

Defined in:

- - - granite/querying.cr - -
- - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - -
- - - diff --git a/docs/Granite/Settings.html b/docs/Granite/Settings.html deleted file mode 100644 index a481c76b..00000000 --- a/docs/Granite/Settings.html +++ /dev/null @@ -1,439 +0,0 @@ - - - - - - - - Granite::Settings - github.com/Amber-Crystal/granite-orm - - - -
- - - - - - -
- -
-

- - class Granite::Settings - -

- - - - - - - - - - - - - - - - - - - - -

Defined in:

- - - granite/settings.cr - -
- - - - - - -

Constructors

-
    - -
  • - .new - -
  • - -
- - - - - -

Instance Method Summary

- - - - - - -
- - - - - - - - - - - - - - - - - - - - - -
- - -

Constructor Detail

- -
-
- - def self.new - - # -
- -
-
- - [View source] - -
-
- - - - - - -

Instance Method Detail

- -
-
- - def database_url : String? - - # -
- -
-
- - [View source] - -
-
- -
-
- - def database_url=(database_url : String?) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def logger : Logger - - # -
- -
-
- - [View source] - -
-
- -
-
- - def logger=(logger : Logger) - - # -
- -
-
- - [View source] - -
-
- - - - - -
- - - diff --git a/docs/Granite/Table.html b/docs/Granite/Table.html deleted file mode 100644 index 0f39407c..00000000 --- a/docs/Granite/Table.html +++ /dev/null @@ -1,433 +0,0 @@ - - - - - - - - Granite::Table - github.com/Amber-Crystal/granite-orm - - - -
- - - - - - -
- -
-

- - module Granite::Table - -

- - - - - - - - - - - - - - - -

Direct including types

- - - - - -

Defined in:

- - - granite/table.cr - -
- - - - - - - - - - - - -

Macro Summary

-
    - -
  • - __process_table - -
  • - -
  • - adapter(name) - -

    specify the database adapter you will be using for this model.

    - -
  • - -
  • - primary(decl) - -

    specify the primary key column and type

    - -
  • - -
  • - primary(decl, auto) - -

    specify the primary key column and type and auto_increment

    - -
  • - -
  • - table_name(name) - -

    specify the table name to use otherwise it will use the model's name

    - -
  • - -
- - - -
- -
- - - - - - - - -

Macro Detail

- -
-
- - macro __process_table - - # -
- -
-
- - [View source] - -
-
- -
-
- - macro adapter(name) - - # -
- -

specify the database adapter you will be using for this model. -mysql, pg, sqlite, etc.

- -
-
- - [View source] - -
-
- -
-
- - macro primary(decl) - - # -
- -

specify the primary key column and type

- -
-
- - [View source] - -
-
- -
-
- - macro primary(decl, auto) - - # -
- -

specify the primary key column and type and auto_increment

- -
-
- - [View source] - -
-
- -
-
- - macro table_name(name) - - # -
- -

specify the table name to use otherwise it will use the model's name

- -
-
- - [View source] - -
-
- - - -
- - - diff --git a/docs/Granite/Transactions.html b/docs/Granite/Transactions.html deleted file mode 100644 index f63b9951..00000000 --- a/docs/Granite/Transactions.html +++ /dev/null @@ -1,415 +0,0 @@ - - - - - - - - Granite::Transactions - github.com/Amber-Crystal/granite-orm - - - -
- - - - - - -
- -
-

- - module Granite::Transactions - -

- - - - - - - - - - - - - - - -

Direct including types

- - - - - -

Defined in:

- - - granite/transactions.cr - -
- - - - - - - - - - -

Instance Method Summary

- - - - -

Macro Summary

- - - - -
- -
- - - - - - -

Instance Method Detail

- -
-
- - def destroyed? : Bool - - # -
- -

Returns true if this object has been destroyed.

- -
-
- - [View source] - -
-
- -
-
- - def new_record? : Bool - - # -
- -

Returns true if this object hasn't been saved yet.

- -
-
- - [View source] - -
-
- -
-
- - def persisted? - - # -
- -

Returns true if the record is persisted.

- -
-
- - [View source] - -
-
- - - - -

Macro Detail

- -
-
- - macro __process_transactions - - # -
- -
-
- - [View source] - -
-
- - - -
- - - diff --git a/docs/Granite/Transactions/ClassMethods.html b/docs/Granite/Transactions/ClassMethods.html deleted file mode 100644 index 75b5fdaf..00000000 --- a/docs/Granite/Transactions/ClassMethods.html +++ /dev/null @@ -1,346 +0,0 @@ - - - - - - - - Granite::Transactions::ClassMethods - github.com/Amber-Crystal/granite-orm - - - -
- - - - - - -
- -
-

- - module Granite::Transactions::ClassMethods - -

- - - - - - - - - - - - - - - - - - -

Defined in:

- - - granite/transactions.cr - -
- - - - - - - - - - -

Instance Method Summary

- - - - - - -
- -
- - - - - - -

Instance Method Detail

- -
-
- - def create(args : Hash(Symbol | String, DB::Any)) - - # -
- -
-
- - [View source] - -
-
- -
-
- - def create - - # -
- -
-
- - [View source] - -
-
- - - - - -
- - - diff --git a/docs/Granite/Validators.html b/docs/Granite/Validators.html deleted file mode 100644 index 75d27570..00000000 --- a/docs/Granite/Validators.html +++ /dev/null @@ -1,370 +0,0 @@ - - - - - - - - Granite::Validators - github.com/Amber-Crystal/granite-orm - - - -
- - - - - - -
- -
-

- - module Granite::Validators - -

- - - - - -

Overview

- -

Analyze validation blocks and procs

- -

By example:

- -
validate :name, "can't be blank" do |user|
-  !user.name.to_s.blank?
-end
-
-validate :name, "can't be blank", ->(user : User) do
-  !user.name.to_s.blank?
-end
-
-name_required = ->(model : Granite::Base) { !model.name.to_s.blank? }
-validate :name, "can't be blank", name_required
- - - - - - - - - - - -

Direct including types

- - - - - -

Defined in:

- - - granite/validators.cr - -
- - - - - - - - - - -

Instance Method Summary

- - - - - - -
- -
- - - - - - -

Instance Method Detail

- -
-
- - def errors - - # -
- -
-
- - [View source] - -
-
- -
-
- - def valid? - - # -
- -
-
- - [View source] - -
-
- - - - - -
- - - diff --git a/docs/callbacks.md b/docs/callbacks.md new file mode 100644 index 00000000..d59e74b7 --- /dev/null +++ b/docs/callbacks.md @@ -0,0 +1,49 @@ +# Callbacks + +Call a specified method on a specific life cycle event. + +Here is an example: + +```crystal +require "granite/adapter/pg" + +class Post < Granite::Base + adapter pg + + before_save :upcase_title + + field title : String + field content : String + timestamps + + def upcase_title + if title = @title + @title = title.upcase + end + end +end +``` + +You can register callbacks for the following events: + +## Create + +- before_save +- before_create +- **save** +- after_create +- after_save + +## Update + +- before_save +- before_update +- **save** +- after_update +- after_save + +## Destroy + +- before_destroy +- **destroy** +- after_destroy diff --git a/docs/crud.md b/docs/crud.md new file mode 100644 index 00000000..a8cab753 --- /dev/null +++ b/docs/crud.md @@ -0,0 +1,112 @@ +# CRUD + +## Create + +Combination of object creation and insertion into database. + +``` +Post.create(name: "Granite Rocks!", body: "Check this out.") # Set attributes and call save +Post.create!(name: "Granite Rocks!", body: "Check this out.") # Set attributes and call save!. Will throw an exception when the save failed +``` + +## Insert + +Inserts an already created object into the database. + +```crystal +post = Post.new +post.name = "Granite Rocks!" +post.body = "Check this out." +post.save + +post = Post.new +post.name = "Granite Rocks!" +post.body = "Check this out." +post.save! # raises when save failed +``` + +## Read + +### find + +Finds the record with the given primary key. + +```crystal +post = Post.find 1 +if post + puts post.name +end + +post = Post.find! 1 # raises when no records found +``` +### find_by + +Finds the record(s) that match the given criteria + +```crystal +post = Post.find_by(slug: "example_slug") +if post + puts post.name +end + +post = Post.find_by!(slug: "foo") # raises when no records found. +other_post = Post.find_by(slug: "foo", type: "bar") # Also works for multiple arguments. +``` +### first + +Returns the first record. + +```crystal +post = Post.first +if post + puts post.name +end + +post = Post.first! # raises when no records exist +``` +### all + +Returns all records of a model. + +```crystal +posts = Post.all +if posts + posts.each do |post| + puts post.name + end +end +``` + + +## Update + +Updates a given record already saved in the database. + +```crystal +post = Post.find 1 +post.name = "Granite Really Rocks!" +post.save + +post = Post.find 1 +post.update(name: "Granite Really Rocks!") # Assigns attributes and calls save + +post = Post.find 1 +post.update!(name: "Granite Really Rocks!") # Assigns attributes and calls save!. Will throw an exception when the save failed +``` +## Delete + +Delete a specific record. + +```crystal +post = Post.find 1 +post.destroy +puts "deleted" unless post + +post = Post.find 1 +post.destroy! # raises when delete failed +``` +Clear all records of a model + +```crystal +Post.clear #truncate the table +``` \ No newline at end of file diff --git a/docs/css/style.css b/docs/css/style.css deleted file mode 100644 index 2994e372..00000000 --- a/docs/css/style.css +++ /dev/null @@ -1,432 +0,0 @@ -html, body { - position: relative; - margin: 0; - padding: 0; - width: 100%; - height: 100%; - overflow: hidden; -} - -body { - font-family: "Avenir", "Tahoma", "Lucida Sans", "Lucida Grande", Verdana, Arial, sans-serif; - color: #333; -} - -a { - color: #263F6C; -} - -a:visited { - color: #112750; -} - -h1, h2, h3, h4, h5, h6 { - margin: 35px 0 25px; - color: #444444; -} - -h1.type-name { - color: #47266E; - margin: 20px 0 30px; - background-color: #F8F8F8; - padding: 10px 12px; - border: 1px solid #EBEBEB; - border-radius: 2px; -} - -h2 { - border-bottom: 1px solid #E6E6E6; - padding-bottom: 5px; -} - -#types-list, #main-content { - position: absolute; - top: 0; - bottom: 0; - overflow: auto; -} - -#types-list { - left: 0; - width: 20%; - background-color: #2E1052; - padding: 0 0 30px; - box-shadow: inset -3px 0 4px rgba(0,0,0,.35); -} - -#types-list #search-box { - padding: 8px 9px; -} - -#types-list input { - display: block; - box-sizing: border-box; - margin: 0; - padding: 5px; - font: inherit; - font-family: inherit; - line-height: 1.2; - width: 100%; - border: 0; - outline: 0; - border-radius: 2px; - box-shadow: 0px 3px 5px rgba(0,0,0,.25); - transition: box-shadow .12s; -} - -#types-list input:focus { - box-shadow: 0px 5px 6px rgba(0,0,0,.5); -} - -#types-list input::-webkit-input-placeholder { /* Chrome/Opera/Safari */ - color: #C8C8C8; - font-size: 14px; - text-indent: 2px; -} - -#types-list input::-moz-placeholder { /* Firefox 19+ */ - color: #C8C8C8; - font-size: 14px; - text-indent: 2px; -} - -#types-list input:-ms-input-placeholder { /* IE 10+ */ - color: #C8C8C8; - font-size: 14px; - text-indent: 2px; -} - -#types-list input:-moz-placeholder { /* Firefox 18- */ - color: #C8C8C8; - font-size: 14px; - text-indent: 2px; -} - -#types-list ul { - margin: 0; - padding: 0; - list-style: none outside; -} - -#types-list li { - display: block; - position: relative; -} - -#types-list li.hide { - display: none; -} - -#types-list a { - display: block; - padding: 5px 15px 5px 30px; - text-decoration: none; - color: #F8F4FD; - transition: color .14s; -} - -#types-list a:focus { - outline: 1px solid #D1B7F1; -} - -#types-list .current > a, -#types-list a:hover { - color: #866BA6; -} - -#types-list li ul { - overflow: hidden; - height: 0; - max-height: 0; - transition: 1s ease-in-out; -} - - -#types-list li.parent { - padding-left: 30px; -} - -#types-list li.parent::before { - box-sizing: border-box; - content: "â–¼"; - display: block; - width: 30px; - height: 30px; - position: absolute; - top: 0; - left: 0; - text-align: center; - color: white; - font-size: 8px; - line-height: 30px; - transform: rotateZ(-90deg); - cursor: pointer; - transition: .2s linear; -} - - -#types-list li.parent > a { - padding-left: 0; -} - -#types-list li.parent.open::before { - transform: rotateZ(0); -} - -#types-list li.open > ul { - height: auto; - max-height: 1000em; -} - -#main-content { - padding: 0 30px 30px 30px; - left: 20%; - right: 0; -} - -.kind { - font-size: 60%; - color: #866BA6; -} - -.superclass-hierarchy { - margin: -15px 0 30px 0; - padding: 0; - list-style: none outside; - font-size: 80%; -} - -.superclass-hierarchy .superclass { - display: inline-block; - margin: 0 7px 0 0; - padding: 0; -} - -.superclass-hierarchy .superclass + .superclass::before { - content: "<"; - margin-right: 7px; -} - -.other-types-list li { - display: inline-block; -} - -.other-types-list, -.list-summary { - margin: 0 0 30px 0; - padding: 0; - list-style: none outside; -} - -.entry-const { - font-family: Consolas, 'Courier New', Courier, Monaco, monospace; -} - -.entry-summary { - padding-bottom: 4px; -} - -.superclass-hierarchy .superclass a, -.other-type a, -.entry-summary .signature { - padding: 4px 8px; - margin-bottom: 4px; - display: inline-block; - background-color: #f8f8f8; - color: #47266E; - border: 1px solid #f0f0f0; - text-decoration: none; - border-radius: 3px; - font-family: Consolas, 'Courier New', Courier, Monaco, monospace; - transition: background .15s, border-color .15s; -} - -.superclass-hierarchy .superclass a:hover, -.other-type a:hover, -.entry-summary .signature:hover { - background: #D5CAE3; - border-color: #624288; -} - -.entry-summary .summary { - padding-left: 32px; -} - -.entry-summary .summary p { - margin: 12px 0 16px; -} - -.entry-summary a { - text-decoration: none; -} - -.entry-detail { - padding: 30px 0; -} - -.entry-detail .signature { - position: relative; - padding: 5px 15px; - margin-bottom: 10px; - display: block; - border-radius: 5px; - background-color: #f8f8f8; - color: #47266E; - border: 1px solid #f0f0f0; - font-family: Consolas, 'Courier New', Courier, Monaco, monospace; - transition: .2s ease-in-out; -} - -.entry-detail:target .signature { - background-color: #D5CAE3; - border: 1px solid #624288; -} - -.entry-detail .signature .method-permalink { - position: absolute; - top: 0; - left: -35px; - padding: 5px 15px; - text-decoration: none; - font-weight: bold; - color: #624288; - opacity: .4; - transition: opacity .2s; -} - -.entry-detail .signature .method-permalink:hover { - opacity: 1; -} - -.entry-detail:target .signature .method-permalink { - opacity: 1; -} - -.methods-inherited { - padding-right: 10%; - line-height: 1.5em; -} - -.methods-inherited h3 { - margin-bottom: 4px; -} - -.methods-inherited a { - display: inline-block; - text-decoration: none; - color: #47266E; -} - -.methods-inherited a:hover { - text-decoration: underline; - color: #6C518B; -} - -.methods-inherited .tooltip>span { - background: #D5CAE3; - padding: 4px 8px; - border-radius: 3px; - margin: -4px -8px; -} - -.methods-inherited .tooltip * { - color: #47266E; -} - -pre { - padding: 10px 20px; - margin-top: 4px; - border-radius: 3px; - line-height: 1.45; - overflow: auto; - color: #333; - background: #fdfdfd; - font-size: 14px; - border: 1px solid #eee; -} - -code { - font-family: Consolas, 'Courier New', Courier, Monaco, monospace; -} - -span.flag { - padding: 2px 4px 1px; - border-radius: 3px; - margin-right: 3px; - font-size: 11px; - border: 1px solid transparent; -} - -span.flag.orange { - background-color: #EE8737; - color: #FCEBDD; - border-color: #EB7317; -} - -span.flag.yellow { - background-color: #E4B91C; - color: #FCF8E8; - border-color: #B69115; -} - -span.flag.green { - background-color: #469C14; - color: #E2F9D3; - border-color: #34700E; -} - -span.flag.red { - background-color: #BF1919; - color: #F9ECEC; - border-color: #822C2C; -} - -span.flag.purple { - background-color: #2E1052; - color: #ECE1F9; - border-color: #1F0B37; -} - -.tooltip>span { - position: absolute; - opacity: 0; - display: none; - pointer-events: none; -} - -.tooltip:hover>span { - display: inline-block; - opacity: 1; -} - -.c { - color: #969896; -} - -.n { - color: #0086b3; -} - -.t { - color: #0086b3; -} - -.s { - color: #183691; -} - -.i { - color: #7f5030; -} - -.k { - color: #a71d5d; -} - -.o { - color: #a71d5d; -} - -.m { - color: #795da3; -} diff --git a/docs/getting_started.md b/docs/getting_started.md new file mode 100644 index 00000000..b86df9cf --- /dev/null +++ b/docs/getting_started.md @@ -0,0 +1,119 @@ +# Getting Started + +## Installation + +Add this library to your projects dependencies along with the driver in +your `shard.yml`. This can be used with any framework but was originally +designed to work with the amber framework in mind. This library will work +with kemal or any other framework as well. + +```yaml +dependencies: + granite: + github: amberframework/granite + + # Pick your database + mysql: + github: crystal-lang/crystal-mysql + + sqlite3: + github: crystal-lang/crystal-sqlite3 + + pg: + github: will/crystal-pg + +``` + +Next you will need to create a `config/database.yml` +You can leverage environment variables using `${}` syntax. + +```yaml +mysql: + database: "mysql://username:password@hostname:3306/database_${AMBER_ENV}" +pg: + database: "postgres://username:password@hostname:5432/database" +sqlite: + database: "sqlite3:./config/${DB_NAME}.db" +``` + +Or you can set the `DATABASE_URL` environment variable. This will override the config/database.yml + +## Usage + +Here is an example using Granite Model + +```crystal +require "granite/adapter/mysql" + +class Post < Granite::Base + adapter mysql + field name : String + field body : String + timestamps +end +``` + +### id, created_at, updated_at + +The primary key is automatically created for you and if you use `timestamps` they will be +automatically updated for you. + +Here are the MySQL field definitions for id, created_at, updated_at + +```mysql + id BIGINT NOT NULL AUTO_INCREMENT + # Your fields go here + created_at TIMESTAMP + updated_at TIMESTAMP +``` + +### Custom Primary Key + +For legacy database mappings, you may already have a table and the primary key is not named `id` or `Int64`. + +Use the `primary` macro to define your own primary key + +```crystal +class Site < Granite::Base + adapter mysql + primary custom_id : Int32 + field name : String +end +``` + +This will override the default primary key of `id : Int64`. + +#### Natural Keys + +For natural keys, you can set `auto: false` option to disable auto increment. + +```crystal +class Site < Granite::Base + adapter mysql + primary code : String, auto: false + field name : String +end +``` + +#### UUIDs + +For databases that utilize UUIDs as the primary key, the `primary` macro can be used again with the `auto: false` option. A `before_create` callback can be added to the model to randomly generate and set a secure UUID on the record before it is saved to the database. + +```crystal +class Book < Granite::Base + require "uuid" + adapter mysql + primary ISBN : String, auto: false + field name : String + + before_create :assign_isbn + + def assign_isbn + @ISBN = UUID.random.to_s + end +end +``` + + + +See the [Docs folder](./) for additional information. \ No newline at end of file diff --git a/docs/imports.md b/docs/imports.md new file mode 100644 index 00000000..010e981a --- /dev/null +++ b/docs/imports.md @@ -0,0 +1,125 @@ +# Bulk Insertions + +## Import + +**Note: Imports do not trigger callbacks automatically. See [Running Callbacks](#running-callbacks).** + +Each model has an `import` class level method to import an array of models in one bulk insert statement. + ```Crystal + models = [ + Model.new(id: 1, name: "Fred", age: 14), + Model.new(id: 2, name: "Joe", age: 25), + Model.new(id: 3, name: "John", age: 30), + ] + + Model.import(models) + ``` + +## update_on_duplicate + +The `import` method has an optional `update_on_duplicate` + `columns` params that allows you to specify the columns (as an array of strings) that should be updated if primary constraint is violated. + ```Crystal + models = [ + Model.new(id: 1, name: "Fred", age: 14), + Model.new(id: 2, name: "Joe", age: 25), + Model.new(id: 3, name: "John", age: 30), + ] + + Model.import(models) + + Model.find!(1).name # => Fred + + models = [ + Model.new(id: 1, name: "George", age: 14), + ] + + Model.import(models, update_on_duplicate: true, columns: %w(name)) + + Model.find!(1).name # => George + ``` + +**NOTE: If using PostgreSQL you must have version 9.5+ to have the on_duplicate_key_update feature.** + +## ignore_on_duplicate + +The `import` method has an optional `ignore_on_duplicate` param, that takes a boolean, which will skip records if the primary constraint is violated. + ```Crystal + models = [ + Model.new(id: 1, name: "Fred", age: 14), + Model.new(id: 2, name: "Joe", age: 25), + Model.new(id: 3, name: "John", age: 30), + ] + + Model.import(models) + + Model.find!(1).name # => Fred + + models = [ + Model.new(id: 1, name: "George", age: 14), + ] + + Model.import(models, ignore_on_duplicate: true) + + Model.find!(1).name # => Fred + ``` + +## batch_size + +The `import` method has an optional `batch_size` param, that takes an integer. The batch_size determines the number of models to import in each INSERT statement. This defaults to the size of the models array, i.e. only 1 INSERT statement. + ```Crystal + models = [ + Model.new(id: 1, name: "Fred", age: 14), + Model.new(id: 2, name: "Joe", age: 25), + Model.new(id: 3, name: "John", age: 30), + Model.new(id: 3, name: "Bill", age: 66), + ] + + Model.import(models, batch_size: 2) + # => First SQL INSERT statement imports Fred and Joe + # => Second SQL INSERT statement imports John and Bill + ``` + +## Running Callbacks + +Since the `import` method runs on the class level, callbacks are not triggered automatically, they have to be triggered manually. For example, using the Item class with a UUID primary key: + ```Crystal + require "uuid" + + class Item < Granite::Base + adapter mysql + table_name items + + primary item_id : String, auto: false + field item_name : String + + before_create :generate_uuid + + def generate_uuid + @item_id = UUID.random.to_s + end + end + ``` + + ```Crystal + items = [ + Item.new(item_name: "item1"), + Item.new(item_name: "item2"), + Item.new(item_name: "item3"), + Item.new(item_name: "item4"), + ] + + # If we did `Item.import(items)` now, it would fail since the item_id wouldn't get set before saving the record, violating the primary key constraint. + + # Manually run the callback on each model to generate the item_id. + items.each(&.before_create) + + # Each model in the array now has a item_id set, so can be imported. + Item.import(items) + + # This can also be used for a single record. + item = Item.new(item_name: "item5") + item.before_create + item.save + ``` + +**Note: Manually running your callbacks is mainly aimed at bulk imports. Running them before a normal `.save`, for example, would run your callbacks twice.** diff --git a/docs/index.html b/docs/index.html deleted file mode 100644 index 484b27b3..00000000 --- a/docs/index.html +++ /dev/null @@ -1,830 +0,0 @@ - - - - - - - - README - github.com/Amber-Crystal/granite-orm - - - -
- - - - - - -
- -
-

Granite

- -

Amber is a web framework written in -the Crystal language.

- -

This project is to provide an ORM in Crystal.

- -

Build Status

- -

Installation

- -

Add this library to your projects dependencies along with the driver in -your shard.yml. This can be used with any framework but was originally -designed to work with the amber framework in mind. This library will work -with kemal or any other framework as well.

- -
dependencies:
-  granite:
-    github: amberframework/granite
-
-  # Pick your database
-  mysql:
-    github: crystal-lang/crystal-mysql
-
-  sqlite3:
-    github: crystal-lang/crystal-sqlite3
-
-  pg:
-    github: will/crystal-pg
-
- -

Next you will need to create a config/database.yml -You can leverage environment variables using ${} syntax.

- -
mysql:
-  database: "mysql://username:password@hostname:3306/database_${AMBER_ENV}"
-pg:
-  database: "postgres://username:password@hostname:5432/database"
-sqlite:
-  database: "sqlite3:./config/${DB_NAME}.db"
- -

Or you can set the DATABASE_URL environment variable. This will override the config/database.yml

- -

Usage

- -

Here is an example using Granite Model

- -
require "granite/adapter/mysql"
-
-class Post < Granite::Base
-  adapter mysql
-  field name : String
-  field body : String
-  timestamps
-end
- -

You can disable the timestamps for SqlLite since TIMESTAMP is not supported for this database:

- -
require "granite/adapter/sqlite"
-
-class Comment < Granite::Base
-  adapter sqlite
-  table_name post_comments
-  field name : String
-  field body : String
-end
- -

id, created_at, updated_at

- -

The primary key is automatically created for you and if you use timestamps they will be -automatically updated for you.

- -

Here are the MySQL field definitions for id, created_at, updated_at

- -
  id BIGINT NOT NULL AUTO_INCREMENT
-  # Your fields go here
-  created_at TIMESTAMP
-  updated_at TIMESTAMP
-  PRIMARY KEY (id)
- -

Custom Primary Key

- -

For legacy database mappings, you may already have a table and the primary key is not named id or Int64.

- -

We have a macro called primary to help you out:

- -
class Site < Granite::Base
-  adapter mysql
-  primary custom_id : Int32
-  field name : String
-end
- -

This will override the default primary key of id : Int64.

- -

Natural Keys

- -

For natural keys, you can set auto: false option to disable auto increment insert.

- -
class Site < Granite::Base
-  adapter mysql
-  primary code : String, auto: false
-  field name : String
-end
- -

UUIDs

- -

For databases that utilize UUIDs as the primary key, the primary macro can be used again with the auto: false option. A before_create callback can be added to the model to randomly generate and set a secure UUID on the record before it is saved to the database.

- -
class Book < Granite::Base
-  require "uuid"
-  adapter mysql
-  primary ISBN : String, auto: false
-  field name : String
-
-  before_create :assign_isbn
-
-  def assign_isbn
-    @ISBN = UUID.random.to_s
-  end
-end
- -

Bulk Insertions

- -

Import

- -

Note: Imports do not trigger callbacks automatically. See Running Callbacks.

- -

Each model has an import class level method to import an array of models in one bulk insert statement.

- -
models = [
-  Model.new(id: 1, name: "Fred", age: 14),
-  Model.new(id: 2, name: "Joe", age: 25),
-  Model.new(id: 3, name: "John", age: 30),
-]
-
-Model.import(models)
- -

update_on_duplicate

- -

The import method has an optional update_on_duplicate + columns params that allows you to specify the columns (as an array of strings) that should be updated if primary constraint is violated.

- -
models = [
-  Model.new(id: 1, name: "Fred", age: 14),
-  Model.new(id: 2, name: "Joe", age: 25),
-  Model.new(id: 3, name: "John", age: 30),
-]
-
-Model.import(models)
-
-Model.find!(1).name # => Fred
-
-models = [
-  Model.new(id: 1, name: "George", age: 14),
-]
-
-Model.import(models, update_on_duplicate: true, columns: %w(name))
-
-Model.find!(1).name # => George
- -

NOTE: If using PostgreSQL you must have version 9.5+ to have the on_duplicate_key_update feature.

- -

ignore_on_duplicate

- -

The import method has an optional ignore_on_duplicate param, that takes a boolean, which will skip records if the primary constraint is violated.

- -
models = [
-  Model.new(id: 1, name: "Fred", age: 14),
-  Model.new(id: 2, name: "Joe", age: 25),
-  Model.new(id: 3, name: "John", age: 30),
-]
-
-Model.import(models)
-
-Model.find!(1).name # => Fred
-
-models = [
-  Model.new(id: 1, name: "George", age: 14),
-]
-
-Model.import(models, ignore_on_duplicate: true)
-
-Model.find!(1).name # => Fred
- -

batch_size

- -

The import method has an optional batch_size param, that takes an integer. The batch_size determines the number of models to import in each INSERT statement. This defaults to the size of the models array, i.e. only 1 INSERT statement.

- -
models = [
-  Model.new(id: 1, name: "Fred", age: 14),
-  Model.new(id: 2, name: "Joe", age: 25),
-  Model.new(id: 3, name: "John", age: 30),
-  Model.new(id: 3, name: "Bill", age: 66),
-]
-
-Model.import(models, batch_size: 2)
-# => First SQL INSERT statement imports Fred and Joe
-# => Second SQL INSERT statement imports John and Bill
- -

Running Callbacks

- -

Since the import method runs on the class level, callbacks are not triggered automatically, they have to be triggered manually. For example, using the Item class with a UUID primary key:

- -
require "uuid"
-
-class Item < Granite::Base
-  adapter mysql
-  table_name items
-
-  primary item_id : String, auto: false
-  field item_name : String
-
-  before_create :generate_uuid
-
-  def generate_uuid
-    @item_id = UUID.random.to_s
-  end
-end  
- -
items = [
-  Item.new(item_name: "item1"),
-  Item.new(item_name: "item2"),
-  Item.new(item_name: "item3"),
-  Item.new(item_name: "item4"),
-]
-
-# If we did `Item.import(items)` now, it would fail since the item_id wouldn't get set before saving the record, violating the primary key constraint.
-
-# Manually run the callback on each model to generate the item_id.
-items.each(&.before_create)
-
-# Each model in the array now has a item_id set, so can be imported.
-Item.import(items)
-
-# This can also be used for a single record.
-item = Item.new(item_name: "item5")
-item.before_create
-item.save
- -

Note: Manually running your callbacks is mainly aimed at bulk imports. Running them before a normal .save, for example, would run your callbacks twice.

- -

SQL

- -

To clear all the rows in the database:

- -
Post.clear #truncate the table
- -

Find All

- -
posts = Post.all
-if posts
-  posts.each do |post|
-    puts post.name
-  end
-end
- -

Find First

- -
post = Post.first
-if post
-  puts post.name
-end
-
-post = Post.first! # raises when no records exist
- -

Find

- -
post = Post.find 1
-if post
-  puts post.name
-end
-
-post = Post.find! 1 # raises when no records found
- -

Find By

- -
post = Post.find_by :slug, "example_slug"
-if post
-  puts post.name
-end
-
-post = Post.find_by! :slug, "foo" # raises when no records found
- -

Insert

- -
post = Post.new
-post.name = "Granite Rocks!"
-post.body = "Check this out."
-post.save
- -

Update

- -
post = Post.find 1
-post.name = "Granite Really Rocks!"
-post.save
- -

Delete

- -
post = Post.find 1
-post.destroy
-puts "deleted" unless post
- -

Queries

- -

The where clause will give you full control over your query.

- -

All

- -

When using the all method, the SQL selected fields will always match the -fields specified in the model.

- -

Always pass in parameters to avoid SQL Injection. Use a ? -in your query as placeholder. Checkout the Crystal DB Driver -for documentation of the drivers.

- -

Here are some examples:

- -
posts = Post.all("WHERE name LIKE ?", ["Joe%"])
-if posts
-  posts.each do |post|
-    puts post.name
-  end
-end
-
-# ORDER BY Example
-posts = Post.all("ORDER BY created_at DESC")
-
-# JOIN Example
-posts = Post.all("JOIN comments c ON c.post_id = post.id
-                  WHERE c.name = ?
-                  ORDER BY post.created_at DESC",
-                  ["Joe"])
-
- -

First

- -

It is common to only want the first result and append a LIMIT 1 to the query. -This is what the first method does.

- -

For example:

- -
post = Post.first("ORDER BY posts.name DESC")
- -

This is the same as:

- -
post = Post.all("ORDER BY posts.name DESC LIMIT 1").first
- -

Relationships

- -

One to Many

- -

belongs_to and has_many macros provide a rails like mapping between Objects.

- -
class User < Granite::Base
-  adapter mysql
-
-  has_many :posts
-
-  field email : String
-  field name : String
-  timestamps
-end
- -

This will add a posts instance method to the user which returns an array of posts.

- -
class Post < Granite::Base
-  adapter mysql
-
-  belongs_to :user
-
-  field title : String
-  timestamps
-end
- -

This will add a user and user= instance method to the post.

- -

For example:

- -
user = User.find 1
-user.posts.each do |post|
-  puts post.title
-end
-
-post = Post.find 1
-puts post.user
-
-post.user = user
-post.save
- -

In this example, you will need to add a user_id and index to your posts table:

- -
CREATE TABLE posts (
-  id BIGSERIAL PRIMARY KEY,
-  user_id BIGINT,
-  title VARCHAR,
-  created_at TIMESTAMP,
-  updated_at TIMESTAMP
-);
-
-CREATE INDEX 'user_id_idx' ON posts (user_id);
- -

Many to Many

- -

Instead of using a hidden many-to-many table, Granite recommends always creating a model for your join tables. For example, let's say you have many users that belong to many rooms. We recommend adding a new model called participants to represent the many-to-many relationship.

- -

Then you can use the belongs_to and has_many relationships going both ways.

- -
class User < Granite::Base
-  has_many :participants
-
-  field name : String
-end
-
-class Participant < Granite::Base
-  belongs_to :user
-  belongs_to :room
-end
-
-class Room < Granite::Base
-  has_many :participants
-
-  field name : String
-end
- -

The Participant class represents the many-to-many relationship between the Users and Rooms.

- -

Here is what the database table would look like:

- -
CREATE TABLE participants (
-  id BIGSERIAL PRIMARY KEY,
-  user_id BIGINT,
-  room_id BIGINT,
-  created_at TIMESTAMP,
-  updated_at TIMESTAMP
-);
-
-CREATE INDEX 'user_id_idx' ON TABLE participants (user_id);
-CREATE INDEX 'room_id_idx' ON TABLE participants (room_id);
- -
has_many through:
- -

As a convenience, we provide a through: clause to simplify accessing the many-to-many relationship:

- -
class User < Granite::Base
-  has_many :participants
-  has_many :rooms, through: participants
-
-  field name : String
-end
-
-class Participant < Granite::Base
-  belongs_to :user
-  belongs_to :room
-end
-
-class Room < Granite::Base
-  has_many :participants
-  has_many :users, through: participants
-
-  field name : String
-end
- -

This will allow you to find all the rooms that a user is in:

- -
user = User.first
-user.rooms.each do |room|
-  puts room.name
-end
- -

And the reverse, all the users in a room:

- -
room = Room.first
-room.users.each do |user|
-  puts user.name
-end
- -

Errors

- -

All database errors are added to the errors array used by Granite::Validators with the symbol ':base'

- -
post = Post.new
-post.save
-post.errors[0].to_s.should eq "ERROR: name cannot be null"
- -

Callbacks

- -

There is support for callbacks on certain events.

- -

Here is an example:

- -
require "granite/adapter/pg"
-
-class Post < Granite::Base
-  adapter pg
-
-  before_save :upcase_title
-
-  field title : String
-  field content : String
-  timestamps
-
-  def upcase_title
-    if title = @title
-      @title = title.upcase
-    end
-  end
-end
- -

You can register callbacks for the following events:

- -

Create

- -
  • before_save
  • before_create
  • save
  • after_create
  • after_save
- -

Update

- -
  • before_save
  • before_update
  • save
  • after_update
  • after_save
- -

Destroy

- -
  • before_destroy
  • destroy
  • after_destroy
- -

Migration

- -
  • migrator provides drop, create and drop_and_create methods
- -
class User < Granite::Base
-  adapter mysql
-  field name : String
-end
-
-User.migrator.drop_and_create
-# => "DROP TABLE IF EXISTS `users`;"
-# => "CREATE TABLE `users` (id BIGSERIAL PRIMARY KEY, name VARCHAR(255));"
-
-User.migrator(table_options: "ENGINE=InnoDB DEFAULT CHARSET=utf8").create
-# => "CREATE TABLE ... ENGINE=InnoDB DEFAULT CHARSET=utf8;"
- -

Contributing

- -
  1. Fork it ( https://github.com/amberframework/granite/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request
- -

Running tests

- -

Granite uses Crystal's built in test framework. The tests can be run with $ crystal spec.

- -

The test suite depends on access to a PostgreSQL, MySQL, and SQLite database to ensure the adapters work as intended.

- -

Docker setup

- -

There is a self-contained testing environment provided via the docker-compose.yml file in this repository.

- -

After you have docker installed do the following to run tests:

- -

First run

- -
- -

Subsequent runs

- -
- -

Cleanup

- -

If you're done testing and you'd like to shut down and clean up the docker dependences run the following:

- -
- -

Local setup

- -

If you'd like to test without docker you can do so by following the instructions below:

- -
  1. Install dependencies with $ crystal deps
  2. Update .env to use appropriate ENV variables, or create appropriate databases.
  3. Setup databases:
- -

PostgreSQL

- -
CREATE USER granite WITH PASSWORD 'password';
-
-CREATE DATABASE granite_db;
-
-GRANT ALL PRIVILEGES ON DATABASE granite_db TO granite;
- -

MySQL

- -
CREATE USER 'granite'@'localhost' IDENTIFIED BY 'password';
-
-CREATE DATABASE granite_db;
-
-GRANT ALL PRIVILEGES ON granite_db.* TO 'granite'@'localhost' WITH GRANT OPTION;
- -
  1. Export .env with $ source .env
  2. $ crystal spec
-
- - diff --git a/docs/index.json b/docs/index.json deleted file mode 100644 index eb8aa4bc..00000000 --- a/docs/index.json +++ /dev/null @@ -1 +0,0 @@ -{"repository_name":"github.com/Amber-Crystal/granite-orm","body":"# Granite\n\n[Amber](https://github.com/Amber-Crystal/amber) is a web framework written in\nthe [Crystal](https://github.com/crystal-lang/crystal) language.\n\nThis project is to provide an ORM in Crystal.\n\n[![Build Status](https://img.shields.io/travis/amberframework/granite.svg?maxAge=360)](https://travis-ci.org/amberframework/granite)\n\n## Installation\n\nAdd this library to your projects dependencies along with the driver in\nyour `shard.yml`. This can be used with any framework but was originally\ndesigned to work with the amber framework in mind. This library will work\nwith kemal or any other framework as well.\n\n```yaml\ndependencies:\n granite:\n github: amberframework/granite\n\n # Pick your database\n mysql:\n github: crystal-lang/crystal-mysql\n\n sqlite3:\n github: crystal-lang/crystal-sqlite3\n\n pg:\n github: will/crystal-pg\n\n```\n\nNext you will need to create a `config/database.yml`\nYou can leverage environment variables using `${}` syntax.\n\n```yaml\nmysql:\n database: \"mysql://username:password@hostname:3306/database_${AMBER_ENV}\"\npg:\n database: \"postgres://username:password@hostname:5432/database\"\nsqlite:\n database: \"sqlite3:./config/${DB_NAME}.db\"\n```\n\nOr you can set the `DATABASE_URL` environment variable. This will override the config/database.yml\n\n## Usage\n\nHere is an example using Granite Model\n\n```crystal\nrequire \"granite/adapter/mysql\"\n\nclass Post < Granite::Base\n adapter mysql\n field name : String\n field body : String\n timestamps\nend\n```\n\nYou can disable the timestamps for SqlLite since TIMESTAMP is not supported for this database:\n\n```crystal\nrequire \"granite/adapter/sqlite\"\n\nclass Comment < Granite::Base\n adapter sqlite\n table_name post_comments\n field name : String\n field body : String\nend\n```\n\n### id, created_at, updated_at\n\nThe primary key is automatically created for you and if you use `timestamps` they will be\nautomatically updated for you.\n\nHere are the MySQL field definitions for id, created_at, updated_at\n\n```mysql\n id BIGINT NOT NULL AUTO_INCREMENT\n # Your fields go here\n created_at TIMESTAMP\n updated_at TIMESTAMP\n PRIMARY KEY (id)\n```\n\n### Custom Primary Key\n\nFor legacy database mappings, you may already have a table and the primary key is not named `id` or `Int64`.\n\nWe have a macro called `primary` to help you out:\n\n```crystal\nclass Site < Granite::Base\n adapter mysql\n primary custom_id : Int32\n field name : String\nend\n```\n\nThis will override the default primary key of `id : Int64`.\n\n#### Natural Keys\n\nFor natural keys, you can set `auto: false` option to disable auto increment insert.\n\n```crystal\nclass Site < Granite::Base\n adapter mysql\n primary code : String, auto: false\n field name : String\nend\n```\n\n#### UUIDs\n\nFor databases that utilize UUIDs as the primary key, the `primary` macro can be used again with the `auto: false` option. A `before_create` callback can be added to the model to randomly generate and set a secure UUID on the record before it is saved to the database.\n\n```crystal\nclass Book < Granite::Base\n require \"uuid\"\n adapter mysql\n primary ISBN : String, auto: false\n field name : String\n\n before_create :assign_isbn\n\n def assign_isbn\n @ISBN = UUID.random.to_s\n end\nend\n```\n\n### Bulk Insertions\n\n#### Import\n\n**Note: Imports do not trigger callbacks automatically. See [Running Callbacks](#running-callbacks).**\n\nEach model has an `import` class level method to import an array of models in one bulk insert statement.\n```Crystal\nmodels = [\n Model.new(id: 1, name: \"Fred\", age: 14),\n Model.new(id: 2, name: \"Joe\", age: 25),\n Model.new(id: 3, name: \"John\", age: 30),\n]\n\nModel.import(models)\n```\n\n#### update_on_duplicate\n\nThe `import` method has an optional `update_on_duplicate` + `columns` params that allows you to specify the columns (as an array of strings) that should be updated if primary constraint is violated.\n```Crystal\nmodels = [\n Model.new(id: 1, name: \"Fred\", age: 14),\n Model.new(id: 2, name: \"Joe\", age: 25),\n Model.new(id: 3, name: \"John\", age: 30),\n]\n\nModel.import(models)\n\nModel.find!(1).name # => Fred\n\nmodels = [\n Model.new(id: 1, name: \"George\", age: 14),\n]\n\nModel.import(models, update_on_duplicate: true, columns: %w(name))\n\nModel.find!(1).name # => George\n```\n\n**NOTE: If using PostgreSQL you must have version 9.5+ to have the on_duplicate_key_update feature.**\n\n#### ignore_on_duplicate\n\nThe `import` method has an optional `ignore_on_duplicate` param, that takes a boolean, which will skip records if the primary constraint is violated.\n```Crystal\nmodels = [\n Model.new(id: 1, name: \"Fred\", age: 14),\n Model.new(id: 2, name: \"Joe\", age: 25),\n Model.new(id: 3, name: \"John\", age: 30),\n]\n\nModel.import(models)\n\nModel.find!(1).name # => Fred\n\nmodels = [\n Model.new(id: 1, name: \"George\", age: 14),\n]\n\nModel.import(models, ignore_on_duplicate: true)\n\nModel.find!(1).name # => Fred\n```\n\n#### batch_size\n\nThe `import` method has an optional `batch_size` param, that takes an integer. The batch_size determines the number of models to import in each INSERT statement. This defaults to the size of the models array, i.e. only 1 INSERT statement.\n```Crystal\nmodels = [\n Model.new(id: 1, name: \"Fred\", age: 14),\n Model.new(id: 2, name: \"Joe\", age: 25),\n Model.new(id: 3, name: \"John\", age: 30),\n Model.new(id: 3, name: \"Bill\", age: 66),\n]\n\nModel.import(models, batch_size: 2)\n# => First SQL INSERT statement imports Fred and Joe\n# => Second SQL INSERT statement imports John and Bill\n```\n\n#### Running Callbacks\n\nSince the `import` method runs on the class level, callbacks are not triggered automatically, they have to be triggered manually. For example, using the Item class with a UUID primary key:\n```Crystal\nrequire \"uuid\"\n\nclass Item < Granite::Base\n adapter mysql\n table_name items\n\n primary item_id : String, auto: false\n field item_name : String\n\n before_create :generate_uuid\n\n def generate_uuid\n @item_id = UUID.random.to_s\n end\nend \n```\n\n```Crystal\nitems = [\n Item.new(item_name: \"item1\"),\n Item.new(item_name: \"item2\"),\n Item.new(item_name: \"item3\"),\n Item.new(item_name: \"item4\"),\n]\n\n# If we did `Item.import(items)` now, it would fail since the item_id wouldn't get set before saving the record, violating the primary key constraint.\n\n# Manually run the callback on each model to generate the item_id.\nitems.each(&.before_create)\n\n# Each model in the array now has a item_id set, so can be imported.\nItem.import(items)\n\n# This can also be used for a single record.\nitem = Item.new(item_name: \"item5\")\nitem.before_create\nitem.save\n```\n\n**Note: Manually running your callbacks is mainly aimed at bulk imports. Running them before a normal `.save`, for example, would run your callbacks twice.**\n\n### SQL\n\nTo clear all the rows in the database:\n\n```crystal\nPost.clear #truncate the table\n```\n\n#### Find All\n\n```crystal\nposts = Post.all\nif posts\n posts.each do |post|\n puts post.name\n end\nend\n```\n\n#### Find First\n\n```crystal\npost = Post.first\nif post\n puts post.name\nend\n\npost = Post.first! # raises when no records exist\n```\n\n#### Find\n\n```crystal\npost = Post.find 1\nif post\n puts post.name\nend\n\npost = Post.find! 1 # raises when no records found\n```\n\n#### Find By\n\n```crystal\npost = Post.find_by :slug, \"example_slug\"\nif post\n puts post.name\nend\n\npost = Post.find_by! :slug, \"foo\" # raises when no records found\n```\n\n#### Insert\n\n```crystal\npost = Post.new\npost.name = \"Granite Rocks!\"\npost.body = \"Check this out.\"\npost.save\n```\n\n#### Update\n\n```crystal\npost = Post.find 1\npost.name = \"Granite Really Rocks!\"\npost.save\n```\n\n#### Delete\n\n```crystal\npost = Post.find 1\npost.destroy\nputs \"deleted\" unless post\n```\n\n### Queries\n\nThe where clause will give you full control over your query.\n\n#### All\n\nWhen using the `all` method, the SQL selected fields will always match the\nfields specified in the model.\n\nAlways pass in parameters to avoid SQL Injection. Use a `?`\nin your query as placeholder. Checkout the [Crystal DB Driver](https://github.com/crystal-lang/crystal-db)\nfor documentation of the drivers.\n\nHere are some examples:\n\n```crystal\nposts = Post.all(\"WHERE name LIKE ?\", [\"Joe%\"])\nif posts\n posts.each do |post|\n puts post.name\n end\nend\n\n# ORDER BY Example\nposts = Post.all(\"ORDER BY created_at DESC\")\n\n# JOIN Example\nposts = Post.all(\"JOIN comments c ON c.post_id = post.id\n WHERE c.name = ?\n ORDER BY post.created_at DESC\",\n [\"Joe\"])\n\n```\n\n#### First\n\nIt is common to only want the first result and append a `LIMIT 1` to the query.\nThis is what the `first` method does.\n\nFor example:\n\n```crystal\npost = Post.first(\"ORDER BY posts.name DESC\")\n```\n\nThis is the same as:\n\n```crystal\npost = Post.all(\"ORDER BY posts.name DESC LIMIT 1\").first\n```\n\n### Relationships\n\n#### One to Many\n\n`belongs_to` and `has_many` macros provide a rails like mapping between Objects.\n\n```crystal\nclass User < Granite::Base\n adapter mysql\n\n has_many :posts\n\n field email : String\n field name : String\n timestamps\nend\n```\n\nThis will add a `posts` instance method to the user which returns an array of posts.\n\n```crystal\nclass Post < Granite::Base\n adapter mysql\n\n belongs_to :user\n\n field title : String\n timestamps\nend\n```\n\nThis will add a `user` and `user=` instance method to the post.\n\nFor example:\n\n```crystal\nuser = User.find 1\nuser.posts.each do |post|\n puts post.title\nend\n\npost = Post.find 1\nputs post.user\n\npost.user = user\npost.save\n```\n\nIn this example, you will need to add a `user_id` and index to your posts table:\n\n```mysql\nCREATE TABLE posts (\n id BIGSERIAL PRIMARY KEY,\n user_id BIGINT,\n title VARCHAR,\n created_at TIMESTAMP,\n updated_at TIMESTAMP\n);\n\nCREATE INDEX 'user_id_idx' ON posts (user_id);\n```\n\n#### Many to Many\n\nInstead of using a hidden many-to-many table, Granite recommends always creating a model for your join tables. For example, let's say you have many `users` that belong to many `rooms`. We recommend adding a new model called `participants` to represent the many-to-many relationship.\n\nThen you can use the `belongs_to` and `has_many` relationships going both ways.\n\n```crystal\nclass User < Granite::Base\n has_many :participants\n\n field name : String\nend\n\nclass Participant < Granite::Base\n belongs_to :user\n belongs_to :room\nend\n\nclass Room < Granite::Base\n has_many :participants\n\n field name : String\nend\n```\n\nThe Participant class represents the many-to-many relationship between the Users and Rooms.\n\nHere is what the database table would look like:\n\n```mysql\nCREATE TABLE participants (\n id BIGSERIAL PRIMARY KEY,\n user_id BIGINT,\n room_id BIGINT,\n created_at TIMESTAMP,\n updated_at TIMESTAMP\n);\n\nCREATE INDEX 'user_id_idx' ON TABLE participants (user_id);\nCREATE INDEX 'room_id_idx' ON TABLE participants (room_id);\n```\n\n##### has_many through:\n\nAs a convenience, we provide a `through:` clause to simplify accessing the many-to-many relationship:\n\n```crystal\nclass User < Granite::Base\n has_many :participants\n has_many :rooms, through: participants\n\n field name : String\nend\n\nclass Participant < Granite::Base\n belongs_to :user\n belongs_to :room\nend\n\nclass Room < Granite::Base\n has_many :participants\n has_many :users, through: participants\n\n field name : String\nend\n```\n\nThis will allow you to find all the rooms that a user is in:\n\n```crystal\nuser = User.first\nuser.rooms.each do |room|\n puts room.name\nend\n```\n\nAnd the reverse, all the users in a room:\n\n```crystal\nroom = Room.first\nroom.users.each do |user|\n puts user.name\nend\n```\n\n### Errors\n\nAll database errors are added to the `errors` array used by Granite::Validators with the symbol ':base'\n\n```crystal\npost = Post.new\npost.save\npost.errors[0].to_s.should eq \"ERROR: name cannot be null\"\n```\n\n### Callbacks\n\nThere is support for callbacks on certain events.\n\nHere is an example:\n\n```crystal\nrequire \"granite/adapter/pg\"\n\nclass Post < Granite::Base\n adapter pg\n\n before_save :upcase_title\n\n field title : String\n field content : String\n timestamps\n\n def upcase_title\n if title = @title\n @title = title.upcase\n end\n end\nend\n```\n\nYou can register callbacks for the following events:\n\n#### Create\n\n- before_save\n- before_create\n- **save**\n- after_create\n- after_save\n\n#### Update\n\n- before_save\n- before_update\n- **save**\n- after_update\n- after_save\n\n#### Destroy\n\n- before_destroy\n- **destroy**\n- after_destroy\n\n### Migration\n\n- `migrator` provides `drop`, `create` and `drop_and_create` methods\n\n```crystal\nclass User < Granite::Base\n adapter mysql\n field name : String\nend\n\nUser.migrator.drop_and_create\n# => \"DROP TABLE IF EXISTS `users`;\"\n# => \"CREATE TABLE `users` (id BIGSERIAL PRIMARY KEY, name VARCHAR(255));\"\n\nUser.migrator(table_options: \"ENGINE=InnoDB DEFAULT CHARSET=utf8\").create\n# => \"CREATE TABLE ... ENGINE=InnoDB DEFAULT CHARSET=utf8;\"\n```\n\n## Contributing\n\n1. Fork it ( https://github.com/amberframework/granite/fork )\n2. Create your feature branch (git checkout -b my-new-feature)\n3. Commit your changes (git commit -am 'Add some feature')\n4. Push to the branch (git push origin my-new-feature)\n5. Create a new Pull Request\n\n## Running tests\n\nGranite uses Crystal's built in test framework. The tests can be run with `$ crystal spec`.\n\nThe test suite depends on access to a PostgreSQL, MySQL, and SQLite database to ensure the adapters work as intended.\n\n### Docker setup\n\nThere is a self-contained testing environment provided via the `docker-compose.yml` file in this repository.\n\nAfter you have docker installed do the following to run tests:\n\n#### First run\n\n```\n$ docker-compose build spec\n$ docker-compose run spec\n```\n\n#### Subsequent runs\n\n```\n$ docker-compose run spec\n```\n\n#### Cleanup\n\nIf you're done testing and you'd like to shut down and clean up the docker dependences run the following:\n\n```\n$ docker-compose down\n```\n\n### Local setup\n\nIf you'd like to test without docker you can do so by following the instructions below:\n\n1. Install dependencies with `$ crystal deps`\n2. Update .env to use appropriate ENV variables, or create appropriate databases.\n3. Setup databases:\n\n#### PostgreSQL\n\n```sql\nCREATE USER granite WITH PASSWORD 'password';\n\nCREATE DATABASE granite_db;\n\nGRANT ALL PRIVILEGES ON DATABASE granite_db TO granite;\n```\n\n#### MySQL\n\n```sql\nCREATE USER 'granite'@'localhost' IDENTIFIED BY 'password';\n\nCREATE DATABASE granite_db;\n\nGRANT ALL PRIVILEGES ON granite_db.* TO 'granite'@'localhost' WITH GRANT OPTION;\n```\n\n4. Export `.env` with `$ source .env`\n5. `$ crystal spec`\n","program":{"html_id":"github.com/Amber-Crystal/granite-orm/toplevel","path":"toplevel.html","kind":"module","full_name":"Top Level Namespace","name":"Top Level Namespace","abstract":false,"superclass":null,"ancestors":[],"locations":[],"repository_name":"github.com/Amber-Crystal/granite-orm","program":true,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":null,"doc":null,"summary":null,"class_methods":[],"constructors":[],"instance_methods":[],"macros":[],"types":[{"html_id":"github.com/Amber-Crystal/granite-orm/Granite","path":"Granite.html","kind":"module","full_name":"Granite","name":"Granite","abstract":false,"superclass":null,"ancestors":[],"locations":[{"filename":"granite/collection.cr","line_number":1,"url":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/collection.cr"},{"filename":"granite/settings.cr","line_number":3,"url":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/settings.cr"},{"filename":"granite/version.cr","line_number":1,"url":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/version.cr"}],"repository_name":"github.com/Amber-Crystal/granite-orm","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[{"name":"VERSION","value":"\"0.10.0\"","doc":null,"summary":null}],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":null,"doc":null,"summary":null,"class_methods":[{"id":"settings-class-method","html_id":"settings-class-method","name":"settings","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/settings.cr#L14","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/settings.cr#L14","def":{"name":"settings","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"@@settings || (@@settings = Settings.new)"}}],"constructors":[],"instance_methods":[],"macros":[],"types":[{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/AssociationCollection","path":"Granite/AssociationCollection.html","kind":"class","full_name":"Granite::AssociationCollection(Owner, Target)","name":"AssociationCollection","abstract":false,"superclass":{"html_id":"github.com/Amber-Crystal/granite-orm/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"github.com/Amber-Crystal/granite-orm/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"github.com/Amber-Crystal/granite-orm/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"granite/association_collection.cr","line_number":1,"url":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/association_collection.cr"}],"repository_name":"github.com/Amber-Crystal/granite-orm","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/Amber-Crystal/granite-orm/Granite","kind":"module","full_name":"Granite","name":"Granite"},"doc":null,"summary":null,"class_methods":[],"constructors":[{"id":"new(owner:Owner,through:Symbol?=nil)-class-method","html_id":"new(owner:Owner,through:Symbol?=nil)-class-method","name":"new","doc":null,"summary":null,"abstract":false,"args":[{"name":"owner","doc":null,"default_value":"","external_name":"owner","restriction":"Owner"},{"name":"through","doc":null,"default_value":"nil","external_name":"through","restriction":"Symbol | ::Nil"}],"args_string":"(owner : Owner, through : Symbol? = nil)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/association_collection.cr#L4","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/association_collection.cr#L4","def":{"name":"new","args":[{"name":"owner","doc":null,"default_value":"","external_name":"owner","restriction":"Owner"},{"name":"through","doc":null,"default_value":"nil","external_name":"through","restriction":"Symbol | ::Nil"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"_ = AssociationCollection(Owner, Target).allocate\n_.initialize(owner, through)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"id":"all(clause="",params=[]ofDB::Any)-instance-method","html_id":"all(clause=&quot;&quot;,params=[]ofDB::Any)-instance-method","name":"all","doc":null,"summary":null,"abstract":false,"args":[{"name":"clause","doc":null,"default_value":"\"\"","external_name":"clause","restriction":""},{"name":"params","doc":null,"default_value":"[] of DB::Any","external_name":"params","restriction":""}],"args_string":"(clause = "", params = [] of DB::Any)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/association_collection.cr#L7","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/association_collection.cr#L7","def":{"name":"all","args":[{"name":"clause","doc":null,"default_value":"\"\"","external_name":"clause","restriction":""},{"name":"params","doc":null,"default_value":"[] of DB::Any","external_name":"params","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"Target.all([query, clause].join(\" \"), [owner.id] + params)"}},{"id":"find(value)-instance-method","html_id":"find(value)-instance-method","name":"find","doc":null,"summary":null,"abstract":false,"args":[{"name":"value","doc":null,"default_value":"","external_name":"value","restriction":""}],"args_string":"(value)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/association_collection.cr#L28","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/association_collection.cr#L28","def":{"name":"find","args":[{"name":"value","doc":null,"default_value":"","external_name":"value","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"find_by(Target.primary_name, value)"}},{"id":"find!(value)-instance-method","html_id":"find!(value)-instance-method","name":"find!","doc":null,"summary":null,"abstract":false,"args":[{"name":"value","doc":null,"default_value":"","external_name":"value","restriction":""}],"args_string":"(value)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/association_collection.cr#L32","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/association_collection.cr#L32","def":{"name":"find!","args":[{"name":"value","doc":null,"default_value":"","external_name":"value","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"find_by!(Target.primary_name, value)"}},{"id":"find_by(field:String|Symbol,value)-instance-method","html_id":"find_by(field:String|Symbol,value)-instance-method","name":"find_by","doc":null,"summary":null,"abstract":false,"args":[{"name":"field","doc":null,"default_value":"","external_name":"field","restriction":"String | Symbol"},{"name":"value","doc":null,"default_value":"","external_name":"value","restriction":""}],"args_string":"(field : String | Symbol, value)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/association_collection.cr#L14","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/association_collection.cr#L14","def":{"name":"find_by","args":[{"name":"field","doc":null,"default_value":"","external_name":"field","restriction":"String | Symbol"},{"name":"value","doc":null,"default_value":"","external_name":"value","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"Target.first([query, \"AND #{Target.table_name}.#{field} = ?\"].join(\" \"), [owner.id, value])"}},{"id":"find_by!(field:String|Symbol,value)-instance-method","html_id":"find_by!(field:String|Symbol,value)-instance-method","name":"find_by!","doc":null,"summary":null,"abstract":false,"args":[{"name":"field","doc":null,"default_value":"","external_name":"field","restriction":"String | Symbol"},{"name":"value","doc":null,"default_value":"","external_name":"value","restriction":""}],"args_string":"(field : String | Symbol, value)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/association_collection.cr#L21","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/association_collection.cr#L21","def":{"name":"find_by!","args":[{"name":"field","doc":null,"default_value":"","external_name":"field","restriction":"String | Symbol"},{"name":"value","doc":null,"default_value":"","external_name":"value","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"(find_by(field, value)) || (raise(Granite::Querying::NotFound.new(\"Couldn't find #{Target.name} with #{field}=#{value}\")))"}}],"macros":[{"id":"method_missing(call)-macro","html_id":"method_missing(call)-macro","name":"method_missing","doc":null,"summary":null,"abstract":false,"args":[{"name":"call","doc":null,"default_value":"","external_name":"call","restriction":""}],"args_string":"(call)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/association_collection.cr#L2","def":{"name":"method_missing","args":[{"name":"call","doc":null,"default_value":"","external_name":"call","restriction":""}],"double_splat":null,"splat_index":null,"block_arg":null,"visibility":"Public","body":" all.\n{{ call }}\n\n \n"}}],"types":[]},{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Associations","path":"Granite/Associations.html","kind":"module","full_name":"Granite::Associations","name":"Associations","abstract":false,"superclass":null,"ancestors":[],"locations":[{"filename":"granite/associations.cr","line_number":1,"url":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/associations.cr"}],"repository_name":"github.com/Amber-Crystal/granite-orm","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Base","kind":"class","full_name":"Granite::Base","name":"Base"}],"namespace":{"html_id":"github.com/Amber-Crystal/granite-orm/Granite","kind":"module","full_name":"Granite","name":"Granite"},"doc":null,"summary":null,"class_methods":[],"constructors":[],"instance_methods":[],"macros":[{"id":"belongs_to(model)-macro","html_id":"belongs_to(model)-macro","name":"belongs_to","doc":"define getter and setter for parent relationship","summary":"

define getter and setter for parent relationship

","abstract":false,"args":[{"name":"model","doc":null,"default_value":"","external_name":"model","restriction":""}],"args_string":"(model)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/associations.cr#L3","def":{"name":"belongs_to","args":[{"name":"model","doc":null,"default_value":"","external_name":"model","restriction":""}],"double_splat":null,"splat_index":null,"block_arg":null,"visibility":"Public","body":" \n{% if model.is_a?(TypeDeclaration) %}\n belongs_to {{ model.var }}, {{ model.type }}, {{ model.var }}_id : Int64\n {% else %}\n belongs_to {{ model.id }}, {{ model.id.camelcase }}, {{ model.id }}_id : Int64\n {% end %}\n\n \n"}},{"id":"belongs_to(model,foreign_key)-macro","html_id":"belongs_to(model,foreign_key)-macro","name":"belongs_to","doc":"ditto","summary":"

ditto

","abstract":false,"args":[{"name":"model","doc":null,"default_value":"","external_name":"model","restriction":""},{"name":"foreign_key","doc":null,"default_value":"","external_name":"foreign_key","restriction":""}],"args_string":"(model, foreign_key)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/associations.cr#L12","def":{"name":"belongs_to","args":[{"name":"model","doc":null,"default_value":"","external_name":"model","restriction":""},{"name":"foreign_key","doc":null,"default_value":"","external_name":"foreign_key","restriction":""}],"double_splat":null,"splat_index":null,"block_arg":null,"visibility":"Public","body":" \n{% if model.is_a?(TypeDeclaration) %}\n belongs_to {{ model.var }}, {{ model.type }}, {{ foreign_key }}\n {% else %}\n belongs_to {{ model.id }}, {{ model.id.camelcase }}, {{ foreign_key }}\n {% end %}\n\n \n"}},{"id":"belongs_to(method_name,model_name,foreign_key)-macro","html_id":"belongs_to(method_name,model_name,foreign_key)-macro","name":"belongs_to","doc":"ditto","summary":"

ditto

","abstract":false,"args":[{"name":"method_name","doc":null,"default_value":"","external_name":"method_name","restriction":""},{"name":"model_name","doc":null,"default_value":"","external_name":"model_name","restriction":""},{"name":"foreign_key","doc":null,"default_value":"","external_name":"foreign_key","restriction":""}],"args_string":"(method_name, model_name, foreign_key)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/associations.cr#L21","def":{"name":"belongs_to","args":[{"name":"method_name","doc":null,"default_value":"","external_name":"method_name","restriction":""},{"name":"model_name","doc":null,"default_value":"","external_name":"model_name","restriction":""},{"name":"foreign_key","doc":null,"default_value":"","external_name":"foreign_key","restriction":""}],"double_splat":null,"splat_index":null,"block_arg":null,"visibility":"Public","body":" field \n{{ foreign_key }}\n\n\n \n# retrieve the parent relationship\n\n def \n{{ method_name.id }}\n\n if parent = \n{{ model_name.id }}\n.find \n{{ foreign_key.var }}\n\n parent\n \nelse\n \n{{ model_name.id }}\n.new\n \nend\n \nend\n\n \n# set the parent relationship\n\n def \n{{ method_name.id }}\n=(parent)\n @\n{{ foreign_key.var }}\n = parent.id\n \nend\n \n"}},{"id":"has_many(children_table)-macro","html_id":"has_many(children_table)-macro","name":"has_many","doc":null,"summary":null,"abstract":false,"args":[{"name":"children_table","doc":null,"default_value":"","external_name":"children_table","restriction":""}],"args_string":"(children_table)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/associations.cr#L39","def":{"name":"has_many","args":[{"name":"children_table","doc":null,"default_value":"","external_name":"children_table","restriction":""}],"double_splat":null,"splat_index":null,"block_arg":null,"visibility":"Public","body":" def \n{{ children_table.id }}\n\n \n{% children_class = children_table.id[0...-1].camelcase %}\n\n Granite::AssociationCollection(self, \n{{ children_class }}\n).new(self)\n \nend\n \n"}},{"id":"has_many(children_table,through)-macro","html_id":"has_many(children_table,through)-macro","name":"has_many","doc":"define getter for related children","summary":"

define getter for related children

","abstract":false,"args":[{"name":"children_table","doc":null,"default_value":"","external_name":"children_table","restriction":""},{"name":"through","doc":null,"default_value":"","external_name":"through","restriction":""}],"args_string":"(children_table, through)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/associations.cr#L47","def":{"name":"has_many","args":[{"name":"children_table","doc":null,"default_value":"","external_name":"children_table","restriction":""},{"name":"through","doc":null,"default_value":"","external_name":"through","restriction":""}],"double_splat":null,"splat_index":null,"block_arg":null,"visibility":"Public","body":" def \n{{ children_table.id }}\n\n \n{% children_class = children_table.id[0...-1].camelcase %}\n\n Granite::AssociationCollection(self, \n{{ children_class }}\n).new(self, \n{{ through }}\n)\n \nend\n \n"}}],"types":[]},{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Base","path":"Granite/Base.html","kind":"class","full_name":"Granite::Base","name":"Base","abstract":false,"superclass":{"html_id":"github.com/Amber-Crystal/granite-orm/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Migrator","kind":"module","full_name":"Granite::Migrator","name":"Migrator"},{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Validators","kind":"module","full_name":"Granite::Validators","name":"Validators"},{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Transactions","kind":"module","full_name":"Granite::Transactions","name":"Transactions"},{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Table","kind":"module","full_name":"Granite::Table","name":"Table"},{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Fields","kind":"module","full_name":"Granite::Fields","name":"Fields"},{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Callbacks","kind":"module","full_name":"Granite::Callbacks","name":"Callbacks"},{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Associations","kind":"module","full_name":"Granite::Associations","name":"Associations"},{"html_id":"github.com/Amber-Crystal/granite-orm/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"github.com/Amber-Crystal/granite-orm/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"granite/base.cr","line_number":15,"url":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/base.cr"}],"repository_name":"github.com/Amber-Crystal/granite-orm","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Associations","kind":"module","full_name":"Granite::Associations","name":"Associations"},{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Callbacks","kind":"module","full_name":"Granite::Callbacks","name":"Callbacks"},{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Fields","kind":"module","full_name":"Granite::Fields","name":"Fields"},{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Migrator","kind":"module","full_name":"Granite::Migrator","name":"Migrator"},{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Table","kind":"module","full_name":"Granite::Table","name":"Table"},{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Transactions","kind":"module","full_name":"Granite::Transactions","name":"Transactions"},{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Validators","kind":"module","full_name":"Granite::Validators","name":"Validators"}],"extended_modules":[{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Querying","kind":"module","full_name":"Granite::Querying","name":"Querying"},{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Transactions/ClassMethods","kind":"module","full_name":"Granite::Transactions::ClassMethods","name":"ClassMethods"}],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/Amber-Crystal/granite-orm/Granite","kind":"module","full_name":"Granite","name":"Granite"},"doc":"Granite::Base is the base class for your model objects.","summary":"

Granite::Base is the base class for your model objects.

","class_methods":[],"constructors":[{"id":"new(args:Hash(Symbol|String,String|JSON::Type))-class-method","html_id":"new(args:Hash(Symbol|String,String|JSON::Type))-class-method","name":"new","doc":null,"summary":null,"abstract":false,"args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":"Hash(Symbol | String, String | JSON::Type)"}],"args_string":"(args : Hash(Symbol | String, String | JSON::Type))","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/base.cr#L41","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/base.cr#L41","def":{"name":"new","args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":"Hash(Symbol | String, String | JSON::Type)"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"_ = allocate\n_.initialize(args)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}},{"id":"new-class-method","html_id":"new-class-method","name":"new","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/base.cr#L37","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/base.cr#L37","def":{"name":"new","args":[],"double_splat":{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":"Object"},"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"_ = allocate\n_.initialize(**args)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}},{"id":"new-class-method","html_id":"new-class-method","name":"new","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/base.cr#L45","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/base.cr#L45","def":{"name":"new","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"_ = allocate\n_.initialize\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[],"macros":[{"id":"__process_querying-macro","html_id":"__process_querying-macro","name":"__process_querying","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/base.cr#L24","def":{"name":"__process_querying","args":[],"double_splat":null,"splat_index":null,"block_arg":null,"visibility":"Public","body":" \n{% primary_name = PRIMARY[:name] %}\n\n \n{% primary_type = PRIMARY[:type] %}\n\n\n \n# Create the from_sql method\n\n def self.from_sql(result)\n model = \n{{ @type.name.id }}\n.new\n model.set_attributes(result)\n model\n \nend\n\n def set_attributes(result : DB::ResultSet)\n \n# Loading from DB means existing records.\n\n @new_record = false\n \n{% for name, options in FIELDS %}\n {% type = options[:type] %}\n {% if type.id.stringify == \"Time\" %}\n if @@adapter.class.name == \"Granite::Adapter::Sqlite\"\n # sqlite3 does not have timestamp type - timestamps are stored as str\n # will break for null timestamps\n self.{{ name.id }} = Time.parse(result.read(String), \"%F %X\" )\n else\n self.{{ name.id }} = result.read(Union({{ type.id }} | Nil))\n end\n {% else %}\n self.{{ name.id }} = result.read(Union({{ type.id }} | Nil))\n {% end %}\n {% end %}\n\n return self\n \nend\n \n"}}],"types":[]},{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Callbacks","path":"Granite/Callbacks.html","kind":"module","full_name":"Granite::Callbacks","name":"Callbacks","abstract":false,"superclass":null,"ancestors":[],"locations":[{"filename":"granite/callbacks.cr","line_number":1,"url":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/callbacks.cr"}],"repository_name":"github.com/Amber-Crystal/granite-orm","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[{"name":"CALLBACK_NAMES","value":"[:before_save, :after_save, :before_create, :after_create, :before_update, :after_update, :before_destroy, :after_destroy] of ::Symbol","doc":null,"summary":null}],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Base","kind":"class","full_name":"Granite::Base","name":"Base"}],"namespace":{"html_id":"github.com/Amber-Crystal/granite-orm/Granite","kind":"module","full_name":"Granite","name":"Granite"},"doc":null,"summary":null,"class_methods":[],"constructors":[],"instance_methods":[{"id":"abort!(message="Abortedat#{@_current_callback}.")-instance-method","html_id":"abort!(message=&quot;Abortedat#{@_current_callback}.&quot;)-instance-method","name":"abort!","doc":null,"summary":null,"abstract":false,"args":[{"name":"message","doc":null,"default_value":"\"Aborted at #{@_current_callback}.\"","external_name":"message","restriction":""}],"args_string":"(message = "Aborted at #{@_current_callback}.")","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/callbacks.cr#L48","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/callbacks.cr#L48","def":{"name":"abort!","args":[{"name":"message","doc":null,"default_value":"\"Aborted at #{@_current_callback}.\"","external_name":"message","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"raise(Abort.new(message))"}}],"macros":[{"id":"__after_create-macro","html_id":"__after_create-macro","name":"__after_create","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/callbacks.cr#L24","def":{"name":"__after_create","args":[],"double_splat":null,"splat_index":null,"block_arg":null,"visibility":"Public","body":" @_current_callback = :after_create\n \n{% for callback in CALLBACKS[:after_create] %}\n {% if callback.is_a?(Block) %}\n begin\n {{ callback.body }}\n end\n {% else %}\n {{ callback.id }}\n {% end %}\n {% end %}\n\n \n"}},{"id":"__after_destroy-macro","html_id":"__after_destroy-macro","name":"__after_destroy","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/callbacks.cr#L24","def":{"name":"__after_destroy","args":[],"double_splat":null,"splat_index":null,"block_arg":null,"visibility":"Public","body":" @_current_callback = :after_destroy\n \n{% for callback in CALLBACKS[:after_destroy] %}\n {% if callback.is_a?(Block) %}\n begin\n {{ callback.body }}\n end\n {% else %}\n {{ callback.id }}\n {% end %}\n {% end %}\n\n \n"}},{"id":"__after_save-macro","html_id":"__after_save-macro","name":"__after_save","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/callbacks.cr#L24","def":{"name":"__after_save","args":[],"double_splat":null,"splat_index":null,"block_arg":null,"visibility":"Public","body":" @_current_callback = :after_save\n \n{% for callback in CALLBACKS[:after_save] %}\n {% if callback.is_a?(Block) %}\n begin\n {{ callback.body }}\n end\n {% else %}\n {{ callback.id }}\n {% end %}\n {% end %}\n\n \n"}},{"id":"__after_update-macro","html_id":"__after_update-macro","name":"__after_update","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/callbacks.cr#L24","def":{"name":"__after_update","args":[],"double_splat":null,"splat_index":null,"block_arg":null,"visibility":"Public","body":" @_current_callback = :after_update\n \n{% for callback in CALLBACKS[:after_update] %}\n {% if callback.is_a?(Block) %}\n begin\n {{ callback.body }}\n end\n {% else %}\n {{ callback.id }}\n {% end %}\n {% end %}\n\n \n"}},{"id":"__before_create-macro","html_id":"__before_create-macro","name":"__before_create","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/callbacks.cr#L24","def":{"name":"__before_create","args":[],"double_splat":null,"splat_index":null,"block_arg":null,"visibility":"Public","body":" @_current_callback = :before_create\n \n{% for callback in CALLBACKS[:before_create] %}\n {% if callback.is_a?(Block) %}\n begin\n {{ callback.body }}\n end\n {% else %}\n {{ callback.id }}\n {% end %}\n {% end %}\n\n \n"}},{"id":"__before_destroy-macro","html_id":"__before_destroy-macro","name":"__before_destroy","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/callbacks.cr#L24","def":{"name":"__before_destroy","args":[],"double_splat":null,"splat_index":null,"block_arg":null,"visibility":"Public","body":" @_current_callback = :before_destroy\n \n{% for callback in CALLBACKS[:before_destroy] %}\n {% if callback.is_a?(Block) %}\n begin\n {{ callback.body }}\n end\n {% else %}\n {{ callback.id }}\n {% end %}\n {% end %}\n\n \n"}},{"id":"__before_save-macro","html_id":"__before_save-macro","name":"__before_save","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/callbacks.cr#L24","def":{"name":"__before_save","args":[],"double_splat":null,"splat_index":null,"block_arg":null,"visibility":"Public","body":" @_current_callback = :before_save\n \n{% for callback in CALLBACKS[:before_save] %}\n {% if callback.is_a?(Block) %}\n begin\n {{ callback.body }}\n end\n {% else %}\n {{ callback.id }}\n {% end %}\n {% end %}\n\n \n"}},{"id":"__before_update-macro","html_id":"__before_update-macro","name":"__before_update","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/callbacks.cr#L24","def":{"name":"__before_update","args":[],"double_splat":null,"splat_index":null,"block_arg":null,"visibility":"Public","body":" @_current_callback = :before_update\n \n{% for callback in CALLBACKS[:before_update] %}\n {% if callback.is_a?(Block) %}\n begin\n {{ callback.body }}\n end\n {% else %}\n {{ callback.id }}\n {% end %}\n {% end %}\n\n \n"}},{"id":"after_create(*callbacks)-macro","html_id":"after_create(*callbacks)-macro","name":"after_create","doc":null,"summary":null,"abstract":false,"args":[{"name":"callbacks","doc":null,"default_value":"","external_name":"callbacks","restriction":""}],"args_string":"(*callbacks)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/callbacks.cr#L24","def":{"name":"after_create","args":[{"name":"callbacks","doc":null,"default_value":"","external_name":"callbacks","restriction":""}],"double_splat":null,"splat_index":0,"block_arg":{"name":"block","doc":null,"default_value":"","external_name":"block","restriction":""},"visibility":"Public","body":" \n{% for callback in callbacks %}\n {% CALLBACKS[:after_create] << callback %}\n {% end %}\n\n \n{% if block.is_a?(Block) %}\n {% CALLBACKS[:after_create] << block %}\n {% end %}\n\n \n"}},{"id":"after_destroy(*callbacks)-macro","html_id":"after_destroy(*callbacks)-macro","name":"after_destroy","doc":null,"summary":null,"abstract":false,"args":[{"name":"callbacks","doc":null,"default_value":"","external_name":"callbacks","restriction":""}],"args_string":"(*callbacks)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/callbacks.cr#L24","def":{"name":"after_destroy","args":[{"name":"callbacks","doc":null,"default_value":"","external_name":"callbacks","restriction":""}],"double_splat":null,"splat_index":0,"block_arg":{"name":"block","doc":null,"default_value":"","external_name":"block","restriction":""},"visibility":"Public","body":" \n{% for callback in callbacks %}\n {% CALLBACKS[:after_destroy] << callback %}\n {% end %}\n\n \n{% if block.is_a?(Block) %}\n {% CALLBACKS[:after_destroy] << block %}\n {% end %}\n\n \n"}},{"id":"after_save(*callbacks)-macro","html_id":"after_save(*callbacks)-macro","name":"after_save","doc":null,"summary":null,"abstract":false,"args":[{"name":"callbacks","doc":null,"default_value":"","external_name":"callbacks","restriction":""}],"args_string":"(*callbacks)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/callbacks.cr#L24","def":{"name":"after_save","args":[{"name":"callbacks","doc":null,"default_value":"","external_name":"callbacks","restriction":""}],"double_splat":null,"splat_index":0,"block_arg":{"name":"block","doc":null,"default_value":"","external_name":"block","restriction":""},"visibility":"Public","body":" \n{% for callback in callbacks %}\n {% CALLBACKS[:after_save] << callback %}\n {% end %}\n\n \n{% if block.is_a?(Block) %}\n {% CALLBACKS[:after_save] << block %}\n {% end %}\n\n \n"}},{"id":"after_update(*callbacks)-macro","html_id":"after_update(*callbacks)-macro","name":"after_update","doc":null,"summary":null,"abstract":false,"args":[{"name":"callbacks","doc":null,"default_value":"","external_name":"callbacks","restriction":""}],"args_string":"(*callbacks)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/callbacks.cr#L24","def":{"name":"after_update","args":[{"name":"callbacks","doc":null,"default_value":"","external_name":"callbacks","restriction":""}],"double_splat":null,"splat_index":0,"block_arg":{"name":"block","doc":null,"default_value":"","external_name":"block","restriction":""},"visibility":"Public","body":" \n{% for callback in callbacks %}\n {% CALLBACKS[:after_update] << callback %}\n {% end %}\n\n \n{% if block.is_a?(Block) %}\n {% CALLBACKS[:after_update] << block %}\n {% end %}\n\n \n"}},{"id":"before_create(*callbacks)-macro","html_id":"before_create(*callbacks)-macro","name":"before_create","doc":null,"summary":null,"abstract":false,"args":[{"name":"callbacks","doc":null,"default_value":"","external_name":"callbacks","restriction":""}],"args_string":"(*callbacks)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/callbacks.cr#L24","def":{"name":"before_create","args":[{"name":"callbacks","doc":null,"default_value":"","external_name":"callbacks","restriction":""}],"double_splat":null,"splat_index":0,"block_arg":{"name":"block","doc":null,"default_value":"","external_name":"block","restriction":""},"visibility":"Public","body":" \n{% for callback in callbacks %}\n {% CALLBACKS[:before_create] << callback %}\n {% end %}\n\n \n{% if block.is_a?(Block) %}\n {% CALLBACKS[:before_create] << block %}\n {% end %}\n\n \n"}},{"id":"before_destroy(*callbacks)-macro","html_id":"before_destroy(*callbacks)-macro","name":"before_destroy","doc":null,"summary":null,"abstract":false,"args":[{"name":"callbacks","doc":null,"default_value":"","external_name":"callbacks","restriction":""}],"args_string":"(*callbacks)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/callbacks.cr#L24","def":{"name":"before_destroy","args":[{"name":"callbacks","doc":null,"default_value":"","external_name":"callbacks","restriction":""}],"double_splat":null,"splat_index":0,"block_arg":{"name":"block","doc":null,"default_value":"","external_name":"block","restriction":""},"visibility":"Public","body":" \n{% for callback in callbacks %}\n {% CALLBACKS[:before_destroy] << callback %}\n {% end %}\n\n \n{% if block.is_a?(Block) %}\n {% CALLBACKS[:before_destroy] << block %}\n {% end %}\n\n \n"}},{"id":"before_save(*callbacks)-macro","html_id":"before_save(*callbacks)-macro","name":"before_save","doc":null,"summary":null,"abstract":false,"args":[{"name":"callbacks","doc":null,"default_value":"","external_name":"callbacks","restriction":""}],"args_string":"(*callbacks)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/callbacks.cr#L24","def":{"name":"before_save","args":[{"name":"callbacks","doc":null,"default_value":"","external_name":"callbacks","restriction":""}],"double_splat":null,"splat_index":0,"block_arg":{"name":"block","doc":null,"default_value":"","external_name":"block","restriction":""},"visibility":"Public","body":" \n{% for callback in callbacks %}\n {% CALLBACKS[:before_save] << callback %}\n {% end %}\n\n \n{% if block.is_a?(Block) %}\n {% CALLBACKS[:before_save] << block %}\n {% end %}\n\n \n"}},{"id":"before_update(*callbacks)-macro","html_id":"before_update(*callbacks)-macro","name":"before_update","doc":null,"summary":null,"abstract":false,"args":[{"name":"callbacks","doc":null,"default_value":"","external_name":"callbacks","restriction":""}],"args_string":"(*callbacks)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/callbacks.cr#L24","def":{"name":"before_update","args":[{"name":"callbacks","doc":null,"default_value":"","external_name":"callbacks","restriction":""}],"double_splat":null,"splat_index":0,"block_arg":{"name":"block","doc":null,"default_value":"","external_name":"block","restriction":""},"visibility":"Public","body":" \n{% for callback in callbacks %}\n {% CALLBACKS[:before_update] << callback %}\n {% end %}\n\n \n{% if block.is_a?(Block) %}\n {% CALLBACKS[:before_update] << block %}\n {% end %}\n\n \n"}}],"types":[{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Callbacks/Abort","path":"Granite/Callbacks/Abort.html","kind":"class","full_name":"Granite::Callbacks::Abort","name":"Abort","abstract":false,"superclass":{"html_id":"github.com/Amber-Crystal/granite-orm/Exception","kind":"class","full_name":"Exception","name":"Exception"},"ancestors":[{"html_id":"github.com/Amber-Crystal/granite-orm/Exception","kind":"class","full_name":"Exception","name":"Exception"},{"html_id":"github.com/Amber-Crystal/granite-orm/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"github.com/Amber-Crystal/granite-orm/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"granite/callbacks.cr","line_number":2,"url":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/callbacks.cr"}],"repository_name":"github.com/Amber-Crystal/granite-orm","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Callbacks","kind":"module","full_name":"Granite::Callbacks","name":"Callbacks"},"doc":null,"summary":null,"class_methods":[],"constructors":[],"instance_methods":[],"macros":[],"types":[]}]},{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Collection","path":"Granite/Collection.html","kind":"class","full_name":"Granite::Collection(M)","name":"Collection","abstract":false,"superclass":{"html_id":"github.com/Amber-Crystal/granite-orm/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"github.com/Amber-Crystal/granite-orm/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"github.com/Amber-Crystal/granite-orm/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"granite/collection.cr","line_number":1,"url":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/collection.cr"}],"repository_name":"github.com/Amber-Crystal/granite-orm","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/Amber-Crystal/granite-orm/Granite","kind":"module","full_name":"Granite","name":"Granite"},"doc":null,"summary":null,"class_methods":[],"constructors":[{"id":"new(loader:->Array(M))-class-method","html_id":"new(loader:->Array(M))-class-method","name":"new","doc":null,"summary":null,"abstract":false,"args":[{"name":"loader","doc":null,"default_value":"","external_name":"loader","restriction":"(-> Array(M))"}],"args_string":"(loader : -> Array(M))","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/collection.cr#L4","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/collection.cr#L4","def":{"name":"new","args":[{"name":"loader","doc":null,"default_value":"","external_name":"loader","restriction":"(-> Array(M))"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"_ = Collection(M).allocate\n_.initialize(loader)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"id":"loaded?-instance-method","html_id":"loaded?-instance-method","name":"loaded?","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/collection.cr#L9","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/collection.cr#L9","def":{"name":"loaded?","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"@loaded"}}],"macros":[{"id":"method_missing(call)-macro","html_id":"method_missing(call)-macro","name":"method_missing","doc":null,"summary":null,"abstract":false,"args":[{"name":"call","doc":null,"default_value":"","external_name":"call","restriction":""}],"args_string":"(call)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/collection.cr#L2","def":{"name":"method_missing","args":[{"name":"call","doc":null,"default_value":"","external_name":"call","restriction":""}],"double_splat":null,"splat_index":null,"block_arg":null,"visibility":"Public","body":" collection.\n{{ call }}\n\n \n"}}],"types":[]},{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Error","path":"Granite/Error.html","kind":"class","full_name":"Granite::Error","name":"Error","abstract":false,"superclass":{"html_id":"github.com/Amber-Crystal/granite-orm/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"github.com/Amber-Crystal/granite-orm/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"github.com/Amber-Crystal/granite-orm/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"granite/error.cr","line_number":1,"url":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/error.cr"}],"repository_name":"github.com/Amber-Crystal/granite-orm","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/Amber-Crystal/granite-orm/Granite","kind":"module","full_name":"Granite","name":"Granite"},"doc":null,"summary":null,"class_methods":[],"constructors":[{"id":"new(field:String|Symbol,message:String?="")-class-method","html_id":"new(field:String|Symbol,message:String?=&quot;&quot;)-class-method","name":"new","doc":null,"summary":null,"abstract":false,"args":[{"name":"field","doc":null,"default_value":"","external_name":"field","restriction":"String | Symbol"},{"name":"message","doc":null,"default_value":"\"\"","external_name":"message","restriction":"String | ::Nil"}],"args_string":"(field : String | Symbol, message : String? = "")","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/error.cr#L4","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/error.cr#L4","def":{"name":"new","args":[{"name":"field","doc":null,"default_value":"","external_name":"field","restriction":"String | Symbol"},{"name":"message","doc":null,"default_value":"\"\"","external_name":"message","restriction":"String | ::Nil"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"_ = allocate\n_.initialize(field, message)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"id":"field:String|Symbol-instance-method","html_id":"field:String|Symbol-instance-method","name":"field","doc":null,"summary":null,"abstract":false,"args":[],"args_string":" : String | Symbol","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/error.cr#L2","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/error.cr#L2","def":{"name":"field","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"@field"}},{"id":"field=(field)-instance-method","html_id":"field=(field)-instance-method","name":"field=","doc":null,"summary":null,"abstract":false,"args":[{"name":"field","doc":null,"default_value":"","external_name":"field","restriction":""}],"args_string":"(field)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/error.cr#L2","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/error.cr#L2","def":{"name":"field=","args":[{"name":"field","doc":null,"default_value":"","external_name":"field","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"@field = field"}},{"id":"message:String?-instance-method","html_id":"message:String?-instance-method","name":"message","doc":null,"summary":null,"abstract":false,"args":[],"args_string":" : String?","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/error.cr#L2","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/error.cr#L2","def":{"name":"message","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"@message"}},{"id":"message=(message)-instance-method","html_id":"message=(message)-instance-method","name":"message=","doc":null,"summary":null,"abstract":false,"args":[{"name":"message","doc":null,"default_value":"","external_name":"message","restriction":""}],"args_string":"(message)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/error.cr#L2","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/error.cr#L2","def":{"name":"message=","args":[{"name":"message","doc":null,"default_value":"","external_name":"message","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"@message = message"}},{"id":"to_s-instance-method","html_id":"to_s-instance-method","name":"to_s","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/error.cr#L7","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/error.cr#L7","def":{"name":"to_s","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"if @field == (:base)\n @message\nelse\n \"#{@field.to_s.capitalize} #{message}\"\nend"}}],"macros":[],"types":[]},{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Fields","path":"Granite/Fields.html","kind":"module","full_name":"Granite::Fields","name":"Fields","abstract":false,"superclass":null,"ancestors":[],"locations":[{"filename":"granite/fields.cr","line_number":3,"url":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/fields.cr"}],"repository_name":"github.com/Amber-Crystal/granite-orm","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[{"name":"TIME_FORMAT_REGEX","value":"/\\d{4,}-\\d{2,}-\\d{2,}\\s\\d{2,}:\\d{2,}:\\d{2,}/","doc":null,"summary":null}],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Base","kind":"class","full_name":"Granite::Base","name":"Base"}],"namespace":{"html_id":"github.com/Amber-Crystal/granite-orm/Granite","kind":"module","full_name":"Granite","name":"Granite"},"doc":null,"summary":null,"class_methods":[],"constructors":[],"instance_methods":[],"macros":[{"id":"__process_fields-macro","html_id":"__process_fields-macro","name":"__process_fields","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/fields.cr#L31","def":{"name":"__process_fields","args":[],"double_splat":null,"splat_index":null,"block_arg":null,"visibility":"Public","body":" \n# merge PK and CONTENT_FIELDS into FIELDS\n\n \n{% FIELDS[PRIMARY[:name]] = PRIMARY %}\n\n \n{% for name, options in CONTENT_FIELDS %}\n {% FIELDS[name] = options %}\n {% end %}\n\n\n \n# Create the properties\n\n \n{% for name, options in FIELDS %}\n {% type = options[:type] %}\n {% suffixes = options[:raise_on_nil] ? [\"?\", \"\"] : [\"\", \"!\"] %}\n property{{ suffixes[0].id }} {{ name.id }} : Union({{ type.id }} | Nil)\n def {{ name.id }}{{ suffixes[1].id }}\n raise {{ @type.name.stringify }} + \"#\" + {{ name.stringify }} + \" cannot be nil\" if @{{ name.id }}.nil?\n @{{ name.id }}.not_nil!\n end\n {% end %}\n\n\n \n# keep a hash of the fields to be used for mapping\n\n def self.fields : Array(String)\n @@fields ||= \n{{ FIELDS.empty? ? \"[] of String\".id : FIELDS.keys.map do |__arg0|\n __arg0.id.stringify\nend }}\n\n \nend\n\n def self.content_fields : Array(String)\n @@content_fields ||= \n{{ CONTENT_FIELDS.empty? ? \"[] of String\".id : CONTENT_FIELDS.keys.map do |__arg1|\n __arg1.id.stringify\nend }}\n\n \nend\n\n \n# keep a hash of the params that will be passed to the adapter.\n\n def content_values\n parsed_params = [] of DB::Any\n \n{% for name, options in CONTENT_FIELDS %}\n {% if options[:type].id == Time.id %}\n parsed_params << {{ name.id }}.try(&.to_s(\"%F %X\"))\n {% else %}\n parsed_params << {{ name.id }}\n {% end %}\n {% end %}\n\n return parsed_params\n \nend\n\n def to_h\n fields = \n{} of String => DB::Any\n\n \n{% for name, options in FIELDS %}\n {% type = options[:type] %}\n {% if type.id == Time.id %}\n fields[\"{{ name }}\"] = {{ name.id }}.try(&.to_s(\"%F %X\"))\n {% else %}{% if type.id == Slice.id %}\n fields[\"{{ name }}\"] = {{ name.id }}.try(&.to_s(\"\"))\n {% else %}\n fields[\"{{ name }}\"] = {{ name.id }}\n {% end %}{% end %}\n {% end %}\n\n\n return fields\n \nend\n\n def to_json(json : JSON::Builder)\n json.object do\n \n{% for name, options in FIELDS %}\n {% type = options[:type] %}\n %field, %value = \"{{ name.id }}\", {{ name.id }}\n {% if type.id == Time.id %}\n json.field %field, %value.try(&.to_s(\"%F %X\"))\n {% else %}{% if type.id == Slice.id %}\n json.field %field, %value.id.try(&.to_s(\"\"))\n {% else %}\n json.field %field, %value\n {% end %}{% end %}\n {% end %}\n\n \nend\n \nend\n\n def set_attributes(args : Hash(String | Symbol, Type))\n args.each do |k, v|\n cast_to_field(k, v.as(Type))\n \nend\n \nend\n\n def set_attributes(**args)\n set_attributes(args.to_h)\n \nend\n\n \n# Casts params and sets fields\n\n private def cast_to_field(name, value : Type)\n \n{% if FIELDS.empty? %}{% else %}\n case name.to_s\n {% for _name, options in FIELDS %}\n {% type = options[:type] %}\n when \"{{ _name.id }}\"\n if \"{{ _name.id }}\" == \"{{ PRIMARY[:name] }}\"\n {% if !PRIMARY[:auto] %}\n @{{ PRIMARY[:name] }} = value.as({{ PRIMARY[:type] }})\n {% end %}\n return\n end\n\n return @{{ _name.id }} = nil if value.nil?\n {% if type.id == Int32.id %}\n @{{ _name.id }} = value.is_a?(String) ? value.to_i32(strict: false) : value.is_a?(Int64) ? value.to_i32 : value.as(Int32)\n {% else %}{% if type.id == Int64.id %}\n @{{ _name.id }} = value.is_a?(String) ? value.to_i64(strict: false) : value.as(Int64)\n {% else %}{% if type.id == Float32.id %}\n @{{ _name.id }} = value.is_a?(String) ? value.to_f32(strict: false) : value.is_a?(Float64) ? value.to_f32 : value.as(Float32)\n {% else %}{% if type.id == Float64.id %}\n @{{ _name.id }} = value.is_a?(String) ? value.to_f64(strict: false) : value.as(Float64)\n {% else %}{% if type.id == Bool.id %}\n @{{ _name.id }} = [\"1\", \"yes\", \"true\", true].includes?(value)\n {% else %}{% if type.id == Time.id %}\n if value.is_a?(Time)\n @{{ _name.id }} = value\n elsif value.to_s =~ TIME_FORMAT_REGEX\n @{{ _name.id }} = Time.parse(value.to_s, \"%F %X\")\n end\n {% else %}\n @{{ _name.id }} = value.to_s\n {% end %}{% end %}{% end %}{% end %}{% end %}{% end %}\n {% end %}\n end\n {% end %}\n\n rescue \nex\n \nerrors << Granite::Error.new(name, \nex.message)\n \nend\n \n"}},{"id":"field(decl,**options)-macro","html_id":"field(decl,**options)-macro","name":"field","doc":"specify the fields you want to define and types","summary":"

specify the fields you want to define and types

","abstract":false,"args":[{"name":"decl","doc":null,"default_value":"","external_name":"decl","restriction":""}],"args_string":"(decl, **options)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/fields.cr#L15","def":{"name":"field","args":[{"name":"decl","doc":null,"default_value":"","external_name":"decl","restriction":""}],"double_splat":{"name":"options","doc":null,"default_value":"","external_name":"options","restriction":""},"splat_index":null,"block_arg":null,"visibility":"Public","body":" \n{% CONTENT_FIELDS[decl.var] = options || ({} of Nil => Nil) %}\n\n \n{% CONTENT_FIELDS[decl.var][:type] = decl.type %}\n\n \n"}},{"id":"field!(decl,**options)-macro","html_id":"field!(decl,**options)-macro","name":"field!","doc":"specify the raise-on-nil fields you want to define and types","summary":"

specify the raise-on-nil fields you want to define and types

","abstract":false,"args":[{"name":"decl","doc":null,"default_value":"","external_name":"decl","restriction":""}],"args_string":"(decl, **options)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/fields.cr#L21","def":{"name":"field!","args":[{"name":"decl","doc":null,"default_value":"","external_name":"decl","restriction":""}],"double_splat":{"name":"options","doc":null,"default_value":"","external_name":"options","restriction":""},"splat_index":null,"block_arg":null,"visibility":"Public","body":" field \n{{ decl }}\n, \n{{ options.double_splat(\", \") }}\nraise_on_nil: true\n \n"}},{"id":"timestamps-macro","html_id":"timestamps-macro","name":"timestamps","doc":"include created_at and updated_at that will automatically be updated","summary":"

include created_at and updated_at that will automatically be updated

","abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/fields.cr#L26","def":{"name":"timestamps","args":[],"double_splat":null,"splat_index":null,"block_arg":null,"visibility":"Public","body":" field created_at : Time\n field updated_at : Time\n "}}],"types":[{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Fields/Type","path":"Granite/Fields/Type.html","kind":"alias","full_name":"Granite::Fields::Type","name":"Type","abstract":false,"superclass":null,"ancestors":[],"locations":[{"filename":"granite/fields.cr","line_number":4,"url":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/fields.cr"}],"repository_name":"github.com/Amber-Crystal/granite-orm","program":false,"enum":false,"alias":true,"aliased":"(Array(JSON::Type) | Bool | Float32 | Float64 | Hash(String, JSON::Type) | Int32 | Int64 | Slice(UInt8) | String | Time | Nil)","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Fields","kind":"module","full_name":"Granite::Fields","name":"Fields"},"doc":null,"summary":null,"class_methods":[],"constructors":[],"instance_methods":[],"macros":[],"types":[]}]},{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Migrator","path":"Granite/Migrator.html","kind":"module","full_name":"Granite::Migrator","name":"Migrator","abstract":false,"superclass":null,"ancestors":[],"locations":[{"filename":"granite/migrator.cr","line_number":18,"url":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/migrator.cr"}],"repository_name":"github.com/Amber-Crystal/granite-orm","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Base","kind":"class","full_name":"Granite::Base","name":"Base"}],"namespace":{"html_id":"github.com/Amber-Crystal/granite-orm/Granite","kind":"module","full_name":"Granite","name":"Granite"},"doc":"DB migration tool that prepares a table for the class\n\n```crystal\nclass User < Granite::Base\n adapter mysql\n field name : String\nend\n\nUser.migrator.drop_and_create\n# => \"DROP TABLE IF EXISTS `users`;\"\n# => \"CREATE TABLE `users` (id BIGSERIAL PRIMARY KEY, name VARCHAR(255));\"\n\nUser.migrator(table_options: \"ENGINE=InnoDB DEFAULT CHARSET=utf8\").create\n# => \"CREATE TABLE ... ENGINE=InnoDB DEFAULT CHARSET=utf8;\"\n```","summary":"

DB migration tool that prepares a table for the class

","class_methods":[],"constructors":[],"instance_methods":[],"macros":[{"id":"__process_migrator-macro","html_id":"__process_migrator-macro","name":"__process_migrator","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/migrator.cr#L38","def":{"name":"__process_migrator","args":[],"double_splat":null,"splat_index":null,"block_arg":null,"visibility":"Public","body":" \n{% primary_name = PRIMARY[:name] %}\n\n \n{% primary_type = PRIMARY[:type] %}\n\n \n{% primary_auto = PRIMARY[:auto] %}\n\n \n{% klass = @type.name %}\n\n \n{% adapter = \"#{klass}.adapter\".id %}\n\n\n class Migrator < Granite::Migrator::Base\n def drop\n \n{{ klass }}\n.exec \"DROP TABLE IF EXISTS #{ @quoted_table_name };\"\n \nend\n\n def create\n resolve = ->(key : String) \n{\n \n{{ adapter }}\n.class.schema_type?(key) || raise \"Migrator(#{ \n{{ adapter }}\n.class.name }) doesn't support '#{key}' yet.\"\n }\n\n stmt = String.build do |s|\n s.puts \"CREATE TABLE #{ @quoted_table_name }(\"\n\n \n# primary key\n\n k = \n{{ adapter }}\n.quote(\"\n{{ primary_name }}\n\")\n v =\n \n{% if primary_auto %}\n resolve.call(\"AUTO_{{ primary_type.id }}\")\n {% else %}\n resolve.call(\"{{ primary_type.id }}\")\n {% end %}\n\n s.print \"#{k} #{v} PRIMARY KEY\"\n\n \n# content fields\n\n \n{% for name, options in CONTENT_FIELDS %}\n s.puts \",\"\n k = {{ adapter }}.quote(\"{{ name }}\")\n v =\n {% if (name.id == \"created_at\") || (name.id == \"updated_at\") %}\n resolve.call(\"{{ name }}\")\n {% else %}\n resolve.call(\"{{ options[:type] }}\")\n {% end %}\n s.puts \"#{k} #{v}\"\n {% end %}\n\n\n s.puts \") #{@table_options};\"\n \nend\n\n \n{{ klass }}\n.exec stmt\n \nend\n \nend\n\n def self.migrator(**args)\n Migrator.new(self, **args)\n \nend\n \n"}}],"types":[{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Migrator/Base","path":"Granite/Migrator/Base.html","kind":"class","full_name":"Granite::Migrator::Base","name":"Base","abstract":false,"superclass":{"html_id":"github.com/Amber-Crystal/granite-orm/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"github.com/Amber-Crystal/granite-orm/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"github.com/Amber-Crystal/granite-orm/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"granite/migrator.cr","line_number":19,"url":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/migrator.cr"}],"repository_name":"github.com/Amber-Crystal/granite-orm","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Migrator","kind":"module","full_name":"Granite::Migrator","name":"Migrator"},"doc":null,"summary":null,"class_methods":[],"constructors":[{"id":"new(klass,table_options="")-class-method","html_id":"new(klass,table_options=&quot;&quot;)-class-method","name":"new","doc":null,"summary":null,"abstract":false,"args":[{"name":"klass","doc":null,"default_value":"","external_name":"klass","restriction":""},{"name":"table_options","doc":null,"default_value":"\"\"","external_name":"table_options","restriction":""}],"args_string":"(klass, table_options = "")","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/migrator.cr#L22","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/migrator.cr#L22","def":{"name":"new","args":[{"name":"klass","doc":null,"default_value":"","external_name":"klass","restriction":""},{"name":"table_options","doc":null,"default_value":"\"\"","external_name":"table_options","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"_ = allocate\n_.initialize(klass, table_options)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"id":"create-instance-method","html_id":"create-instance-method","name":"create","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/migrator.cr#L34","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/migrator.cr#L34","def":{"name":"create","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":""}},{"id":"drop-instance-method","html_id":"drop-instance-method","name":"drop","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/migrator.cr#L31","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/migrator.cr#L31","def":{"name":"drop","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":""}},{"id":"drop_and_create-instance-method","html_id":"drop_and_create-instance-method","name":"drop_and_create","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/migrator.cr#L26","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/migrator.cr#L26","def":{"name":"drop_and_create","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"drop\ncreate\n"}}],"macros":[],"types":[]}]},{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Query","path":"Granite/Query.html","kind":"module","full_name":"Granite::Query","name":"Query","abstract":false,"superclass":null,"ancestors":[],"locations":[{"filename":"query_builder.cr","line_number":1,"url":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/query_builder.cr"}],"repository_name":"github.com/Amber-Crystal/granite-orm","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/Amber-Crystal/granite-orm/Granite","kind":"module","full_name":"Granite","name":"Granite"},"doc":null,"summary":null,"class_methods":[],"constructors":[],"instance_methods":[],"macros":[],"types":[{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Query/Assembler","path":"Granite/Query/Assembler.html","kind":"module","full_name":"Granite::Query::Assembler","name":"Assembler","abstract":false,"superclass":null,"ancestors":[],"locations":[{"filename":"granite/query/assemblers/base.cr","line_number":1,"url":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/assemblers/base.cr"},{"filename":"granite/query/assemblers/postgresql.cr","line_number":3,"url":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/assemblers/postgresql.cr"}],"repository_name":"github.com/Amber-Crystal/granite-orm","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Query","kind":"module","full_name":"Granite::Query","name":"Query"},"doc":"Query runner which finalizes a query and runs it.\nThis will likely require adapter specific subclassing :[.","summary":"

Query runner which finalizes a query and runs it.

","class_methods":[],"constructors":[],"instance_methods":[],"macros":[],"types":[{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Query/Assembler/Base","path":"Granite/Query/Assembler/Base.html","kind":"class","full_name":"Granite::Query::Assembler::Base(Model)","name":"Base","abstract":true,"superclass":{"html_id":"github.com/Amber-Crystal/granite-orm/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"github.com/Amber-Crystal/granite-orm/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"github.com/Amber-Crystal/granite-orm/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"granite/query/assemblers/base.cr","line_number":2,"url":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/assemblers/base.cr"}],"repository_name":"github.com/Amber-Crystal/granite-orm","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Query/Assembler/Postgresql","kind":"class","full_name":"Granite::Query::Assembler::Postgresql(Model)","name":"Postgresql"}],"including_types":[],"namespace":{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Query/Assembler","kind":"module","full_name":"Granite::Query::Assembler","name":"Assembler"},"doc":null,"summary":null,"class_methods":[],"constructors":[{"id":"new(query:Granite::Query::Builder(Model))-class-method","html_id":"new(query:Granite::Query::Builder(Model))-class-method","name":"new","doc":null,"summary":null,"abstract":false,"args":[{"name":"query","doc":null,"default_value":"","external_name":"query","restriction":"Builder(Model)"}],"args_string":"(query : Granite::Query::Builder(Model))","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/assemblers/base.cr#L3","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/assemblers/base.cr#L3","def":{"name":"new","args":[{"name":"query","doc":null,"default_value":"","external_name":"query","restriction":"Builder(Model)"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"_ = Base(Model).allocate\n_.initialize(query)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"id":"add_aggregate_field(name:String)-instance-method","html_id":"add_aggregate_field(name:String)-instance-method","name":"add_aggregate_field","doc":null,"summary":null,"abstract":false,"args":[{"name":"name","doc":null,"default_value":"","external_name":"name","restriction":"String"}],"args_string":"(name : String)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/assemblers/base.cr#L17","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/assemblers/base.cr#L17","def":{"name":"add_aggregate_field","args":[{"name":"name","doc":null,"default_value":"","external_name":"name","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"@aggregate_fields << name"}},{"id":"add_parameter(value:DB::Any):String-instance-method","html_id":"add_parameter(value:DB::Any):String-instance-method","name":"add_parameter","doc":null,"summary":null,"abstract":false,"args":[{"name":"value","doc":null,"default_value":"","external_name":"value","restriction":"DB::Any"}],"args_string":"(value : DB::Any) : String","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/assemblers/base.cr#L8","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/assemblers/base.cr#L8","def":{"name":"add_parameter","args":[{"name":"value","doc":null,"default_value":"","external_name":"value","restriction":"DB::Any"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"String","visibility":"Public","body":"@numbered_parameters << value\n\"$#{@numbered_parameters.size}\"\n"}},{"id":"count:Int64-instance-method","html_id":"count:Int64-instance-method","name":"count","doc":null,"summary":null,"abstract":true,"args":[],"args_string":" : Int64","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/assemblers/base.cr#L29","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/assemblers/base.cr#L29","def":{"name":"count","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"Int64","visibility":"Public","body":""}},{"id":"delete-instance-method","html_id":"delete-instance-method","name":"delete","doc":null,"summary":null,"abstract":true,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/assemblers/base.cr#L31","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/assemblers/base.cr#L31","def":{"name":"delete","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":""}},{"id":"field_list-instance-method","html_id":"field_list-instance-method","name":"field_list","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/assemblers/base.cr#L25","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/assemblers/base.cr#L25","def":{"name":"field_list","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"[Model.fields].flatten.join(\", \")"}},{"id":"first(n:Int32=1):Array(Model)-instance-method","html_id":"first(n:Int32=1):Array(Model)-instance-method","name":"first","doc":null,"summary":null,"abstract":true,"args":[{"name":"n","doc":null,"default_value":"1","external_name":"n","restriction":"Int32"}],"args_string":"(n : Int32 = 1) : Array(Model)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/assemblers/base.cr#L30","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/assemblers/base.cr#L30","def":{"name":"first","args":[{"name":"n","doc":null,"default_value":"1","external_name":"n","restriction":"Int32"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"Array(Model)","visibility":"Public","body":""}},{"id":"numbered_parameters-instance-method","html_id":"numbered_parameters-instance-method","name":"numbered_parameters","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/assemblers/base.cr#L13","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/assemblers/base.cr#L13","def":{"name":"numbered_parameters","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"@numbered_parameters"}},{"id":"table_name-instance-method","html_id":"table_name-instance-method","name":"table_name","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/assemblers/base.cr#L21","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/assemblers/base.cr#L21","def":{"name":"table_name","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"Model.table_name"}}],"macros":[],"types":[]},{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Query/Assembler/Postgresql","path":"Granite/Query/Assembler/Postgresql.html","kind":"class","full_name":"Granite::Query::Assembler::Postgresql(Model)","name":"Postgresql","abstract":false,"superclass":{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Query/Assembler/Base","kind":"class","full_name":"Granite::Query::Assembler::Base","name":"Base"},"ancestors":[{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Query/Assembler/Base","kind":"class","full_name":"Granite::Query::Assembler::Base","name":"Base"},{"html_id":"github.com/Amber-Crystal/granite-orm/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"github.com/Amber-Crystal/granite-orm/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"granite/query/assemblers/postgresql.cr","line_number":4,"url":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/assemblers/postgresql.cr"}],"repository_name":"github.com/Amber-Crystal/granite-orm","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Query/Assembler","kind":"module","full_name":"Granite::Query::Assembler","name":"Assembler"},"doc":null,"summary":null,"class_methods":[],"constructors":[{"id":"new(query:Granite::Query::Builder(Model))-class-method","html_id":"new(query:Granite::Query::Builder(Model))-class-method","name":"new","doc":null,"summary":null,"abstract":false,"args":[{"name":"query","doc":null,"default_value":"","external_name":"query","restriction":"Builder(Model)"}],"args_string":"(query : Granite::Query::Builder(Model))","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/assemblers/base.cr#L3","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/assemblers/base.cr#L3","def":{"name":"new","args":[{"name":"query","doc":null,"default_value":"","external_name":"query","restriction":"Builder(Model)"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"_ = Postgresql(Model).allocate\n_.initialize(query)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"id":"build_group_by-instance-method","html_id":"build_group_by-instance-method","name":"build_group_by","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/assemblers/postgresql.cr#L53","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/assemblers/postgresql.cr#L53","def":{"name":"build_group_by","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"if @aggregate_fields.any?\n \"GROUP BY #{@aggregate_fields.join(\", \")}\"\nelse\n \"\"\nend"}},{"id":"build_order(use_default_order=true)-instance-method","html_id":"build_order(use_default_order=true)-instance-method","name":"build_order","doc":null,"summary":null,"abstract":false,"args":[{"name":"use_default_order","doc":null,"default_value":"true","external_name":"use_default_order","restriction":""}],"args_string":"(use_default_order = true)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/assemblers/postgresql.cr#L22","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/assemblers/postgresql.cr#L22","def":{"name":"build_order","args":[{"name":"use_default_order","doc":null,"default_value":"true","external_name":"use_default_order","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"order_fields = @query.order_fields\nif order_fields.none?\n if use_default_order\n order_fields = default_order\n else\n return \"\"\n end\nend\norder_clauses = order_fields.map do |expression|\n add_aggregate_field(expression[:field])\n if expression[:direction] == Builder::Sort::Ascending\n \"#{expression[:field]} ASC\"\n else\n \"#{expression[:field]} DESC\"\n end\nend\n\"ORDER BY #{order_clauses.join(\", \")}\"\n"}},{"id":"build_where-instance-method","html_id":"build_where-instance-method","name":"build_where","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/assemblers/postgresql.cr#L5","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/assemblers/postgresql.cr#L5","def":{"name":"build_where","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"clauses = @query.where_fields.map do |field, value|\n add_aggregate_field(field)\n if value.nil?\n \"#{field} IS NULL\"\n else\n \"#{field} = #{add_parameter(value)}\"\n end\nend\nif clauses.none?\n return \"\"\nend\n\"WHERE #{clauses.join(\" AND \")}\"\n"}},{"id":"count:Granite::Query::Executor::Value(Model,Int64)-instance-method","html_id":"count:Granite::Query::Executor::Value(Model,Int64)-instance-method","name":"count","doc":null,"summary":null,"abstract":false,"args":[],"args_string":" : Granite::Query::Executor::Value(Model, Int64)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/assemblers/postgresql.cr#L61","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/assemblers/postgresql.cr#L61","def":{"name":"count","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"Executor::Value(Model, Int64)","visibility":"Public","body":"where = build_where\norder = build_order(use_default_order = false)\ngroup = build_group_by\nsql = \" SELECT COUNT(*)\n FROM #{table_name}\n #{where}\n #{group}\n #{order}\"\nExecutor::Value(Model, Int64).new(sql, numbered_parameters, default: 0_i64)\n"}},{"id":"default_order-instance-method","html_id":"default_order-instance-method","name":"default_order","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/assemblers/postgresql.cr#L49","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/assemblers/postgresql.cr#L49","def":{"name":"default_order","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"[{field: Model.primary_name, direction: \"ASC\"}]"}},{"id":"delete-instance-method","html_id":"delete-instance-method","name":"delete","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/assemblers/postgresql.cr#L89","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/assemblers/postgresql.cr#L89","def":{"name":"delete","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"sql = \" DELETE\n FROM #{table_name}\n #{build_where}\"\nlog(sql, numbered_parameters)\nModel.adapter.open do |db|\n db.exec(sql, numbered_parameters)\nend\n"}},{"id":"first(n:Int32=1):Granite::Query::Executor::List(Model)-instance-method","html_id":"first(n:Int32=1):Granite::Query::Executor::List(Model)-instance-method","name":"first","doc":null,"summary":null,"abstract":false,"args":[{"name":"n","doc":null,"default_value":"1","external_name":"n","restriction":"Int32"}],"args_string":"(n : Int32 = 1) : Granite::Query::Executor::List(Model)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/assemblers/postgresql.cr#L77","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/assemblers/postgresql.cr#L77","def":{"name":"first","args":[{"name":"n","doc":null,"default_value":"1","external_name":"n","restriction":"Int32"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"Executor::List(Model)","visibility":"Public","body":"sql = \" SELECT #{field_list}\n FROM #{table_name}\n #{build_where}\n #{build_order}\n LIMIT #{n}\"\nExecutor::List(Model).new(sql, numbered_parameters)\n"}},{"id":"log(*stuff)-instance-method","html_id":"log(*stuff)-instance-method","name":"log","doc":null,"summary":null,"abstract":false,"args":[{"name":"stuff","doc":null,"default_value":"","external_name":"stuff","restriction":""}],"args_string":"(*stuff)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/assemblers/postgresql.cr#L46","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/assemblers/postgresql.cr#L46","def":{"name":"log","args":[{"name":"stuff","doc":null,"default_value":"","external_name":"stuff","restriction":""}],"double_splat":null,"splat_index":0,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":""}},{"id":"select-instance-method","html_id":"select-instance-method","name":"select","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/assemblers/postgresql.cr#L102","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/assemblers/postgresql.cr#L102","def":{"name":"select","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"sql = \" SELECT #{field_list}\n FROM #{table_name}\n #{build_where}\n #{build_order}\"\nExecutor::List(Model).new(sql, numbered_parameters)\n"}}],"macros":[],"types":[]}]},{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Query/Builder","path":"Granite/Query/Builder.html","kind":"class","full_name":"Granite::Query::Builder(Model)","name":"Builder","abstract":false,"superclass":{"html_id":"github.com/Amber-Crystal/granite-orm/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"github.com/Amber-Crystal/granite-orm/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"github.com/Amber-Crystal/granite-orm/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"granite/query/builder.cr","line_number":18,"url":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder.cr"}],"repository_name":"github.com/Amber-Crystal/granite-orm","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Query","kind":"module","full_name":"Granite::Query","name":"Query"},"doc":"Data structure which will allow chaining of query components,\nnesting of boolean logic, etc.\n\nShould return self, or another instance of Builder wherever\nchaining should be possible.\n\nCurrent query syntax:\n- where(field: value) => \"WHERE field = 'value'\"\n\nHopefully soon:\n- Model.where(field: value).not( Model.where(field2: value2) )\nor\n- Model.where(field: value).not { where(field2: value2) }\n\n- Model.where(field: value).or( Model.where(field3: value3) )\nor\n- Model.where(field: value).or { whehre(field3: value3) }","summary":"

Data structure which will allow chaining of query components, nesting of boolean logic, etc.

","class_methods":[],"constructors":[{"id":"new(boolean_operator=:and)-class-method","html_id":"new(boolean_operator=:and)-class-method","name":"new","doc":null,"summary":null,"abstract":false,"args":[{"name":"boolean_operator","doc":null,"default_value":":and","external_name":"boolean_operator","restriction":""}],"args_string":"(boolean_operator = :and)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder.cr#L30","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder.cr#L30","def":{"name":"new","args":[{"name":"boolean_operator","doc":null,"default_value":":and","external_name":"boolean_operator","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"_ = Builder(Model).allocate\n_.initialize(boolean_operator)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"id":"any?:Bool-instance-method","html_id":"any?:Bool-instance-method","name":"any?","doc":null,"summary":null,"abstract":false,"args":[],"args_string":" : Bool","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder.cr#L94","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder.cr#L94","def":{"name":"any?","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"Bool","visibility":"Public","body":"!(first.nil?)"}},{"id":"assembler-instance-method","html_id":"assembler-instance-method","name":"assembler","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder.cr#L35","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder.cr#L35","def":{"name":"assembler","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"Assembler::Postgresql(Model).new(self)"}},{"id":"count:Granite::Query::Executor::Value(Model,Int64)-instance-method","html_id":"count:Granite::Query::Executor::Value(Model,Int64)-instance-method","name":"count","doc":null,"summary":null,"abstract":false,"args":[],"args_string":" : Granite::Query::Executor::Value(Model, Int64)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder.cr#L82","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder.cr#L82","def":{"name":"count","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"Executor::Value(Model, Int64)","visibility":"Public","body":"assembler.count"}},{"id":"delete-instance-method","html_id":"delete-instance-method","name":"delete","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder.cr#L98","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder.cr#L98","def":{"name":"delete","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"assembler.delete"}},{"id":"each(&block)-instance-method","html_id":"each(&block)-instance-method","name":"each","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"(&block)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder.cr#L116","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder.cr#L116","def":{"name":"each","args":[],"double_splat":null,"splat_index":null,"yields":1,"block_arg":null,"return_type":"","visibility":"Public","body":"assembler.select.tap do |record_set|\n record_set.each do |record|\n yield record\n end\nend"}},{"id":"first(n:Int32):Granite::Query::Executor::List(Model)-instance-method","html_id":"first(n:Int32):Granite::Query::Executor::List(Model)-instance-method","name":"first","doc":null,"summary":null,"abstract":false,"args":[{"name":"n","doc":null,"default_value":"","external_name":"n","restriction":"Int32"}],"args_string":"(n : Int32) : Granite::Query::Executor::List(Model)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder.cr#L90","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder.cr#L90","def":{"name":"first","args":[{"name":"n","doc":null,"default_value":"","external_name":"n","restriction":"Int32"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"Executor::List(Model)","visibility":"Public","body":"assembler.first(n)"}},{"id":"first:Model?-instance-method","html_id":"first:Model?-instance-method","name":"first","doc":null,"summary":null,"abstract":false,"args":[],"args_string":" : Model?","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder.cr#L86","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder.cr#L86","def":{"name":"first","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"Model | ::Nil","visibility":"Public","body":"(first(1)).first?"}},{"id":"map(&block)-instance-method","html_id":"map(&block)-instance-method","name":"map","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"(&block)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder.cr#L124","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder.cr#L124","def":{"name":"map","args":[],"double_splat":null,"splat_index":null,"yields":1,"block_arg":null,"return_type":"","visibility":"Public","body":"assembler.select.run.map do |record|\n yield record\nend"}},{"id":"order-instance-method","html_id":"order-instance-method","name":"order","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder.cr#L64","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder.cr#L64","def":{"name":"order","args":[],"double_splat":{"name":"dsl","doc":null,"default_value":"","external_name":"dsl","restriction":""},"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"dsl.each do |field, dsl_direction|\n direction = Sort::Ascending\n if (dsl_direction == \"desc\") || (dsl_direction == (:desc))\n direction = Sort::Descending\n end\n @order_fields << ({field: field.to_s, direction: direction})\nend\nself\n"}},{"id":"order(fields:Array(Symbol))-instance-method","html_id":"order(fields:Array(Symbol))-instance-method","name":"order","doc":null,"summary":null,"abstract":false,"args":[{"name":"fields","doc":null,"default_value":"","external_name":"fields","restriction":"Array(Symbol)"}],"args_string":"(fields : Array(Symbol))","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder.cr#L56","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder.cr#L56","def":{"name":"order","args":[{"name":"fields","doc":null,"default_value":"","external_name":"fields","restriction":"Array(Symbol)"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"fields.each do |field|\n order(field)\nend\nself\n"}},{"id":"order(field:Symbol)-instance-method","html_id":"order(field:Symbol)-instance-method","name":"order","doc":null,"summary":null,"abstract":false,"args":[{"name":"field","doc":null,"default_value":"","external_name":"field","restriction":"Symbol"}],"args_string":"(field : Symbol)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder.cr#L50","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder.cr#L50","def":{"name":"order","args":[{"name":"field","doc":null,"default_value":"","external_name":"field","restriction":"Symbol"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"@order_fields << ({field: field.to_s, direction: Sort::Ascending})\nself\n"}},{"id":"order_fields-instance-method","html_id":"order_fields-instance-method","name":"order_fields","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder.cr#L28","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder.cr#L28","def":{"name":"order_fields","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"@order_fields"}},{"id":"raw_sql-instance-method","html_id":"raw_sql-instance-method","name":"raw_sql","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder.cr#L78","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder.cr#L78","def":{"name":"raw_sql","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"assembler.select.raw_sql"}},{"id":"reject(&block)-instance-method","html_id":"reject(&block)-instance-method","name":"reject","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"(&block)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder.cr#L110","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder.cr#L110","def":{"name":"reject","args":[],"double_splat":null,"splat_index":null,"yields":1,"block_arg":null,"return_type":"","visibility":"Public","body":"assembler.select.run.reject do |record|\n yield record\nend"}},{"id":"select-instance-method","html_id":"select-instance-method","name":"select","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder.cr#L102","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder.cr#L102","def":{"name":"select","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"assembler.select.run"}},{"id":"size-instance-method","html_id":"size-instance-method","name":"size","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder.cr#L106","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder.cr#L106","def":{"name":"size","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"count"}},{"id":"where-instance-method","html_id":"where-instance-method","name":"where","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder.cr#L42","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder.cr#L42","def":{"name":"where","args":[],"double_splat":{"name":"matches","doc":null,"default_value":"","external_name":"matches","restriction":""},"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"matches.each do |field, data|\n @where_fields[field.to_s] = data\nend\nself\n"}},{"id":"where_fields-instance-method","html_id":"where_fields-instance-method","name":"where_fields","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder.cr#L27","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder.cr#L27","def":{"name":"where_fields","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"@where_fields"}}],"macros":[],"types":[{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Query/Builder/FieldData","path":"Granite/Query/Builder/FieldData.html","kind":"alias","full_name":"Granite::Query::Builder::FieldData","name":"FieldData","abstract":false,"superclass":null,"ancestors":[],"locations":[{"filename":"granite/query/builder.cr","line_number":20,"url":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder.cr"}],"repository_name":"github.com/Amber-Crystal/granite-orm","program":false,"enum":false,"alias":true,"aliased":"(Bool | Float32 | Float64 | Int32 | Int64 | Slice(UInt8) | String | Time | Nil)","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Query/Builder","kind":"class","full_name":"Granite::Query::Builder(Model)","name":"Builder"},"doc":null,"summary":null,"class_methods":[],"constructors":[],"instance_methods":[],"macros":[],"types":[]},{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Query/Builder/FieldName","path":"Granite/Query/Builder/FieldName.html","kind":"alias","full_name":"Granite::Query::Builder::FieldName","name":"FieldName","abstract":false,"superclass":null,"ancestors":[],"locations":[{"filename":"granite/query/builder.cr","line_number":19,"url":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder.cr"}],"repository_name":"github.com/Amber-Crystal/granite-orm","program":false,"enum":false,"alias":true,"aliased":"String","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Query/Builder","kind":"class","full_name":"Granite::Query::Builder(Model)","name":"Builder"},"doc":null,"summary":null,"class_methods":[],"constructors":[],"instance_methods":[],"macros":[],"types":[]},{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Query/Builder/Sort","path":"Granite/Query/Builder/Sort.html","kind":"enum","full_name":"Granite::Query::Builder::Sort","name":"Sort","abstract":false,"superclass":null,"ancestors":[{"html_id":"github.com/Amber-Crystal/granite-orm/Enum","kind":"struct","full_name":"Enum","name":"Enum"},{"html_id":"github.com/Amber-Crystal/granite-orm/Comparable","kind":"module","full_name":"Comparable","name":"Comparable"},{"html_id":"github.com/Amber-Crystal/granite-orm/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"github.com/Amber-Crystal/granite-orm/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"granite/query/builder.cr","line_number":22,"url":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder.cr"}],"repository_name":"github.com/Amber-Crystal/granite-orm","program":false,"enum":true,"alias":false,"aliased":"","const":false,"constants":[{"name":"Ascending","value":"0","doc":null,"summary":null},{"name":"Descending","value":"1","doc":null,"summary":null}],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Query/Builder","kind":"class","full_name":"Granite::Query::Builder(Model)","name":"Builder"},"doc":null,"summary":null,"class_methods":[],"constructors":[],"instance_methods":[{"id":"ascending?-instance-method","html_id":"ascending?-instance-method","name":"ascending?","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder.cr#L23","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder.cr#L23","def":{"name":"ascending?","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"self == Ascending"}},{"id":"descending?-instance-method","html_id":"descending?-instance-method","name":"descending?","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder.cr#L24","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder.cr#L24","def":{"name":"descending?","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"self == Descending"}}],"macros":[],"types":[]}]},{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Query/BuilderMethods","path":"Granite/Query/BuilderMethods.html","kind":"module","full_name":"Granite::Query::BuilderMethods","name":"BuilderMethods","abstract":false,"superclass":null,"ancestors":[],"locations":[{"filename":"granite/query/builder_methods.cr","line_number":7,"url":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder_methods.cr"}],"repository_name":"github.com/Amber-Crystal/granite-orm","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Query","kind":"module","full_name":"Granite::Query","name":"Query"},"doc":"DSL to be included into a model\nTo activate, simply\n\nclass Model < Granite::Base\n include Query::BuilderMethods\nend","summary":"

DSL to be included into a model To activate, simply

","class_methods":[],"constructors":[],"instance_methods":[{"id":"__builder-instance-method","html_id":"__builder-instance-method","name":"__builder","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder_methods.cr#L8","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder_methods.cr#L8","def":{"name":"__builder","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"Builder(self).new"}},{"id":"count:Granite::Query::Executor::Value(self,Int64)-instance-method","html_id":"count:Granite::Query::Executor::Value(self,Int64)-instance-method","name":"count","doc":null,"summary":null,"abstract":false,"args":[],"args_string":" : Granite::Query::Executor::Value(self, Int64)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder_methods.cr#L12","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder_methods.cr#L12","def":{"name":"count","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"Executor::Value(self, Int64)","visibility":"Public","body":"__builder.count"}},{"id":"first(n:Int32):Granite::Query::Executor::List(self)-instance-method","html_id":"first(n:Int32):Granite::Query::Executor::List(self)-instance-method","name":"first","doc":null,"summary":null,"abstract":false,"args":[{"name":"n","doc":null,"default_value":"","external_name":"n","restriction":"Int32"}],"args_string":"(n : Int32) : Granite::Query::Executor::List(self)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder_methods.cr#L24","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder_methods.cr#L24","def":{"name":"first","args":[{"name":"n","doc":null,"default_value":"","external_name":"n","restriction":"Int32"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"Executor::List(self)","visibility":"Public","body":"__builder.first(n)"}},{"id":"first:self?-instance-method","html_id":"first:self?-instance-method","name":"first","doc":null,"summary":null,"abstract":false,"args":[],"args_string":" : self?","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder_methods.cr#L20","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder_methods.cr#L20","def":{"name":"first","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"self | ::Nil","visibility":"Public","body":"__builder.first"}},{"id":"where:Builder-instance-method","html_id":"where:Builder-instance-method","name":"where","doc":null,"summary":null,"abstract":false,"args":[],"args_string":" : Builder","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder_methods.cr#L16","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/builder_methods.cr#L16","def":{"name":"where","args":[],"double_splat":{"name":"match_data","doc":null,"default_value":"","external_name":"match_data","restriction":""},"splat_index":null,"yields":null,"block_arg":null,"return_type":"Builder","visibility":"Public","body":"__builder.where(**match_data)"}}],"macros":[],"types":[]},{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Query/Executor","path":"Granite/Query/Executor.html","kind":"module","full_name":"Granite::Query::Executor","name":"Executor","abstract":false,"superclass":null,"ancestors":[],"locations":[{"filename":"granite/query/executors/base.cr","line_number":1,"url":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/base.cr"},{"filename":"granite/query/executors/list.cr","line_number":1,"url":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/list.cr"},{"filename":"granite/query/executors/value.cr","line_number":1,"url":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/value.cr"}],"repository_name":"github.com/Amber-Crystal/granite-orm","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Query","kind":"module","full_name":"Granite::Query","name":"Query"},"doc":null,"summary":null,"class_methods":[],"constructors":[],"instance_methods":[],"macros":[],"types":[{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Query/Executor/List","path":"Granite/Query/Executor/List.html","kind":"class","full_name":"Granite::Query::Executor::List(Model)","name":"List","abstract":false,"superclass":{"html_id":"github.com/Amber-Crystal/granite-orm/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Query/Executor/Shared","kind":"module","full_name":"Granite::Query::Executor::Shared","name":"Shared"},{"html_id":"github.com/Amber-Crystal/granite-orm/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"github.com/Amber-Crystal/granite-orm/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"granite/query/executors/list.cr","line_number":2,"url":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/list.cr"}],"repository_name":"github.com/Amber-Crystal/granite-orm","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Query/Executor/Shared","kind":"module","full_name":"Granite::Query::Executor::Shared","name":"Shared"}],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Query/Executor","kind":"module","full_name":"Granite::Query::Executor","name":"Executor"},"doc":null,"summary":null,"class_methods":[],"constructors":[{"id":"new(sql:String,args=[]ofDB::Any)-class-method","html_id":"new(sql:String,args=[]ofDB::Any)-class-method","name":"new","doc":null,"summary":null,"abstract":false,"args":[{"name":"sql","doc":null,"default_value":"","external_name":"sql","restriction":"String"},{"name":"args","doc":null,"default_value":"[] of DB::Any","external_name":"args","restriction":""}],"args_string":"(sql : String, args = [] of DB::Any)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/list.cr#L5","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/list.cr#L5","def":{"name":"new","args":[{"name":"sql","doc":null,"default_value":"","external_name":"sql","restriction":"String"},{"name":"args","doc":null,"default_value":"[] of DB::Any","external_name":"args","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"_ = List(Model).allocate\n_.initialize(sql, args)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"id":"[](*args,**options)-instance-method","html_id":"[](*args,**options)-instance-method","name":"[]","doc":null,"summary":null,"abstract":false,"args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"args_string":"(*args, **options)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/list.cr#L24","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/list.cr#L24","def":{"name":"[]","args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"double_splat":{"name":"options","doc":null,"default_value":"","external_name":"options","restriction":""},"splat_index":0,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"run[*args, **options]"}},{"id":"[](*args,**options,&block)-instance-method","html_id":"[](*args,**options,&block)-instance-method","name":"[]","doc":null,"summary":null,"abstract":false,"args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"args_string":"(*args, **options, &block)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/list.cr#L24","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/list.cr#L24","def":{"name":"[]","args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"double_splat":{"name":"options","doc":null,"default_value":"","external_name":"options","restriction":""},"splat_index":0,"yields":1,"block_arg":null,"return_type":"","visibility":"Public","body":"run[*args, **options] do |*yield_args|\n yield *yield_args\nend"}},{"id":"each(*args,**options)-instance-method","html_id":"each(*args,**options)-instance-method","name":"each","doc":null,"summary":null,"abstract":false,"args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"args_string":"(*args, **options)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/list.cr#L24","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/list.cr#L24","def":{"name":"each","args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"double_splat":{"name":"options","doc":null,"default_value":"","external_name":"options","restriction":""},"splat_index":0,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"run.each(*args, **options)"}},{"id":"each(*args,**options,&block)-instance-method","html_id":"each(*args,**options,&block)-instance-method","name":"each","doc":null,"summary":null,"abstract":false,"args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"args_string":"(*args, **options, &block)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/list.cr#L24","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/list.cr#L24","def":{"name":"each","args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"double_splat":{"name":"options","doc":null,"default_value":"","external_name":"options","restriction":""},"splat_index":0,"yields":1,"block_arg":null,"return_type":"","visibility":"Public","body":"run.each(*args, **options) do |*yield_args|\n yield *yield_args\nend"}},{"id":"first(*args,**options)-instance-method","html_id":"first(*args,**options)-instance-method","name":"first","doc":null,"summary":null,"abstract":false,"args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"args_string":"(*args, **options)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/list.cr#L24","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/list.cr#L24","def":{"name":"first","args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"double_splat":{"name":"options","doc":null,"default_value":"","external_name":"options","restriction":""},"splat_index":0,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"run.first(*args, **options)"}},{"id":"first(*args,**options,&block)-instance-method","html_id":"first(*args,**options,&block)-instance-method","name":"first","doc":null,"summary":null,"abstract":false,"args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"args_string":"(*args, **options, &block)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/list.cr#L24","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/list.cr#L24","def":{"name":"first","args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"double_splat":{"name":"options","doc":null,"default_value":"","external_name":"options","restriction":""},"splat_index":0,"yields":1,"block_arg":null,"return_type":"","visibility":"Public","body":"run.first(*args, **options) do |*yield_args|\n yield *yield_args\nend"}},{"id":"first?(*args,**options)-instance-method","html_id":"first?(*args,**options)-instance-method","name":"first?","doc":null,"summary":null,"abstract":false,"args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"args_string":"(*args, **options)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/list.cr#L24","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/list.cr#L24","def":{"name":"first?","args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"double_splat":{"name":"options","doc":null,"default_value":"","external_name":"options","restriction":""},"splat_index":0,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"run.first?(*args, **options)"}},{"id":"first?(*args,**options,&block)-instance-method","html_id":"first?(*args,**options,&block)-instance-method","name":"first?","doc":null,"summary":null,"abstract":false,"args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"args_string":"(*args, **options, &block)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/list.cr#L24","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/list.cr#L24","def":{"name":"first?","args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"double_splat":{"name":"options","doc":null,"default_value":"","external_name":"options","restriction":""},"splat_index":0,"yields":1,"block_arg":null,"return_type":"","visibility":"Public","body":"run.first?(*args, **options) do |*yield_args|\n yield *yield_args\nend"}},{"id":"group_by(*args,**options)-instance-method","html_id":"group_by(*args,**options)-instance-method","name":"group_by","doc":null,"summary":null,"abstract":false,"args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"args_string":"(*args, **options)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/list.cr#L24","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/list.cr#L24","def":{"name":"group_by","args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"double_splat":{"name":"options","doc":null,"default_value":"","external_name":"options","restriction":""},"splat_index":0,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"run.group_by(*args, **options)"}},{"id":"group_by(*args,**options,&block)-instance-method","html_id":"group_by(*args,**options,&block)-instance-method","name":"group_by","doc":null,"summary":null,"abstract":false,"args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"args_string":"(*args, **options, &block)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/list.cr#L24","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/list.cr#L24","def":{"name":"group_by","args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"double_splat":{"name":"options","doc":null,"default_value":"","external_name":"options","restriction":""},"splat_index":0,"yields":1,"block_arg":null,"return_type":"","visibility":"Public","body":"run.group_by(*args, **options) do |*yield_args|\n yield *yield_args\nend"}},{"id":"run:Array(Model)-instance-method","html_id":"run:Array(Model)-instance-method","name":"run","doc":null,"summary":null,"abstract":false,"args":[],"args_string":" : Array(Model)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/list.cr#L8","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/list.cr#L8","def":{"name":"run","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"Array(Model)","visibility":"Public","body":"log(@sql, @args)\nresults = [] of Model\nModel.adapter.open do |db|\n db.query(@sql, @args) do |record_set|\n record_set.each do\n results << (Model.from_sql(record_set))\n end\n end\nend\nresults\n"}},{"id":"to_s(*args,**options)-instance-method","html_id":"to_s(*args,**options)-instance-method","name":"to_s","doc":null,"summary":null,"abstract":false,"args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"args_string":"(*args, **options)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/list.cr#L25","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/list.cr#L25","def":{"name":"to_s","args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"double_splat":{"name":"options","doc":null,"default_value":"","external_name":"options","restriction":""},"splat_index":0,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"run.to_s(*args, **options)"}},{"id":"to_s(*args,**options,&block)-instance-method","html_id":"to_s(*args,**options,&block)-instance-method","name":"to_s","doc":null,"summary":null,"abstract":false,"args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"args_string":"(*args, **options, &block)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/list.cr#L25","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/list.cr#L25","def":{"name":"to_s","args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"double_splat":{"name":"options","doc":null,"default_value":"","external_name":"options","restriction":""},"splat_index":0,"yields":1,"block_arg":null,"return_type":"","visibility":"Public","body":"run.to_s(*args, **options) do |*yield_args|\n yield *yield_args\nend"}}],"macros":[],"types":[]},{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Query/Executor/Shared","path":"Granite/Query/Executor/Shared.html","kind":"module","full_name":"Granite::Query::Executor::Shared","name":"Shared","abstract":false,"superclass":null,"ancestors":[],"locations":[{"filename":"granite/query/executors/base.cr","line_number":2,"url":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/base.cr"}],"repository_name":"github.com/Amber-Crystal/granite-orm","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Query/Executor/List","kind":"class","full_name":"Granite::Query::Executor::List(Model)","name":"List"},{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Query/Executor/Value","kind":"class","full_name":"Granite::Query::Executor::Value(Model, Scalar)","name":"Value"}],"namespace":{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Query/Executor","kind":"module","full_name":"Granite::Query::Executor","name":"Executor"},"doc":null,"summary":null,"class_methods":[],"constructors":[],"instance_methods":[{"id":"log(*messages)-instance-method","html_id":"log(*messages)-instance-method","name":"log","doc":null,"summary":null,"abstract":false,"args":[{"name":"messages","doc":null,"default_value":"","external_name":"messages","restriction":""}],"args_string":"(*messages)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/base.cr#L7","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/base.cr#L7","def":{"name":"log","args":[{"name":"messages","doc":null,"default_value":"","external_name":"messages","restriction":""}],"double_splat":null,"splat_index":0,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"Granite::Logger.log(messages)"}},{"id":"raw_sql:String-instance-method","html_id":"raw_sql:String-instance-method","name":"raw_sql","doc":null,"summary":null,"abstract":false,"args":[],"args_string":" : String","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/base.cr#L3","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/base.cr#L3","def":{"name":"raw_sql","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"String","visibility":"Public","body":"@sql"}}],"macros":[],"types":[]},{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Query/Executor/Value","path":"Granite/Query/Executor/Value.html","kind":"class","full_name":"Granite::Query::Executor::Value(Model, Scalar)","name":"Value","abstract":false,"superclass":{"html_id":"github.com/Amber-Crystal/granite-orm/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Query/Executor/Shared","kind":"module","full_name":"Granite::Query::Executor::Shared","name":"Shared"},{"html_id":"github.com/Amber-Crystal/granite-orm/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"github.com/Amber-Crystal/granite-orm/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"granite/query/executors/value.cr","line_number":2,"url":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/value.cr"}],"repository_name":"github.com/Amber-Crystal/granite-orm","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Query/Executor/Shared","kind":"module","full_name":"Granite::Query::Executor::Shared","name":"Shared"}],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Query/Executor","kind":"module","full_name":"Granite::Query::Executor","name":"Executor"},"doc":null,"summary":null,"class_methods":[],"constructors":[{"id":"new(sql:String,args=[]ofDB::Any,default:Scalar=nil)-class-method","html_id":"new(sql:String,args=[]ofDB::Any,default:Scalar=nil)-class-method","name":"new","doc":null,"summary":null,"abstract":false,"args":[{"name":"sql","doc":null,"default_value":"","external_name":"sql","restriction":"String"},{"name":"args","doc":null,"default_value":"[] of DB::Any","external_name":"args","restriction":""},{"name":"default","doc":null,"default_value":"nil","external_name":"default","restriction":"Scalar"}],"args_string":"(sql : String, args = [] of DB::Any, default : Scalar = nil)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/value.cr#L5","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/value.cr#L5","def":{"name":"new","args":[{"name":"sql","doc":null,"default_value":"","external_name":"sql","restriction":"String"},{"name":"args","doc":null,"default_value":"[] of DB::Any","external_name":"args","restriction":""},{"name":"default","doc":null,"default_value":"nil","external_name":"default","restriction":"Scalar"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"_ = Value(Model, Scalar).allocate\n_.initialize(sql, args, default)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"id":"<(*args,**options)-instance-method","html_id":"<(*args,**options)-instance-method","name":"<","doc":null,"summary":null,"abstract":false,"args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"args_string":"(*args, **options)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/value.cr#L24","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/value.cr#L24","def":{"name":"<","args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"double_splat":{"name":"options","doc":null,"default_value":"","external_name":"options","restriction":""},"splat_index":0,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"run.<(*args, **options)"}},{"id":"<(*args,**options,&block)-instance-method","html_id":"<(*args,**options,&block)-instance-method","name":"<","doc":null,"summary":null,"abstract":false,"args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"args_string":"(*args, **options, &block)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/value.cr#L24","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/value.cr#L24","def":{"name":"<","args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"double_splat":{"name":"options","doc":null,"default_value":"","external_name":"options","restriction":""},"splat_index":0,"yields":1,"block_arg":null,"return_type":"","visibility":"Public","body":"run.<(*args, **options) do |*yield_args|\n yield *yield_args\nend"}},{"id":"<=(*args,**options)-instance-method","html_id":"<=(*args,**options)-instance-method","name":"<=","doc":null,"summary":null,"abstract":false,"args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"args_string":"(*args, **options)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/value.cr#L24","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/value.cr#L24","def":{"name":"<=","args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"double_splat":{"name":"options","doc":null,"default_value":"","external_name":"options","restriction":""},"splat_index":0,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"run.<=(*args, **options)"}},{"id":"<=(*args,**options,&block)-instance-method","html_id":"<=(*args,**options,&block)-instance-method","name":"<=","doc":null,"summary":null,"abstract":false,"args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"args_string":"(*args, **options, &block)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/value.cr#L24","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/value.cr#L24","def":{"name":"<=","args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"double_splat":{"name":"options","doc":null,"default_value":"","external_name":"options","restriction":""},"splat_index":0,"yields":1,"block_arg":null,"return_type":"","visibility":"Public","body":"run.<=(*args, **options) do |*yield_args|\n yield *yield_args\nend"}},{"id":">(*args,**options)-instance-method","html_id":">(*args,**options)-instance-method","name":">","doc":null,"summary":null,"abstract":false,"args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"args_string":"(*args, **options)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/value.cr#L24","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/value.cr#L24","def":{"name":">","args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"double_splat":{"name":"options","doc":null,"default_value":"","external_name":"options","restriction":""},"splat_index":0,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"run.>(*args, **options)"}},{"id":">(*args,**options,&block)-instance-method","html_id":">(*args,**options,&block)-instance-method","name":">","doc":null,"summary":null,"abstract":false,"args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"args_string":"(*args, **options, &block)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/value.cr#L24","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/value.cr#L24","def":{"name":">","args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"double_splat":{"name":"options","doc":null,"default_value":"","external_name":"options","restriction":""},"splat_index":0,"yields":1,"block_arg":null,"return_type":"","visibility":"Public","body":"run.>(*args, **options) do |*yield_args|\n yield *yield_args\nend"}},{"id":">=(*args,**options)-instance-method","html_id":">=(*args,**options)-instance-method","name":">=","doc":null,"summary":null,"abstract":false,"args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"args_string":"(*args, **options)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/value.cr#L24","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/value.cr#L24","def":{"name":">=","args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"double_splat":{"name":"options","doc":null,"default_value":"","external_name":"options","restriction":""},"splat_index":0,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"run.>=(*args, **options)"}},{"id":">=(*args,**options,&block)-instance-method","html_id":">=(*args,**options,&block)-instance-method","name":">=","doc":null,"summary":null,"abstract":false,"args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"args_string":"(*args, **options, &block)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/value.cr#L24","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/value.cr#L24","def":{"name":">=","args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"double_splat":{"name":"options","doc":null,"default_value":"","external_name":"options","restriction":""},"splat_index":0,"yields":1,"block_arg":null,"return_type":"","visibility":"Public","body":"run.>=(*args, **options) do |*yield_args|\n yield *yield_args\nend"}},{"id":"run:Scalar-instance-method","html_id":"run:Scalar-instance-method","name":"run","doc":null,"summary":null,"abstract":false,"args":[],"args_string":" : Scalar","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/value.cr#L8","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/value.cr#L8","def":{"name":"run","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"Scalar","visibility":"Public","body":"log(@sql, @args)\nif @default\nelse\n raise(\"No default provided\")\nend\nModel.adapter.open do |db|\n db.query_one?(@sql, @args) do |record_set|\n return record_set.read.as(Scalar)\n end\nend\n@default.not_nil!\n"}},{"id":"to_i(*args,**options)-instance-method","html_id":"to_i(*args,**options)-instance-method","name":"to_i","doc":null,"summary":null,"abstract":false,"args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"args_string":"(*args, **options)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/value.cr#L25","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/value.cr#L25","def":{"name":"to_i","args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"double_splat":{"name":"options","doc":null,"default_value":"","external_name":"options","restriction":""},"splat_index":0,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"run.to_i(*args, **options)"}},{"id":"to_i(*args,**options,&block)-instance-method","html_id":"to_i(*args,**options,&block)-instance-method","name":"to_i","doc":null,"summary":null,"abstract":false,"args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"args_string":"(*args, **options, &block)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/value.cr#L25","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/value.cr#L25","def":{"name":"to_i","args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"double_splat":{"name":"options","doc":null,"default_value":"","external_name":"options","restriction":""},"splat_index":0,"yields":1,"block_arg":null,"return_type":"","visibility":"Public","body":"run.to_i(*args, **options) do |*yield_args|\n yield *yield_args\nend"}},{"id":"to_s(*args,**options)-instance-method","html_id":"to_s(*args,**options)-instance-method","name":"to_s","doc":null,"summary":null,"abstract":false,"args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"args_string":"(*args, **options)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/value.cr#L25","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/value.cr#L25","def":{"name":"to_s","args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"double_splat":{"name":"options","doc":null,"default_value":"","external_name":"options","restriction":""},"splat_index":0,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"run.to_s(*args, **options)"}},{"id":"to_s(*args,**options,&block)-instance-method","html_id":"to_s(*args,**options,&block)-instance-method","name":"to_s","doc":null,"summary":null,"abstract":false,"args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"args_string":"(*args, **options, &block)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/value.cr#L25","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/query/executors/value.cr#L25","def":{"name":"to_s","args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""}],"double_splat":{"name":"options","doc":null,"default_value":"","external_name":"options","restriction":""},"splat_index":0,"yields":1,"block_arg":null,"return_type":"","visibility":"Public","body":"run.to_s(*args, **options) do |*yield_args|\n yield *yield_args\nend"}}],"macros":[],"types":[]}]}]},{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Querying","path":"Granite/Querying.html","kind":"module","full_name":"Granite::Querying","name":"Querying","abstract":false,"superclass":null,"ancestors":[],"locations":[{"filename":"granite/querying.cr","line_number":1,"url":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/querying.cr"}],"repository_name":"github.com/Amber-Crystal/granite-orm","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/Amber-Crystal/granite-orm/Granite","kind":"module","full_name":"Granite","name":"Granite"},"doc":null,"summary":null,"class_methods":[],"constructors":[],"instance_methods":[{"id":"all(clause="",params=[]ofDB::Any)-instance-method","html_id":"all(clause=&quot;&quot;,params=[]ofDB::Any)-instance-method","name":"all","doc":"All will return all rows in the database. The clause allows you to specify\na WHERE, JOIN, GROUP BY, ORDER BY and any other SQL92 compatible query to\nyour table. The result will be a Collection(Model) object which lazy loads\nan array of instantiated instances of your Model class.\nThis allows you to take full advantage of the database\nthat you are using so you are not restricted or dummied down to support a\nDSL.\nLazy load prevent running unnecessary queries from unused variables.","summary":"

All will return all rows in the database.

","abstract":false,"args":[{"name":"clause","doc":null,"default_value":"\"\"","external_name":"clause","restriction":""},{"name":"params","doc":null,"default_value":"[] of DB::Any","external_name":"params","restriction":""}],"args_string":"(clause = "", params = [] of DB::Any)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/querying.cr#L63","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/querying.cr#L63","def":{"name":"all","args":[{"name":"clause","doc":null,"default_value":"\"\"","external_name":"clause","restriction":""},{"name":"params","doc":null,"default_value":"[] of DB::Any","external_name":"params","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"Collection(self).new(-> do\n raw_all(clause, params)\nend)"}},{"id":"clear-instance-method","html_id":"clear-instance-method","name":"clear","doc":"Clear is used to remove all rows from the table and reset the counter for\nthe primary key.","summary":"

Clear is used to remove all rows from the table and reset the counter for the primary key.

","abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/querying.cr#L41","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/querying.cr#L41","def":{"name":"clear","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"@@adapter.clear(@@table_name)"}},{"id":"count:Int32-instance-method","html_id":"count:Int32-instance-method","name":"count","doc":"count returns a count of all the records","summary":"

count returns a count of all the records

","abstract":false,"args":[],"args_string":" : Int32","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/querying.cr#L122","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/querying.cr#L122","def":{"name":"count","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"Int32","visibility":"Public","body":"scalar(\"SELECT COUNT(*) FROM #{quoted_table_name}\") do |__arg0|\n __arg0.to_s.to_i\nend"}},{"id":"exec(clause="")-instance-method","html_id":"exec(clause=&quot;&quot;)-instance-method","name":"exec","doc":null,"summary":null,"abstract":false,"args":[{"name":"clause","doc":null,"default_value":"\"\"","external_name":"clause","restriction":""}],"args_string":"(clause = "")","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/querying.cr#L126","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/querying.cr#L126","def":{"name":"exec","args":[{"name":"clause","doc":null,"default_value":"\"\"","external_name":"clause","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"@@adapter.open do |db|\n db.exec(clause)\nend"}},{"id":"find(value)-instance-method","html_id":"find(value)-instance-method","name":"find","doc":"find returns the row with the primary key specified.\nit checks by primary by default, but one can pass\nanother field for comparison","summary":"

find returns the row with the primary key specified.

","abstract":false,"args":[{"name":"value","doc":null,"default_value":"","external_name":"value","restriction":""}],"args_string":"(value)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/querying.cr#L79","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/querying.cr#L79","def":{"name":"find","args":[{"name":"value","doc":null,"default_value":"","external_name":"value","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"return find_by(@@primary_name, value)"}},{"id":"find!(value)-instance-method","html_id":"find!(value)-instance-method","name":"find!","doc":null,"summary":null,"abstract":false,"args":[{"name":"value","doc":null,"default_value":"","external_name":"value","restriction":""}],"args_string":"(value)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/querying.cr#L83","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/querying.cr#L83","def":{"name":"find!","args":[{"name":"value","doc":null,"default_value":"","external_name":"value","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"return find_by!(@@primary_name, value)"}},{"id":"find_by(field:String|Symbol,value)-instance-method","html_id":"find_by(field:String|Symbol,value)-instance-method","name":"find_by","doc":"find_by returns the first row found where the field maches the value","summary":"

find_by returns the first row found where the field maches the value

","abstract":false,"args":[{"name":"field","doc":null,"default_value":"","external_name":"field","restriction":"String | Symbol"},{"name":"value","doc":null,"default_value":"","external_name":"value","restriction":""}],"args_string":"(field : String | Symbol, value)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/querying.cr#L88","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/querying.cr#L88","def":{"name":"find_by","args":[{"name":"field","doc":null,"default_value":"","external_name":"field","restriction":"String | Symbol"},{"name":"value","doc":null,"default_value":"","external_name":"value","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"row = nil\n@@adapter.select_one(@@table_name, fields, field.to_s, value) do |result|\n if result\n row = from_sql(result)\n end\nend\nreturn row\n"}},{"id":"find_by!(field:String|Symbol,value)-instance-method","html_id":"find_by!(field:String|Symbol,value)-instance-method","name":"find_by!","doc":null,"summary":null,"abstract":false,"args":[{"name":"field","doc":null,"default_value":"","external_name":"field","restriction":"String | Symbol"},{"name":"value","doc":null,"default_value":"","external_name":"value","restriction":""}],"args_string":"(field : String | Symbol, value)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/querying.cr#L96","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/querying.cr#L96","def":{"name":"find_by!","args":[{"name":"field","doc":null,"default_value":"","external_name":"field","restriction":"String | Symbol"},{"name":"value","doc":null,"default_value":"","external_name":"value","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"(find_by(field, value)) || (raise(NotFound.new((\"Couldn't find \" + ({{ @type.name.stringify }})) + \" with #{field}=#{value}\")))"}},{"id":"find_each(clause="",params=[]ofDB::Any,batch_sizelimit=100,offset=0,&block)-instance-method","html_id":"find_each(clause=&quot;&quot;,params=[]ofDB::Any,batch_sizelimit=100,offset=0,&block)-instance-method","name":"find_each","doc":null,"summary":null,"abstract":false,"args":[{"name":"clause","doc":null,"default_value":"\"\"","external_name":"clause","restriction":""},{"name":"params","doc":null,"default_value":"[] of DB::Any","external_name":"params","restriction":""},{"name":"limit","doc":null,"default_value":"100","external_name":"batch_size","restriction":""},{"name":"offset","doc":null,"default_value":"0","external_name":"offset","restriction":""}],"args_string":"(clause = "", params = [] of DB::Any, batch_size limit = 100, offset = 0, &block)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/querying.cr#L100","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/querying.cr#L100","def":{"name":"find_each","args":[{"name":"clause","doc":null,"default_value":"\"\"","external_name":"clause","restriction":""},{"name":"params","doc":null,"default_value":"[] of DB::Any","external_name":"params","restriction":""},{"name":"limit","doc":null,"default_value":"100","external_name":"batch_size","restriction":""},{"name":"offset","doc":null,"default_value":"0","external_name":"offset","restriction":""}],"double_splat":null,"splat_index":null,"yields":1,"block_arg":null,"return_type":"","visibility":"Public","body":"find_in_batches(clause, params, batch_size: limit, offset: offset) do |batch|\n batch.each do |record|\n yield record\n end\nend"}},{"id":"find_in_batches(clause="",params=[]ofDB::Any,batch_sizelimit=100,offset=0,&block)-instance-method","html_id":"find_in_batches(clause=&quot;&quot;,params=[]ofDB::Any,batch_sizelimit=100,offset=0,&block)-instance-method","name":"find_in_batches","doc":null,"summary":null,"abstract":false,"args":[{"name":"clause","doc":null,"default_value":"\"\"","external_name":"clause","restriction":""},{"name":"params","doc":null,"default_value":"[] of DB::Any","external_name":"params","restriction":""},{"name":"limit","doc":null,"default_value":"100","external_name":"batch_size","restriction":""},{"name":"offset","doc":null,"default_value":"0","external_name":"offset","restriction":""}],"args_string":"(clause = "", params = [] of DB::Any, batch_size limit = 100, offset = 0, &block)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/querying.cr#L108","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/querying.cr#L108","def":{"name":"find_in_batches","args":[{"name":"clause","doc":null,"default_value":"\"\"","external_name":"clause","restriction":""},{"name":"params","doc":null,"default_value":"[] of DB::Any","external_name":"params","restriction":""},{"name":"limit","doc":null,"default_value":"100","external_name":"batch_size","restriction":""},{"name":"offset","doc":null,"default_value":"0","external_name":"offset","restriction":""}],"double_splat":null,"splat_index":null,"yields":1,"block_arg":null,"return_type":"","visibility":"Public","body":"if limit < 1\n raise(ArgumentError.new(\"batch_size must be >= 1\"))\nend\nwhile true\n results = all(\"#{clause} LIMIT ? OFFSET ?\", params + [limit, offset])\n if results.any?\n else\n break\n end\n yield results\n offset = offset + limit\nend\n"}},{"id":"first(clause="",params=[]ofDB::Any)-instance-method","html_id":"first(clause=&quot;&quot;,params=[]ofDB::Any)-instance-method","name":"first","doc":"First adds a `LIMIT 1` clause to the query and returns the first result","summary":"

First adds a LIMIT 1 clause to the query and returns the first result

","abstract":false,"args":[{"name":"clause","doc":null,"default_value":"\"\"","external_name":"clause","restriction":""},{"name":"params","doc":null,"default_value":"[] of DB::Any","external_name":"params","restriction":""}],"args_string":"(clause = "", params = [] of DB::Any)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/querying.cr#L68","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/querying.cr#L68","def":{"name":"first","args":[{"name":"clause","doc":null,"default_value":"\"\"","external_name":"clause","restriction":""},{"name":"params","doc":null,"default_value":"[] of DB::Any","external_name":"params","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"(all([clause.strip, \"LIMIT 1\"].join(\" \"), params)).first?"}},{"id":"first!(clause="",params=[]ofDB::Any)-instance-method","html_id":"first!(clause=&quot;&quot;,params=[]ofDB::Any)-instance-method","name":"first!","doc":null,"summary":null,"abstract":false,"args":[{"name":"clause","doc":null,"default_value":"\"\"","external_name":"clause","restriction":""},{"name":"params","doc":null,"default_value":"[] of DB::Any","external_name":"params","restriction":""}],"args_string":"(clause = "", params = [] of DB::Any)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/querying.cr#L72","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/querying.cr#L72","def":{"name":"first!","args":[{"name":"clause","doc":null,"default_value":"\"\"","external_name":"clause","restriction":""},{"name":"params","doc":null,"default_value":"[] of DB::Any","external_name":"params","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"(first(clause, params)) || (raise(NotFound.new((\"Couldn't find \" + ({{ @type.name.stringify }})) + \" with first(#{clause})\")))"}},{"id":"query(clause="",params=[]ofDB::Any,&block)-instance-method","html_id":"query(clause=&quot;&quot;,params=[]ofDB::Any,&block)-instance-method","name":"query","doc":null,"summary":null,"abstract":false,"args":[{"name":"clause","doc":null,"default_value":"\"\"","external_name":"clause","restriction":""},{"name":"params","doc":null,"default_value":"[] of DB::Any","external_name":"params","restriction":""}],"args_string":"(clause = "", params = [] of DB::Any, &block)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/querying.cr#L130","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/querying.cr#L130","def":{"name":"query","args":[{"name":"clause","doc":null,"default_value":"\"\"","external_name":"clause","restriction":""},{"name":"params","doc":null,"default_value":"[] of DB::Any","external_name":"params","restriction":""}],"double_splat":null,"splat_index":null,"yields":1,"block_arg":null,"return_type":"","visibility":"Public","body":"@@adapter.open do |db|\n yield db.query(clause, params)\nend"}},{"id":"raw_all(clause="",params=[]ofDB::Any)-instance-method","html_id":"raw_all(clause=&quot;&quot;,params=[]ofDB::Any)-instance-method","name":"raw_all","doc":null,"summary":null,"abstract":false,"args":[{"name":"clause","doc":null,"default_value":"\"\"","external_name":"clause","restriction":""},{"name":"params","doc":null,"default_value":"[] of DB::Any","external_name":"params","restriction":""}],"args_string":"(clause = "", params = [] of DB::Any)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/querying.cr#L45","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/querying.cr#L45","def":{"name":"raw_all","args":[{"name":"clause","doc":null,"default_value":"\"\"","external_name":"clause","restriction":""},{"name":"params","doc":null,"default_value":"[] of DB::Any","external_name":"params","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"rows = [] of self\n@@adapter.select(@@table_name, fields, clause, params) do |results|\n results.each do\n rows << (from_sql(results))\n end\nend\nreturn rows\n"}},{"id":"scalar(clause="",&block)-instance-method","html_id":"scalar(clause=&quot;&quot;,&block)-instance-method","name":"scalar","doc":null,"summary":null,"abstract":false,"args":[{"name":"clause","doc":null,"default_value":"\"\"","external_name":"clause","restriction":""}],"args_string":"(clause = "", &block)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/querying.cr#L134","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/querying.cr#L134","def":{"name":"scalar","args":[{"name":"clause","doc":null,"default_value":"\"\"","external_name":"clause","restriction":""}],"double_splat":null,"splat_index":null,"yields":1,"block_arg":null,"return_type":"","visibility":"Public","body":"@@adapter.open do |db|\n yield db.scalar(clause)\nend"}}],"macros":[],"types":[{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Querying/NotFound","path":"Granite/Querying/NotFound.html","kind":"class","full_name":"Granite::Querying::NotFound","name":"NotFound","abstract":false,"superclass":{"html_id":"github.com/Amber-Crystal/granite-orm/Exception","kind":"class","full_name":"Exception","name":"Exception"},"ancestors":[{"html_id":"github.com/Amber-Crystal/granite-orm/Exception","kind":"class","full_name":"Exception","name":"Exception"},{"html_id":"github.com/Amber-Crystal/granite-orm/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"github.com/Amber-Crystal/granite-orm/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"granite/querying.cr","line_number":2,"url":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/querying.cr"}],"repository_name":"github.com/Amber-Crystal/granite-orm","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Querying","kind":"module","full_name":"Granite::Querying","name":"Querying"},"doc":null,"summary":null,"class_methods":[],"constructors":[],"instance_methods":[],"macros":[],"types":[]}]},{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Settings","path":"Granite/Settings.html","kind":"class","full_name":"Granite::Settings","name":"Settings","abstract":false,"superclass":{"html_id":"github.com/Amber-Crystal/granite-orm/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"github.com/Amber-Crystal/granite-orm/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"github.com/Amber-Crystal/granite-orm/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"granite/settings.cr","line_number":4,"url":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/settings.cr"}],"repository_name":"github.com/Amber-Crystal/granite-orm","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/Amber-Crystal/granite-orm/Granite","kind":"module","full_name":"Granite","name":"Granite"},"doc":null,"summary":null,"class_methods":[],"constructors":[{"id":"new-class-method","html_id":"new-class-method","name":"new","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/settings.cr#L8","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/settings.cr#L8","def":{"name":"new","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"_ = allocate\n_.initialize\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"id":"database_url:String?-instance-method","html_id":"database_url:String?-instance-method","name":"database_url","doc":null,"summary":null,"abstract":false,"args":[],"args_string":" : String?","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/settings.cr#L5","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/settings.cr#L5","def":{"name":"database_url","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"String | ::Nil","visibility":"Public","body":"@database_url"}},{"id":"database_url=(database_url:String?)-instance-method","html_id":"database_url=(database_url:String?)-instance-method","name":"database_url=","doc":null,"summary":null,"abstract":false,"args":[{"name":"database_url","doc":null,"default_value":"","external_name":"database_url","restriction":"String | ::Nil"}],"args_string":"(database_url : String?)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/settings.cr#L5","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/settings.cr#L5","def":{"name":"database_url=","args":[{"name":"database_url","doc":null,"default_value":"","external_name":"database_url","restriction":"String | ::Nil"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"@database_url = database_url"}},{"id":"logger:Logger-instance-method","html_id":"logger:Logger-instance-method","name":"logger","doc":null,"summary":null,"abstract":false,"args":[],"args_string":" : Logger","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/settings.cr#L6","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/settings.cr#L6","def":{"name":"logger","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"Logger","visibility":"Public","body":"@logger"}},{"id":"logger=(logger:Logger)-instance-method","html_id":"logger=(logger:Logger)-instance-method","name":"logger=","doc":null,"summary":null,"abstract":false,"args":[{"name":"logger","doc":null,"default_value":"","external_name":"logger","restriction":"Logger"}],"args_string":"(logger : Logger)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/settings.cr#L6","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/settings.cr#L6","def":{"name":"logger=","args":[{"name":"logger","doc":null,"default_value":"","external_name":"logger","restriction":"Logger"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"@logger = logger"}}],"macros":[],"types":[]},{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Table","path":"Granite/Table.html","kind":"module","full_name":"Granite::Table","name":"Table","abstract":false,"superclass":null,"ancestors":[],"locations":[{"filename":"granite/table.cr","line_number":1,"url":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/table.cr"}],"repository_name":"github.com/Amber-Crystal/granite-orm","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Base","kind":"class","full_name":"Granite::Base","name":"Base"}],"namespace":{"html_id":"github.com/Amber-Crystal/granite-orm/Granite","kind":"module","full_name":"Granite","name":"Granite"},"doc":null,"summary":null,"class_methods":[],"constructors":[],"instance_methods":[],"macros":[{"id":"__process_table-macro","html_id":"__process_table-macro","name":"__process_table","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/table.cr#L37","def":{"name":"__process_table","args":[],"double_splat":null,"splat_index":null,"block_arg":null,"visibility":"Public","body":" \n{% name_space = (@type.name.gsub(/::/, \"_\")).underscore.id %}\n\n \n{% table_name = SETTINGS[:table_name] || (name_space + \"s\") %}\n\n \n{% primary_name = PRIMARY[:name] %}\n\n \n{% primary_type = PRIMARY[:type] %}\n\n \n{% primary_auto = PRIMARY[:auto] %}\n\n\n @@table_name = \"\n{{ table_name }}\n\"\n @@primary_name = \"\n{{ primary_name }}\n\"\n @@primary_auto = \"\n{{ primary_auto }}\n\"\n\n def self.table_name\n @@table_name\n \nend\n\n def self.primary_name\n @@primary_name\n \nend\n\n def self.primary_auto\n @@primary_auto\n \nend\n\n def self.quoted_table_name\n @@adapter.quote(table_name)\n \nend\n\n def self.quote(column_name)\n @@adapter.quote(column_name)\n \nend\n \n"}},{"id":"adapter(name)-macro","html_id":"adapter(name)-macro","name":"adapter","doc":"specify the database adapter you will be using for this model.\nmysql, pg, sqlite, etc.","summary":"

specify the database adapter you will be using for this model.

","abstract":false,"args":[{"name":"name","doc":null,"default_value":"","external_name":"name","restriction":""}],"args_string":"(name)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/table.cr#L11","def":{"name":"adapter","args":[{"name":"name","doc":null,"default_value":"","external_name":"name","restriction":""}],"double_splat":null,"splat_index":null,"block_arg":null,"visibility":"Public","body":" @@adapter = Granite::Adapter::\n{{ name.id.capitalize }}\n.new(\"\n{{ name.id }}\n\")\n\n def self.adapter\n @@adapter\n \nend\n \n"}},{"id":"primary(decl)-macro","html_id":"primary(decl)-macro","name":"primary","doc":"specify the primary key column and type","summary":"

specify the primary key column and type

","abstract":false,"args":[{"name":"decl","doc":null,"default_value":"","external_name":"decl","restriction":""}],"args_string":"(decl)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/table.cr#L25","def":{"name":"primary","args":[{"name":"decl","doc":null,"default_value":"","external_name":"decl","restriction":""}],"double_splat":null,"splat_index":null,"block_arg":null,"visibility":"Public","body":" \n{% PRIMARY[:name] = decl.var %}\n\n \n{% PRIMARY[:type] = decl.type %}\n\n \n"}},{"id":"primary(decl,auto)-macro","html_id":"primary(decl,auto)-macro","name":"primary","doc":"specify the primary key column and type and auto_increment","summary":"

specify the primary key column and type and auto_increment

","abstract":false,"args":[{"name":"decl","doc":null,"default_value":"","external_name":"decl","restriction":""},{"name":"auto","doc":null,"default_value":"","external_name":"auto","restriction":""}],"args_string":"(decl, auto)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/table.cr#L31","def":{"name":"primary","args":[{"name":"decl","doc":null,"default_value":"","external_name":"decl","restriction":""},{"name":"auto","doc":null,"default_value":"","external_name":"auto","restriction":""}],"double_splat":null,"splat_index":null,"block_arg":null,"visibility":"Public","body":" \n{% PRIMARY[:name] = decl.var %}\n\n \n{% PRIMARY[:type] = decl.type %}\n\n \n{% PRIMARY[:auto] = auto %}\n\n \n"}},{"id":"table_name(name)-macro","html_id":"table_name(name)-macro","name":"table_name","doc":"specify the table name to use otherwise it will use the model's name","summary":"

specify the table name to use otherwise it will use the model's name

","abstract":false,"args":[{"name":"name","doc":null,"default_value":"","external_name":"name","restriction":""}],"args_string":"(name)","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/table.cr#L20","def":{"name":"table_name","args":[{"name":"name","doc":null,"default_value":"","external_name":"name","restriction":""}],"double_splat":null,"splat_index":null,"block_arg":null,"visibility":"Public","body":" \n{% SETTINGS[:table_name] = name.id %}\n\n \n"}}],"types":[]},{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Transactions","path":"Granite/Transactions.html","kind":"module","full_name":"Granite::Transactions","name":"Transactions","abstract":false,"superclass":null,"ancestors":[],"locations":[{"filename":"granite/transactions.cr","line_number":1,"url":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/transactions.cr"}],"repository_name":"github.com/Amber-Crystal/granite-orm","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Base","kind":"class","full_name":"Granite::Base","name":"Base"}],"namespace":{"html_id":"github.com/Amber-Crystal/granite-orm/Granite","kind":"module","full_name":"Granite","name":"Granite"},"doc":null,"summary":null,"class_methods":[],"constructors":[],"instance_methods":[{"id":"destroyed?:Bool-instance-method","html_id":"destroyed?:Bool-instance-method","name":"destroyed?","doc":"Returns true if this object has been destroyed.","summary":"

Returns true if this object has been destroyed.

","abstract":false,"args":[],"args_string":" : Bool","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/transactions.cr#L157","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/transactions.cr#L157","def":{"name":"destroyed?","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"Bool","visibility":"Public","body":"@destroyed"}},{"id":"new_record?:Bool-instance-method","html_id":"new_record?:Bool-instance-method","name":"new_record?","doc":"Returns true if this object hasn't been saved yet.","summary":"

Returns true if this object hasn't been saved yet.

","abstract":false,"args":[],"args_string":" : Bool","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/transactions.cr#L154","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/transactions.cr#L154","def":{"name":"new_record?","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"Bool","visibility":"Public","body":"@new_record"}},{"id":"persisted?-instance-method","html_id":"persisted?-instance-method","name":"persisted?","doc":"Returns true if the record is persisted.","summary":"

Returns true if the record is persisted.

","abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/transactions.cr#L160","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/transactions.cr#L160","def":{"name":"persisted?","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"!(new_record? || destroyed?)"}}],"macros":[{"id":"__process_transactions-macro","html_id":"__process_transactions-macro","name":"__process_transactions","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/transactions.cr#L15","def":{"name":"__process_transactions","args":[],"double_splat":null,"splat_index":null,"block_arg":null,"visibility":"Public","body":" \n{% primary_name = PRIMARY[:name] %}\n\n \n{% primary_type = PRIMARY[:type] %}\n\n \n{% primary_auto = PRIMARY[:auto] %}\n\n\n @updated_at : Time?\n @created_at : Time?\n\n \n# The import class method will run a batch INSERT statement for each model in the array\n\n \n# the array must contain only one model class\n\n \n# invalid model records will be skipped\n\n def self.import(model_array : Array(self) | Granite::Collection(self), batch_size : Int32 = model_array.size)\n begin\n fields_duplicate = fields.dup\n model_array.each_slice(batch_size, true) do |slice|\n @@adapter.import(table_name, primary_name, primary_auto, fields_duplicate, slice)\n \nend\n rescue \nerr\n raise DB::Error.new(\nerr.message)\n \nend\n \nend\n\n def self.import(model_array : Array(self) | Granite::Collection(self), update_on_duplicate : Bool, columns : Array(String), batch_size : Int32 = model_array.size)\n begin\n fields_duplicate = fields.dup\n model_array.each_slice(batch_size, true) do |slice|\n @@adapter.import(table_name, primary_name, primary_auto, fields_duplicate, slice, update_on_duplicate: update_on_duplicate, columns: columns)\n \nend\n rescue \nerr\n raise DB::Error.new(\nerr.message)\n \nend\n \nend\n\n def self.import(model_array : Array(self) | Granite::Collection(self), ignore_on_duplicate : Bool, batch_size : Int32 = model_array.size)\n begin\n fields_duplicate = fields.dup\n model_array.each_slice(batch_size, true) do |slice|\n @@adapter.import(table_name, primary_name, primary_auto, fields_duplicate, slice, ignore_on_duplicate: ignore_on_duplicate)\n \nend\n rescue \nerr\n raise DB::Error.new(\nerr.message)\n \nend\n \nend\n\n private def __create\n @created_at = @updated_at = Time.now.to_utc\n fields = self.class.content_fields.dup\n params = content_values\n if value = @\n{{ primary_name }}\n\n fields << \"\n{{ primary_name }}\n\"\n params << value\n \nend\n begin\n \n{% if primary_type.id == \"Int32\" %}\n @{{ primary_name }} = @@adapter.insert(@@table_name, fields, params, lastval: true).to_i32\n {% else %}{% if primary_type.id == \"Int64\" %}\n @{{ primary_name }} = @@adapter.insert(@@table_name, fields, params, lastval: true)\n {% else %}{% if primary_auto == true %}\n {% raise(\"Failed to define #{@type.name}#save: Primary key must be Int(32|64), or set `auto: false` for natural keys.\n\n primary #{primary_name} : #{primary_type}, auto: false\n\") %}\n {% else %}\n if @{{ primary_name }}\n @@adapter.insert(@@table_name, fields, params, lastval: false)\n else\n message = \"Primary key('{{ primary_name }}') cannot be null\"\n errors << Granite::Error.new(\"{{ primary_name }}\", message)\n raise DB::Error.new\n end\n {% end %}{% end %}{% end %}\n\n rescue \nerr : DB::Error\n raise \nerr\n rescue \nerr\n raise DB::Error.new(\nerr.message)\n \nend\n @new_record = false\n \nend\n\n private def __update\n @updated_at = Time.now.to_utc\n fields = self.class.content_fields\n params = content_values + [@\n{{ primary_name }}\n]\n\n begin\n @@adapter.update @@table_name, @@primary_name, fields, params\n rescue \nerr\n raise DB::Error.new(\nerr.message)\n \nend\n \nend\n\n private def __destroy\n @@adapter.delete(@@table_name, @@primary_name, @\n{{ primary_name }}\n)\n @destroyed = true\n \nend\n\n \n# The save method will check to see if the primary exists yet. If it does it\n\n \n# will call the update method, otherwise it will call the create method.\n\n \n# This will update the timestamps appropriately.\n\n def save\n return false unless valid?\n\n begin\n __before_save\n if @\n{{ primary_name }}\n && !new_record?\n __before_update\n __update\n __after_update\n \nelse\n __before_create\n __create\n __after_create\n \nend\n __after_save\n rescue \nex : DB::Error | Granite::Callbacks::Abort\n if message = \nex.message\n Granite.settings.logger.error \"Save Exception: #{message}\"\n \nerrors << Granite::Error.new(:base, message)\n \nend\n return false\n \nend\n true\n \nend\n\n \n# Destroy will remove this from the database.\n\n def destroy\n begin\n __before_destroy\n __destroy\n __after_destroy\n rescue \nex : DB::Error | Granite::Callbacks::Abort\n if message = \nex.message\n Granite.settings.logger.error \"Destroy Exception: #{message}\"\n \nerrors << Granite::Error.new(:base, message)\n \nend\n return false\n \nend\n true\n \nend\n \n"}}],"types":[{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Transactions/ClassMethods","path":"Granite/Transactions/ClassMethods.html","kind":"module","full_name":"Granite::Transactions::ClassMethods","name":"ClassMethods","abstract":false,"superclass":null,"ancestors":[],"locations":[{"filename":"granite/transactions.cr","line_number":2,"url":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/transactions.cr"}],"repository_name":"github.com/Amber-Crystal/granite-orm","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Transactions","kind":"module","full_name":"Granite::Transactions","name":"Transactions"},"doc":null,"summary":null,"class_methods":[],"constructors":[],"instance_methods":[{"id":"create(args:Hash(Symbol|String,DB::Any))-instance-method","html_id":"create(args:Hash(Symbol|String,DB::Any))-instance-method","name":"create","doc":null,"summary":null,"abstract":false,"args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":"Hash(Symbol | String, DB::Any)"}],"args_string":"(args : Hash(Symbol | String, DB::Any))","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/transactions.cr#L7","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/transactions.cr#L7","def":{"name":"create","args":[{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":"Hash(Symbol | String, DB::Any)"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"instance = new\ninstance.set_attributes(args)\ninstance.save\ninstance\n"}},{"id":"create-instance-method","html_id":"create-instance-method","name":"create","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/transactions.cr#L3","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/transactions.cr#L3","def":{"name":"create","args":[],"double_splat":{"name":"args","doc":null,"default_value":"","external_name":"args","restriction":""},"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"create(args.to_h)"}}],"macros":[],"types":[]}]},{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Validators","path":"Granite/Validators.html","kind":"module","full_name":"Granite::Validators","name":"Validators","abstract":false,"superclass":null,"ancestors":[],"locations":[{"filename":"granite/validators.cr","line_number":18,"url":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/validators.cr"}],"repository_name":"github.com/Amber-Crystal/granite-orm","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[{"html_id":"github.com/Amber-Crystal/granite-orm/Granite/Base","kind":"class","full_name":"Granite::Base","name":"Base"}],"namespace":{"html_id":"github.com/Amber-Crystal/granite-orm/Granite","kind":"module","full_name":"Granite","name":"Granite"},"doc":"Analyze validation blocks and procs\n\nBy example:\n```\nvalidate :name, \"can't be blank\" do |user|\n !user.name.to_s.blank?\nend\n\nvalidate :name, \"can't be blank\", ->(user : User) do\n !user.name.to_s.blank?\nend\n\nname_required = ->(model : Granite::Base) { !model.name.to_s.blank? }\nvalidate :name, \"can't be blank\", name_required\n```","summary":"

Analyze validation blocks and procs

","class_methods":[],"constructors":[],"instance_methods":[{"id":"errors-instance-method","html_id":"errors-instance-method","name":"errors","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/validators.cr#L19","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/validators.cr#L19","def":{"name":"errors","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"@errors"}},{"id":"valid?-instance-method","html_id":"valid?-instance-method","name":"valid?","doc":null,"summary":null,"abstract":false,"args":[],"args_string":"","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/validators.cr#L43","source_link":"https://github.com/Amber-Crystal/granite-orm/blob/30ec77fcef1f89a8da9045be6696365d51ff1f66/src/granite/validators.cr#L43","def":{"name":"valid?","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"@@validators.each do |validator|\n if validator[:block].call(self)\n else\n errors << (Error.new(validator[:field], validator[:message]))\n end\nend\nerrors.empty?\n"}}],"macros":[],"types":[]}]}]}} \ No newline at end of file diff --git a/docs/js/doc.js b/docs/js/doc.js deleted file mode 100644 index c7ee0385..00000000 --- a/docs/js/doc.js +++ /dev/null @@ -1,111 +0,0 @@ -document.addEventListener('DOMContentLoaded', function() { - var sessionStorage; - try { - sessionStorage = window.sessionStorage; - } catch (e) { } - if(!sessionStorage) { - sessionStorage = { - setItem: function() {}, - getItem: function() {}, - removeItem: function() {} - }; - } - - var repositoryName = document.getElementById('repository-name').getAttribute('content'); - var typesList = document.getElementById('types-list'); - var searchInput = document.getElementById('search-input'); - var parents = document.querySelectorAll('#types-list li.parent'); - - for(var i = 0; i < parents.length; i++) { - var _parent = parents[i]; - _parent.addEventListener('click', function(e) { - e.stopPropagation(); - - if(e.target.tagName.toLowerCase() == 'li') { - if(e.target.className.match(/open/)) { - sessionStorage.removeItem(e.target.getAttribute('data-id')); - e.target.className = e.target.className.replace(/ +open/g, ''); - } else { - sessionStorage.setItem(e.target.getAttribute('data-id'), '1'); - if(e.target.className.indexOf('open') == -1) { - e.target.className += ' open'; - } - } - } - }); - - if(sessionStorage.getItem(_parent.getAttribute('data-id')) == '1') { - _parent.className += ' open'; - } - }; - - var childMatch = function(type, regexp){ - var types = type.querySelectorAll("ul li"); - for (var j = 0; j < types.length; j ++) { - var t = types[j]; - if(regexp.exec(t.getAttribute('data-name'))){ return true; }; - }; - return false; - }; - - var searchTimeout; - var performSearch = function() { - clearTimeout(searchTimeout); - searchTimeout = setTimeout(function() { - var text = searchInput.value; - var types = document.querySelectorAll('#types-list li'); - var words = text.toLowerCase().split(/\s+/).filter(function(word) { - return word.length > 0; - }); - var regexp = new RegExp(words.join('|')); - - for(var i = 0; i < types.length; i++) { - var type = types[i]; - if(words.length == 0 || regexp.exec(type.getAttribute('data-name')) || childMatch(type, regexp)) { - type.className = type.className.replace(/ +hide/g, ''); - var is_parent = new RegExp("parent").exec(type.className); - var is_not_opened = !(new RegExp("open").exec(type.className)); - if(childMatch(type,regexp) && is_parent && is_not_opened){ - type.className += " open"; - }; - } else { - if(type.className.indexOf('hide') == -1) { - type.className += ' hide'; - }; - }; - if(words.length == 0){ - type.className = type.className.replace(/ +open/g, ''); - }; - } - }, 200); - }; - if (searchInput.value.length > 0) { - performSearch(); - } - searchInput.addEventListener('keyup', performSearch); - searchInput.addEventListener('input', performSearch); - - typesList.onscroll = function() { - var y = typesList.scrollTop; - sessionStorage.setItem(repositoryName + '::types-list:scrollTop', y); - }; - - var initialY = parseInt(sessionStorage.getItem(repositoryName + '::types-list:scrollTop') + "", 10); - if(initialY > 0) { - typesList.scrollTop = initialY; - } - - var scrollToEntryFromLocationHash = function() { - var hash = window.location.hash; - if (hash) { - var targetAnchor = unescape(hash.substr(1)); - var targetEl = document.querySelectorAll('.entry-detail[id="' + targetAnchor + '"]'); - - if (targetEl && targetEl.length > 0) { - targetEl[0].offsetParent.scrollTop = targetEl[0].offsetTop; - } - } - }; - window.addEventListener("hashchange", scrollToEntryFromLocationHash, false); - scrollToEntryFromLocationHash(); -}); diff --git a/docs/json_support.md b/docs/json_support.md new file mode 100644 index 00000000..eb17b019 --- /dev/null +++ b/docs/json_support.md @@ -0,0 +1,140 @@ +# JSON Support + +Granite has native support for serializing and deserializing to and from JSON strings via the [JSON::Serializable](https://crystal-lang.org/api/0.25.1/JSON/Serializable.html) module. + +## JSON::Field + +Allows for control over the serialization and deserialization of instance variables. + + ```Crystal +class Foo < Granite::Base + adapter mysql + table_name foos + + field name : String + field password : String, json_options: {ignore: true} # skip this field in serialization and deserialization + field age : Int32, json_options: {key: "HowOldTheyAre"} # the value of the key in the json object + field todayBirthday : Bool, json_options: {emit_null: true} # emits a null value for nilable property + field isNil : Bool +end + ``` + +`foo = Foo.from_json(%({"name": "Granite1", "HowOldTheyAre": 12, "password": "12345"}))` + + ```Crystal +# + ``` + +`foo.to_json` + + ```JSON +{ + "name":"Granite1", + "HowOldTheyAre":12, + "todayBirthday":null +} + ``` + +Notice how `isNil` is omitted from the JSON output since it is Nil. If you wish to always show Nil instance variables on a class level you can do: + + ```Crystal +@[JSON::Serializable::Options(emit_nulls: true)] +class Foo < Granite::Base + adapter mysql + table_name foos + + field name : String + field age : Int32 +end + ``` + +This would be functionally the same as adding `json_options: {emit_null: true}` on each property. + +## after_initialize + +This method gets called after `from_json` is done parsing the given JSON string. This allows you to set other fields that are not in the JSON directly or that require some more logic. + + ```Crystal +class Foo < Granite::Base + adapter mysql + table_name foos + + field name : String + field age : Int32 + field date_added : Time + + def after_initialize + @date_added = Time.utc_now + end +end + ``` + +`foo = Foo.from_json(%({"name": "Granite1"}))` + + ```Crystal + + ``` + +## JSON::Serializable::Unmapped + +If the `JSON::Serializable::Unmapped` module is included, unknown properties in the JSON document will be stored in a Hash(String, JSON::Any). On serialization, any keys inside `json_unmapped` will be serialized appended to the current JSON object. + + ```Crystal +class Foo < Granite::Base + include JSON::Serializable::Unmapped + + adapter mysql + table_name foos + + field name : String + field age : Int32 +end + ``` + +`foo = Foo.from_json(%({"name": "Granite1", "age": 12, "foobar": true}))` + + ```Crystal + true}, + @name="Granite1", + @new_record=true, + @updated_at=nil> + ``` + +`foo.to_json` + + ```JSON +{ + "name": "Granite", + "age": 12, + "foobar": true +} + ``` \ No newline at end of file diff --git a/docs/migrations.md b/docs/migrations.md new file mode 100644 index 00000000..7c8f0c92 --- /dev/null +++ b/docs/migrations.md @@ -0,0 +1,95 @@ +# Migrations + +## migrator + +Provides `drop`, `create` and `drop_and_create` methods + + ```crystal + class User < Granite::Base + adapter mysql + field name : String + end + + User.migrator.drop_and_create + # => "DROP TABLE IF EXISTS `users`;" + # => "CREATE TABLE `users` (id BIGSERIAL PRIMARY KEY, name VARCHAR(255));" + + User.migrator(table_options: "ENGINE=InnoDB DEFAULT CHARSET=utf8").create + # => "CREATE TABLE ... ENGINE=InnoDB DEFAULT CHARSET=utf8;" + ``` +## Database Migrations with micrate + +If you're using Granite ORM to query your data you likely want to manage your database schema as well. Migrations are a great way to do that, so let's take a look at [micrate](https://github.com/juanedi/micrate), a project to manage migrations. We'll use it as a dependency instead of a pre-build binary. + +### Install + +Add micrate your shards.yml + +```yaml +dependencies: + micrate: + github: juanedi/micrate +``` + +Update shards +```sh +$ shards update +``` + +Create an executable to run the `Micrate::Cli`. For this example, we'll create `bin/micrate` in the root of our project where we're using Granite ORM. This assumes you're exporting the `DATABASE_URL` for your project and an environment variable instead of using a `database.yml`. + +```crystal +#! /usr/bin/env crystal +# +# To build a standalone command line client, require the +# driver you wish to use and use `Micrate::Cli`. +# + +require "micrate" +require "pg" + +Micrate::DB.connection_url = ENV["DATABASE_URL"] +Micrate::Cli.run +``` + +Make it executable: +```sh +$ chmod +x bin/micrate +``` + +We should now be able to run micrate commands. + +`$ bin/micrate help` => should output help commands. + +### Creating a migration + +Let's create a `posts` table in our database. + +```sh +$ bin/micrate create create_posts +``` + +This will create a file under `db/migrations`. Let's open it and define our posts schema. + +```sql +-- +micrate Up +-- SQL in section 'Up' is executed when this migration is applied +CREATE TABLE posts( + id BIGSERIAL PRIMARY KEY, + title VARCHAR NOT NULL, + body TEXT NOT NULL, + created_at TIMESTAMP, + updated_at TIMESTAMP +); + +-- +micrate Down +-- SQL section 'Down' is executed when this migration is rolled back +DROP TABLE posts; +``` + +And now let's run the migration +```sh +$ bin/micrate up +``` + +You should now have a `posts` table in your database ready to query. diff --git a/docs/querying.md b/docs/querying.md new file mode 100644 index 00000000..d5286dbe --- /dev/null +++ b/docs/querying.md @@ -0,0 +1,77 @@ +# Querying + +The query macro and where clause combine to give you full control over your query. + +## All + +When using the `all` method, the SQL selected fields will match the +fields specified in the model unless the `query` macro was used to customize +the SELECT. + +Always pass in parameters to avoid SQL Injection. Use a `?` +in your query as placeholder. Checkout the [Crystal DB Driver](https://github.com/crystal-lang/crystal-db) +for documentation of the drivers. + +Here are some examples: + +```crystal +posts = Post.all("WHERE name LIKE ?", ["Joe%"]) +if posts + posts.each do |post| + puts post.name + end +end + +# ORDER BY Example +posts = Post.all("ORDER BY created_at DESC") + +# JOIN Example +posts = Post.all("JOIN comments c ON c.post_id = post.id + WHERE c.name = ? + ORDER BY post.created_at DESC", + ["Joe"]) +``` + +## First + +It is common to only want the first result and append a `LIMIT 1` to the query. +This is what the `first` method does. + +For example: + +```crystal +post = Post.first("ORDER BY posts.name DESC") +``` + +This is the same as: + +```crystal +post = Post.all("ORDER BY posts.name DESC LIMIT 1").first +``` + +## Customizing SELECT + +The `select_statement` macro allows you to customize the entire query, including the SELECT portion. This shouldn't be necessary in most cases, but allows you to craft more complex (i.e. cross-table) queries if needed: + +```crystal +class CustomView < Granite:Base + adapter pg + field articlebody : String + field commentbody : String + + select_statement <<-SQL + SELECT articles.articlebody, comments.commentbody + FROM articles + JOIN comments + ON comments.articleid = articles.id + SQL +end +``` + +You can combine this with an argument to `all` or `first` for maximum flexibility: + +```crystal +results = CustomView.all("WHERE articles.author = ?", ["Noah"]) +``` + +## \ No newline at end of file diff --git a/docs/relationships.md b/docs/relationships.md new file mode 100644 index 00000000..228e4358 --- /dev/null +++ b/docs/relationships.md @@ -0,0 +1,146 @@ +# Relationships + +## One to Many + +`belongs_to` and `has_many` macros provide a rails like mapping between Objects. + +```crystal +class User < Granite::Base + adapter mysql + + has_many :posts + + field email : String + field name : String + timestamps +end +``` + +This will add a `posts` instance method to the user which returns an array of posts. + +```crystal +class Post < Granite::Base + adapter mysql + + belongs_to :user + + field title : String + timestamps +end +``` + +This will add a `user` and `user=` instance method to the post. + +For example: + +```crystal +user = User.find 1 +user.posts.each do |post| + puts post.title +end + +post = Post.find 1 +puts post.user + +post.user = user +post.save +``` + +In this example, you will need to add a `user_id` and index to your posts table: + +```mysql +CREATE TABLE posts ( + id BIGSERIAL PRIMARY KEY, + user_id BIGINT, + title VARCHAR, + created_at TIMESTAMP, + updated_at TIMESTAMP +); + +CREATE INDEX 'user_id_idx' ON posts (user_id); +``` + +## Many to Many + +Instead of using a hidden many-to-many table, Granite recommends always creating a model for your join tables. For example, let's say you have many `users` that belong to many `rooms`. We recommend adding a new model called `participants` to represent the many-to-many relationship. + +Then you can use the `belongs_to` and `has_many` relationships going both ways. + +```crystal +class User < Granite::Base + has_many :participants + + field name : String +end + +class Participant < Granite::Base + belongs_to :user + belongs_to :room +end + +class Room < Granite::Base + has_many :participants + + field name : String +end +``` + +The Participant class represents the many-to-many relationship between the Users and Rooms. + +Here is what the database table would look like: + +```mysql +CREATE TABLE participants ( + id BIGSERIAL PRIMARY KEY, + user_id BIGINT, + room_id BIGINT, + created_at TIMESTAMP, + updated_at TIMESTAMP +); + +CREATE INDEX 'user_id_idx' ON TABLE participants (user_id); +CREATE INDEX 'room_id_idx' ON TABLE participants (room_id); +``` + +## has_many through: + +As a convenience, we provide a `through:` clause to simplify accessing the many-to-many relationship: + +```crystal +class User < Granite::Base + has_many :participants + has_many :rooms, through: participants + + field name : String +end + +class Participant < Granite::Base + belongs_to :user + belongs_to :room +end + +class Room < Granite::Base + has_many :participants + has_many :users, through: participants + + field name : String +end +``` + +This will allow you to find all the rooms that a user is in: + +```crystal +user = User.first +user.rooms.each do |room| + puts room.name +end +``` + +And the reverse, all the users in a room: + +```crystal +room = Room.first +room.users.each do |user| + puts user.name +end +``` diff --git a/docs/validations.md b/docs/validations.md new file mode 100644 index 00000000..360d7ac8 --- /dev/null +++ b/docs/validations.md @@ -0,0 +1,66 @@ +# Errors + +All database errors are added to the `errors` array used by Granite::Validators with the symbol ':base' + +```crystal +post = Post.new +post.save +post.errors[0].to_s.should eq "ERROR: name cannot be null" +``` +## Validations + +Validations can be made on models to ensure that given criteria are met. + +Models that do not pass the validations will not be saved, and will have the errors added to the model's `errors` array. + +For example, asserting that the title on a post is not blank: + +```Crystal +class Post < Granite::Base + adapter mysql + + field title : String + + validate :title, "can't be blank" do |post| + !post.title.to_s.blank? + end +end +` +``` + +## Validation Helpers + +A set of common validation macros exist to make validations easier to manage/create. + +### Common + +- `validate_not_nil :field` - Validates that field should not be nil. +- `validate_is_nil :field` - Validates that field should be nil. +- `validate_is_valid_choice :type, ["allowedType1", "allowedType2"]` - Validates that type should be one of a preset option. +- `validate_uniqueness :field` - Validates that the field is unique + +### String + +- `validate_not_blank :field` - Validates that field should not be blank. +- `validate_is_blank :field` - Validates that field should be blank. +- `validate_min_length :field, 5` - Validates that field should be at least 5 long +- `validate_max_length :field, 20` - Validates that field should be at most 20 long + +### String + +- `validate_greater_than :field, 0` - Validates that field should be greater than 0. +- `validate_greater_than :field, 0, true` - Validates that field should be greater than or equal to 0. +- `validate_less_than :field, 100` - Validates that field should be less than 100. +- `validate_less_than :field, 100, true` - Validates that field should be less than or equal to 100. + +Using the helpers, the previous example could have been written like: + +```Crystal +class Post < Granite::Base + adapter mysql + + field title : String + + validate_not_blank :title +end +``` \ No newline at end of file diff --git a/docs/yaml_support.md b/docs/yaml_support.md new file mode 100644 index 00000000..0554228e --- /dev/null +++ b/docs/yaml_support.md @@ -0,0 +1,137 @@ +# YAML Support + +Granite has native support for serializing and deserializing to and from YAML strings via the [YAML::Serializable](https://crystal-lang.org/api/0.25.1/YAML/Serializable.html) module. + +## YAML::Field + +Allows for control over the serialization and deserialization of instance variables. + + ```Crystal +class Foo < Granite::Base + adapter mysql + table_name foos + + field name : String + field password : String, yaml_options: {ignore: true} # skip this field in serialization and deserialization + field age : Int32, yaml_options: {key: "HowOldTheyAre"} # the value of the key in the json object + field todayBirthday : Bool, yaml_options: {emit_null: true} # emits a null value for nilable property + field isNil : Bool +end + ``` + +`foo = Foo.from_yaml(%({"name": "Granite1", "HowOldTheyAre": 12, "password": "12345"}))` + + ```Crystal +# + ``` + +`foo.to_yaml` + + ```YAML +--- +name: Granite1 +HowOldTheyAre: 12 + ``` + +Notice how `isNil` is omitted from the YAML output since it is Nil. If you wish to always show Nil instance variables on a class level you can do: + + ```Crystal +@[YAML::Serializable::Options(emit_nulls: true)] +class Foo < Granite::Base + adapter mysql + table_name foos + + field name : String + field age : Int32 +end + ``` + +This would be functionally the same as adding `yaml_options: {emit_null: true}` on each property. + +## after_initialize + +This method gets called after `from_yaml` is done parsing the given YAML string. This allows you to set other fields that are not in the YAML directly or that require some more logic. + + ```Crystal +class Foo < Granite::Base + adapter mysql + table_name foos + + field name : String + field age : Int32 + field date_added : Time + + def after_initialize + @date_added = Time.utc_now + end +end + ``` + +`foo = Foo.from_yaml(%({"name": "Granite1"}))` + + ```Crystal + + ``` + +## YAML::Serializable::Unmapped + +If the `YAML::Serializable::Unmapped` module is included, unknown properties in the YAML document will be stored in a Hash(String, YAML::Any). On serialization, any keys inside `yaml_unmapped` will be serialized appended to the current YAML object. + + ```Crystal +class Foo < Granite::Base + include YAML::Serializable::Unmapped + + adapter mysql + table_name foos + + field name : String + field age : Int32 +end + ``` + +`foo = Foo.from_yaml(%({"name": "Granite1", "age": 12, "foobar": true}))` + + ```Crystal +# true}> + ``` + +`foo.to_yaml` + + ```YAML +--- +name: Granite1 +age: 12 +foobar: true + ``` diff --git a/shard.yml b/shard.yml index 90875bc9..959b84eb 100644 --- a/shard.yml +++ b/shard.yml @@ -1,6 +1,8 @@ name: granite + version: 0.12.1 -crystal: 0.25.0 + +crystal: 0.25.1 authors: - drujensen