Table of Contents generated with DocToc
- Changelog
- #36 - @KronicDeth
- Update to latest
mix.lock
format. - JaSerializer supports sparse fieldsets, but
Calcinator.JaSerializer.PhoenixView
'sparams_to_render_opts/1
was only copyingparams["include"]
toopts[:include]
, so now copy over both"include"
and"fields"
if present.
- Update to latest
- [#37[(https://github.com/C-S-D/calcinator/pull/37) - @KronicDeth
-
Calcinator.Resource.Ecto.Repo.list/2
supports configurable pagination throughconfig :calcinator, Calcinator.Resources.Ecto.Repo, paginator: paginator
4
Calcinator.Resources.Ecto.Repo.Pagination
callback modules are includedCalcinator.Resources.Ecto.Repo.Pagination.Ignore
-query_options[:page]
is ignored: all resources are always returned. There is no pagination information ever returned. This replicates the old, bugged behavior.Calcinator.Resources.Ecto.Repo.Pagination.Disallow
- All resources withnil
pagination is returned whenquery_options[:page]
isnil
, but an error is returns ifquery_optons[:page]
is notnil
. This is an improvement overCalcinator.Resources.Ecto.Repo.Pagination.Ignore
because it will tell callers thatquery_options[:page]
will not be honored.Calcinator.Resources.Ecto.Repo.Pagination.Allow
- All resources withnil
pagination is returned whenquery_options[:page]
isnil
. A page of resources with the pagination information is returned whenquery_options[:page]
is notnil
. This is the default paginator.Calcinator.Resources.Ecto.Repo.Pagination.Require
- An error is returned whenquery_options[:page]
isnil
. A page of resources with the pagination information is returned whenquery_options[:page]
is notnil
. This is a stronger form ofCalcinator.Resources.Ecto.Repo.Pagination.Allow
because it forces the caller to declare what page it wants. UsingCalcinator.Resources.Ecto.Repo.Pagination.Require
(or a default and maximum size) is recommended when not paginating would have a detrimental performance impact.
-
Calcinator.Resources.Page.from_params/1
supports default and maximum page sizes.config :calcinator, Calcinator.Resources.Page, size: [default: 10, maximum: 25]
-
Update
credo
to0.8.10
for Elixir 1.6 compatibility.
-
- #41 - @KronicDeth
-
c:Calcinator.Resources.list/1
fromuse Calcinator.Resources.Ecto.Repo
can sort any of attribute of the primaryEcto.Schema.t
returned byc:Calcinator.Resources.Ecto.Repo.ecto_schema_module/0
TestPosts.list(%{sorts: [%Calcinator.Resources.Sort{direction: :ascending, field: :inserted_at}]}) TestPosts.list(%{sorts: [%Calcinator.Resources.Sort{direction: :descending, field: :inserted_at}]})
or any attribute of relationships that are mapped to associations of the primary data
TestPosts.list(%{ sorts: [ %Calcinator.Resources.Sort{ association: :author, direction: :ascending, field: :name } ] }) TestPosts.list(%{ sorts: [ %Calcinator.Resources.Sort{ association: :author, direction: :descending, field: :name } ] })
-
- #38 - @KronicDeth
- Update deps
ex_doc
0.18.3
ex_machina
2.2.0
excoveralls
0.8.1
faker
0.10.0
junit_formatter
2.2.0
phoenix
1.3.2
postgrex
0.13.5
pryin
1.5.1
- Update deps
- #36 - @KronicDeth
- Fix Elixir 1.6 GenServer warning about not defining
init/1
explicitly.
- Fix Elixir 1.6 GenServer warning about not defining
- #37 -
query_options[:page]
is no longer ignored when passed touse Calcinator.Resources.Ecto.Repo
'slist/1
by default. To restore the old behavior change the paginator toCalcinator.Resources.Ecto.Repo.Pagination.Ignore
. - @KronicDeth - #41 - add missing
alias Calcinator.Resources.Sorts
toCalcinator.Resources
to fixSorts.t
being unknown - @KronicDeth - #43 - Port @jeffutter #34 to
insert/3
because similar toupdate/3
,insert/3
was missing a change to expectchangeset/2
to return an{:ok, changeset} | {:error, reason}
tuple instead of a just achangeset
. - @KronicDeth - #38 - Remove
scrivener_ecto
as #37 ended up not usingscrivener
and instead usingEcto
directly. - @KronicDeth - #42 - Fix
Unknown type 'Elixir.Resources'
dialyzer errors by adding missing qualifiers oralias
es. - @KronicDeth
- #31 - @KronicDeth
-
Calcinator
now instruments calls to subsystem with events, similar toPhoenix
instrumentation.event subsystem alembic
Alembic
calcinator_authorization
Calcinator.Authorization
calcinator_resources
Calcinator.Resources
calcinator_view
Calcinator.View
Instrumenters can be configured with
config :calcinator, instrumenters: [...]
-
pryin
instrumentation can be configured following thepryin
installation instructions and then addingCalcinator.PryIn.Instrumenter
to your:calcinator
configconfig :calcinator, :instrumenters: [Calcinator.PryIn.Instrumenter]
-
Custom instrumenters can be created following the docs in
Calcinator.Instrument
-
-
- #32 - @KronicDeth
- Update deps
credo
0.8.8
ex_doc
0.17.1
ex_machina
2.1.0
excoveralls
0.7.4
faker
0.9.0
junit_formatter
2.0.0
uuid
1.1.8
- Update deps
- #33 - Include the
id
field subject and target structs inCalcinator.PryIn.Instrumenter
context entries. - @KronicDeth
- #31 - The
@typedoc
and@type
forCalcinator.t
now has all the current struct fields documented and typed. - @KronicDeth - #32 - @KronicDeth
- README formatting
- Consistently use
--
instead of---
for path marker as--
becomes em dash in Markdown to HTML conversion - Add missing ``` for code blocks.
- Consistently use
- README formatting
- #31 - In order to facilitate passing the entire
Calcinator.t
struct tocalcinator_resources
event callbacks in instrumenters,Calcinator. get(Calcinator.Resources.t, params, id_key :: String.t, Resources.query_options)
has changed toCalcinator. get(Calcinator.t, params, id_key :: String.t, Resources.query_options)
: The first argument must be the entireCalcinator.t
struct instead of theCalcinator.Resources.t
module that was in theCalcinator.t
resources_module
field. - @KronicDeth
- #30 - @KronicDeth
Calcinator.Resources.changeset/1,2
is allowed to getmany_to_many
associations from the backing store, so during testing, this means that the sandbox access must be allowed prior to callingchangeset
. This was already the case for other actions, but forcreate
,allow_sandbox_access
was not called until theEcto.Changeset.t
was authorized and about to be created.
- #28 - @KronicDeth
use Calcinator.Resources.Ecto.Repo
'schangeset/2
will- (New) Preload any
many_to_many
associations that appear inparams
- Cast
params
intodata
usingoptional_field/0
andrequired_fields/0
of the module - (New) Puts
many_to_many
associations fromparams
into changeset. If any ids don't exist, they will generate changeset errors. - Validates changeset with
module
ecto_schema_module/0
changeset/0
.
- (New) Preload any
- #29 - @KronicDeth
- Update dependencies
alembic
3.4.0
credo
0.8.6
ex_doc
0.16.3
excoveralls
07.2
phoenix
1.3.0
- Use Elixir
1.5.1
for CircleCI build- Use
@impl
for callbacks
- Use
- Update dependencies
- #28 - @KronicDeth
- Use
dockerize
to wait for postgres port to open - Use
calcinator.ecto.wait
mix
task to ensure port can receive queries after opening
- Use
- #28 - @KronicDeth
Calcinator.Resources.changeset/1,2
return goes fromEcto.Changeset.t
to{:ok, Ecto.Changeset.t} | {:error, :ownership}
aschangeset/1,2
will access database to preload, validate ids, andput_assoc
onmany_to_many
association. Accessing the database can lead to an ownership error, so{:error, :ownership}
is necessary.
- #19 - @KronicDeth
- Can now return (and is preferred to return instead of a timeout exit)
{:error, :timeout}
from allCalcinator.Resources
action@callbacks
. The following were added:Calcinator.Resources.delete/2
Calcinator.Resources.get/2
Calcinator.Resources.insert/2
Calcinator.Resources.update/2
Calcinator.Resources.update/3
- Can now return (and is preferred to return instead of a timeout exit)
- #21 - @KronicDeth
- Pass all JSON errors through
Calcinator.Controller.Error.render_json
to eliminate redundant pipelines. - When structs are deleted directly instead of changesets, there's no way to add constraints, such as
no_assoc_constraint
orassoc_constraint
that would transform DB errors into validation errors, soCalcinator.delete/3
generate a changeset fromCalcinator.Resources.changeset(struct, %{})
- Docs are updated to include tips are using changeset to add constraints
- The docs for
Calcinator.Resources.changeset/2
is updated so that it states it will be used for both updating (which it was previously) and (now) deleting
- Comment the expected path in the
get_related_resource
andshow_relationship
examples to makes it easier to remember whenget_related_resource
andshow_relationship
are called. - Test reproducible clauses in
Calcinator.Controller
cases (the majority of the bug fixes came from this testing). [I couldn't remember how to trigger{:error, :ownership}
and didn't want to fake it since I know I've produced it before because that's whywrap_ownership_error
exists.] - Remove
{:ok, rendered}
duplication inCalcinator.Controller
- Deduplicate
related_property
responses inCalcinator.Controller
- Extract all the error-tuple handling in
Calcinator.Controller
toCalcinator.Controller.Error.put_calcinator_error
as most clauses were duplicated in the various actions. This would technically allow some unexpected errors (like{:error, {:not_found, parameter}}
for create) to be handled, but it is unlikely to cause problems since it will lead toconn
response instead of aCaseClauseError
as would be the case if some of the clauses were missing as was the case before this PR.
- Pass all JSON errors through
- #22 - @KronicDeth
- Make the
Alembic.Document.t
andAlembic.Error.t
thatCalcinator.Controller.Error
uses internally available inCalcinator.Alembic.Document
andCalcinator.Alembic.Error
, respectively, so they can be reused in overrides andretort
. - Pass
:meta
throughCalcinator.Retort.query_options
, which allows pass through of meta like fromCalcinator.Meta.Beam
, which is necessary for indirect callbacks through RPC calls forretort
. - Move
Calcinator.Meta.Beam
key to module attribute to prevent typos. Calcinator.Meta.beam.put_new_laz
allows beam information to only be set inmeta
if its not already there to allow for loops betweenCalcinator
servers.
- Make the
- #23 - Update to
phoenix
1.2.4
- @KronicDeth
- #19 - @KronicDeth
- Previously, the
Calcinator
actions (create/2
,delete/2
,get_related_resource/3
,index/3
,show/2
,show_relationship/3
, andupdate/2
)@spec
and@doc
include (hopefully) all the errors they can return now{:error, :sandbox_access_disallowed}
{:error, :sandbox_token_missing}
{:error, :timeout}
@callback
s with the same name/arity can only have on@doc
, so the second form ofCalcinator.Resources.insert/2
did not show up.- Change first level of header to
##
to match style guide for ex_doc inCalcinator.Resources
. - Rearrange
Calcinator.Resources.update/2
, so it's beforeCalcinator.Resources.update/3
to match doc sorted order.
- Previously, the
- #21 - @KronicDeth
- Ensure
Calcinator.Controller
actions havecase
clauses for all the declared return types fromCalcinator
calls. - Disable
mix docs
backquote check get_related_resources
could not handle has_many related resources, specificallyCalcinator.JaSerializer.PhoenixView.get_related_resource/3
would not allowdata
to be alist
.Calcinator.RelatedView.render
with data assumes the data was singular and "links" could be added to that "data" map.Calcinator.authorized
did not allow the unfiltered data to belist
.
- Fix
source
assigns
forget_related_resource
example: example still used pre-open-sourcingassociation
andid_key
. - Fix show_relationship example that was just wrong. The same
assigns
asget_related_resource
should be used. Since at first I couldn't figure out why showing a relationship would need a view module and I wrote the code, I added a note explaining its for theview_module.type/0
callback since relationships are resource identifiers withid
andtype
. Calcinator.RelationshipView.data/1
assumed that[:related][:resource]
wasnil
or amap
, which didn't handle thelist
for has_many relationships.
- Ensure
- #22 - Fix
Calcinator.Alembic.Error.sandbox_token_missing/0
type, which should have returned anAlembic.Error.t
instead of anAlembic.Document.t
. - @KronicDeth
- #19 - @KronicDeth
Calcinator.Resources.allow_sandbox_access/1
must now return:ok | {:error, :sandbox_access_disallowed}
. The previous{:already, :allowed | :owner}
maps to:ok
while:not_found
maps to{:error, :sandbox_access_disallowed}
.- If you previously had total coverage for all return types from
Calcinator
actions, they now also return{:error, :sandbox_access_disallowed}
and{:error, :timeout}
. Previously, instead of{:error, :sandbox_access_disallowed}
,:not_found
may been returned, but that was a bug that leaked an implementation detail from howDBConnection.Ownership
works, so it was removed.
- #21 - @KronicDeth
Calcinator.delete
deletes a changeset instead of a resource structCalcinator.Resources.delete/1
must expect anEcto.Changeset.t
instead of a resourcestruct
use Calcinator.Resources.Ecto.Repo
generatesdelete/1
that expects anEcto.Changeset.t
and callsCalcinator.Resources.Ecto.Repo.delete/2
, which now expects a changeset instead of resource struct as the second argument.
- #22 - @KronicDeth
:meta
is now a required key inCalcinator.Resources.query_options
.Calcinator.Resources.delete/2
must now accept both theEcto.Changeset.t
with any constraints and theCalcinator.Resources.query_options
, so that the newmeta
key can be used to continue propagating theCalcinator.Meta.Beam
from the original caller in a chain of calls.
- #18 - @KronicDeth
- JSONAPI filter values that allow multiple values, similar to includes, are comma separated without spaces, instead of having to do
String.split(comma_separated_values, ",")
in all filters that accept multiple values,Calcinator.Resources.split_filter_value/1
can be used. - Pass the final
query
with all filters applied throughdistinct(query, true)
, so that filters don't need to ensure they return distinct results, which is an expectation of JSONAPI.
- JSONAPI filter values that allow multiple values, similar to includes, are comma separated without spaces, instead of having to do
- #17 - @KronicDeth
- Guard
Calcinator.Resources.params
andCalcinator.Resources.query_options
withis_map/1
- Update to
postgrex
0.13.2
for Elixir1.5.0-dev
compatibility Calcinator.Resources.query_options
:filters
should be a map from filter name to filter value, each being aString.t
instead of a list single-entry maps because filter names can only be used once and order should not matter.
- Guard
- #16 -
Calcinator.Resources.Ecto.Repo.filter(query, name, value)
is a new optional callback thatuse Calcinator.Resources.Ecto.Repo
modules can implement to support filters on the query beforemodule
repo
all
is called. - @KronicDeth
- #14 - @KronicDeth
- Dependency updates
alembic
to3.2.0
ex_doc
to0.15.1
ja_serializer
to0.12.0
(but continue compatibility with older versions)phoenix
to1.2.3
credo
to0.7.3
- Add
excoveralls
for coverage tracking - Add CircleCI build status badge
- Add CodeClimate
credo
status badge - Add HexFaktor dependencies status badge
- Add InchEx documentation badge
- Use Erlang 19.3 and Elixir 1.4.1 on CircleCI
- Dependency updates
- #12 - Regression tests that
%Calcinator{}
defaultauthorization_module
implementsCalcinator.Authorization
behaviour. - @KronicDeth
- #12 - Fix capitalization of
SubjectLess
when used as the%Calcinator{}
defaultauthorization_module
. - @KronicDeth
- #10 - @KronicDeth
- Explain why
relationships/2
is overridden in views - Routing docs for
get_related_resource
andshow_relationship
- Actions and related Authorization docs for
Calcinator.Controller
- Use
Ecto.Repo
config/0
instead of requiringsandboxed?/0
to be defined.
- Explain why
- #10 - @KronicDeth
- Add missing renames for README controllers
alias InterpreterServerWeb.Controller
->alias Calcinator.Controller
use Controller.Resources,
->use Controller,
- Replace
use MyApp.Web, :view
withuse JaSerializer.PhoenixView
, so it doesn't requireMyApp.Web.view/0
to includeuse JaSerializer.PhoenixView
- Renamed second
Author
Ecto.Schema
modules toPost
- Don't require
user
assign inCalcinator.Controller
- Fix Elixir 1.4
()
warnings.
- Add missing renames for README controllers
- #11 -
Code.ensure_loaded?(Phoenix.Controller)
can be used to protectCalcinator.Controller.Error
andCalcinator.Controller
, so that it is not defined when its dependency,Phoenix.Controller
is not available. Without this change,(CompileError) lib/calcinator/controller/error.ex:12: module Phoenix.Controller is not loaded and could not be found
is raised in retort. - @KronicDeth
- #10 - Instead of requiring user assign in
Plug.Conn
to getsubject
for%Calcinator{}
, a private key,:calcinator_subject
, will be used usingPlug.Conn.put_private
. Thesubject
will be stored usingCalcinator.Controller.put_subject
and retrieved withCalcinator.Controller.get_subject
. Callingput_subject
in a plug is shown in README andCalcinator.Controller
examples. - @KronicDeth
- #9 - Examples for how to
use Calcinator.Resources.Ecto.Repo
inCalcinator.Resources.Ecto.Repo
's@moduledoc
- @KronicDeth
- #9 - Add missing
ecto_schema_module/0
callback toREADME
example ofuse Calcinator.Resources.Ecto.Repo
- @KronicDeth
- #8 - @KronicDeth
use Calcinator.Controller
can be used inside aPhoenix
controller to define JSONAPI actions.Calcinator.Controller.Error
defines functions for JSONAPI formatted errors thatCalcinator.Controller
may respond with.- Document how to use
Calcinator.Controller
to accessRetort.Client.Generic
backedCalcinator.Resource
- Document how to use
Calcinator.Controller
to accessCalcinator.Resources.Ecto.Repo
- #7 -
preload(module, queryable, opts)
returns{:ok, query}
instead of justquery
now. - @KronicDeth
- #6 - @KronicDeth
- Add
{:error, :ownership}
∀Calcinator.Resources
callbacks - Add
{:error, :ownership}
∀Calcinator
actions
- Add
- #6 - Previously
get
andlist
were the onlyCalcinator.Resources.Ecto.Repo
functions that convertedDBConnection.OwnershipError
to{:error, :ownership}
, but the otherEcto.Repo
calls could also throw the Error, so all calls need to be protected for consistency. - @KronicDeth
- #4 -
use Calcinator.Resources.Ecto.Repo
will define the callbacks forCalcinator.Resources
backed by anEcto.Repo
. The only callbacks that are required then areecto_schema_module/0
,full_associations/1
andrepo/0
. - @KronicDeth - #5 - @KronicDeth
- Update to
credo
0.5.3
- Update to
ja_serializer
0.11.2
- Update to
- #3 - @KronicDeth
Calcinator.Authorization
implementationsCalcinator.Authorization.SubjectLess
allows allaction
s on alltarget
s, but only if the passedsubject
isnil
. Use it for when you don't actually want authorization checks.
- Document Steps and Returns of
Calcinator
actions. Steps make it clearer which parts ofstate
are used when. Returns explain why a given return happens. - Document and clarify
Calcinator.Authorization
calling patterns- Document each callback with the target shape for each action.
- Break up the callbacks into multiple signatures for the different call site
- #3 - @KronicDeth
- Add missing related
Calcinator.View
callbacks,get_related_resource
andshow_relationship
, that are needed for their respective functions inCalcinator
. - Add missing newline at end of file.
- Remove
argN
arguments in docs by naming arguments in specs - Remove extra blank line
- Add missing related
- #2 - Doctests for
Calcinator.Resources.attribute_to_field/2
- @KronicDeth
- #2 -
Calcinator.Resources.attribute_to_field/2
now works with virtual fields. - @KronicDeth
- #1 - Expose
attribute_to_field
that was used inCalcinator.Resources.Sort
as it is useful in other places instead of usingString.to_existing_atom
, which doesn't handle the hyphenation and can fail if the atom hasn't been loaded yet. - @KronicDeth
- #1 - @KronicDeth
- Add missing top-level files to extras:
CHANGELOG.md
CODE_OF_CONDUCT.md
CONTRIBUTING.md
LICENSE.md
- Add missing top-level files to extras: