libamxd  6.4.1
Data Model Manager
Transactions

A transaction is a sequence of actions that needs to be performed on one or more objects. More...

Macros

#define amxd_trans_set_value(type, trans, name, value)    amxd_trans_set_ ## type(trans, name, value)
 Helper macro for setting a value. More...
 

Typedefs

typedef enum _amxd_tattr_id amxd_tattr_id_t
 Transaction attributes. More...
 

Enumerations

enum  _amxd_tattr_id { amxd_tattr_change_ro , amxd_tattr_change_pub , amxd_tattr_change_prot , amxd_tattr_change_priv }
 Transaction attributes. More...
 

Functions

amxd_status_t amxd_trans_init (amxd_trans_t *const trans)
 Initializes a transaction object. More...
 
void amxd_trans_clean (amxd_trans_t *const trans)
 Cleans the transaction object. More...
 
amxd_status_t amxd_trans_new (amxd_trans_t **trans)
 Allocates a transaction object on the heap and initializes it. More...
 
void amxd_trans_delete (amxd_trans_t **trans)
 Frees the memory previously allocated for a transaction object. More...
 
amxd_status_t amxd_trans_set_attr (amxd_trans_t *trans, amxd_tattr_id_t attr, bool enable)
 Set the transaction attributes. More...
 
amxd_status_t amxd_trans_add_action (amxd_trans_t *const trans, const amxd_action_t reason, const amxc_var_t *data)
 Adds an action to a transaction. More...
 
amxd_status_t amxd_trans_select_pathf (amxd_trans_t *const trans, const char *path,...) __attribute__((format(printf
 Selects an object using a absolute or relative path. More...
 
amxd_status_t amxd_status_t amxd_trans_select_object (amxd_trans_t *trans, const amxd_object_t *const object)
 Selects an object using an object pointer. More...
 
amxd_status_t amxd_trans_set_param (amxd_trans_t *const trans, const char *param_name, amxc_var_t *const value)
 Adds a set value action to a transaction. More...
 
amxd_status_t amxd_trans_add_inst (amxd_trans_t *const trans, const uint32_t index, const char *name)
 Adds an instance add action to a transaction. More...
 
amxd_status_t amxd_trans_del_inst (amxd_trans_t *const trans, const uint32_t index, const char *name)
 Adds an instance delete action to a transaction. More...
 
amxd_status_t amxd_trans_apply (amxd_trans_t *const trans, amxd_dm_t *const dm)
 Applies all previously added actions. More...
 
void amxd_trans_dump (const amxd_trans_t *const trans, const int fd, const bool reverse)
 Dumps the transaction to a file descriptor. More...
 

Detailed Description

A transaction is a sequence of actions that needs to be performed on one or more objects.

The squence of actions (transaction) can be considered as an atomic operation. Either all actions succeed or none is applied.

Typically an object is selected to work on with amxd_trans_select_pathf or amxd_trans_select_object, and the a set of actions is added.

Adding action to a transaction have no effect immediatly. The actions are executed as soon as amxd_trans_apply is called.

When amxd_trans_apply fails no changes are done. When amxd_trans_apply succeeds all changes are applied and events are send.

In one transaction it is possible to change many objects.

Macro Definition Documentation

◆ amxd_trans_set_value

#define amxd_trans_set_value (   type,
  trans,
  name,
  value 
)     amxd_trans_set_ ## type(trans, name, value)

Helper macro for setting a value.

This helper macro sets a value, using a type indicator

Parameters
typethe data type, must be a valid parameter type, or must be convertable to a valid parameter type
transpointer to a transaction object
nameparameter name of the current selected object
valuethe new value, must match the type

Definition at line 144 of file amxd_transaction.h.

Typedef Documentation

◆ amxd_tattr_id_t

Transaction attributes.

Transaction attributes can be set using amxd_trans_set_attr

Enumeration Type Documentation

◆ _amxd_tattr_id

Transaction attributes.

Transaction attributes can be set using amxd_trans_set_attr

Enumerator
amxd_tattr_change_ro 

When set transaction can change read-only params or object

amxd_tattr_change_pub 

Set transaction access level to public

amxd_tattr_change_prot 

Set transaction access level to protected

amxd_tattr_change_priv 

Set transaction access level to private

Definition at line 102 of file amxd_transaction.h.

102  {
enum _amxd_tattr_id amxd_tattr_id_t
Transaction attributes.
@ amxd_tattr_change_prot
@ amxd_tattr_change_ro
@ amxd_tattr_change_priv
@ amxd_tattr_change_pub

Function Documentation

◆ amxd_trans_add_action()

amxd_status_t amxd_trans_add_action ( amxd_trans_t *const  trans,
const amxd_action_t  reason,
const amxc_var_t *  data 
)

Adds an action to a transaction.

Adds an action to a transaction, providing the action data.

This function is mostly no called directly, some convience wrapper functions are provide to make it easier to add an action to a transaction.

Use one of these methods instead

Parameters
transpointer to a transaction object
reasonthe action identifier
datathe action data
Returns
amxd_status_ok when the atcion is added to the transaction.

Definition at line 597 of file amxd_transaction.c.

599  {
601  amxd_trans_action_t* action = NULL;
602 
603  when_null(trans, exit);
604  when_true_status(reason != action_any &&
605  reason != action_object_write &&
606  reason != action_object_add_inst &&
607  reason != action_object_del_inst,
608  exit,
610 
611  action = amxd_trans_new_action(trans, reason);
612  when_null(action, exit);
613  amxc_var_copy(&action->data, data);
615 
616 exit:
617  if(trans != NULL) {
618  trans->status = status;
619  }
620  return status;
621 }
static amxd_trans_action_t * amxd_trans_new_action(amxd_trans_t *trans, amxd_action_t reason)
@ action_object_write
Definition: amxd_types.h:118
@ action_object_add_inst
Definition: amxd_types.h:123
@ action_object_del_inst
Definition: amxd_types.h:124
@ action_any
Definition: amxd_types.h:111
enum _amxd_status amxd_status_t
@ amxd_status_ok
Definition: amxd_types.h:78
@ amxd_status_unknown_error
Definition: amxd_types.h:79
@ amxd_status_invalid_action
Definition: amxd_types.h:89
amxd_status_t status
static amxd_status_t status

◆ amxd_trans_add_inst()

amxd_status_t amxd_trans_add_inst ( amxd_trans_t *const  trans,
const uint32_t  index,
const char *  name 
)

Adds an instance add action to a transaction.

The instance add action works on the currently selected object. The currently selected object must be a multi-instance object.

The newly added instance will become the currently selected object.

Parameters
transpointer to a transaction object
indexthe index for the instance, no other instance should exist with this index, or 0 to automatically assing an index
namename of the instance or NULL. If the multi-instance object contains a "Alias" parameter the name is stored in that parameter. No other instance of the selected multi-instance object should have the same name. When no names need to be set, use a NULL pointer for this argument
Returns
amxd_status_ok when the instance add atcion is added to the transaction.

Definition at line 738 of file amxd_transaction.c.

740  {
742  amxd_trans_action_t* action = NULL;
743 
744  when_null(trans, exit);
745 
747  when_null(action, exit);
748 
749  when_null(amxc_var_add_key(bool,
750  &action->data,
751  "set_read_only",
752  trans->attr.read_only == 1),
753  exit);
754  when_null(amxc_var_add_key(uint32_t,
755  &action->data,
756  "access",
757  trans->access),
758  exit);
759  when_null(amxc_var_add_key(uint32_t, &action->data, "index", index),
760  exit);
761  when_null(amxc_var_add_key(cstring_t,
762  &action->data,
763  "name",
764  name == NULL ? "" : name),
765  exit);
766 
768 
769 exit:
770  if(trans != NULL) {
771  trans->status = status;
772  }
773  return status;
774 }
amxd_dm_access_t access
amxd_trans_attr_t attr

◆ amxd_trans_apply()

amxd_status_t amxd_trans_apply ( amxd_trans_t *const  trans,
amxd_dm_t *const  dm 
)

Applies all previously added actions.

Executes all actions of the transaction in the order the actions were added. During execution, a reverse transaction is created. Whenever the execution of one of the actions fail, the reverse transaction is executed to restore the original state.

Either all actions of a transaction are applied, or none.

When the transaction succeeds (all actions executed) the transaction will send events for all changed/adds/deletes done.

Parameters
transpointer to a transaction object
dmthe data model the transaction needs to be applied on
Returns
amxd_status_ok when the all actions are applied, otherwise an other error code and no changes in the data model are done.

Definition at line 841 of file amxd_transaction.c.

842  {
843  static bool trans_buzy = false;
845  amxd_trans_t rollback;
846 
847  amxd_trans_init(&rollback);
848  when_true(trans_buzy, exit);
849  when_null(trans, exit);
850  when_null(dm, exit);
851  when_failed_status(trans->status, exit, status = trans->status);
852  trans_buzy = true;
853  trans->fail_index = 0;
854  amxc_var_clean(&trans->retvals);
855  amxc_var_set_type(&trans->retvals, AMXC_VAR_ID_LIST);
856  amxc_llist_for_each(it, (&trans->actions)) {
857  amxd_trans_action_t* action =
858  amxc_llist_it_get_data(it, amxd_trans_action_t, it);
859  status = amxd_trans_invoke_action(trans, dm, action, &rollback);
860  when_failed(status, exit);
861  trans->fail_index++;
862  }
864 
865 exit:
866  if(trans != NULL) {
867  trans->status = status;
868  if(status != amxd_status_ok) {
869  amxd_trans_select_object(&rollback, trans->current);
870  amxd_trans_revert(&rollback, dm);
871  amxc_llist_clean(&trans->garbage, amxc_string_list_it_free);
872  trans->current = NULL;
873  } else {
874  amxc_llist_clean(&trans->actions, amxd_trans_free_action_it);
875  }
876  amxd_trans_clean(&rollback);
877  }
878  trans_buzy = false;
879  return status;
880 }
#define when_failed_status(x, l, c)
Definition: amxd_assert.h:65
static void amxd_trans_free_action_it(amxc_llist_it_t *it)
static amxd_status_t amxd_trans_validate_objects(amxd_trans_t *trans, amxd_dm_t *dm)
static void amxd_trans_revert(amxd_trans_t *trans, amxd_dm_t *dm)
static amxd_status_t amxd_trans_invoke_action(amxd_trans_t *trans, amxd_dm_t *dm, amxd_trans_action_t *action, amxd_trans_t *rollback)
void amxd_trans_clean(amxd_trans_t *const trans)
Cleans the transaction object.
amxd_status_t amxd_trans_select_object(amxd_trans_t *const trans, const amxd_object_t *const object)
Selects an object using an object pointer.
amxd_status_t amxd_trans_init(amxd_trans_t *const trans)
Initializes a transaction object.
amxd_object_t * current
amxc_llist_t actions
amxc_llist_t garbage
static amxd_dm_t dm

◆ amxd_trans_clean()

void amxd_trans_clean ( amxd_trans_t *const  trans)

Cleans the transaction object.

After cleaning the transaction obnject, it is ready to be re-used.

This function will reset all internal bookkeeping objects, but keeps the current selected object and the transaction attributes

Parameters
transpointer to a transaction object

Definition at line 529 of file amxd_transaction.c.

529  {
530  when_null(trans, exit);
531 
532  amxc_llist_clean(&trans->actions, amxd_trans_free_action_it);
533  amxc_llist_clean(&trans->garbage, amxc_string_list_it_free);
534  amxc_llist_clean(&trans->validate, amxd_trans_free_validate_it);
535  amxc_var_clean(&trans->retvals);
536 
537  trans->status = amxd_status_ok;
538  trans->fail_index = -1;
539 
540 exit:
541  return;
542 }
static void amxd_trans_free_validate_it(amxc_llist_it_t *it)
amxc_llist_t validate

◆ amxd_trans_del_inst()

amxd_status_t amxd_trans_del_inst ( amxd_trans_t *const  trans,
const uint32_t  index,
const char *  name 
)

Adds an instance delete action to a transaction.

The instance delete action works on the currently selected object. The currently selected object must be a multi-instance object.

The deleted instance is selected by index or by name. When both are specified, the index takes precedence over the name. At least one of them should be specified.

The transaction will fail if no instance is found with the index or name specified.

Note
The instance is added to the garbage collector and is really deleted when all actions of the transaction are applied successful. The reason for this implementation is that it would otherwise not be possible to rollback the executed actions when on failure.
Parameters
transpointer to a transaction object
indexthe index for the instance that will be deleted or 0
namename of the instance that will be deleted or NULL.
Returns
amxd_status_ok when the instance add atcion is added to the transaction.

Definition at line 776 of file amxd_transaction.c.

778  {
780  amxd_trans_action_t* action = NULL;
781 
782  when_null(trans, exit);
783 
785  when_null(action, exit);
786  when_true((index == 0 && (name == NULL || *name == 0)), exit);
787 
788  when_null(amxc_var_add_key(bool,
789  &action->data,
790  "set_read_only",
791  trans->attr.read_only == 1),
792  exit);
793  when_null(amxc_var_add_key(uint32_t,
794  &action->data,
795  "access",
796  trans->access),
797  exit);
798  when_null(amxc_var_add_key(uint32_t, &action->data, "index", index),
799  exit);
800  when_null(amxc_var_add_key(cstring_t,
801  &action->data,
802  "name",
803  name == NULL ? "" : name),
804  exit);
805 
807 
808 exit:
809  if(trans != NULL) {
810  trans->status = status;
811  }
812  return status;
813 }

◆ amxd_trans_delete()

void amxd_trans_delete ( amxd_trans_t **  trans)

Frees the memory previously allocated for a transaction object.

First calls amxd_trans_clean and then frees the memory allocated for the transaction object.

Note
Only call this function on transaction objects previously allocated with amxd_trans_new
Parameters
transpointer to pointer to a transaction object

Definition at line 557 of file amxd_transaction.c.

557  {
558  when_null(trans, exit);
559  when_null((*trans), exit);
560 
561  amxd_trans_clean(*trans);
562 
563  free(*trans);
564  *trans = NULL;
565 
566 exit:
567  return;
568 }

◆ amxd_trans_dump()

void amxd_trans_dump ( const amxd_trans_t *const  trans,
const int  fd,
const bool  reverse 
)

Dumps the transaction to a file descriptor.

Dumps in human readable text format all actions of a transaction in the order the actions were added.

This function can be used for debugging purposes.

Parameters
transpointer to a transaction object
fda valid file descriptor
reversewhen set to true, dumps the action in reverse order

Definition at line 882 of file amxd_transaction.c.

884  {
885  if(reverse) {
886  amxc_llist_for_each_reverse(it, (&trans->actions)) {
887  amxd_trans_action_t* action =
888  amxc_llist_it_get_data(it, amxd_trans_action_t, it);
889  amxd_trans_dump_action(action, fd);
890  }
891  } else {
892  amxc_llist_for_each(it, (&trans->actions)) {
893  amxd_trans_action_t* action =
894  amxc_llist_it_get_data(it, amxd_trans_action_t, it);
895  amxd_trans_dump_action(action, fd);
896  }
897  }
898 }
static void amxd_trans_dump_action(amxd_trans_action_t *action, int fd)

◆ amxd_trans_init()

amxd_status_t amxd_trans_init ( amxd_trans_t *const  trans)

Initializes a transaction object.

Sets the internal transaction fields to a default value:

  • Sets current object to NULL
  • Transaction can not change read-only parameters
  • The transaction can change public and protected parameters
  • Initializes internal bookkeeping objects (garbage collection, rollback info, ...)
Parameters
transpointer to a transaction object
Returns
amxd_status_ok if the transaction object is correctly initialized.

Definition at line 507 of file amxd_transaction.c.

507  {
509  when_null(trans, exit);
510 
511  amxc_llist_init(&trans->actions);
512  amxc_llist_init(&trans->garbage);
513  amxc_llist_init(&trans->validate);
514  amxc_var_init(&trans->retvals);
515  amxc_var_set_type(&trans->retvals, AMXC_VAR_ID_LIST);
516 
517  trans->current = NULL;
518  trans->status = amxd_status_ok;
519  trans->fail_index = -1;
520  trans->attr.read_only = 0;
522 
524 
525 exit:
526  return status;
527 }
@ amxd_dm_access_protected
Definition: amxd_types.h:139

◆ amxd_trans_new()

amxd_status_t amxd_trans_new ( amxd_trans_t **  trans)

Allocates a transaction object on the heap and initializes it.

Allocates memory for a transaction object and then calls amxd_trans_init

Note
A transaction object allocated on the heap must be freed using amxd_trans_delete
Parameters
transpointer to pointer to a transaction object
Returns
amxd_status_ok if the transaction object is allocated and correctly initialized.

Definition at line 544 of file amxd_transaction.c.

544  {
546  when_null(trans, exit);
547 
548  *trans = (amxd_trans_t*) calloc(1, sizeof(amxd_trans_t));
549  when_null((*trans), exit);
550 
551  status = amxd_trans_init(*trans);
552 
553 exit:
554  return status;
555 }

◆ amxd_trans_select_object()

amxd_status_t amxd_status_t amxd_trans_select_object ( amxd_trans_t trans,
const amxd_object_t *const  object 
)

Selects an object using an object pointer.

Selects an object on which the next actions must be applied.

The path of the object is stored in the select action, not the object itself.

Parameters
transpointer to a transaction object
objectpointer to an object in the data model
Returns
amxd_status_ok when the select atcion is added to the transaction.

Definition at line 666 of file amxd_transaction.c.

667  {
669  char* full_path = NULL;
670  amxd_trans_action_t* action = NULL;
671 
672  when_null(trans, exit);
673 
675  action = amxd_trans_new_action(trans, action_any);
676  when_null(action, exit);
677  when_null(amxc_var_add_key(cstring_t,
678  &action->data,
679  "path",
680  full_path),
681  exit);
682 
683  when_null(object, exit);
684 
686 
687 exit:
688  if(trans != NULL) {
689  trans->status = status;
690  }
691  free(full_path);
692  return status;
693 }
#define AMXD_OBJECT_INDEXED
Name and path format flag - use index for instance objects.
Definition: amxd_object.h:176
#define AMXD_OBJECT_TERMINATE
Path format flag - when set the object path is terminated with a dot.
Definition: amxd_object.h:214
amxd_object_t amxd_status_t amxd_status_t char * amxd_object_get_path(const amxd_object_t *object, const uint32_t flags)
Get the full path of the object.

◆ amxd_trans_select_pathf()

amxd_status_t amxd_trans_select_pathf ( amxd_trans_t *const  trans,
const char *  path,
  ... 
)

Selects an object using a absolute or relative path.

Selects an object on which the next actions must be applied. The object is selected using a path. This path can be absolute or relative.

A relative path must start with a '.' and is relative to the currently selected object in the transaction.

The path may be a search path. The search path must only return one object.

This function supports printf formatting.

To go up in the hierarchy of objects, relative from the current object the symbol '^' can be used.

Parameters
transpointer to a transaction object
pathrelative or abosule path, can be a search path
Returns
amxd_status_ok when the select atcion is added to the transaction.

◆ amxd_trans_set_attr()

amxd_status_t amxd_trans_set_attr ( amxd_trans_t trans,
amxd_tattr_id_t  attr,
bool  enable 
)

Set the transaction attributes.

Using the transaction attributes it is possible to change the behavior of a transaction.

By default a transaction can not change or update read-only parameters or objects and only works on public or protected parameters and objects.

The following attributes can be set:

Note
Parameters
transpointer to a transaction object
attrone of amxd_tattr_id_t
enableenable or disables the attrivbute
Returns
amxd_status_ok if the attribute is set or unset.

Definition at line 570 of file amxd_transaction.c.

572  {
574  when_null(trans, exit);
575 
576  switch(attr) {
578  trans->attr.read_only = enable;
579  break;
581  trans->access = amxd_dm_access_public;
582  break;
585  break;
588  break;
589  }
590 
591  retval = amxd_status_ok;
592 
593 exit:
594  return retval;
595 }
@ amxd_dm_access_private
Definition: amxd_types.h:141
@ amxd_dm_access_public
Definition: amxd_types.h:136

◆ amxd_trans_set_param()

amxd_status_t amxd_trans_set_param ( amxd_trans_t *const  trans,
const char *  param_name,
amxc_var_t *const  value 
)

Adds a set value action to a transaction.

The set action works on the currently selected object.

When mutiple set actions are added to the transaction in sequence, the transaction will combine these as one write action on the selected object.

Parameters
transpointer to a transaction object
param_namename of the parameter
valuethe new value
Returns
amxd_status_ok when the set atcion is added to the transaction.

Definition at line 695 of file amxd_transaction.c.

697  {
699  amxd_trans_action_t* action = NULL;
700  amxc_var_t* params = NULL;
701 
702  when_null(trans, exit);
703  when_str_empty(param_name, exit);
704  when_null(value, exit);
705 
706  action = amxd_trans_find_write_action(trans);
707  if(action == NULL) {
709  when_null(action, exit);
710  when_null(amxc_var_add_key(bool, &action->data, "set_read_only",
711  trans->attr.read_only == 1),
712  exit);
713  when_null(amxc_var_add_key(uint32_t, &action->data, "access", trans->access),
714  exit);
715  }
716 
717  params = amxc_var_get_key(&action->data, "parameters",
718  AMXC_VAR_FLAG_DEFAULT);
719  if(params == NULL) {
720  params = amxc_var_add_key(amxc_htable_t, (&action->data), "parameters",
721  NULL);
722  when_null(params, exit);
723  }
724 
725  when_failed(amxc_var_set_key(params, param_name, value,
726  AMXC_VAR_FLAG_UPDATE | AMXC_VAR_FLAG_COPY),
727  exit);
728 
730 
731 exit:
732  if(trans != NULL) {
733  trans->status = status;
734  }
735  return status;
736 }
static amxd_trans_action_t * amxd_trans_find_write_action(amxd_trans_t *trans)