[asterisk-commits] file: branch file/res_sorcery_astdb r383442 - /team/file/res_sorcery_astdb/res/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Mar 20 14:00:43 CDT 2013


Author: file
Date: Wed Mar 20 14:00:42 2013
New Revision: 383442

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=383442
Log:
Implement the remaining retrieve functions, clean up, tweak.

Modified:
    team/file/res_sorcery_astdb/res/res_sorcery_astdb.c

Modified: team/file/res_sorcery_astdb/res/res_sorcery_astdb.c
URL: http://svnview.digium.com/svn/asterisk/team/file/res_sorcery_astdb/res/res_sorcery_astdb.c?view=diff&rev=383442&r1=383441&r2=383442
==============================================================================
--- team/file/res_sorcery_astdb/res/res_sorcery_astdb.c (original)
+++ team/file/res_sorcery_astdb/res/res_sorcery_astdb.c Wed Mar 20 14:00:42 2013
@@ -38,9 +38,6 @@
 #include "asterisk/sorcery.h"
 #include "asterisk/astdb.h"
 #include "asterisk/json.h"
-
-/* This define is taken from db.c, but should be made available elsewhere */
-#define MAX_DB_FIELD 256
 
 static void *sorcery_astdb_open(const char *data);
 static int sorcery_astdb_create(const struct ast_sorcery *sorcery, void *data, void *object);
@@ -110,6 +107,22 @@
 	return objset;
 }
 
+/*! \brief Helper function which compares two json objects and sees if they are equal, but only looks at the criteria provided */
+static int sorcery_json_equal(struct ast_json *object, struct ast_json *criteria)
+{
+	struct ast_json_iter *field;
+
+	for (field = ast_json_object_iter(criteria); field; field = ast_json_object_iter_next(criteria, field)) {
+		struct ast_json *object_field = ast_json_object_get(object, ast_json_object_iter_key(field));
+
+		if (!object_field || !ast_json_equal(object_field, ast_json_object_iter_value(field))) {
+			return 0;
+		}
+	}
+
+	return 1;
+}
+
 static int sorcery_astdb_create(const struct ast_sorcery *sorcery, void *data, void *object)
 {
 	RAII_VAR(struct ast_variable *, objset, ast_sorcery_objectset_create(sorcery, object), ast_variables_destroy);
@@ -127,15 +140,60 @@
 	return ast_db_put(family, ast_sorcery_object_get_id(object), value);
 }
 
+/*! \brief Internal helper function which retrieves an object, or multiple objects, using fields for criteria */
+static void *sorcery_astdb_retrieve_fields_common(const struct ast_sorcery *sorcery, void *data, const char *type, const struct ast_variable *fields, struct ao2_container *objects)
+{
+	const char *prefix = data;
+	char family[strlen(prefix) + strlen(type) + 2];
+	RAII_VAR(struct ast_db_entry *, entries, NULL, ast_db_freetree);
+	RAII_VAR(struct ast_json *, criteria, NULL, ast_json_unref);
+	struct ast_db_entry *entry;
+
+	snprintf(family, sizeof(family), "%s/%s", prefix, type);
+
+	if (!(entries = ast_db_gettree(family, NULL)) || (fields && !(criteria = sorcery_objectset_to_json(fields)))) {
+		return NULL;
+	}
+
+	for (entry = entries; entry; entry = entry->next) {
+		const char *key = entry->key + strlen(family) + 2;
+		RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
+		struct ast_json_error error;
+		RAII_VAR(struct ast_variable *, objset, NULL, ast_variables_destroy);
+		void *object = NULL;
+
+		if (!(json = ast_json_load_string(entry->data, &error))) {
+			return NULL;
+		} else if (criteria && !sorcery_json_equal(json, criteria)) {
+			continue;
+		} else if (!(objset = sorcery_json_to_objectset(json)) ||
+			!(object = ast_sorcery_alloc(sorcery, type, key)) ||
+			ast_sorcery_objectset_apply(sorcery, object, objset)) {
+			ao2_cleanup(object);
+			return NULL;
+		}
+
+		if (!objects) {
+			return object;
+		}
+
+		ao2_link(objects, object);
+		ao2_cleanup(object);
+	}
+
+	return NULL;
+}
+
 static void *sorcery_astdb_retrieve_fields(const struct ast_sorcery *sorcery, void *data, const char *type, const struct ast_variable *fields)
 {
-	return NULL;
+	return sorcery_astdb_retrieve_fields_common(sorcery, data, type, fields, NULL);
 }
 
 static void *sorcery_astdb_retrieve_id(const struct ast_sorcery *sorcery, void *data, const char *type, const char *id)
 {
 	const char *prefix = data;
-	char family[strlen(prefix) + strlen(type) + 2], value[MAX_DB_FIELD];
+	char family[strlen(prefix) + strlen(type) + 2];
+	RAII_VAR(char *, value, NULL, ast_free_ptr);
 	RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
 	struct ast_json_error error;
 	RAII_VAR(struct ast_variable *, objset, NULL, ast_variables_destroy);
@@ -143,7 +201,7 @@
 
 	snprintf(family, sizeof(family), "%s/%s", prefix, type);
 
-	if (ast_db_get(family, id, value, sizeof(value)) || !(json = ast_json_load_string(value, &error)) ||
+	if (ast_db_get_allocated(family, id, &value) || !(json = ast_json_load_string(value, &error)) ||
 		!(objset = sorcery_json_to_objectset(json)) || !(object = ast_sorcery_alloc(sorcery, type, id)) ||
 		ast_sorcery_objectset_apply(sorcery, object, objset)) {
 		ao2_cleanup(object);
@@ -155,6 +213,7 @@
 
 static void sorcery_astdb_retrieve_multiple(const struct ast_sorcery *sorcery, void *data, const char *type, struct ao2_container *objects, const struct ast_variable *fields)
 {
+	sorcery_astdb_retrieve_fields_common(sorcery, data, type, fields, objects);
 }
 
 static void sorcery_astdb_retrieve_regex(const struct ast_sorcery *sorcery, void *data, const char *type, struct ao2_container *objects, const char *regex)
@@ -197,11 +256,11 @@
 static int sorcery_astdb_update(const struct ast_sorcery *sorcery, void *data, void *object)
 {
 	const char *prefix = data;
-	char family[strlen(prefix) + strlen(ast_sorcery_object_get_type(object)) + 2];
-	char value[MAX_DB_FIELD];
+	char family[strlen(prefix) + strlen(ast_sorcery_object_get_type(object)) + 2], value[2];
 
 	snprintf(family, sizeof(family), "%s/%s", prefix, ast_sorcery_object_get_type(object));
 
+	/* It is okay for the value to be truncated, we are only checking that it exists */
 	if (ast_db_get(family, ast_sorcery_object_get_id(object), value, sizeof(value))) {
 		return -1;
 	}




More information about the asterisk-commits mailing list