39 #define UUID_FIELD "id"
41 enum unqualified_fetch {
43 UNQUALIFIED_FETCH_WARN,
44 UNQUALIFIED_FETCH_YES,
45 UNQUALIFIED_FETCH_ERROR,
49 enum unqualified_fetch fetch;
53 static void *sorcery_realtime_open(
const char *data);
54 static int sorcery_realtime_create(
const struct ast_sorcery *sorcery,
void *data,
void *
object);
55 static void *sorcery_realtime_retrieve_id(
const struct ast_sorcery *sorcery,
void *data,
const char *type,
const char *
id);
56 static void *sorcery_realtime_retrieve_fields(
const struct ast_sorcery *sorcery,
void *data,
const char *type,
const struct ast_variable *fields);
57 static void sorcery_realtime_retrieve_multiple(
const struct ast_sorcery *sorcery,
void *data,
const char *type,
struct ao2_container *objects,
59 static void sorcery_realtime_retrieve_regex(
const struct ast_sorcery *sorcery,
void *data,
const char *type,
struct ao2_container *objects,
const char *regex);
60 static void sorcery_realtime_retrieve_prefix(
const struct ast_sorcery *sorcery,
void *data,
const char *type,
61 struct ao2_container *objects,
const char *prefix,
const size_t prefix_len);
62 static int sorcery_realtime_update(
const struct ast_sorcery *sorcery,
void *data,
void *
object);
63 static int sorcery_realtime_delete(
const struct ast_sorcery *sorcery,
void *data,
void *
object);
64 static void sorcery_realtime_close(
void *data);
68 .open = sorcery_realtime_open,
69 .create = sorcery_realtime_create,
70 .retrieve_id = sorcery_realtime_retrieve_id,
71 .retrieve_fields = sorcery_realtime_retrieve_fields,
72 .retrieve_multiple = sorcery_realtime_retrieve_multiple,
73 .retrieve_regex = sorcery_realtime_retrieve_regex,
74 .retrieve_prefix = sorcery_realtime_retrieve_prefix,
75 .update = sorcery_realtime_update,
76 .delete = sorcery_realtime_delete,
77 .close = sorcery_realtime_close,
80 static int sorcery_realtime_create(
const struct ast_sorcery *sorcery,
void *data,
void *
object)
112 const struct ast_sorcery *sorcery,
const char *type)
114 struct ast_variable *previous = NULL, *field = objectset;
119 ast_log(LOG_WARNING,
"Unknown sorcery object type %s. Expect errors\n", type);
124 int remove_field = 0;
125 int delete_field = 0;
130 }
else if (object_type &&
132 ast_debug(1,
"Filtering out realtime field '%s' from retrieval\n", field->name);
143 objectset = field->
next;
148 removed->
next = NULL;
158 ao2_cleanup(object_type);
163 static void *sorcery_realtime_retrieve_fields(
const struct ast_sorcery *sorcery,
void *data,
const char *type,
const struct ast_variable *fields)
186 static void *sorcery_realtime_retrieve_id(
const struct ast_sorcery *sorcery,
void *data,
const char *type,
const char *
id)
190 return sorcery_realtime_retrieve_fields(sorcery, data, type, fields);
203 if (config->fetch == UNQUALIFIED_FETCH_NO) {
206 if (config->fetch == UNQUALIFIED_FETCH_ERROR) {
207 ast_log(LOG_ERROR,
"Unqualified fetch prevented on %s\n", config->family);
210 if (config->fetch == UNQUALIFIED_FETCH_WARN) {
211 ast_log(LOG_WARNING,
"Unqualified fetch requested on %s\n", config->family);
215 snprintf(field,
sizeof(field),
"%s LIKE",
UUID_FIELD);
216 snprintf(value,
sizeof(value),
"%%");
218 if (!(all = ast_variable_new(field, value,
""))) {
230 struct ast_variable *objectset = ast_category_detach_variables(row);
232 RAII_VAR(
void *,
object, NULL, ao2_cleanup);
246 static void sorcery_realtime_retrieve_regex(
const struct ast_sorcery *sorcery,
void *data,
const char *type,
struct ao2_container *objects,
const char *regex)
248 char field[strlen(
UUID_FIELD) + 6], value[strlen(regex) + 3];
251 if (!ast_strlen_zero(regex)) {
253 snprintf(field,
sizeof(field),
"%s LIKE",
UUID_FIELD);
254 if (regex[0] ==
'^') {
255 snprintf(value,
sizeof(value),
"%s%%", regex + 1);
257 snprintf(value,
sizeof(value),
"%%%s%%", regex);
260 if (!(fields = ast_variable_new(field, value,
""))) {
265 sorcery_realtime_retrieve_multiple(sorcery, data, type, objects, fields);
268 static void sorcery_realtime_retrieve_prefix(
const struct ast_sorcery *sorcery,
void *data,
const char *type,
269 struct ao2_container *objects,
const char *prefix,
const size_t prefix_len)
271 char field[strlen(
UUID_FIELD) + 6], value[prefix_len + 2];
275 snprintf(field,
sizeof(field),
"%s LIKE",
UUID_FIELD);
276 snprintf(value,
sizeof(value),
"%.*s%%", (
int) prefix_len, prefix);
277 if (!(fields = ast_variable_new(field, value,
""))) {
282 sorcery_realtime_retrieve_multiple(sorcery, data, type, objects, fields);
285 static int sorcery_realtime_update(
const struct ast_sorcery *sorcery,
void *data,
void *
object)
297 static int sorcery_realtime_delete(
const struct ast_sorcery *sorcery,
void *data,
void *
object)
304 static void *sorcery_realtime_open(
const char *data)
312 if (ast_strlen_zero(data)) {
317 family = strsep(&tmp,
",");
323 config =
ast_calloc(1,
sizeof(*config) + strlen(family) + 1);
328 strcpy(config->family, family);
329 config->fetch = UNQUALIFIED_FETCH_YES;
331 while ((option = strsep(&tmp,
","))) {
332 char *name = strsep(&option,
"=");
333 char *value = option;
335 if (!strcasecmp(name,
"allow_unqualified_fetch")) {
336 if (ast_strlen_zero(value) || !strcasecmp(value,
"yes")) {
337 config->fetch = UNQUALIFIED_FETCH_YES;
338 }
else if (!strcasecmp(value,
"no")) {
339 config->fetch = UNQUALIFIED_FETCH_NO;
340 }
else if (!strcasecmp(value,
"warn")) {
341 config->fetch = UNQUALIFIED_FETCH_WARN;
342 }
else if (!strcasecmp(value,
"error")) {
343 config->fetch = UNQUALIFIED_FETCH_ERROR;
345 ast_log(LOG_ERROR,
"Unrecognized value in %s:%s: '%s'\n", family, name, value);
349 ast_log(LOG_ERROR,
"Unrecognized option in %s: '%s'\n", family, name);
357 static void sorcery_realtime_close(
void *data)
362 static int load_module(
void)
371 static int unload_module(
void)
377 AST_MODULE_INFO(
ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER,
"Sorcery Realtime Object Wizard",
378 .support_level = AST_MODULE_SUPPORT_CORE,
380 .unload = unload_module,
struct ast_variable * next
Asterisk main include file. File version handling, generic pbx functions.
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Structure for variables, used for configurations and for channel variables.
struct ast_config * ast_load_realtime_multientry_fields(const char *family, const struct ast_variable *fields)
Retrieve realtime configuration.
Full structure for sorcery.
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.
static struct ast_variable * sorcery_realtime_filter_objectset(struct ast_variable *objectset, struct ast_variable **id, const struct ast_sorcery *sorcery, const char *type)
Internal helper function which returns a filtered objectset.
const char * name
Name of the wizard.
struct ast_category * ast_category_browse_filtered(struct ast_config *config, const char *category_name, struct ast_category *prev, const char *filter)
Browse categories with filters.
Structure for registered object type.
#define ast_strdupa(s)
duplicate a string in memory from the stack
int ast_store_realtime_fields(const char *family, const struct ast_variable *fields)
Create realtime configuration.
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 ao2_global_obj objects
Objects retrieved from the configuration file.
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.
Structure for storing configuration file sourced objects.
#define ast_sorcery_wizard_register(interface)
See __ast_sorcery_wizard_register()
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.
#define ast_sorcery_objectset_create(sorcery, object)
Create an object set (KVP list) for an object.
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.
#define ast_calloc(num, len)
A wrapper for calloc()
Module has failed to load, may be in an inconsistent state.
int ast_realtime_is_mapping_defined(const char *family)
Determine if a mapping exists for a given family.
Interface for a sorcery wizard.
struct ast_variable * ast_load_realtime_fields(const char *family, const struct ast_variable *fields)
Retrieve realtime configuration.
#define UUID_FIELD
They key field used to store the unique identifier for the object.
int ast_update_realtime_fields(const char *family, const char *keyfield, const char *lookup, const struct ast_variable *fields)
Update realtime configuration.
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
int ast_destroy_realtime_fields(const char *family, const char *keyfield, const char *lookup, const struct ast_variable *fields)
Destroy realtime configuration.
#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.
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.