### Add Repo to Application Supervisor (Existing File) Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/tutorials/getting-started-with-ash-sqlite.md Ensure the Helpdesk.Repo is started as part of the application's supervision tree. ```elixir # in lib/helpdesk/application.ex (when the file is already exists) def start(_type, _args) do children = [ # Starts a worker by calling: Helpdesk.Worker.start_link(arg) # {Helpdesk.Worker, arg} Helpdesk.Repo ] ... ``` -------------------------------- ### Start IEx with Mix Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/tutorials/getting-started-with-ash-sqlite.md Command to start an interactive Elixir shell with your Mix project loaded, allowing you to interact with your Ash SQLite setup. ```bash iex -S mix ``` -------------------------------- ### Configure Foreign Key References Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/topics/resources/references.md Use the `references` block to define foreign key constraints on a resource. This example shows how to set `on_delete` and `on_update` actions, and name the foreign key constraint. ```elixir references do reference :post, on_delete: :delete, on_update: :update, name: "comments_to_posts_fkey" end ``` -------------------------------- ### Configure SQLite Data Layer Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/dsls/DSL-AshSqlite.DataLayer.md Configure the SQLite data layer by specifying the repository and table name. This is a basic setup for the data layer. ```elixir sqlite do repo MyApp.Repo table "organizations" end ``` -------------------------------- ### Add Index to Migration Generator Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/dsls/DSL-AshSqlite.DataLayer.md Add an index to be managed by the migration generator. This example shows how to specify columns, uniqueness, and a WHERE clause for the index. ```elixir index ["column", "column2"], unique: true, where: "thing = TRUE" ``` -------------------------------- ### Configure Repo with Transaction Settings Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/topics/about-ash-sqlite/transactions.md Configure your application's repo to enable immediate transactions and set a busy timeout for SQLite. This helps prevent write conflicts by acquiring the lock at the start of a transaction and retrying for a specified duration. ```elixir config :my_app, MyApp.Repo, database: "path/to/my_app.db", pool_size: 1, default_transaction_mode: :immediate, busy_timeout: 5000 ``` -------------------------------- ### Generate Ash SQLite Migrations Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/tutorials/getting-started-with-ash-sqlite.md Use this command to generate database migrations for your Ash SQLite setup. For iterative development, the --dev flag can be used. ```bash mix ash_sqlite.generate_migrations --name add_tickets_and_representatives ``` ```bash mix ash_sqlite.generate_migrations --dev ``` -------------------------------- ### Use Fragments in Database Migrations Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/topics/advanced/expressions.md Fragments are useful in migrations for generating default values or performing complex initializations. This example uses `UUID_GENERATE_V4()` for a default primary key. ```elixir create table(:managers, primary_key: false) do add :id, :uuid, null: false, default: fragment("UUID_GENERATE_V4()", primary_key: true) end ``` -------------------------------- ### Use Fragments in Ash Calculations Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/topics/advanced/expressions.md Fragments can be integrated into Ash calculations to perform custom transformations on attributes. This example shows converting a name to lowercase using SQLite's LOWER function. ```elixir calculations do calculate :lower_name, :string, expr( fragment("LOWER(?)", name) ) end ``` -------------------------------- ### Create Application File with Repo Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/tutorials/getting-started-with-ash-sqlite.md Create a new application file if it does not exist, including the Helpdesk.Repo in the children list. ```elixir # in lib/helpdesk/application.ex (new file) defmodule Helpdesk.Application do @moduledoc false use Application def start(_type, _args) do children = [ Helpdesk.Repo ] opts = [strategy: :one_for_one, name: Helpdesk.Supervisor] Supervisor.start_link(children, opts) end end ``` -------------------------------- ### Create Configuration Files Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/tutorials/getting-started-with-ash-sqlite.md Generate necessary configuration files for different environments. ```bash mkdir -p config touch config/config.exs touch config/dev.exs touch config/runtime.exs touch config/test.exs ``` -------------------------------- ### Test Configuration (test.exs) Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/tutorials/getting-started-with-ash-sqlite.md Configure the database path for tests, incorporating test partitioning and using Ecto.Adapters.SQL.Sandbox. ```elixir # in config/test.exs import Config # Configure your database # # The MIX_TEST_PARTITION environment variable can be used # to provide built-in test partitioning in CI environment. # Run `mix help test` for more information. config :helpdesk, Helpdesk.Repo, database: Path.join(__DIR__, "../path/to/your#{System.get_env("MIX_TEST_PARTITION")}.db"), pool: Ecto.Adapters.SQL.Sandbox, pool_size: 10 ``` -------------------------------- ### Runtime Configuration (runtime.exs) Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/tutorials/getting-started-with-ash-sqlite.md Configure the connection pool size for the production environment, allowing it to be set via an environment variable. ```elixir # in config/runtime.exs import Config if config_env() == :prod do config :helpdesk, Helpdesk.Repo, pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10") end ``` -------------------------------- ### Development Configuration (dev.exs) Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/tutorials/getting-started-with-ash-sqlite.md Configure the database path and connection pool size for development environment. ```elixir # in config/dev.exs import Config # Configure your database config :helpdesk, Helpdesk.Repo, database: Path.join(__DIR__, "../path/to/your.db"), show_sensitive_data_on_connection_error: true, pool_size: 10 ``` -------------------------------- ### Base Configuration (config.exs) Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/tutorials/getting-started-with-ash-sqlite.md Set up base configuration for Ash domains, APIs, and Ecto repos. This file should be at the bottom of the configuration stack. ```elixir # in config/config.exs import Config # This should already have been added from the getting started guide config :helpdesk, ash_domains: [Helpdesk.Support] config :helpdesk, ash_apis: [Helpdesk.Support] config :helpdesk, ecto_repos: [Helpdesk.Repo] # Import environment specific config. This must remain at the bottom # of this file so it overrides the configuration defined above. import_config "#{config_env()}.exs" ``` -------------------------------- ### Configure Separate Read and Write Repos Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/topics/about-ash-sqlite/transactions.md Set up two distinct repositories: one for writes with `pool_size: 1` and immediate transactions, and another for reads with a larger `pool_size` and `read_only: true`. This improves read concurrency by offloading read operations to a dedicated pool. ```elixir config :my_app, MyApp.Repo, database: "path/to/my_app.db", pool_size: 1, default_transaction_mode: :immediate, busy_timeout: 5000 config :my_app, MyApp.Repo.ReadOnly, database: "path/to/my_app.db", pool_size: 10, read_only: true ``` -------------------------------- ### Create and Migrate Ash SQLite Database Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/tutorials/getting-started-with-ash-sqlite.md Commands to create the local SQLite database and apply the generated migrations. ```bash mix ash_sqlite.create mix ash_sqlite.migrate ``` -------------------------------- ### Configure Representative Resource with AshSqlite Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/tutorials/getting-started-with-ash-sqlite.md Define the 'representatives' table and associate it with the Helpdesk.Repo for the Representative resource. ```elixir # in lib/helpdesk/support/resources/representative.ex use Ash.Resource, domain: Helpdesk.Support, data_layer: AshSqlite.DataLayer sqlite do table "representatives" repo Helpdesk.Repo end ``` -------------------------------- ### Basic Reference Syntax Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/dsls/DSL-AshSqlite.DataLayer.md The `reference` DSL is used within resource migrations to define database foreign key constraints for relationships. It requires the relationship name as the first argument. ```elixir reference relationship ``` -------------------------------- ### Define AshSqlite Repo Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/tutorials/getting-started-with-ash-sqlite.md Create a custom Repo module that uses AshSqlite.Repo, specifying the OTP app name. ```elixir # in lib/helpdesk/repo.ex defmodule Helpdesk.Repo do use AshSqlite.Repo, otp_app: :helpdesk end ``` -------------------------------- ### Configure Ticket Resource with AshSqlite Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/tutorials/getting-started-with-ash-sqlite.md Define the 'tickets' table and associate it with the Helpdesk.Repo for the Ticket resource. ```elixir # in lib/helpdesk/support/resources/ticket.ex use Ash.Resource, domain: Helpdesk.Support, data_layer: AshSqlite.DataLayer sqlite do table "tickets" repo Helpdesk.Repo end ``` -------------------------------- ### Configure Formatter with AshSqlite Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/tutorials/getting-started-with-ash-sqlite.md Include :ash_sqlite in the import_deps for your .formatter.exs file to ensure proper code formatting. ```elixir [ # import the formatter rules from `:ash_sqlite` import_deps: [..., :ash_sqlite], inputs: [...] ] ``` -------------------------------- ### Link Application in mix.exs Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/tutorials/getting-started-with-ash-sqlite.md Ensure the application module is correctly specified in the application function within mix.exs. ```elixir # in mix.exs ... def application do [ mod: {Helpdesk.Application, []}, ... ] end ... ``` -------------------------------- ### Implement Manual Relationship Logic with AshSqlite Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/topics/advanced/manual-relationships.md Implement the `load`, `ash_sqlite_join`, and `ash_sqlite_subquery` functions to define how the manual relationship is loaded and joined using AshSqlite. ```elixir # in the resource relationships do has_many :tickets_above_threshold, Helpdesk.Support.Ticket do manual Helpdesk.Support.Ticket.Relationships.TicketsAboveThreshold end end # implementation defmodule Helpdesk.Support.Ticket.Relationships.TicketsAboveThreshold do use Ash.Resource.ManualRelationship use AshSqlite.ManualRelationship require Ash.Query require Ecto.Query def load(records, _opts, %{query: query, actor: actor, authorize?: authorize?}) do # Use existing records to limit resultds rep_ids = Enum.map(records, & &1.id) # Using Ash to get the destination records is ideal, so you can authorize access like normal # but if you need to use a raw ecto query here, you can. As long as you return the right structure. {:ok, query |> Ash.Query.filter(representative_id in ^rep_ids) |> Ash.Query.filter(priority > representative.priority_threshold) |> Helpdesk.Support.read!(actor: actor, authorize?: authorize?) # Return the items grouped by the primary key of the source, i.e representative.id => [...tickets above threshold] |> Enum.group_by(& &1.representative_id)} end # query is the "source" query that is being built. # _opts are options provided to the manual relationship, i.e `{Manual, opt: :val}` # current_binding is what the source of the relationship is bound to. Access fields with `as(^current_binding).field` # as_binding is the binding that your join should create. When you join, make sure you say `as: ^as_binding` on the # part of the query that represents the destination of the relationship # type is `:inner` or `:left`. # destination_query is what you should join to to add the destination to the query, i.e `join: dest in ^destination-query` def ash_sqlite_join(query, _opts, current_binding, as_binding, :inner, destination_query) do {:ok, Ecto.Query.from(_ in query, join: dest in ^destination_query, as: ^as_binding, on: dest.representative_id == as(^current_binding).id, on: dest.priority > as(^current_binding).priority_threshold )} end def ash_sqlite_join(query, _opts, current_binding, as_binding, :left, destination_query) do {:ok, Ecto.Query.from(_ in query, left_join: dest in ^destination_query, as: ^as_binding, on: dest.representative_id == as(^current_binding).id, on: dest.priority > as(^current_binding).priority_threshold )} end # _opts are options provided to the manual relationship, i.e `{Manual, opt: :val}` # current_binding is what the source of the relationship is bound to. Access fields with `parent_as(^current_binding).field` # as_binding is the binding that has already been created for your join. Access fields on it via `as(^as_binding)` # destination_query is what you should use as the basis of your query def ash_sqlite_subquery(_opts, current_binding, as_binding, destination_query) do {:ok, Ecto.Query.from(_ in destination_query, where: parent_as(^current_binding).id == as(^as_binding).representative_id, where: as(^as_binding).priority > parent_as(^current_binding).priority_threshold )} end end ``` -------------------------------- ### Configure Relationship Reference Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/dsls/DSL-AshSqlite.DataLayer.md Use `reference` to configure foreign key constraints for relationships in resource migrations. Specify options like `on_delete`, `on_update`, and `name` to control constraint behavior and naming. ```elixir reference :post, on_delete: :delete, on_update: :update, name: "comments_to_posts_fkey" ``` -------------------------------- ### Route Reads and Writes to Appropriate Repos Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/topics/about-ash-sqlite/transactions.md Implement a function within the `repo` DSL option to dynamically route resource operations to either the write repository (`MyApp.Repo`) or the read-only repository (`MyApp.Repo.ReadOnly`) based on the operation type (`:mutate` or `:read`). ```elixir sqlite do repo fn _resource, type -> case type do :mutate -> MyApp.Repo :read -> MyApp.Repo.ReadOnly end end table "posts" end ``` -------------------------------- ### Define Read and Write Repo Modules Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/topics/about-ash-sqlite/transactions.md Define separate Elixir modules for your write and read-only repositories using `AshSqlite.Repo`. Ensure the `otp_app` option is correctly set for each. ```elixir defmodule MyApp.Repo do use AshSqlite.Repo, otp_app: :my_app end defmodule MyApp.Repo.ReadOnly do use AshSqlite.Repo, otp_app: :my_app end ``` -------------------------------- ### Table Specific Actions with `set_context` Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/topics/resources/polymorphic-resources.md Define actions on a polymorphic resource that target specific tables using the `set_context` query preparation. This allows actions to operate on different tables as needed. ```elixir defmodule MyApp.Reaction do actions do read :for_comments do prepare set_context(%{data_layer: %{table: "comment_reactions"}}) end read :for_posts do prepare set_context(%{data_layer: %{table: "post_reactions"}}) end end end ``` -------------------------------- ### Add AshSqlite Dependency Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/tutorials/getting-started-with-ash-sqlite.md Add the :ash_sqlite dependency to your project's mix.exs file. ```elixir {:ash_sqlite, "~> 0.2.17"} ``` -------------------------------- ### Create Representative and Tickets Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/tutorials/getting-started-with-ash-sqlite.md Elixir code to create a representative and then create and assign tickets to them. It also includes logic to close odd-numbered tickets. ```elixir representative = ( Helpdesk.Support.Representative |> Ash.Changeset.for_create(:create, %{name: "Joe Armstrong"}) |> Ash.create!() ) for i <- 1..5 do # 1) open the ticket ticket = Helpdesk.Support.Ticket |> Ash.Changeset.for_create(:open, %{subject: "Issue #{i}"}) |> Ash.create!() # 2) assign the representative ticket = ticket |> Ash.Changeset.for_update(:assign, %{representative_id: representative.id}) |> Ash.update!() # 3) close if odd if rem(i, 2) == 1 do ticket |> Ash.Changeset.for_update(:close, %{}) |> Ash.update!() end end ``` -------------------------------- ### Define Polymorphic Resource Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/topics/resources/polymorphic-resources.md Configure a resource to be polymorphic by setting `polymorphic? true` in the `sqlite` configuration. This is required before specifying table contexts in relationships. ```elixir defmodule MyApp.Reaction do use Ash.Resource, domain: MyApp.Domain, data_layer: AshSqlite.DataLayer sqlite do polymorphic? true # Without this, `table` is a required configuration end attributes do attribute(:resource_id, :uuid) end ... end ``` -------------------------------- ### Define Custom Index with Options Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/dsls/DSL-AshSqlite.DataLayer.md Define a custom index for the migration generator, including options for uniqueness and conditional indexing. Use this for complex indexing needs beyond simple identities. ```elixir custom_indexes do index [:column1, :column2], unique: true, where: "thing = TRUE" end ``` -------------------------------- ### Define an AshSqlite Resource Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/topics/about-ash-sqlite/what-is-ash-sqlite.md Use this to define a resource that will be persisted in a SQLite table. Specify the table name and the repository to use. ```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 ``` -------------------------------- ### Configure Custom SQL Statements for Migrations Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/dsls/DSL-AshSqlite.DataLayer.md Use custom statements to add or modify database structures during migrations. The `up` function defines the creation logic, and the `down` function defines the rollback logic. The statement name is crucial for Ash to detect changes. ```elixir custom_statements do # the name is used to detect if you remove or modify the statement statement :pgweb_idx do up "CREATE INDEX pgweb_idx ON pgweb USING GIN (to_tsvector('english', title || ' ' || body));" down "DROP INDEX pgweb_idx;" end end ``` -------------------------------- ### Production Release Migration Module Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/topics/development/migrations-and-tasks.md An Elixir module for running Ash migrations in a production release, as 'mix' is not available. It loads the application and iterates through repositories to apply migrations. ```elixir defmodule MyApp.Release do @moduledoc """ Houses tasks that need to be executed in the released application (because mix is not present in releases). """ @app :my_ap def migrate do load_app() for repo <- repos() do {:ok, _, _} = Ecto.Migrator.with_repo(repo, &Ecto.Migrator.run(&1, :up, all: true)) end end def rollback(repo, version) do load_app() {:ok, _, _} = Ecto.Migrator.with_repo(repo, &Ecto.Migrator.run(&1, :down, to: version)) end defp repos do domains() |> Enum.flat_map(fn domain -> domain |> Ash.Domain.Info.resources() |> Enum.map(&AshSqlite.repo/1) end) |> Enum.uniq() end defp domains do Application.fetch_env!(:my_app, :ash_domains) end defp load_app do Application.load(@app) end end ``` -------------------------------- ### sqlite.references.reference Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/dsls/DSL-AshSqlite.DataLayer.md Configures the reference for a relationship in resource migrations. This allows specifying behavior for foreign keys when referenced records are deleted or updated. ```APIDOC ## sqlite.references.reference ### Description Configures the reference for a relationship in resource migrations. ### Arguments #### Required Arguments - **relationship** (atom) - The relationship to be configured #### Options - **ignore?** (boolean) - If set to true, no reference is created for the given relationship. This is useful if you need to define it in some custom way - **on_delete** (:delete | :nilify | :nothing | :restrict) - What should happen to records of this resource when the referenced record of the *destination* resource is deleted. - **on_update** (:update | :nilify | :nothing | :restrict) - What should happen to records of this resource when the referenced destination_attribute of the *destination* record is update. - **deferrable** (false | true | :initially) - Wether or not the constraint is deferrable. This only affects the migration generator. Defaults to `false`. - **name** (String.t) - The name of the foreign key to generate in the database. Defaults to `__fkey` ### Example ```elixir reference :post, on_delete: :delete, on_update: :update, name: "comments_to_posts_fkey" ``` ``` -------------------------------- ### Regenerate Migrations Script Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/topics/development/migrations-and-tasks.md A bash script to rollback, delete, and regenerate migrations, optionally running them afterwards. Useful for undoing changes and re-applying migrations. ```bash #!/bin/bash # Get count of untracked migrations N_MIGRATIONS=$(git ls-files --others priv/repo/migrations | wc -l) # Rollback untracked migrations mix ash_sqlite.rollback -n $N_MIGRATIONS # Delete untracked migrations and snapshots git ls-files --others priv/repo/migrations | xargs rm git ls-files --others priv/resource_snapshots | xargs rm # Regenerate migrations mix ash.codegen --name $1 # Run migrations if flag if echo $* | grep -e "-m" -q then mix ash.migrate fi ``` -------------------------------- ### Define a Custom Statement with Up and Down Migrations Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/dsls/DSL-AshSqlite.DataLayer.md Define a specific custom statement for migrations, including its creation (`up`) and deletion (`down`) SQL commands. This is useful for complex schema changes not covered by standard Ash migrations. ```elixir statement :pgweb_idx do up "CREATE INDEX pgweb_idx ON pgweb USING GIN (to_tsvector('english', title || ' ' || body));" down "DROP INDEX pgweb_idx;" end ``` -------------------------------- ### Call SQLite Functions with Fragments Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/topics/advanced/expressions.md Fragments can be used to call built-in SQLite functions. Ensure the function and its arguments are correctly formatted for SQLite. ```elixir fragment("repeat('hello', 4)") ``` -------------------------------- ### Define Manual Relationship in Resource Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/topics/advanced/manual-relationships.md Declare a `has_many` relationship using the `manual` option, pointing to the implementation module for custom logic. ```elixir relationships do has_many :tickets_above_threshold, Helpdesk.Support.Ticket do manual Helpdesk.Support.Ticket.Relationships.TicketsAboveThreshold end end ``` -------------------------------- ### Define Polymorphic Relationships Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/topics/resources/polymorphic-resources.md In related resources, define `has_many` relationships to the polymorphic resource. Use `relationship_context` to specify the exact table for each relationship. ```elixir defmodule MyApp.Post do use Ash.Resource, domain: MyApp.Domain, data_layer: AshSqlite.DataLayer ... relationships do has_many :reactions, MyApp.Reaction, relationship_context: %{data_layer: %{table: "post_reactions"}}, destination_attribute: :resource_id end end ``` ```elixir defmodule MyApp.Comment do use Ash.Resource, domain: MyApp.Domain, data_layer: AshSqlite.DataLayer ... relationships do has_many :reactions, MyApp.Reaction, relationship_context: %{data_layer: %{table: "comment_reactions"}}, destination_attribute: :resource_id end end ``` -------------------------------- ### Embed Entire SQLite Queries in Fragments Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/topics/advanced/expressions.md As a last resort, you can embed entire SQLite subqueries within fragments. This is powerful but should be used cautiously due to potential performance implications. ```elixir fragment("points > (SELECT SUM(points) FROM games WHERE user_id = ? AND id != ?)", user_id, id) ``` -------------------------------- ### Use Simple SQLite Expressions with Fragments Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/topics/advanced/expressions.md Fragments allow embedding arbitrary SQLite expressions directly into Ash queries. Use this for simple arithmetic or operations not directly supported by Ash. ```elixir fragment("? / ?", points, count) ``` -------------------------------- ### Perform Pattern Matching with 'like' Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/topics/advanced/expressions.md The 'like' operator in AshSqlite wraps the SQLite LIKE operator for pattern matching. Remember that '%' and '_' are special characters in patterns and case sensitivity applies. ```elixir Ash.Query.filter(User, like(name, "%obo%")) # name contains obo anywhere in the string, case sensitively ``` -------------------------------- ### Test Ticket Calculation in IEx Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/tutorials/getting-started-with-ash-sqlite.md Elixir code to test the 'status_subject' calculation by filtering open tickets and loading the calculated field. ```elixir Ash.Query Helpdesk.Support.Ticket |> Ash.Query.filter(status == :open) |> Ash.Query.load(:status_subject) |> Ash.read!() ``` -------------------------------- ### Disable Async Operations for SQLite Testing Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/topics/development/testing.md When testing with SQLite, set `:disable_async?` to `true` in your Ash configuration. This prevents Ash from spawning tasks, which is necessary due to SQLite's limitation of having only one write transaction open at a time. ```elixir config :ash, :disable_async?, true ``` -------------------------------- ### Query Closed Tickets Not Equal to 'barbaz' Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/tutorials/getting-started-with-ash-sqlite.md Elixir code to query and read tickets that are closed and whose subject does not equal 'barbaz'. Requires Ash.Query to be required. ```elixir require Ash.Query # Show the tickets that are closed and their subject does not equal "barbaz" Helpdesk.Support.Ticket |> Ash.Query.filter(status == :closed and not(subject == "barbaz")) |> Ash.read!() ``` -------------------------------- ### Define Calculation for Ticket Status and Subject Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/tutorials/getting-started-with-ash-sqlite.md Elixir code snippet for defining a calculation within a Ticket module that concatenates the status and subject fields. ```elixir # in lib/helpdesk/support/ticket.ex defmodule Helpdesk.Support.Ticket do ... calculations do calculate :status_subject, :string, expr("#{status}: #{subject}") end end ``` -------------------------------- ### Query Tickets Containing '2' in Subject Source: https://github.com/ash-project/ash_sqlite/blob/main/documentation/tutorials/getting-started-with-ash-sqlite.md Elixir code to query and read tickets where the subject contains the character '2'. Requires Ash.Query to be required. ```elixir require Ash.Query Helpdesk.Support.Ticket |> Ash.Query.filter(contains(subject, "2")) |> Ash.read!() ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.