feat: Support updating existing records.
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing

This commit is contained in:
James Harton 2023-10-02 15:15:11 +13:00
parent 98d722f20d
commit 6b1954baf6
Signed by: james
GPG key ID: 90E82DAA13F624F4
5 changed files with 47 additions and 10 deletions

View file

@ -21,7 +21,7 @@ AshCubDb is still a work in progress. Feel free to give it a go.
| Read (sort) | ✅ |
| Read (calculations) | ❌ |
| Read (aggregates) | ❌ |
| Update | |
| Update | |
| Destroy | ❌ |
## Github Mirror

View file

@ -10,4 +10,6 @@ config :git_ops,
if Mix.env() in ~w[dev test]a do
config :ash_cubdb, ash_apis: [Support.Api]
config :spark, :formatter, remove_parens?: true
end

View file

@ -14,6 +14,7 @@ defmodule AshCubDB.DataLayer do
Changeset,
Error,
Error.Changes.InvalidAttribute,
Error.Changes.StaleRecord,
Error.Invalid.TenantRequired,
Filter.Runtime,
Resource
@ -50,6 +51,7 @@ defmodule AshCubDB.DataLayer do
@doc false
@impl true
def can?(resource, :create), do: Dir.writable?(resource)
def can?(resource, :update), do: Dir.writable?(resource)
def can?(resource, :upsert), do: Dir.writable?(resource)
def can?(resource, :read), do: Dir.readable?(resource)
def can?(_, :multitenancy), do: true
@ -107,6 +109,22 @@ defmodule AshCubDB.DataLayer do
end
end
@doc false
@impl true
def update(resource, changeset) do
with :ok <- validate_tenant_configuration(resource, changeset.tenant),
{:ok, db} <- start(resource),
{:ok, record} <- Changeset.apply_attributes(changeset),
{:ok, key, data} <- Serde.serialise(record),
true <- CubDB.has_key?(db, key),
:ok <- CubDB.put(db, key, data) do
{:ok, set_loaded(record)}
else
false -> {:error, StaleRecord.exception(resource: resource)}
{:error, reason} -> {:error, Ash.Error.to_ash_error(reason)}
end
end
@doc false
@impl true
def run_query(query, resource, parent \\ nil) do

View file

@ -129,6 +129,21 @@ defmodule AshCubDB.DataLayerTest do
end
end
describe "update" do
test "records can be updated" do
post = insert!(Post)
params = Post |> params!() |> Map.take([:title])
assert {:ok, updated} = Post.update(post, params)
assert updated.id == post.id
assert updated.title == params.title
assert {:ok, updated} = Post.get(post.id)
assert updated.id == post.id
assert updated.title == params.title
end
end
defp dump(resource) do
resource
|> via()

View file

@ -7,27 +7,29 @@ defmodule Support.Post do
end
attributes do
uuid_primary_key(:id) do
writable?(true)
uuid_primary_key :id do
writable? true
end
attribute(:title, :string)
attribute(:body, :string)
attribute :title, :string
attribute :body, :string
end
actions do
# defaults ~w[create read update destroy]a
defaults(~w[create read]a)
defaults ~w[create read update]a
end
relationships do
belongs_to(:author, Support.Author)
belongs_to :author, Support.Author
end
code_interface do
define_for(Support.Api)
define_for Support.Api
define(:create)
define(:read)
define :create
define :read
define :update
define :get, action: :read, get_by: [:id]
end
end