New migration patches: 11
- Reverted refactoring from v0.12 causing an exception in Postgres 14.0 to 14.5 when inserting into or deleting from multiple tables within a single transaction.
- Add
:order_by
option toCarbonite.Query.changes/2
to either disable default ordering or specify the order.
New migration patches: 10
- Improve performance of test setups by using a transaction-local variable in
override_mode/2
. The previous implementation could cause parallel tests to wait for row locks on thetriggers
table. - Replaced calls to
Ecto.Migration.timestamps/1
in migrations with explicitadd(:inserted_at, ...)
calls. This ensures that we don't be affected by users'@migration_timestamps
options.
New migration patches: 9
- Fix
set_transaction_id
trigger not using the PK index ontransactions
due to being dependent onCURRVAL
for every row. Replaced with a CTE theEXIST
query is now an index-only scan as it was intended to be. As a consequence, scalability of inserts into thetransactions
table has been greatly improved.
- Fix incomplete rollback logic in migration 8, leading to leftover procedures in the carbonite prefix when rolling back all the way (e.g.
Carbonite.Migrations.down(8..1)
). (#100, @xadhoom)
New migration patches: 8
- Make the trigger function correctly mask the
filtered_columns
in thechanged_from
JSON object ifstore_changed_from
is set. (#96)
changed_from
object even though they were listed in the filtered_columns
. All users who combine store_changed_from: true
with a filtered_columns
setting should upgrade and assess the impact of this potential data leak.
- Migration: Creating table
changes
failed when Ecto's@migration_foreign_key
is set to[column: <anything but id>]
.
New migration patches: 7
- Add a new index on
transaction_id
in thechanges
table, to speed up queries for a transaction's changes and thepurge
operation. The existingchanges_transaction_id_index
(ontransaction_xact_id
column) has been renamed tochanges_transaction_xact_id_index
. - Allow ranges of migration patches in
Carbonite.Migrations.up/2
/down/2
.
- Fixed a minor incompatibility with recently released Postgres 16.0.
New migration patches: 6
- Correctly detect changes to array fields.
Previously, detection of changes was done via the @>
operator to test "containment" of a {col: old_value}
JSON object in the JSON object of the new record. Unfortunately, Postgres' "jsonb containment" (see docs) views array subsets as contained within their subsets, as well as arrays in different orders to be contained within each other. Both of these cases we want to track as a changed value.
changed
and changed_from
columns of the Carbonite.Change
record. Unfortunately, this also means that versions may have been discarded entirely if no other fields of a record were updated at the same time.
- Add
:to
option toCarbonite.override_mode/2
to specify an explicit target mode. Useful for toggling the mode around test fixtures.
- Fix
Carbonite.process/4
success typing by explicitly picking options.
- Fix
carbonite_prefix
onQuery.outbox_done/2
. Apply the prefix on the nested outbox query as well.
Carbonite.override_mode/2
and most functions inCarbonite.Query
were broken when using a non-defaultcarbonite_prefix
option. Fixed by moving theprefix
option onto thefrom
expression.
- Added
:initially
option tocreate_trigger/2
to create triggers withIMMEDIATE DEFERRED
constraint option. This allows to conditionally insert theCarbonite.Transaction
record at the end of the transaction. In order to use this for already existing triggers, you need to drop them (drop_trigger/2
) and re-create them.
- Made the changes trigger
DEFERRABLE
. As part of the:initially
option ofcreate_trigger/2
, we chose to make triggersDEFERRABLE
by default. Again, for any existing triggers, this won't take effect, but newly created triggers will use this constraint option. - Dropped support for
preload: atom | [atom]
-style of specifying preloads on a query inCarbonite.Query
.
New migration patches: 5
- Optional tracking of previous data in changes. Set the
store_changed_from
trigger option.
- Added
@schema_prefix "carbonite_default"
on all schemas. This will enable the manual usage ofRepo.insert/2
& friends on transactions without specifying a prefix, when using the default carbonite prefix.
New migration patches: 4
- The
id
column ontransactions
has been replaced with an ordinary autoincrementing integer PK, filled from a sequence. Next to it a newxact_id
column continues to store the transaction id (frompg_current_xact_id
). Both values used together ensure that, first theid
is monotonically increasing and survives a backup restore (see issue #45), and second thechanges
records can still only be inserted within the same transaction.
Carbonite.Migrations.insert_migration_transaction/1
and its macro friend,insert_migration_transaction_after_begin
, help with data migrations.Carbonite.fetch_changes
returns the changes of the current (ongoing) transaction.
New migration patches: 2, 3
Carbonite.override_mode/2
(kept a wrapper inCarbonite.Multi
)Carbonite.insert_transaction/3
(kept a wrapper inCarbonite.Multi
)Carbonite.process/4
(previouslyCarbonite.Outbox.process/3
with major changes)Carbonite.purge/2
(previouslyCarbonite.Outbox.purge/1
with major changes)
- Split into query / processing
- Simplify processing
- No more transaction
- New capabilities: memo, halting, chunking
- Explicit for now with
Carbonite.Migrations.up(non_neg_integer())
Carbonite.Migrations.install_schema/1
is nowCarbonite.Migrations.up/2
Carbonite.Migrations.put_trigger_option/4
to ensure old migrations continue to work- At the same time removed long configuration statement from
Carbonite.Migrations.install_trigger/1
, so this does not need to be versioned and continues to work - Mix task for generating the "initial" migration
- Optionally derive Jason.Encoder for
Carbonite.Transaction
andCarbonite.Change
- Made all prefix options binary-only (no atom) as
Ecto.Query.put_query_prefix/2
only accepts strings
table_prefix
option toQuery.changes/2
allows to override schema prefix of given recordQuery.transactions/1
query selects all transactions
Carbonite.Migrations.drop_tables/1
allows to drop the carbonite audit trail without removing the schema
- Renamed the option that can be passed to
Carbonite.Migrations.drop_schema/1
fromprefix
tocarbonite_prefix
- Changed
Carbonite.Migrations.drop_schema/1
to also drop the tables - Made
Carbonite.Multi.insert_transaction/3
ignore conflictingINSERT
s within the same transaction - Also, changed
Carbonite.Multi.insert_transaction/3
to always reloads all fields from the database after insertion, immediately returning the JSONinifiedmeta
payload
- Fixed ignore mode when
override_transaction_id
is NULL
- Fixed broken documentation
- Store primary key(s) on changes table and index them
- Add
Carbonite.Query
modulecurrent_transaction/2
allows to fetch the ongoing transaction (for sandbox tests)changes/2
allows to fetch the changes of an individual source record
- Update Postgrex to 0.15.11 and drop local
Xid8
type - Add
mode
field to trigger (capture or ignore) - Add "override mode" reversing the
mode
option for the current transaction to enable/disable capturing on demand (e.g. in tests) - Add filtered columns
- Moved top-level functions to nested modules
Transaction
andMulti
- Made
table_pk
beNULL
whenprimary_key_columns
is an empty array - Default
primary_key_columns
to["id"]
- Renamed
prefix
option tocarbonite_prefix
oninstall_schema/2
for consistency
- Initial release.