[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