40 static void *sorcery_astdb_open(
const char *data);
41 static int sorcery_astdb_create(
const struct ast_sorcery *sorcery,
void *data,
void *
object);
42 static void *sorcery_astdb_retrieve_id(
const struct ast_sorcery *sorcery,
void *data,
const char *type,
const char *
id);
43 static void *sorcery_astdb_retrieve_fields(
const struct ast_sorcery *sorcery,
void *data,
const char *type,
const struct ast_variable *fields);
44 static void sorcery_astdb_retrieve_multiple(
const struct ast_sorcery *sorcery,
void *data,
const char *type,
struct ao2_container *objects,
46 static void sorcery_astdb_retrieve_regex(
const struct ast_sorcery *sorcery,
void *data,
const char *type,
struct ao2_container *objects,
const char *regex);
47 static void sorcery_astdb_retrieve_prefix(
const struct ast_sorcery *sorcery,
void *data,
const char *type,
struct ao2_container *objects,
const char *prefix,
const size_t prefix_len);
48 static int sorcery_astdb_update(
const struct ast_sorcery *sorcery,
void *data,
void *
object);
49 static int sorcery_astdb_delete(
const struct ast_sorcery *sorcery,
void *data,
void *
object);
50 static void sorcery_astdb_close(
void *data);
54 .open = sorcery_astdb_open,
55 .create = sorcery_astdb_create,
56 .retrieve_id = sorcery_astdb_retrieve_id,
57 .retrieve_fields = sorcery_astdb_retrieve_fields,
58 .retrieve_multiple = sorcery_astdb_retrieve_multiple,
59 .retrieve_regex = sorcery_astdb_retrieve_regex,
60 .retrieve_prefix = sorcery_astdb_retrieve_prefix,
61 .update = sorcery_astdb_update,
62 .delete = sorcery_astdb_delete,
63 .close = sorcery_astdb_close,
66 static int sorcery_astdb_create(
const struct ast_sorcery *sorcery,
void *data,
void *
object)
70 const char *prefix = data;
96 struct ast_variable *previous = NULL, *field = objectset;
101 ast_log(LOG_WARNING,
"Unknown sorcery object type %s. Expect errors\n", type);
114 ast_debug(1,
"Filtering out astdb field '%s' from retrieval\n", field->name);
119 objectset = field->
next;
124 removed->
next = NULL;
129 ao2_cleanup(object_type);
137 const char *prefix = data;
138 char family[strlen(prefix) + strlen(type) + 2];
142 snprintf(family,
sizeof(family),
"%s/%s", prefix, type);
148 for (entry = entries; entry; entry = entry->next) {
149 const char *key = entry->key + strlen(family) + 2;
186 static void *sorcery_astdb_retrieve_fields(
const struct ast_sorcery *sorcery,
void *data,
const char *type,
const struct ast_variable *fields)
191 static void *sorcery_astdb_retrieve_id(
const struct ast_sorcery *sorcery,
void *data,
const char *type,
const char *
id)
193 const char *prefix = data;
194 char family[strlen(prefix) + strlen(type) + 2];
201 snprintf(family,
sizeof(family),
"%s/%s", prefix, type);
209 ast_debug(3,
"Failed to retrieve object '%s' from astdb\n",
id);
235 static int make_astdb_prefix_pattern(
char *tree,
const char *regex)
240 for (dst = tree, src = regex + 1; *src; ++src) {
248 }
else if (*src ==
'$') {
254 }
else if (strchr(
".?*+{[(|", *src)) {
278 static void sorcery_astdb_retrieve_regex(
const struct ast_sorcery *sorcery,
void *data,
const char *type,
struct ao2_container *objects,
const char *regex)
280 const char *prefix = data;
281 char family[strlen(prefix) + strlen(type) + 2];
282 char tree[strlen(regex) + 1];
287 snprintf(family,
sizeof(family),
"%s/%s", prefix, type);
289 if (regex[0] ==
'^') {
295 if (make_astdb_prefix_pattern(tree, regex)) {
303 || regcomp(&expression, regex, REG_EXTENDED | REG_NOSUB)) {
307 for (entry = entries; entry; entry = entry->next) {
309 const char *key = entry->key + strlen(family) + 2;
312 RAII_VAR(
void *,
object, NULL, ao2_cleanup);
315 if (regexec(&expression, key, 0, NULL, 0)) {
322 regfree(&expression);
329 regfree(&expression);
332 static void sorcery_astdb_retrieve_prefix(
const struct ast_sorcery *sorcery,
void *data,
const char *type,
struct ao2_container *objects,
const char *prefix,
const size_t prefix_len)
334 const char *family_prefix = data;
335 size_t family_len = strlen(family_prefix) + strlen(type) + 1;
336 char family[family_len + 1];
337 char tree[prefix_len + 1];
341 snprintf(tree,
sizeof(tree),
"%.*s", (
int) prefix_len, prefix);
342 snprintf(family,
sizeof(family),
"%s/%s", family_prefix, type);
348 for (entry = entries; entry; entry = entry->next) {
350 const char *key = entry->key + family_len + 2;
353 RAII_VAR(
void *,
object, NULL, ao2_cleanup);
368 static int sorcery_astdb_update(
const struct ast_sorcery *sorcery,
void *data,
void *
object)
370 const char *prefix = data;
381 return sorcery_astdb_create(sorcery, data,
object);
384 static int sorcery_astdb_delete(
const struct ast_sorcery *sorcery,
void *data,
void *
object)
386 const char *prefix = data;
399 static void *sorcery_astdb_open(
const char *data)
402 if (ast_strlen_zero(data)) {
409 static void sorcery_astdb_close(
void *data)
414 static int load_module(
void)
423 static int unload_module(
void)
429 AST_MODULE_INFO(
ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER,
"Sorcery Astdb Object Wizard",
430 .support_level = AST_MODULE_SUPPORT_CORE,
432 .unload = unload_module,
struct ast_variable * next
Asterisk main include file. File version handling, generic pbx functions.
static struct ast_variable * sorcery_astdb_filter_objectset(struct ast_variable *objectset, const struct ast_sorcery *sorcery, const char *type)
Internal helper function which returns a filtered objectset.
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
void ast_db_freetree(struct ast_db_entry *entry)
Free structure created by ast_db_gettree()
void ast_json_free(void *p)
Asterisk's custom JSON allocator. Exposed for use by unit tests.
Structure for variables, used for configurations and for channel variables.
#define ast_json_dump_string(root)
Encode a JSON value to a compact string.
Full structure for sorcery.
int ast_db_get_allocated(const char *family, const char *key, char **out)
Get key value specified by family/key as a heap allocated string.
int ast_sorcery_objectset_apply(const struct ast_sorcery *sorcery, void *object, struct ast_variable *objectset)
Apply an object set (KVP list) to an object.
struct ast_json * ast_json_load_string(const char *input, struct ast_json_error *error)
Parse null terminated string into a JSON object or array.
#define ast_strdup(str)
A wrapper for strdup()
const char * name
Name of the wizard.
void ast_free_ptr(void *ptr)
free() wrapper
JSON parsing error information.
const char * ast_sorcery_object_get_type(const void *object)
Get the type of a sorcery object.
Structure for registered object type.
Asterisk JSON abstraction layer.
struct ast_db_entry * ast_db_gettree_by_prefix(const char *family, const char *key_prefix)
Get a list of values with the given key prefix.
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
#define ast_debug(level,...)
Log a DEBUG message.
struct ast_sorcery_object_type * ast_sorcery_get_object_type(const struct ast_sorcery *sorcery, const char *type)
Get the sorcery object type given a type name.
#define ast_sorcery_wizard_register(interface)
See __ast_sorcery_wizard_register()
struct ast_db_entry * ast_db_gettree(const char *family, const char *keytree)
Get a list of values within the astdb tree.
int ast_sorcery_wizard_unregister(const struct ast_sorcery_wizard *interface)
Unregister a sorcery wizard.
void * ast_sorcery_alloc(const struct ast_sorcery *sorcery, const char *type, const char *id)
Allocate an object.
enum ast_json_to_ast_vars_code ast_json_to_ast_variables(struct ast_json *json_variables, struct ast_variable **variables)
Convert a ast_json list of key/value pair tuples into a ast_variable list.
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)
Internal helper function which retrieves an object, or multiple objects, using fields for criteria...
int ast_sorcery_is_object_field_registered(const struct ast_sorcery_object_type *object_type, const char *field_name)
Determine if a particular object field has been registered with sorcery.
Module has failed to load, may be in an inconsistent state.
int ast_db_get(const char *family, const char *key, char *value, int valuelen)
Get key value specified by family/key.
Interface for a sorcery wizard.
int ast_variable_lists_match(const struct ast_variable *left, const struct ast_variable *right, int exact_match)
Tests 2 variable lists to see if they match.
int ast_db_del(const char *family, const char *key)
Delete entry in astdb.
Abstract JSON element (object, array, string, int, ...).
struct ast_json * ast_sorcery_objectset_json_create(const struct ast_sorcery *sorcery, const void *object)
Create an object set in JSON format for an object.
int ast_db_put(const char *family, const char *key, const char *value)
Store value addressed by family/key.
#define ASTERISK_GPL_KEY
The text the key() function should return.
Asterisk module definitions.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Persistent data storage (akin to *doze registry)
char name[MAX_OBJECT_TYPE]
Unique name of the object type.
Sorcery Data Access Layer API.
#define ao2_link(container, obj)
Add an object to a container.