[asterisk-commits] file: branch file/sorcery r380041 - in /team/file/sorcery: include/asterisk/ ...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Thu Jan 24 08:24:39 CST 2013
Author: file
Date: Thu Jan 24 08:24:34 2013
New Revision: 380041
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=380041
Log:
Incorporate review feedback.
Modified:
team/file/sorcery/include/asterisk/sorcery.h
team/file/sorcery/main/sorcery.c
team/file/sorcery/res/res_sorcery_config.c
team/file/sorcery/res/res_sorcery_memory.c
team/file/sorcery/tests/test_sorcery.c
Modified: team/file/sorcery/include/asterisk/sorcery.h
URL: http://svnview.digium.com/svn/asterisk/team/file/sorcery/include/asterisk/sorcery.h?view=diff&rev=380041&r1=380040&r2=380041
==============================================================================
--- team/file/sorcery/include/asterisk/sorcery.h (original)
+++ team/file/sorcery/include/asterisk/sorcery.h Thu Jan 24 08:24:34 2013
@@ -33,55 +33,60 @@
* Usage of sorcery is accomplished by first opening a sorcery structure. This structure holds
* all information about the object types, object fields, and object mappings. All API functions
* require the sorcery structure to operate. When sorcery is no longer needed the structure can
- * be unreferenced using ast_sorcery_unref.
+ * be unreferenced using \ref ast_sorcery_unref
*
* Once opened the sorcery structure must have object mappings applied to it. This maps the
* object types to their respective wizards (object storage modules). If the developer would like
* to allow the user to configure this using the sorcery.conf configuration file the
- * ast_sorcery_apply_config API call can be used to read in the configuration file and apply the
+ * \ref ast_sorcery_apply_config API call can be used to read in the configuration file and apply the
* mappings. If the storage of the object types are such that a default wizard can be used this can
- * be applied using the ast_sorcery_apply_default API call. Note that the default mappings will not
+ * be applied using the \ref ast_sorcery_apply_default API call. Note that the default mappings will not
* override configured mappings. They are only used in the case where no configured mapping exists.
*
- * Configuring object mappings implicitly create a basic version of an object type. The object type
- * must be fully registered, however, using the ast_sorcery_object_type_register API call before any
+ * Configuring object mappings implicitly creates a basic version of an object type. The object type
+ * must be fully registered, however, using the \ref ast_sorcery_object_type_register API call before any
* objects of the type can be allocated, created, or retrieved.
*
* Once the object type itself has been fully registered the individual fields within the object must
- * be registered using the ast_sorcery_object_field_register API call. Note that not all fields *need*
+ * be registered using the \ref ast_sorcery_object_field_register API call. Note that not all fields *need*
* be registered. Only fields that should be accessible using the sorcery API have to be registered.
*
* \par Creating Objects
*
* Before an object can be created within the sorcery API it must first be allocated using the
- * ast_sorcery_alloc API call. This allocates a new instance of the object, sets sorcery specific
+ * \ref ast_sorcery_alloc API call. This allocates a new instance of the object, sets sorcery specific
* details, and applies default values to the object. A unique identifier can optionally be specified
* when allocating an object. If it is not provided one will be automatically generated. Allocating
* an object does not create it within any object storage mechanisms that are configured for the
- * object type. Creation must explicitly be done using the ast_sorcery_create API call. This API call
+ * object type. Creation must explicitly be done using the \ref ast_sorcery_create API call. This API call
* passes the object to each configured object storage mechanism for the object type until one
* successfully persists the object.
*
* \par Retrieving Objects
*
- * Object retrieval is accomplished using the ast_sorcery_retrieve API call. Objects themselves can be
- * retrieved using either the unique identifier OR by specifying specific fields within the object and the
- * respective values to look for. If the criteria given could result in multiple objects being returned the
- * AST_RETRIEVE_FLAG_MULTIPLE flag can be enabled which returns all objects in an astobj2 container. Note
- * that the returned object(s) should *NOT* be modified as they may be shared.
+ * To retrieve a single object using its unique identifier the \ref ast_sorcery_retrieve_by_id API call
+ * can be used.
+ *
+ * To retrieve potentially multiple objects using specific fields the \ref ast_sorcery_retrieve_by_fields
+ * API call can be used. The behavior of this API call is controlled using different flags. If the
+ * AST_RETRIEVE_FLAG_MULTIPLE flag is used a container will be returned which contains all matching objects.
+ * To retrieve all objects the AST_RETRIEVE_FLAG_ALL flag can be specified. Note that when specifying this flag
+ * you do not need to pass any fields.
+ *
+ * Both API calls return shared objects. Modification of the object can not occur until it has been copied.
*
* \par Updating Objects
*
* As retrieved objects may be shared the first step to updating the object with new details is creating a
- * copy using the ast_sorcery_copy API call. This will return a new object which is specific to the caller.
+ * copy using the \ref ast_sorcery_copy API call. This will return a new object which is specific to the caller.
* Any field within the object may be modified as needed. Once changes are done the changes can be committed
- * using the ast_sorcery_update API call. Note that as the copied object is specific to the caller it must
+ * using the \ref ast_sorcery_update API call. Note that as the copied object is specific to the caller it must
* be unreferenced after use.
*
* \par Deleting Objects
*
- * To delete an object simply call the ast_sorcery_delete API call with an object retrieved using the
- * ast_sorcery_retrieve API call or a copy returned from ast_sorcery_copy.
+ * To delete an object simply call the \ref ast_sorcery_delete API call with an object retrieved using the
+ * ast_sorcery_retrieve_by_* API calls or a copy returned from \ref ast_sorcery_copy.
*/
#ifndef _ASTERISK_SORCERY_H
@@ -111,20 +116,6 @@
AST_RETRIEVE_FLAG_ALL = (1 << 1),
};
-/*!
- * \brief Retrieval parameters
- */
-enum ast_sorcery_retrieve_params {
- /*! \brief Object identifier */
- AST_RETRIEVE_PARAM_ID = 0,
-
- /*! \brief Object field */
- AST_RETRIEVE_PARAM_FIELD,
-
- /*! \brief End of retrieval parameters */
- AST_RETRIEVE_PARAM_END,
-};
-
/*! \brief Forward declaration for the sorcery main structure */
struct ast_sorcery;
@@ -133,13 +124,12 @@
*
* \param obj Object to get value from
* \param args Where the field is
- * \param buf Buffer to place string into
- * \param len Size of the buffer
- *
- * \retval 0 success
- * \retval -1 failure
- */
-typedef int (*sorcery_field_handler)(const void *obj, const intptr_t *args, char *buf, size_t len);
+ * \param buf Pointer to the buffer that the handler has created which contains the field value
+ *
+ * \retval 0 success
+ * \retval -1 failure
+ */
+typedef int (*sorcery_field_handler)(const void *obj, const intptr_t *args, char **buf);
/*!
* \brief A callback function for performing a transformation on an object set
@@ -402,13 +392,14 @@
*
* \param original Original object set
* \param modified Modified object set
- *
- * \retval non-NULL if any changes are present
- * \retval NULL if no changes exist
+ * \param changes Pointer to hold any changes between the object sets
+ *
+ * \retval 0 success
+ * \retval -1 failure
*
* \note The returned ast_variable list must be destroyed using ast_variables_destroy
*/
-struct ast_variable *ast_sorcery_changeset_create(const struct ast_variable *original, const struct ast_variable *modified);
+int ast_sorcery_changeset_create(const struct ast_variable *original, const struct ast_variable *modified, struct ast_variable **changes);
/*!
* \brief Allocate an object
@@ -439,15 +430,16 @@
* \param sorcery Pointer to a sorcery structure
* \param original Original object
* \param modified Modified object
- *
- * \retval non-NULL differences exist
- * \retval NULL no differences exist
+ * \param changes Pointer which will be populated with changes if any exist
+ *
+ * \retval 0 success
+ * \retval -1 failure
*
* \note The returned ast_variable list must be destroyed using ast_variables_destroy
*
* \note While the objects must be of the same type they do not have to be the same object
*/
- struct ast_variable *ast_sorcery_diff(const struct ast_sorcery *sorcery, const void *original, const void *modified);
+int ast_sorcery_diff(const struct ast_sorcery *sorcery, const void *original, const void *modified, struct ast_variable **changes);
/*!
* \brief Create and potentially persist an object using an available wizard
@@ -461,22 +453,35 @@
int ast_sorcery_create(const struct ast_sorcery *sorcery, void *object);
/*!
- * \brief Retrieve an object or multiple objects
+ * \brief Retrieve an object using its unique identifier
+ *
+ * \param sorcery Pointer to a sorcery structure
+ * \param type Type of object to retrieve
+ * \param id Unique object identifier
+ *
+ * \retval non-NULL if found
+ * \retval NULL if not found
+ */
+void *ast_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id);
+
+/*!
+ * \brief Retrieve an object or multiple objects using specific fields
*
* \param sorcery Pointer to a sorcery structure
* \param type Type of object to retrieve
* \param flags Flags to control behavior
- * \param params Parameters to dictate search
+ * \param fields Optional jbject fields and values to match against
*
* \retval non-NULL if found
* \retval NULL if not found
*
- * \note The parameters must end with AST_RETRIEVE_PARAM_END
- *
* \note If the AST_RETRIEVE_FLAG_MULTIPLE flag is specified the returned value will be an
* ao2_container that must be unreferenced after use.
- */
-void *ast_sorcery_retrieve(const struct ast_sorcery *sorcery, const char *type, unsigned int flags, ...);
+ *
+ * \note If the AST_RETRIEVE_FLAG_ALL flag is used you may omit fields to retrieve all objects
+ * of the given type.
+ */
+void *ast_sorcery_retrieve_by_fields(const struct ast_sorcery *sorcery, const char *type, unsigned int flags, struct ast_variable *fields);
/*!
* \brief Update an object
Modified: team/file/sorcery/main/sorcery.c
URL: http://svnview.digium.com/svn/asterisk/team/file/sorcery/main/sorcery.c?view=diff&rev=380041&r1=380040&r2=380041
==============================================================================
--- team/file/sorcery/main/sorcery.c (original)
+++ team/file/sorcery/main/sorcery.c Thu Jan 24 08:24:34 2013
@@ -39,10 +39,10 @@
#include "asterisk/netsock2.h"
#include "asterisk/module.h"
-/*! \brief Number of buckets for wizards */
+/*! \brief Number of buckets for wizards (should be prime for performance reasons) */
#define WIZARD_BUCKETS 7
-/*! \brief Number of buckets for types */
+/*! \brief Number of buckets for types (should be prime for performance reasons) */
#define TYPE_BUCKETS 53
/*! \brief Maximum length of an object field name */
@@ -84,7 +84,7 @@
sorcery_field_handler handler;
/*! \brief Position of the field */
- intptr_t args[0];
+ intptr_t args[];
};
/*! \brief Structure for a wizard instance which operates on objects */
@@ -120,57 +120,66 @@
/*! \brief Registered sorcery wizards */
struct ao2_container *wizards;
-static int int_handler_fn(const void *obj, const intptr_t *args, char *buf, size_t len)
+static int int_handler_fn(const void *obj, const intptr_t *args, char **buf)
{
int *field = (int *)(obj + args[0]);
- snprintf(buf, len, "%d", *field);
- return 0;
-}
-
-static int uint_handler_fn(const void *obj, const intptr_t *args, char *buf, size_t len)
+ char value[256];
+
+ snprintf(value, sizeof(value), "%d", *field);
+ *buf = ast_strdup(value);
+ return 0;
+}
+
+static int uint_handler_fn(const void *obj, const intptr_t *args, char **buf)
{
unsigned int *field = (unsigned int *)(obj + args[0]);
- snprintf(buf, len, "%u", *field);
- return 0;
-}
-
-static int double_handler_fn(const void *obj, const intptr_t *args, char *buf, size_t len)
+ char value[256];
+
+ snprintf(value, sizeof(value), "%u", *field);
+ *buf = ast_strdup(value);
+ return 0;
+}
+
+static int double_handler_fn(const void *obj, const intptr_t *args, char **buf)
{
double *field = (double *)(obj + args[0]);
- snprintf(buf, len, "%f", *field);
- return 0;
-}
-
-static int stringfield_handler_fn(const void *obj, const intptr_t *args, char *buf, size_t len)
+ char value[256];
+
+ snprintf(value, sizeof(value), "%f", *field);
+ *buf = ast_strdup(value);
+ return 0;
+}
+
+static int stringfield_handler_fn(const void *obj, const intptr_t *args, char **buf)
{
ast_string_field *field = (const char **)(obj + args[0]);
- ast_copy_string(buf, *field, len);
- return 0;
-}
-
-static int bool_handler_fn(const void *obj, const intptr_t *args, char *buf, size_t len)
+ *buf = ast_strdup(*field);
+ return 0;
+}
+
+static int bool_handler_fn(const void *obj, const intptr_t *args, char **buf)
{
unsigned int *field = (unsigned int *)(obj + args[0]);
- snprintf(buf, len, *field ? "true" : "false");
- return 0;
-}
-
-static int sockaddr_handler_fn(const void *obj, const intptr_t *args, char *buf, size_t len)
+ *buf = ast_strdup(*field ? "true" : "false");
+ return 0;
+}
+
+static int sockaddr_handler_fn(const void *obj, const intptr_t *args, char **buf)
{
struct ast_sockaddr *field = (struct ast_sockaddr *)(obj + args[0]);
- snprintf(buf, len, "%s", ast_sockaddr_stringify(field));
- return 0;
-}
-
-static int noop_handler_fn(const void *obj, const intptr_t *args, char *buf, size_t len)
-{
- return 0;
-}
-
-static int chararray_handler_fn(const void *obj, const intptr_t *args, char *buf, size_t len)
+ *buf = ast_strdup(ast_sockaddr_stringify(field));
+ return 0;
+}
+
+static int noop_handler_fn(const void *obj, const intptr_t *args, char **buf)
+{
+ return 0;
+}
+
+static int chararray_handler_fn(const void *obj, const intptr_t *args, char **buf)
{
char *field = (char *)(obj + args[0]);
- ast_copy_string(buf, field, len);
+ *buf = ast_strdup(field);
return 0;
}
@@ -213,6 +222,8 @@
int ast_sorcery_init(void)
{
+ ast_assert(wizards == NULL);
+
if (!(wizards = ao2_container_alloc(WIZARD_BUCKETS, sorcery_wizard_hash, sorcery_wizard_cmp))) {
return -1;
}
@@ -534,6 +545,8 @@
} else if (argc == 3) {
__aco_option_register(object_type->info, name, ACO_EXACT, object_type->file->types, default_val, opt_type, config_handler, flags, argc,
va_arg(args, size_t), va_arg(args, size_t), va_arg(args, size_t));
+ } else {
+ ast_assert(0); /* The hack... she does us no good for this */
}
va_end(args);
@@ -607,7 +620,7 @@
i = ao2_iterator_init(object_type->fields, 0);
for (; (object_field = ao2_iterator_next(&i)); ao2_ref(object_field, -1)) {
- char buf[512];
+ RAII_VAR(char *, buf, NULL, ast_free);
struct ast_variable *tmp;
/* Any fields with no handler just get skipped */
@@ -615,8 +628,8 @@
continue;
}
- if ((res = object_field->handler(object, object_field->args, buf, sizeof(buf))) ||
- !(tmp = ast_variable_new(object_field->name, buf, ""))) {
+ if ((res = object_field->handler(object, object_field->args, &buf)) ||
+ !(tmp = ast_variable_new(object_field->name, S_OR(buf, ""), ""))) {
res = -1;
ao2_ref(object_field, -1);
break;
@@ -682,15 +695,16 @@
return NULL;
}
-struct ast_variable *ast_sorcery_changeset_create(const struct ast_variable *original, const struct ast_variable *modified)
+int ast_sorcery_changeset_create(const struct ast_variable *original, const struct ast_variable *modified, struct ast_variable **changes)
{
const struct ast_variable *field;
- struct ast_variable *changes = NULL;
int res = 0;
+
+ *changes = NULL;
/* Unless the ast_variable list changes when examined... it can't differ from itself */
if (original == modified) {
- return NULL;
+ return 0;
}
for (field = modified; field; field = field->next) {
@@ -704,18 +718,18 @@
break;
}
- tmp->next = changes;
- changes = tmp;
+ tmp->next = *changes;
+ *changes = tmp;
}
}
/* If an error occurred do not return a partial changeset */
if (res) {
- ast_variables_destroy(changes);
- changes = NULL;
- }
-
- return changes;
+ ast_variables_destroy(*changes);
+ *changes = NULL;
+ }
+
+ return res;
}
void *ast_sorcery_alloc(const struct ast_sorcery *sorcery, const char *type, const char *id)
@@ -768,19 +782,21 @@
return copy;
}
-struct ast_variable *ast_sorcery_diff(const struct ast_sorcery *sorcery, const void *original, const void *modified)
+int ast_sorcery_diff(const struct ast_sorcery *sorcery, const void *original, const void *modified, struct ast_variable **changes)
{
RAII_VAR(struct ast_variable *, objectset1, NULL, ast_variables_destroy);
RAII_VAR(struct ast_variable *, objectset2, NULL, ast_variables_destroy);
+ *changes = NULL;
+
if (strcmp(ast_sorcery_object_get_type(original), ast_sorcery_object_get_type(modified))) {
- return NULL;
+ return -1;
}
objectset1 = ast_sorcery_objectset_create(sorcery, original);
objectset2 = ast_sorcery_objectset_create(sorcery, modified);
- return ast_sorcery_changeset_create(objectset1, objectset2);
+ return ast_sorcery_changeset_create(objectset1, objectset2, changes);
}
/*! \brief Internal function used to create an object in caching wizards */
@@ -797,47 +813,48 @@
return 0;
}
-void *ast_sorcery_retrieve(const struct ast_sorcery *sorcery, const char *type, unsigned int flags, ...)
+void *ast_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id)
{
RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, type, OBJ_KEY), ao2_cleanup);
- RAII_VAR(struct ast_variable *, fields, NULL, ast_variables_destroy);
- va_list args;
- enum ast_sorcery_retrieve_params param;
- const char *id = NULL;
void *object = NULL;
struct ao2_iterator i;
struct ast_sorcery_object_wizard *wizard;
unsigned int cached = 0;
+ if (!object_type || ast_strlen_zero(id)) {
+ return NULL;
+ }
+
+ i = ao2_iterator_init(object_type->wizards, 0);
+ for (; (wizard = ao2_iterator_next(&i)); ao2_ref(wizard, -1)) {
+ if (wizard->wizard->retrieve_id &&
+ !(object = wizard->wizard->retrieve_id(sorcery, wizard->data, object_type->name, id))) {
+ continue;
+ }
+
+ cached = wizard->caching;
+
+ ao2_ref(wizard, -1);
+ break;
+ }
+ ao2_iterator_destroy(&i);
+
+ if (!cached && object) {
+ ao2_callback(object_type->wizards, 0, sorcery_cache_create, object);
+ }
+
+ return object;
+}
+
+void *ast_sorcery_retrieve_by_fields(const struct ast_sorcery *sorcery, const char *type, unsigned int flags, struct ast_variable *fields)
+{
+ RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, type, OBJ_KEY), ao2_cleanup);
+ void *object = NULL;
+ struct ao2_iterator i;
+ struct ast_sorcery_object_wizard *wizard;
+ unsigned int cached = 0;
+
if (!object_type) {
- return NULL;
- }
-
- va_start(args, flags);
- for (param = va_arg(args, enum ast_sorcery_retrieve_params);
- param != AST_RETRIEVE_PARAM_END;
- param = va_arg(args, enum ast_sorcery_retrieve_params)) {
- if (param == AST_RETRIEVE_PARAM_ID && !id) {
- id = va_arg(args, const char *);
- } else if (param == AST_RETRIEVE_PARAM_FIELD) {
- const char *name = va_arg(args, const char *), *value = va_arg(args, const char *);
- struct ast_variable *tmp;
-
- if (!(tmp = ast_variable_new(name, value, ""))) {
- return NULL;
- }
-
- tmp->next = fields;
- fields = tmp;
- } else {
- /* If they pass an unsupported parameter type this operation *will* fail */
- return NULL;
- }
- }
- va_end(args);
-
- /* Uh... if no parameters are there we obviously can't do anything */
- if (ast_strlen_zero(id) && !fields && (!(flags & AST_RETRIEVE_FLAG_MULTIPLE) || !(flags & AST_RETRIEVE_FLAG_ALL))) {
return NULL;
}
@@ -855,10 +872,6 @@
if (wizard->wizard->retrieve_multiple) {
wizard->wizard->retrieve_multiple(sorcery, wizard->data, object_type->name, object, fields);
}
- } else if (!ast_strlen_zero(id)) {
- if (wizard->wizard->retrieve_id) {
- object = wizard->wizard->retrieve_id(sorcery, wizard->data, object_type->name, id);
- }
} else if (fields && wizard->wizard->retrieve_fields) {
if (wizard->wizard->retrieve_fields) {
object = wizard->wizard->retrieve_fields(sorcery, wizard->data, object_type->name, fields);
Modified: team/file/sorcery/res/res_sorcery_config.c
URL: http://svnview.digium.com/svn/asterisk/team/file/sorcery/res/res_sorcery_config.c?view=diff&rev=380041&r1=380040&r2=380041
==============================================================================
--- team/file/sorcery/res/res_sorcery_config.c (original)
+++ team/file/sorcery/res/res_sorcery_config.c Thu Jan 24 08:24:34 2013
@@ -127,7 +127,8 @@
*/
if (params->fields &&
(!(objset = ast_sorcery_objectset_create(params->sorcery, obj)) ||
- (diff = ast_sorcery_changeset_create(objset, params->fields)))) {
+ (ast_sorcery_changeset_create(objset, params->fields, &diff)) ||
+ diff)) {
return 0;
}
@@ -190,7 +191,7 @@
{
RAII_VAR(struct ast_variable *, diff, NULL, ast_variables_destroy);
- return (!criteria || !(diff = ast_sorcery_changeset_create(objset, criteria))) ? 1 : 0;
+ return (!criteria || (!ast_sorcery_changeset_create(objset, criteria, &diff) && !diff)) ? 1 : 0;
}
static void sorcery_config_internal_load(void *data, const struct ast_sorcery *sorcery, const char *type, unsigned int reload)
@@ -210,14 +211,12 @@
} else if (cfg == CONFIG_STATUS_FILEINVALID) {
ast_log(LOG_ERROR, "Contents of config file '%s' are invalid and cannot be parsed\n", config->filename);
return;
- } else if (cfg == CONFIG_STATUS_FILEMISSING) {
- ast_log(LOG_ERROR, "Config file '%s' is missing\n", config->filename);
- return;
}
if (!(objects = ao2_container_alloc(config->buckets, sorcery_config_hash, sorcery_config_cmp))) {
ast_log(LOG_ERROR, "Could not create bucket for new objects from '%s', keeping existing objects\n",
config->filename);
+ ast_config_destroy(cfg);
return;
}
Modified: team/file/sorcery/res/res_sorcery_memory.c
URL: http://svnview.digium.com/svn/asterisk/team/file/sorcery/res/res_sorcery_memory.c?view=diff&rev=380041&r1=380040&r2=380041
==============================================================================
--- team/file/sorcery/res/res_sorcery_memory.c (original)
+++ team/file/sorcery/res/res_sorcery_memory.c Thu Jan 24 08:24:34 2013
@@ -106,7 +106,8 @@
*/
if (params->fields &&
(!(objset = ast_sorcery_objectset_create(params->sorcery, obj)) ||
- (diff = ast_sorcery_changeset_create(objset, params->fields)))) {
+ (ast_sorcery_changeset_create(objset, params->fields, &diff)) ||
+ diff)) {
return 0;
}
Modified: team/file/sorcery/tests/test_sorcery.c
URL: http://svnview.digium.com/svn/asterisk/team/file/sorcery/tests/test_sorcery.c?view=diff&rev=380041&r1=380040&r2=380041
==============================================================================
--- team/file/sorcery/tests/test_sorcery.c (original)
+++ team/file/sorcery/tests/test_sorcery.c Thu Jan 24 08:24:34 2013
@@ -577,7 +577,9 @@
obj2->bob = 99;
obj2->joe = 42;
- if (!(changes = ast_sorcery_diff(sorcery, obj1, obj2))) {
+ if (ast_sorcery_diff(sorcery, obj1, obj2, &changes)) {
+ ast_test_status_update(test, "Failed to diff obj1 and obj2\n");
+ } else if (!changes) {
ast_test_status_update(test, "Failed to produce a diff of two objects, despite there being differences\n");
return AST_TEST_FAIL;
}
@@ -759,7 +761,7 @@
ast_test_status_update(test, "Failed to open sorcery structure\n");
return AST_TEST_FAIL;
}
-
+
if (ast_sorcery_apply_default(sorcery, "test", "memory", NULL)) {
ast_test_status_update(test, "Failed to set a known wizard as a default\n");
return AST_TEST_FAIL;
@@ -850,7 +852,10 @@
tmp->next = modified;
modified = tmp;
- if (!(changes = ast_sorcery_changeset_create(original, modified))) {
+ if (ast_sorcery_changeset_create(original, modified, &changes)) {
+ ast_test_status_update(test, "Failed to create a changeset due to an error\n");
+ return AST_TEST_FAIL;
+ } else if (!changes) {
ast_test_status_update(test, "Failed to produce a changeset when there should be one\n");
return AST_TEST_FAIL;
}
@@ -903,7 +908,10 @@
tmp->next = original;
original = tmp;
- if ((changes = ast_sorcery_changeset_create(original, original))) {
+ if (ast_sorcery_changeset_create(original, original, &changes)) {
+ ast_test_status_update(test, "Failed to create a changeset due to an error\n");
+ return AST_TEST_FAIL;
+ } else if (changes) {
ast_test_status_update(test, "Created a changeset when no changes actually exist\n");
return AST_TEST_FAIL;
}
@@ -922,7 +930,10 @@
tmp->next = same;
same = tmp;
- if ((changes = ast_sorcery_changeset_create(original, same))) {
+ if (ast_sorcery_changeset_create(original, same, &changes)) {
+ ast_test_status_update(test, "Failed to create a changeset due to an error\n");
+ return AST_TEST_FAIL;
+ } else if (changes) {
ast_test_status_update(test, "Created a changeset between two different objectsets when no changes actually exist\n");
return AST_TEST_FAIL;
}
@@ -1011,7 +1022,7 @@
ao2_cleanup(obj);
- if (!(obj = ast_sorcery_retrieve(sorcery, "test", AST_RETRIEVE_FLAG_DEFAULT, AST_RETRIEVE_PARAM_ID, "blah", AST_RETRIEVE_PARAM_END))) {
+ if (!(obj = ast_sorcery_retrieve_by_id(sorcery, "test", "blah"))) {
ast_test_status_update(test, "Failed to retrieve properly created object using id of 'blah'\n");
return AST_TEST_FAIL;
} else if (strcmp(ast_sorcery_object_get_id(obj), "blah")) {
@@ -1026,6 +1037,7 @@
{
RAII_VAR(struct ast_sorcery *, sorcery, NULL, ast_sorcery_unref);
RAII_VAR(struct test_sorcery_object *, obj, NULL, ao2_cleanup);
+ RAII_VAR(struct ast_variable *, fields, ast_variable_new("joe", "42", ""), ast_variables_destroy);
switch (cmd) {
case TEST_INIT:
@@ -1037,6 +1049,11 @@
return AST_TEST_NOT_RUN;
case TEST_EXECUTE:
break;
+ }
+
+ if (!fields) {
+ ast_test_status_update(test, "Failed to create fields for object retrieval attempt\n");
+ return AST_TEST_FAIL;
}
if (!(sorcery = alloc_and_initialize_sorcery())) {
@@ -1058,14 +1075,20 @@
ao2_cleanup(obj);
- if (!(obj = ast_sorcery_retrieve(sorcery, "test", AST_RETRIEVE_FLAG_DEFAULT, AST_RETRIEVE_PARAM_FIELD, "joe", "42", AST_RETRIEVE_PARAM_END))) {
+ if (!(obj = ast_sorcery_retrieve_by_fields(sorcery, "test", AST_RETRIEVE_FLAG_DEFAULT, fields))) {
ast_test_status_update(test, "Failed to retrieve properly created object using 'joe' field\n");
return AST_TEST_FAIL;
}
ao2_cleanup(obj);
-
- if ((obj = ast_sorcery_retrieve(sorcery, "test", AST_RETRIEVE_FLAG_DEFAULT, AST_RETRIEVE_PARAM_FIELD, "joe", "49", AST_RETRIEVE_PARAM_END))) {
+ ast_variables_destroy(fields);
+
+ if (!(fields = ast_variable_new("joe", "49", ""))) {
+ ast_test_status_update(test, "Failed to create fields for object retrieval attempt\n");
+ return AST_TEST_FAIL;
+ }
+
+ if ((obj = ast_sorcery_retrieve_by_fields(sorcery, "test", AST_RETRIEVE_FLAG_DEFAULT, fields))) {
ast_test_status_update(test, "Retrieved an object using a field with an in-correct value... that should not happen\n");
return AST_TEST_FAIL;
}
@@ -1118,7 +1141,7 @@
return AST_TEST_FAIL;
}
- if (!(objects = ast_sorcery_retrieve(sorcery, "test", AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, AST_RETRIEVE_PARAM_END))) {
+ if (!(objects = ast_sorcery_retrieve_by_fields(sorcery, "test", AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL))) {
ast_test_status_update(test, "Failed to retrieve a container of all objects\n");
return AST_TEST_FAIL;
} else if (ao2_container_count(objects) != 2) {
@@ -1134,6 +1157,7 @@
RAII_VAR(struct ast_sorcery *, sorcery, NULL, ast_sorcery_unref);
RAII_VAR(struct test_sorcery_object *, obj, NULL, ao2_cleanup);
RAII_VAR(struct ao2_container *, objects, NULL, ao2_cleanup);
+ RAII_VAR(struct ast_variable *, fields, ast_variable_new("joe", "6", ""), ast_variables_destroy);
switch (cmd) {
case TEST_INIT:
@@ -1145,6 +1169,11 @@
return AST_TEST_NOT_RUN;
case TEST_EXECUTE:
break;
+ }
+
+ if (!fields) {
+ ast_test_status_update(test, "Failed to create fields for multiple retrieve\n");
+ return AST_TEST_FAIL;
}
if (!(sorcery = alloc_and_initialize_sorcery())) {
@@ -1164,7 +1193,7 @@
return AST_TEST_FAIL;
}
- if (!(objects = ast_sorcery_retrieve(sorcery, "test", AST_RETRIEVE_FLAG_MULTIPLE, AST_RETRIEVE_PARAM_FIELD, "joe", "6", AST_RETRIEVE_PARAM_END))) {
+ if (!(objects = ast_sorcery_retrieve_by_fields(sorcery, "test", AST_RETRIEVE_FLAG_MULTIPLE, fields))) {
ast_test_status_update(test, "Failed to retrieve a container of all objects\n");
return AST_TEST_FAIL;
} else if (ao2_container_count(objects) != 1) {
@@ -1173,8 +1202,12 @@
}
ao2_cleanup(objects);
-
- if (!(objects = ast_sorcery_retrieve(sorcery, "test", AST_RETRIEVE_FLAG_MULTIPLE, AST_RETRIEVE_PARAM_FIELD, "joe", "7", AST_RETRIEVE_PARAM_END))) {
+ ast_variables_destroy(fields);
+
+ if (!(fields = ast_variable_new("joe", "7", ""))) {
+ ast_test_status_update(test, "Failed to create fields for multiple retrieval\n");
+ return AST_TEST_FAIL;
+ } else if (!(objects = ast_sorcery_retrieve_by_fields(sorcery, "test", AST_RETRIEVE_FLAG_MULTIPLE, fields))) {
ast_test_status_update(test, "Failed to retrieve an empty container when retrieving multiple\n");
return AST_TEST_FAIL;
} else if (ao2_container_count(objects)) {
@@ -1230,7 +1263,7 @@
return AST_TEST_FAIL;
}
- if (!(obj = ast_sorcery_retrieve(sorcery, "test", AST_RETRIEVE_FLAG_DEFAULT, AST_RETRIEVE_PARAM_ID, "blah", AST_RETRIEVE_PARAM_END))) {
+ if (!(obj = ast_sorcery_retrieve_by_id(sorcery, "test", "blah"))) {
ast_test_status_update(test, "Failed to retrieve properly updated object\n");
return AST_TEST_FAIL;
} else if (obj != obj2) {
@@ -1315,7 +1348,7 @@
ao2_cleanup(obj);
- if ((obj = ast_sorcery_retrieve(sorcery, "test", AST_RETRIEVE_FLAG_DEFAULT, AST_RETRIEVE_PARAM_ID, "blah", AST_RETRIEVE_PARAM_END))) {
+ if ((obj = ast_sorcery_retrieve_by_id(sorcery, "test", "blah"))) {
ast_test_status_update(test, "Retrieved deleted object that should not be there\n");
return AST_TEST_FAIL;
}
@@ -1424,13 +1457,13 @@
ao2_cleanup(obj);
- if (!(obj = ast_sorcery_retrieve(sorcery, "test", AST_RETRIEVE_FLAG_DEFAULT, AST_RETRIEVE_PARAM_ID, "blah", AST_RETRIEVE_PARAM_END))) {
+ if (!(obj = ast_sorcery_retrieve_by_id(sorcery, "test", "blah"))) {
ast_test_status_update(test, "Failed to retrieve just created object\n");
goto end;
} else if (!cache.created) {
ast_test_status_update(test, "Caching wizard was not told to cache just created object\n");
goto end;
- } else if (!(obj2 = ast_sorcery_retrieve(sorcery, "test", AST_RETRIEVE_FLAG_DEFAULT, AST_RETRIEVE_PARAM_ID, "blah", AST_RETRIEVE_PARAM_END))) {
+ } else if (!(obj2 = ast_sorcery_retrieve_by_id(sorcery, "test", "blah"))) {
ast_test_status_update(test, "Failed to retrieve just cached object\n");
goto end;
} else if (obj == obj2) {
@@ -1452,7 +1485,7 @@
ao2_cleanup(obj2);
- if ((obj2 = ast_sorcery_retrieve(sorcery, "test", AST_RETRIEVE_FLAG_DEFAULT, AST_RETRIEVE_PARAM_ID, "blah", AST_RETRIEVE_PARAM_END))) {
+ if ((obj2 = ast_sorcery_retrieve_by_id(sorcery, "test", "blah"))) {
ast_test_status_update(test, "Retrieved an object that should have been deleted\n");
goto end;
}
@@ -1517,10 +1550,10 @@
ast_sorcery_load(sorcery);
- if ((obj = ast_sorcery_retrieve(sorcery, "test", AST_RETRIEVE_FLAG_DEFAULT, AST_RETRIEVE_PARAM_ID, "hey2", AST_RETRIEVE_PARAM_END))) {
+ if ((obj = ast_sorcery_retrieve_by_id(sorcery, "test", "hey2"))) {
ast_test_status_update(test, "Retrieved object which has an unknown field\n");
return AST_TEST_FAIL;
- } else if (!(obj = ast_sorcery_retrieve(sorcery, "test", AST_RETRIEVE_FLAG_DEFAULT, AST_RETRIEVE_PARAM_ID, "hey", AST_RETRIEVE_PARAM_END))) {
+ } else if (!(obj = ast_sorcery_retrieve_by_id(sorcery, "test", "hey"))) {
ast_test_status_update(test, "Failed to retrieve a known object that has been configured in the configuration file\n");
return AST_TEST_FAIL;
} else if (obj->bob != 98) {
@@ -1580,7 +1613,7 @@
ast_sorcery_load(sorcery);
- if ((obj = ast_sorcery_retrieve(sorcery, "test", AST_RETRIEVE_FLAG_DEFAULT, AST_RETRIEVE_PARAM_ID, "hey", AST_RETRIEVE_PARAM_END))) {
+ if ((obj = ast_sorcery_retrieve_by_id(sorcery, "test", "hey"))) {
ast_test_status_update(test, "Retrieved object which has an unknown field\n");
return AST_TEST_FAIL;
}
@@ -1635,10 +1668,10 @@
ast_sorcery_load(sorcery);
- if ((obj = ast_sorcery_retrieve(sorcery, "test", AST_RETRIEVE_FLAG_DEFAULT, AST_RETRIEVE_PARAM_ID, "hey", AST_RETRIEVE_PARAM_END))) {
+ if ((obj = ast_sorcery_retrieve_by_id(sorcery, "test", "hey"))) {
ast_test_status_update(test, "Retrieved object which did not match criteria\n");
return AST_TEST_FAIL;
- } else if (!(obj = ast_sorcery_retrieve(sorcery, "test", AST_RETRIEVE_FLAG_DEFAULT, AST_RETRIEVE_PARAM_ID, "hey2", AST_RETRIEVE_PARAM_END))) {
+ } else if (!(obj = ast_sorcery_retrieve_by_id(sorcery, "test", "hey2"))) {
ast_test_status_update(test, "Failed to retrieve a known object which matches criteria\n");
return AST_TEST_FAIL;
}
@@ -1652,6 +1685,7 @@
struct ast_config *config;
RAII_VAR(struct ast_sorcery *, sorcery, NULL, ast_sorcery_unref);
RAII_VAR(struct test_sorcery_object *, obj, NULL, ao2_cleanup);
+ RAII_VAR(struct ast_variable *, fields, ast_variable_new("joe", "41", ""), ast_variables_destroy);
switch (cmd) {
case TEST_INIT:
@@ -1692,7 +1726,7 @@
ast_sorcery_load(sorcery);
- if (!(obj = ast_sorcery_retrieve(sorcery, "test", AST_RETRIEVE_FLAG_DEFAULT, AST_RETRIEVE_PARAM_FIELD, "joe", "41", AST_RETRIEVE_PARAM_END))) {
+ if (!(obj = ast_sorcery_retrieve_by_fields(sorcery, "test", AST_RETRIEVE_FLAG_DEFAULT, fields))) {
ast_test_status_update(test, "Failed to retrieve a known object that has been configured with the correct field\n");
return AST_TEST_FAIL;
} else if (strcmp(ast_sorcery_object_get_id(obj), "hey")) {
@@ -1709,6 +1743,7 @@
struct ast_config *config;
RAII_VAR(struct ast_sorcery *, sorcery, NULL, ast_sorcery_unref);
RAII_VAR(struct ao2_container *, objects, NULL, ao2_cleanup);
+ RAII_VAR(struct ast_variable *, fields, ast_variable_new("joe", "99", ""), ast_variables_destroy);
switch (cmd) {
case TEST_INIT:
@@ -1729,6 +1764,11 @@
ast_config_destroy(config);
+ if (!fields) {
+ ast_test_status_update(test, "Failed to create fields for multiple retrieve\n");
+ return AST_TEST_FAIL;
+ }
+
if (!(sorcery = ast_sorcery_open())) {
ast_test_status_update(test, "Failed to open sorcery structure\n");
return AST_TEST_FAIL;
@@ -1749,7 +1789,7 @@
ast_sorcery_load(sorcery);
- if (!(objects = ast_sorcery_retrieve(sorcery, "test", AST_RETRIEVE_FLAG_MULTIPLE, AST_RETRIEVE_PARAM_FIELD, "joe", "99", AST_RETRIEVE_PARAM_END))) {
+ if (!(objects = ast_sorcery_retrieve_by_fields(sorcery, "test", AST_RETRIEVE_FLAG_MULTIPLE, fields))) {
ast_test_status_update(test, "Failed to retrieve an empty container when retrieving multiple\n");
return AST_TEST_FAIL;
} else if (ao2_container_count(objects)) {
@@ -1758,8 +1798,12 @@
}
ao2_cleanup(objects);
-
- if (!(objects = ast_sorcery_retrieve(sorcery, "test", AST_RETRIEVE_FLAG_MULTIPLE, AST_RETRIEVE_PARAM_FIELD, "joe", "41", AST_RETRIEVE_PARAM_END))) {
+ ast_variables_destroy(fields);
+
+ if (!(fields = ast_variable_new("joe", "41", ""))) {
+ ast_test_status_update(test, "Failed to create fields for multiple retrieve\n");
+ return AST_TEST_FAIL;
+ } else if (!(objects = ast_sorcery_retrieve_by_fields(sorcery, "test", AST_RETRIEVE_FLAG_MULTIPLE, fields))) {
ast_test_status_update(test, "Failed to retrieve a container when retrieving multiple\n");
return AST_TEST_FAIL;
} else if (ao2_container_count(objects) != 1) {
@@ -1816,7 +1860,7 @@
ast_sorcery_load(sorcery);
- if (!(objects = ast_sorcery_retrieve(sorcery, "test", AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, AST_RETRIEVE_PARAM_END))) {
+ if (!(objects = ast_sorcery_retrieve_by_fields(sorcery, "test", AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL))) {
ast_test_status_update(test, "Failed to retrieve a container with all objects when there should be one\n");
return AST_TEST_FAIL;
} else if (ao2_container_count(objects) != 2) {
More information about the asterisk-commits
mailing list