DSL extensions for configuring ScyllaDB-specific options on Ash resources.
Supports Ash Framework 3.0+ features including base_filter, identities, aggregates, calculations, preparations, changes, validations, pipelines, multitenancy, code_interface, and extended action options.
Usage
defmodule MyApp.MyResource do
use Ash.Resource,
data_layer: AshScylla.DataLayer
ash_scylla do
table "my_table"
keyspace "my_keyspace"
consistency :quorum
ttl 3600
lwt true
base_filter [status: "active"]
default_context %{tenant: "org_123"}
description "My resource description"
secondary_index :email
secondary_index [:name, :age]
secondary_index :status, name: "idx_user_status"
materialized_view :users_by_email,
primary_key: [:email, :id],
include_columns: [:name, :age]
pagination :token
per_action_consistency read: :one, create: :quorum
end
attributes do
uuid_primary_key :id
uuid_v7_primary_key :vid
integer_primary_key :seq_id
create_timestamp :inserted_at
update_timestamp :updated_at
attribute :name, :string, public?: true, writable?: true
attribute :email, :string, sensitive?: false
attribute :status, :string
attribute :age, :integer
end
identities do
identity :unique_email, [:email]
end
aggregates do
count :total_count
count :active_count, filter: [status: "active"]
end
calculations do
calculate :display_name, :string, expr(name)
end
preparations do
prepare build(:load, [:email])
end
changes do
change fn changeset, _context -> changeset end
end
validations do
validate attribute_equals(:status, "active")
end
pipelines do
pipe_through :read
end
multitenancy do
strategy :attribute
attribute :org_id
end
code_interface do
define :create_user
define_calculation :active_count
end
relationships do
belongs_to :organization, MyApp.Organization
has_one :profile, MyApp.Profile
has_many :posts, MyApp.Post
many_to_many :tags, MyApp.Tag
end
actions do
create :create do
accept [:name, :email, :status]
argument :organization_id, :uuid
change fn changeset, _context -> changeset end
validate present([:name])
end
read :read do
prepare build(:load, [:email])
pagination offset?: true, max_page_size: 100
metadata :total_count, :integer
filter [status: "active"]
end
update :update do
accept [:name, :status]
change fn changeset, _context -> changeset end
validate present([:name])
end
destroy :destroy do
soft? true
change fn changeset, _context -> changeset end
end
end
endOptions
:table- The table name in ScyllaDB (overrides default):keyspace- The keyspace to use (overrides repo default):consistency- The consistency level for reads/writes:ttl- Default TTL for inserted records (in seconds):lwt- Enable Lightweight Transactions (LWT) for atomic upserts usingINSERT ... IF NOT EXISTS(default:false):allow_filtering- Whentrue, appendsALLOW FILTERINGto queries that use secondary indexes (default:false):secondary_index- Define secondary indexes for non-primary key columns:materialized_view- Define materialized views with different primary key structure:pagination- Pagination mode::offset(default) or:tokenfor token-based pagination:per_action_consistency- Per-action consistency overrides as a keyword list, e.g.[read: :one, create: :quorum]:base_filter- A filter expression applied to all queries on this resource (Ash 3.0):default_context- Default context map merged into every query/changeset (Ash 3.0):description- Human-readable description of the resource (Ash 3.0):identity- Define unique identity constraints for upsert operations:aggregate- Define aggregate queries (count, sum, avg, min, max):calculation- Define expression-based calculations:preparation- Define query preparations:change- Define changes applied to changesets:validation- Define attribute validations:pipeline- Define action pipelines via pipe_through:multitenancy- Configure multitenancy strategy (:context or :attribute):code_interface- Define code interface functions:relationship- Define relationships (belongs_to, has_one, has_many, many_to_many):action- Define actions with extended options (accept, argument, change, validate, prepare, pagination, metadata, filter, soft?)
Features
The data layer supports:
- Upsert (
:upsert) - Insert-or-update semantics with optional LWT - Atomic updates (
{:atomic, :update}) - LWT-based conditional updates - Atomic upserts (
{:atomic, :upsert}) - LWT-based insert-or-update - Bulk update/destroy -
update_queryanddestroy_queryfor filtered operations - Distinct - On partition-key columns only
- Aggregates - COUNT via
:countaggregate - Expression calculations - In-memory post-processing
- Boolean filter - With OR-to-IN rewriting
- Base filter - Automatic filter applied to all queries (Ash 3.0)
- Default context - Context merged into all queries (Ash 3.0)
- Identities - Unique constraints for upsert operations (Ash 3.0)
- Multitenancy - Context-based and attribute-based strategies (Ash 3.0)
Summary
Functions
Gets the action configurations defined for a resource.
Gets the aggregates defined for a resource.
Gets the allow_filtering setting for a resource.
Macro for configuring ScyllaDB options in Ash resources.
Gets the base_filter configured for a resource.
Gets the calculations defined for a resource.
Gets the changes defined for a resource.
Gets the configured consistency level for a resource.
Gets the default_context configured for a resource.
Gets the description configured for a resource.
Checks if a column has a secondary index defined.
Gets the identities defined for a resource.
Gets the configured keyspace for a resource.
Gets the materialized views defined for a resource.
Gets the multitenancy configuration for a resource.
Gets the pagination mode for a resource.
Gets the per-action consistency configuration for a resource.
Gets the pipelines defined for a resource.
Gets the preparations defined for a resource.
Gets the relationships defined for a resource.
Gets the configured repo for a resource.
Gets the code_interface configuration for a resource.
Gets the secondary indexes defined for a resource.
Gets the configured table name for a resource.
Gets the configured TTL for a resource.
Gets the validations defined for a resource.
Functions
Gets the action configurations defined for a resource.
Returns a list of maps with keys:
:type- the action type (:create, :read, :update, :destroy):name- the action name (atom):options- action options (accept, argument, change, validate, etc.)
Gets the aggregates defined for a resource.
Returns a list of maps with keys:
:type- the aggregate type (:count, :sum, :avg, :min, :max):name- the aggregate name (atom):field- the field to aggregate on (optional):options- additional options (filter, etc.)
Gets the allow_filtering setting for a resource.
When true, ALLOW FILTERING is appended to queries that use
secondary indexes, allowing ScyllaDB to execute them without
requiring partition key filters.
Defaults to false.
Macro for configuring ScyllaDB options in Ash resources.
Examples
ash_scylla do
table "users"
keyspace "my_keyspace"
consistency :quorum
ttl 3600
base_filter [status: "active"]
default_context %{tenant: "org_123"}
description "User accounts"
secondary_index :email
secondary_index [:name, :age]
materialized_view :users_by_email,
primary_key: [:email, :id],
include_columns: [:name, :age]
pagination :token
per_action_consistency read: :one, create: :quorum
identity :unique_email, [:email]
aggregate :count, :total_users
aggregate :count, :active_users, filter: [status: "active"]
calculation :display_name, :string, expr(name)
preparation build(:load, [:email])
change fn changeset, _context -> changeset end
validation present([:name])
pipeline :read
multitenancy do
strategy :attribute
attribute :org_id
end
code_interface do
define :create_user
define_calculation :active_users
end
relationship :belongs_to, :organization, MyApp.Organization
relationship :has_one, :profile, MyApp.Profile
relationship :has_many, :posts, MyApp.Post
relationship :many_to_many, :tags, MyApp.Tag
action :create, :create_user do
accept [:name, :email]
argument :organization_id, :uuid
change fn changeset, _context -> changeset end
validate present([:name])
end
action :read, :list_users do
pagination offset?: true, max_page_size: 100
metadata :total_count, :integer
filter [status: "active"]
end
action :update, :update_user do
accept [:name, :status]
change fn changeset, _context -> changeset end
end
action :destroy, :delete_user do
soft? true
end
end
Gets the base_filter configured for a resource.
The base_filter is a filter expression that is automatically applied to all queries on this resource (Ash 3.0 feature).
Gets the calculations defined for a resource.
Returns a list of maps with keys:
:name- the calculation name (atom):type- the calculation type (atom):expression- the expression to evaluate:options- additional options
Gets the changes defined for a resource.
Gets the configured consistency level for a resource.
Gets the default_context configured for a resource.
The default_context is a map that is merged into every query and changeset context for this resource (Ash 3.0 feature).
Gets the description configured for a resource.
Checks if a column has a secondary index defined.
Gets the identities defined for a resource.
Returns a list of maps with keys:
:name- the identity name (atom):columns- list of column names (atoms):options- additional options
Gets the configured keyspace for a resource.
Gets the materialized views defined for a resource.
Returns a list of maps with keys:
:name- the view name (atom):config- the view configuration keyword list
Gets the multitenancy configuration for a resource.
Returns a map with keys:
:strategy- :context or :attribute:attribute- the attribute name for :attribute strategy (optional)
@spec pagination(module()) :: :offset | :token
Gets the pagination mode for a resource.
Returns :offset or :token.
Gets the per-action consistency configuration for a resource.
Returns a map of action_name => consistency_level.
Gets the pipelines defined for a resource.
Gets the preparations defined for a resource.
Gets the relationships defined for a resource.
Returns a list of maps with keys:
:type- :belongs_to, :has_one, :has_many, or :many_to_many:name- the relationship name (atom):target- the target resource module:options- additional options
Gets the configured repo for a resource.
Gets the code_interface configuration for a resource.
Gets the secondary indexes defined for a resource.
Returns a list of maps with keys:
:columns- list of column names (atoms):name- optional custom index name:options- additional options
Gets the configured table name for a resource.
@spec ttl(module()) :: pos_integer() | nil
Gets the configured TTL for a resource.
Gets the validations defined for a resource.