mirror of
https://github.com/ash-project/ash_sqlite.git
synced 2024-09-19 12:52:50 +12:00
docs: docs overhaul
This commit is contained in:
parent
7747628f4f
commit
2930019cf7
16 changed files with 149 additions and 164 deletions
65
README.md
65
README.md
|
@ -1,55 +1,38 @@
|
||||||
|
![Logo](https://github.com/ash-project/ash/blob/main/logos/cropped-for-header-black-text.png?raw=true#gh-light-mode-only)
|
||||||
|
![Logo](https://github.com/ash-project/ash/blob/main/logos/cropped-for-header-white-text.png?raw=true#gh-dark-mojde-only)
|
||||||
|
|
||||||
|
[![CI](https://github.com/ash-project/ash_sqlite/actions/workflows/elixir.yml/badge.svg)](https://github.com/ash-project/ash_sqlite/actions/workflows/elixir.yml)
|
||||||
|
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
|
||||||
|
[![Hex version badge](https://img.shields.io/hexpm/v/ash_sqlite.svg)](https://hex.pm/packages/ash_sqlite)
|
||||||
|
[![Hexdocs badge](https://img.shields.io/badge/docs-hexdocs-purple)](https://hexdocs.pm/ash_sqlite)
|
||||||
|
|
||||||
# AshSqlite
|
# AshSqlite
|
||||||
|
|
||||||
![Elixir CI](https://github.com/ash-project/ash_sqlite/workflows/Elixir%20CI/badge.svg)
|
Welcome! `AshSqlite` is the SQLite data layer for [Ash Framework](https://hexdocs.pm/ash).
|
||||||
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
|
|
||||||
[![Coverage Status](https://coveralls.io/repos/github/ash-project/ash_sqlite/badge.svg?branch=main)](https://coveralls.io/github/ash-project/ash_sqlite?branch=main)
|
|
||||||
[![Hex version badge](https://img.shields.io/hexpm/v/ash_sqlite.svg)](https://hex.pm/packages/ash_sqlite)
|
|
||||||
|
|
||||||
## Notice: Beta
|
## Tutorials
|
||||||
|
|
||||||
This is a newly released library. You can expect some hiccups here and there. Please report any issues you find!
|
- [Get Started](documentation/tutorials/getting-started-with-ash-sqlite.md)
|
||||||
|
|
||||||
## DSL
|
## Topics
|
||||||
|
|
||||||
See the DSL documentation in `AshSqlite.DataLayer` for DSL documentation
|
- [What is AshSqlite?](documentation/topics/about-ash-sqlite/what-is-ash-sqlite.md)
|
||||||
|
|
||||||
## Usage
|
### Resources
|
||||||
|
|
||||||
Add `ash_sqlite` to your `mix.exs` file.
|
- [References](documentation/topics/resources/references.md)
|
||||||
|
- [Polymorphic Resources](documentation/topics/resources/polymorphic-resources.md)
|
||||||
|
|
||||||
```elixir
|
### Development
|
||||||
{:ash_sqlite, "~> 0.1.2-rc.0"}
|
|
||||||
```
|
|
||||||
|
|
||||||
To use this data layer, you need to chage your Ecto Repo's from `use Ecto.Repo`, to `use Sqlite.Repo`. because AshSqlite adds functionality to Ecto Repos.
|
- [Migrations and tasks](documentation/topics/development/migrations-and-tasks.md)
|
||||||
|
- [Testing](documentation/topics/development/testing.md)
|
||||||
|
|
||||||
Then, configure each of your `Ash.Resource` resources by adding `use Ash.Resource, data_layer: AshSqlite.DataLayer` like so:
|
### Advanced
|
||||||
|
|
||||||
```elixir
|
- [Expressions](documentation/topics/advanced/expressions.md)
|
||||||
defmodule MyApp.SomeResource do
|
- [Manual Relationships](documentation/topics/advanced/manual-relationships.md)
|
||||||
use Ash.Resource, domain: MyDomain, data_layer: AshSqlite.DataLayer
|
|
||||||
|
|
||||||
sqlite do
|
## Reference
|
||||||
repo MyApp.Repo
|
|
||||||
table "table_name"
|
|
||||||
end
|
|
||||||
|
|
||||||
attributes do
|
- [AshSqlite.DataLayer DSL](documentation/dsls/DSL:-AshSqlite.DataLayer.md)
|
||||||
# ... Attribute definitions
|
|
||||||
end
|
|
||||||
end
|
|
||||||
```
|
|
||||||
|
|
||||||
## Generating Migrations
|
|
||||||
|
|
||||||
See the documentation for `Mix.Tasks.AshSqlite.GenerateMigrations` for how to generate migrations from your resources
|
|
||||||
|
|
||||||
# Contributors
|
|
||||||
|
|
||||||
Ash is made possible by its excellent community!
|
|
||||||
|
|
||||||
<a href="https://github.com/ash-project/ash_sqlite/graphs/contributors">
|
|
||||||
<img src="https://contrib.rocks/image?repo=ash-project/ash_sqlite" />
|
|
||||||
</a>
|
|
||||||
|
|
||||||
[Become a contributor](https://ash-hq.org/docs/guides/ash/latest/how_to/contribute.md)
|
|
||||||
|
|
|
@ -10,7 +10,10 @@ if Mix.env() == :dev do
|
||||||
manage_mix_version?: true,
|
manage_mix_version?: true,
|
||||||
# Instructs the tool to manage the version in your README.md
|
# Instructs the tool to manage the version in your README.md
|
||||||
# Pass in `true` to use `"README.md"` or a string to customize
|
# Pass in `true` to use `"README.md"` or a string to customize
|
||||||
manage_readme_version: ["README.md", "documentation/tutorials/get-started-with-sqlite.md"],
|
manage_readme_version: [
|
||||||
|
"README.md",
|
||||||
|
"documentation/tutorials/getting-started-with-ash-sqlite.md"
|
||||||
|
],
|
||||||
version_tag_prefix: "v"
|
version_tag_prefix: "v"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ end
|
||||||
| [`foreign_key_names`](#sqlite-foreign_key_names){: #sqlite-foreign_key_names } | `list({atom, String.t} \| {String.t, String.t})` | `[]` | A list of foreign keys that could raise errors, or an mfa to a function that takes a changeset and returns a list. In the format: `{:key, "name_of_constraint"}` or `{:key, "name_of_constraint", "custom error message"}` |
|
| [`foreign_key_names`](#sqlite-foreign_key_names){: #sqlite-foreign_key_names } | `list({atom, String.t} \| {String.t, String.t})` | `[]` | A list of foreign keys that could raise errors, or an mfa to a function that takes a changeset and returns a list. In the format: `{:key, "name_of_constraint"}` or `{:key, "name_of_constraint", "custom error message"}` |
|
||||||
| [`migration_ignore_attributes`](#sqlite-migration_ignore_attributes){: #sqlite-migration_ignore_attributes } | `list(atom)` | `[]` | A list of attributes that will be ignored when generating migrations. |
|
| [`migration_ignore_attributes`](#sqlite-migration_ignore_attributes){: #sqlite-migration_ignore_attributes } | `list(atom)` | `[]` | A list of attributes that will be ignored when generating migrations. |
|
||||||
| [`table`](#sqlite-table){: #sqlite-table } | `String.t` | | The table to store and read the resource from. If this is changed, the migration generator will not remove the old table. |
|
| [`table`](#sqlite-table){: #sqlite-table } | `String.t` | | The table to store and read the resource from. If this is changed, the migration generator will not remove the old table. |
|
||||||
| [`polymorphic?`](#sqlite-polymorphic?){: #sqlite-polymorphic? } | `boolean` | `false` | Declares this resource as polymorphic. See the [polymorphic resources guide](/documentation/topics/polymorphic_resources.md) for more. |
|
| [`polymorphic?`](#sqlite-polymorphic?){: #sqlite-polymorphic? } | `boolean` | `false` | Declares this resource as polymorphic. See the [polymorphic resources guide](/documentation/topics/resources/polymorphic-resources.md) for more. |
|
||||||
|
|
||||||
|
|
||||||
## sqlite.custom_indexes
|
## sqlite.custom_indexes
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
# Using Fragments
|
|
||||||
|
|
||||||
Fragments allow you to use arbitrary sqlite expressions in your queries. Fragments can often be an escape hatch to allow you to do things that don't have something officially supported with Ash.
|
|
||||||
|
|
||||||
## Examples
|
|
||||||
|
|
||||||
Use simple expressions
|
|
||||||
|
|
||||||
```elixir
|
|
||||||
fragment("? / ?", points, count)
|
|
||||||
```
|
|
||||||
|
|
||||||
Call functions
|
|
||||||
|
|
||||||
```elixir
|
|
||||||
fragment("repeat('hello', 4)")
|
|
||||||
```
|
|
||||||
|
|
||||||
Use entire queries
|
|
||||||
|
|
||||||
```elixir
|
|
||||||
fragment("points > (SELECT SUM(points) FROM games WHERE user_id = ? AND id != ?)", user_id, id)
|
|
||||||
```
|
|
||||||
|
|
||||||
Using entire queries like the above is a last resort, but can often help us avoid having to add extra structure unnecessarily.
|
|
34
documentation/topics/about-ash-sqlite/what-is-ash-sqlite.md
Normal file
34
documentation/topics/about-ash-sqlite/what-is-ash-sqlite.md
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
# What is AshSqlite?
|
||||||
|
|
||||||
|
AshSqlite is the SQLite `Ash.DataLayer` for [Ash Framework](https://hexdocs.pm/ash). This doesn't have all of the features of [AshPostgres](https://hexdocs.pm/ash_postgres), but it does support most of the features of Ash data layers. The main feature missing is Aggregate support.
|
||||||
|
|
||||||
|
Use this to persist records in a SQLite table. For example, the resource below would be persisted in a table called `tweets`:
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
defmodule MyApp.Tweet do
|
||||||
|
use Ash.Resource,
|
||||||
|
data_layer: AshSQLite.DataLayer
|
||||||
|
|
||||||
|
attributes do
|
||||||
|
integer_primary_key :id
|
||||||
|
attribute :text, :string
|
||||||
|
end
|
||||||
|
|
||||||
|
relationships do
|
||||||
|
belongs_to :author, MyApp.User
|
||||||
|
end
|
||||||
|
|
||||||
|
sqlite do
|
||||||
|
table "tweets"
|
||||||
|
repo MyApp.Repo
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
The table might look like this:
|
||||||
|
|
||||||
|
| id | text | author_id |
|
||||||
|
| --- | --------------- | --------- |
|
||||||
|
| 1 | "Hello, world!" | 1 |
|
||||||
|
|
||||||
|
Creating records would add to the table, destroying records would remove from the table, and updating records would update the table.
|
61
documentation/topics/advanced/expressions.md
Normal file
61
documentation/topics/advanced/expressions.md
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
# Expressions
|
||||||
|
|
||||||
|
In addition to the expressions listed in the [Ash expressions guide](https://hexdocs.pm/ash/expressions.html), AshSqlite provides the following expressions
|
||||||
|
|
||||||
|
# Fragments
|
||||||
|
|
||||||
|
Fragments allow you to use arbitrary sqlite expressions in your queries. Fragments can often be an escape hatch to allow you to do things that don't have something officially supported with Ash.
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
#### Simple expressions
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
fragment("? / ?", points, count)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Calling functions
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
fragment("repeat('hello', 4)")
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Using entire queries
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
fragment("points > (SELECT SUM(points) FROM games WHERE user_id = ? AND id != ?)", user_id, id)
|
||||||
|
```
|
||||||
|
|
||||||
|
> ### a last resport {: .warning}
|
||||||
|
>
|
||||||
|
> Using entire queries as shown above is a last resort, but can sometimes be the best way to accomplish a given task.
|
||||||
|
|
||||||
|
#### In calculations
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
calculations do
|
||||||
|
calculate :lower_name, :string, expr(
|
||||||
|
fragment("LOWER(?)", name)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
#### In migrations
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
create table(:managers, primary_key: false) do
|
||||||
|
add :id, :uuid, null: false, default: fragment("UUID_GENERATE_V4()"), primary_key: true
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
## Like
|
||||||
|
|
||||||
|
These wrap the sqlite builtin like operator
|
||||||
|
|
||||||
|
Please be aware, these match _patterns_ not raw text. Use `contains/1` if you want to match text without supporting patterns, i.e `%` and `_` have semantic meaning!
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
Ash.Query.filter(User, like(name, "%obo%")) # name contains obo anywhere in the string, case sensitively
|
||||||
|
```
|
|
@ -1,24 +0,0 @@
|
||||||
# Sqlite Expressions
|
|
||||||
|
|
||||||
In addition to the expressions listed in the [Ash expressions guide](https://hexdocs.pm/ash/expressions.html), AshSqlite provides the following expressions
|
|
||||||
|
|
||||||
## Fragments
|
|
||||||
`fragment` allows you to embed raw sql into the query. Use question marks to interpolate values from the outer expression.
|
|
||||||
|
|
||||||
For example:
|
|
||||||
|
|
||||||
```elixir
|
|
||||||
Ash.Query.filter(User, fragment("? IS NOT NULL", first_name))
|
|
||||||
```
|
|
||||||
|
|
||||||
# Like
|
|
||||||
|
|
||||||
This wraps the builtin sqlite `LIKE` operator.
|
|
||||||
|
|
||||||
Please be aware, these match *patterns* not raw text. Use `contains/1` if you want to match text without supporting patterns, i.e `%` and `_` have semantic meaning!
|
|
||||||
|
|
||||||
For example:
|
|
||||||
|
|
||||||
```elixir
|
|
||||||
Ash.Query.filter(User, like(name, "%obo%")) # name contains obo anywhere in the string, case sensitively
|
|
||||||
```
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Get Started With Sqlite
|
# Getting Started With AshSqlite
|
||||||
|
|
||||||
## Goals
|
## Goals
|
||||||
|
|
|
@ -2,6 +2,6 @@ defmodule AshSqlite do
|
||||||
@moduledoc """
|
@moduledoc """
|
||||||
The AshSqlite extension gives you tools to map a resource to a sqlite database table.
|
The AshSqlite extension gives you tools to map a resource to a sqlite database table.
|
||||||
|
|
||||||
For more, check out the [getting started guide](/documentation/tutorials/get-started-with-sqlite.md)
|
For more, check out the [getting started guide](/documentation/tutorials/getting-started-with-ash-sqlite.md)
|
||||||
"""
|
"""
|
||||||
end
|
end
|
||||||
|
|
|
@ -276,7 +276,7 @@ defmodule AshSqlite.DataLayer do
|
||||||
type: :boolean,
|
type: :boolean,
|
||||||
default: false,
|
default: false,
|
||||||
doc: """
|
doc: """
|
||||||
Declares this resource as polymorphic. See the [polymorphic resources guide](/documentation/topics/polymorphic_resources.md) for more.
|
Declares this resource as polymorphic. See the [polymorphic resources guide](/documentation/topics/resources/polymorphic-resources.md) for more.
|
||||||
"""
|
"""
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
85
mix.exs
85
mix.exs
|
@ -2,8 +2,7 @@ defmodule AshSqlite.MixProject do
|
||||||
use Mix.Project
|
use Mix.Project
|
||||||
|
|
||||||
@description """
|
@description """
|
||||||
A sqlite data layer for `Ash` resources. Leverages Ecto's sqlite
|
The SQLite data layer for Ash Framework.
|
||||||
support, and delegates to a configured repo.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@version "0.1.2-rc.0"
|
@version "0.1.2-rc.0"
|
||||||
|
@ -63,78 +62,32 @@ defmodule AshSqlite.MixProject do
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
defp extras() do
|
defp docs do
|
||||||
"documentation/**/*.{md,livemd,cheatmd}"
|
|
||||||
|> Path.wildcard()
|
|
||||||
|> Enum.map(fn path ->
|
|
||||||
title =
|
|
||||||
path
|
|
||||||
|> Path.basename(".md")
|
|
||||||
|> Path.basename(".livemd")
|
|
||||||
|> Path.basename(".cheatmd")
|
|
||||||
|> String.split(~r/[-_]/)
|
|
||||||
|> Enum.map_join(" ", &capitalize/1)
|
|
||||||
|> case do
|
|
||||||
"F A Q" ->
|
|
||||||
"FAQ"
|
|
||||||
|
|
||||||
other ->
|
|
||||||
other
|
|
||||||
end
|
|
||||||
|
|
||||||
{String.to_atom(path),
|
|
||||||
[
|
|
||||||
title: title
|
|
||||||
]}
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
|
|
||||||
defp capitalize(string) do
|
|
||||||
string
|
|
||||||
|> String.split(" ")
|
|
||||||
|> Enum.map(fn string ->
|
|
||||||
[hd | tail] = String.graphemes(string)
|
|
||||||
String.capitalize(hd) <> Enum.join(tail)
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
|
|
||||||
defp groups_for_extras() do
|
|
||||||
[
|
[
|
||||||
|
main: "readme",
|
||||||
|
source_ref: "v#{@version}",
|
||||||
|
logo: "logos/small-logo.png",
|
||||||
|
extras: [
|
||||||
|
{"README.md", title: "Home"},
|
||||||
|
"documentation/tutorials/getting-started-with-ash-sqlite.md",
|
||||||
|
"documentation/topics/about-ash-sqlite/what-is-ash-sqlite.md",
|
||||||
|
"documentation/topics/resources/references.md",
|
||||||
|
"documentation/topics/resources/polymorphic-resources.md",
|
||||||
|
"documentation/topics/development/migrations-and-tasks.md",
|
||||||
|
"documentation/topics/development/testing.md",
|
||||||
|
"documentation/topics/advanced/expressions.md",
|
||||||
|
"documentation/topics/advanced/manual-relationships.md",
|
||||||
|
"documentation/dsls/DSL:-AshSqlite.DataLayer.md",
|
||||||
|
"CHANGELOG.md"
|
||||||
|
],
|
||||||
|
groups_for_extras: [
|
||||||
Tutorials: [
|
Tutorials: [
|
||||||
~r'documentation/tutorials'
|
~r'documentation/tutorials'
|
||||||
],
|
],
|
||||||
"How To": ~r'documentation/how_to',
|
"How To": ~r'documentation/how_to',
|
||||||
Topics: ~r'documentation/topics',
|
Topics: ~r'documentation/topics',
|
||||||
DSLs: ~r'documentation/dsls'
|
DSLs: ~r'documentation/dsls'
|
||||||
]
|
|
||||||
end
|
|
||||||
|
|
||||||
defp docs do
|
|
||||||
[
|
|
||||||
main: "get-started-with-sqlite",
|
|
||||||
source_ref: "v#{@version}",
|
|
||||||
logo: "logos/small-logo.png",
|
|
||||||
extras: extras(),
|
|
||||||
spark: [
|
|
||||||
mix_tasks: [
|
|
||||||
SQLite: [
|
|
||||||
Mix.Tasks.AshSqlite.GenerateMigrations,
|
|
||||||
Mix.Tasks.AshSqlite.Create,
|
|
||||||
Mix.Tasks.AshSqlite.Drop,
|
|
||||||
Mix.Tasks.AshSqlite.Migrate,
|
|
||||||
Mix.Tasks.AshSqlite.Rollback
|
|
||||||
]
|
|
||||||
],
|
],
|
||||||
extensions: [
|
|
||||||
%{
|
|
||||||
module: AshSqlite.DataLayer,
|
|
||||||
name: "AshSqlite",
|
|
||||||
target: "Ash.Resource",
|
|
||||||
type: "DataLayer"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
],
|
|
||||||
groups_for_extras: groups_for_extras(),
|
|
||||||
groups_for_modules: [
|
groups_for_modules: [
|
||||||
AshSqlite: [
|
AshSqlite: [
|
||||||
AshSqlite,
|
AshSqlite,
|
||||||
|
|
Loading…
Reference in a new issue