[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