# Ecto Schema Store
This library is used to create customizable data stores for individual ecto schemas.
With the following schema:
```elixir
defmodule Person do
  use EctoTest.Web, :model
  schema "people" do
    field :name, :string
    field :email, :string
    timestamps
  end
  def changeset(model, params) do
    model
    |> cast(params, [:name, :email])
  end
end
```
You can create a store with the following:
```elixir
defmodule PersonStore do
  use EctoSchemaStore, schema: Person, repo: MyApp.Repo
end
```
## Querying ##
The following functions are provided in a store for retrieving data.
* `all`         - Fetch all records
* `one`         - Return a single record
Sample Queries:
```elixir
# Get all records in a table.
PersonStore.all
# Get all records fields that match the provided value.
PersonStore.all %{name: "Bob"}
PersonStore.all %{name: "Bob", email: "bob@nowhere.test"}
# Return a single record.
PersonStore.one %{name: "Bob"}
# Return a specific record by id.
PersonStore.one 12
```
## Editing ##
The following functions are provided in a store for editing data.
* `insert`       - Insert a record based upon supplied parameters map.
* `insert!`      - Same as `insert` but throws an error instead of returning a tuple.
* `update`       - Update a record based upon supplied parameters map.
* `update!`      - Same as `update` but throws an error instead of returning a tuple.
* `delete`       - Delete a record.
* `delete!`      - Same as `delete` but throws an error instead of returning a tuple.
Sample Usage:
```elixir
bob = PersonStore.insert! %{name: "Bob", email: "bob@nowhere.test"}
bob = PersonStore.update! bob, %{email: "bob2@nowhere.test"}
PersonStore.delete bob
# Updates/deletes can also occur by id.
PersonStore.update! 12, %{email: "bob2@nowhere.test"}
PersonStore.delete 12
```
## Changesets ##
The `insert` and `update` functions by default use a changeset on the provided schema name `:changeset` for inserting and updating.
This can be overridden and a specific changeset name provided.
```elixir
bob = PersonStore.insert! %{name: "Bob", email: "bob@nowhere.test"}, :insert_changeset
bob = PersonStore.update! bob, %{email: "bob2@nowhere.test"}, :update_changeset
bob = PersonStore.update! bob, %{email: "bob2@nowhere.test"}, :my_other_custom_changeset
``` 
## References ##
The internal references to the schema and the provided Ecto Repo are provided as convience functions.
* `schema`         - returns the schema reference used internally by the store.
* `repo`           - returns the Ecto Repo reference used internally by the store.
## Custom Actions ##
Since a store is just an ordinary module, you can add your actions and build off private APIs to the store. For convience
`Ecto.Query` is already fully imported into the module.
A store is provided the following custom internal API:
* `build_query`       - Builds a `Ecto.Query` struct based upon the map params input.
```elixir
defmodule PersonStore do
  use EctoSchemaStore, schema: Person, repo: MyApp.Repo
  def get_all_ordered_by_name do
    build_query
    |> order_by([:name])
    |> all
  end
  def find_by_email(email) do
    %{email: email}
    |> build_query
    |> order_by([:name])
    |> all
  end
  def get_all_ordered_by_name_using_ecto_directly do
    query = from p in schema,
            order_by: [p.name]
    
    repo.all query
  end
end
```
## Schema Field Aliases ##
Sometimes field names get changed or the developer wishes to have an alias that represents another field.
These work for both querying and editing schema models.
```elixir
defmodule PersonStore do
  use EctoSchemaStore, schema: Person, repo: MyApp.Repo
  alias_fields email_address: :email
end
PersonStore.all %{email_address: "bob@nowhere.test"}
PersonStore.update! 12, %{email_address: "bob@nowhere.test"}
```