[asterisk-commits] file: branch file/sorcery r378146 - in /team/file/sorcery: include/asterisk/ ...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Dec 19 10:43:56 CST 2012
Author: file
Date: Wed Dec 19 10:43:52 2012
New Revision: 378146
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=378146
Log:
Add ast_sorcery_retrieve and a test to confirm it works. Still more tweaking and tests to write!
Modified:
team/file/sorcery/include/asterisk/sorcery.h
team/file/sorcery/main/sorcery.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=378146&r1=378145&r2=378146
==============================================================================
--- team/file/sorcery/include/asterisk/sorcery.h (original)
+++ team/file/sorcery/include/asterisk/sorcery.h Wed Dec 19 10:43:52 2012
@@ -48,6 +48,28 @@
struct ast_sorcery_object_wizard;
/*!
+ * \brief Retrieval flags
+ */
+enum ast_sorcery_retrieve_flags {
+ /*! \brief Default retrieval flags */
+ AST_RETRIEVE_FLAG_DEFAULT = 0,
+};
+
+/*!
+ * \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 A callback function for translating a value into a string
*
* \param obj Object to get value from
@@ -73,6 +95,12 @@
/*! \brief Callback for creating an object */
int (*create)(void *data, void *object);
+
+ /*! \brief Callback for retrieving an object using an id */
+ void *(*retrieve_id)(void *data, const char *id);
+
+ /*! \brief Optional callback for retrieving an object using fields */
+ void *(*retrieve_fields)(void *data, const struct ast_variable *fields);
/*! \brief Callback for updating an object */
int (*update)(void *data, void *object);
@@ -327,6 +355,21 @@
int ast_sorcery_create(struct ast_sorcery *sorcery, void *object);
/*!
+ * \brief Retrieve an object or multiple objects
+ *
+ * \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
+ *
+ * \retval non-NULL if found
+ * \retval NULL if not found
+ *
+ * \note The parameters must end with AST_RETRIEVE_PARAM_END
+ */
+void *ast_sorcery_retrieve(const struct ast_sorcery *sorcery, const char *type, unsigned int flags, ...);
+
+/*!
* \brief Update an object
*
* \param sorcery Pointer to a sorcery structure
Modified: team/file/sorcery/main/sorcery.c
URL: http://svnview.digium.com/svn/asterisk/team/file/sorcery/main/sorcery.c?view=diff&rev=378146&r1=378145&r2=378146
==============================================================================
--- team/file/sorcery/main/sorcery.c (original)
+++ team/file/sorcery/main/sorcery.c Wed Dec 19 10:43:52 2012
@@ -685,6 +685,70 @@
return ast_sorcery_changeset_create(objectset1, objectset2);
}
+void *ast_sorcery_retrieve(const struct ast_sorcery *sorcery, const char *type, unsigned int flags, ...)
+{
+ 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;
+
+ 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 = 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) {
+ return NULL;
+ }
+
+ /* Inquire with the available wizards for retrieval */
+ i = ao2_iterator_init(object_type->wizards, 0);
+ for (; (wizard = ao2_iterator_next(&i)); ao2_ref(wizard, -1)) {
+ if (!ast_strlen_zero(id)) {
+ object = wizard->wizard->retrieve_id(wizard->data, id);
+ } else if (fields && wizard->wizard->retrieve_fields) {
+ object = wizard->wizard->retrieve_fields(wizard->data, fields);
+ }
+
+ if (!object) {
+ continue;
+ }
+
+ ao2_ref(wizard, -1);
+ break;
+ }
+ ao2_iterator_destroy(&i);
+
+ return object;
+}
+
/*! \brief Internal function which returns if the wizard has created the object */
static int sorcery_wizard_create(void *obj, void *arg, int flags)
{
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=378146&r1=378145&r2=378146
==============================================================================
--- team/file/sorcery/res/res_sorcery_memory.c (original)
+++ team/file/sorcery/res/res_sorcery_memory.c Wed Dec 19 10:43:52 2012
@@ -41,6 +41,7 @@
static void *sorcery_memory_open(const char *data);
static int sorcery_memory_create(void *data, void *object);
+static void *sorcery_memory_retrieve_id(void *data, const char *id);
static int sorcery_memory_update(void *data, void *object);
static int sorcery_memory_delete(void *data, void *object);
static void sorcery_memory_close(void *data);
@@ -49,6 +50,7 @@
.name = "memory",
.open = sorcery_memory_open,
.create = sorcery_memory_create,
+ .retrieve_id = sorcery_memory_retrieve_id,
.update = sorcery_memory_update,
.delete = sorcery_memory_delete,
.close = sorcery_memory_close,
@@ -74,6 +76,11 @@
{
ao2_link(data, object);
return 0;
+}
+
+static void *sorcery_memory_retrieve_id(void *data, const char *id)
+{
+ return ao2_find(data, id, OBJ_KEY);
}
static int sorcery_memory_update(void *data, void *object)
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=378146&r1=378145&r2=378146
==============================================================================
--- team/file/sorcery/tests/test_sorcery.c (original)
+++ team/file/sorcery/tests/test_sorcery.c Wed Dec 19 10:43:52 2012
@@ -668,6 +668,58 @@
return AST_TEST_PASS;
}
+AST_TEST_DEFINE(object_retrieve)
+{
+ RAII_VAR(struct ast_sorcery *, sorcery, NULL, ast_sorcery_unref);
+ RAII_VAR(struct test_sorcery_object *, obj, NULL, ao2_cleanup);
+
+ switch (cmd) {
+ case TEST_INIT:
+ info->name = "object_retrieve";
+ info->category = "/main/sorcery/";
+ info->summary = "sorcery object retrieval unit test";
+ info->description =
+ "Test object retrieval in sorcery";
+ return AST_TEST_NOT_RUN;
+ case TEST_EXECUTE:
+ break;
+ }
+
+ if (!(sorcery = ast_sorcery_open())) {
+ ast_test_status_update(test, "Failed to open sorcery with NULL name\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;
+ }
+
+ if (ast_sorcery_object_register(sorcery, "test", &test_object)) {
+ ast_test_status_update(test, "Failed to register object type\n");
+ return AST_TEST_FAIL;
+ }
+
+ if (!(obj = ast_sorcery_alloc(sorcery, "test", "blah"))) {
+ ast_test_status_update(test, "Failed to allocate a known object type\n");
+ return AST_TEST_FAIL;
+ }
+
+ if (ast_sorcery_create(sorcery, obj)) {
+ ast_test_status_update(test, "Failed to create object using in-memory wizard\n");
+ return AST_TEST_FAIL;
+ }
+
+ ao2_cleanup(obj);
+
+ if (!(obj = ast_sorcery_retrieve(sorcery, "test", AST_RETRIEVE_FLAG_DEFAULT, AST_RETRIEVE_PARAM_ID, "blah", AST_RETRIEVE_PARAM_END))) {
+ ast_test_status_update(test, "Failed to retrieve properly created object\n");
+ return AST_TEST_FAIL;
+ }
+
+ return AST_TEST_PASS;
+}
+
AST_TEST_DEFINE(object_delete)
{
RAII_VAR(struct ast_sorcery *, sorcery, NULL, ast_sorcery_unref);
@@ -732,6 +784,7 @@
AST_TEST_UNREGISTER(changeset_create);
AST_TEST_UNREGISTER(changeset_create_unchanged);
AST_TEST_UNREGISTER(object_create);
+ AST_TEST_UNREGISTER(object_retrieve);
AST_TEST_UNREGISTER(object_delete);
return 0;
}
@@ -750,6 +803,7 @@
AST_TEST_REGISTER(changeset_create);
AST_TEST_REGISTER(changeset_create_unchanged);
AST_TEST_REGISTER(object_create);
+ AST_TEST_REGISTER(object_retrieve);
AST_TEST_REGISTER(object_delete);
return AST_MODULE_LOAD_SUCCESS;
}
More information about the asterisk-commits
mailing list