58 #include <amxo/amxo_save.h>
59 #include <amxd/amxd_object.h>
60 #include <amxp/amxp_dir.h>
84 when_null(paths, exit);
86 if(amxc_var_type_of(paths) == AMXC_VAR_ID_CSTRING) {
87 amxc_var_cast(paths, AMXC_VAR_ID_CSV_STRING);
88 amxc_var_cast(paths, AMXC_VAR_ID_LIST);
89 }
else if(amxc_var_type_of(paths) == AMXC_VAR_ID_CSV_STRING) {
90 amxc_var_cast(paths, AMXC_VAR_ID_LIST);
91 }
else if(amxc_var_type_of(paths) != AMXC_VAR_ID_LIST) {
102 char* resolved_dir = NULL;
104 amxc_string_init(&dir, 0);
105 if(odl_dir == NULL) {
108 if(odl_dir != NULL) {
109 amxc_string_setf(&dir,
"%s", odl_dir);
110 amxc_string_resolve(&dir, &parser->config);
111 resolved_dir = amxc_string_take_buffer(&dir);
119 amxc_string_t include;
120 bool is_empty_dir =
false;
122 amxd_object_t* root = amxd_dm_get_root(dm);
125 bool orig_eventing = GET_BOOL(eventing, NULL);
128 amxc_string_init(&include, 0);
130 if((odl_dir == NULL) || (*odl_dir == 0)) {
135 amxc_var_set(
bool, eventing, dm_eventing_enabled);
136 amxp_sigmngr_enable(&dm->sigmngr, dm_eventing_enabled);
138 amxc_string_setf(&include,
"include \"%s\";", odl_dir);
139 status = amxo_parser_parse_string(parser, amxc_string_get(&include, 0), root);
141 is_empty_dir = amxp_dir_is_empty(odl_dir);
143 if((status != 0) || is_empty_dir) {
146 when_true((def == NULL) || (*def == 0), exit);
148 amxc_string_setf(&include,
"include \"%s\";", def);
149 status = amxo_parser_parse_string(parser, amxc_string_get(&include, 0), root);
156 amxp_sigmngr_enable(&dm->sigmngr,
true);
157 amxc_var_set(
bool, eventing, orig_eventing);
159 amxc_string_clean(&include);
164 amxd_object_t*
object,
169 amxc_string_init(&file, 0);
171 amxc_string_setf(&file,
"%s/%s.odl", dir, name);
172 status = amxo_parser_save_object(parser, amxc_string_get(&file, 0),
object,
false);
173 when_failed_status(status, exit,
174 amxrt_print_error(
"Export - Failed to write %s file", amxc_string_get(&file, 0)));
177 amxc_string_clean(&file);
186 amxc_string_t file_name;
188 amxc_string_init(&file_name, 0);
190 when_true_status((odl_dir == NULL) || (*odl_dir == 0), exit,
194 amxd_object_t* root = amxd_dm_get_root(dm);
196 when_null_status(name, exit, status = -1);
201 when_true(amxc_var_type_of(paths) != AMXC_VAR_ID_LIST, exit);
203 amxc_var_for_each(path, paths) {
204 const char* op = amxc_var_constcast(cstring_t, path);
205 amxd_object_t* obj = NULL;
206 amxc_string_setf(&file_name,
"%2.2d_%s", index, op);
207 amxc_string_trimr(&file_name,
isdot);
208 obj = amxd_dm_findf(dm,
"%s", op);
218 amxc_string_clean(&file_name);
224 bool persistent =
true;
225 amxd_object_t* parent = amxd_object_get_parent(
object);
227 while(amxd_object_get_type(parent) != amxd_object_root &&
229 persistent &= amxd_object_is_attr_set(
object, amxd_oattr_persistent);
230 parent = amxd_object_get_parent(parent);
237 const amxc_var_t* data) {
238 bool persistent =
false;
239 amxc_var_t* params = GET_ARG(data,
"parameters");
241 amxc_var_for_each(param, params) {
242 const char* name = amxc_var_key(param);
243 amxd_param_t* param_def = amxd_object_get_param_def(
object, name);
244 persistent |= amxd_param_is_attr_set(param_def, amxd_pattr_persistent);
254 amxc_string_t* save_path = NULL;
258 amxc_string_t* set_path = amxc_string_from_llist_it(it);
259 if(strcmp(path, amxc_string_get(set_path, 0)) == 0) {
265 amxc_string_new(&save_path, 0);
266 amxc_string_setf(save_path,
"%s", path);
272 bool save_needed =
false;
273 char* obj_path = amxd_object_get_path(
object, AMXD_OBJECT_INDEXED);
276 when_null_status(paths, exit, save_needed =
true);
278 when_true(amxc_var_type_of(paths) != AMXC_VAR_ID_LIST, exit);
280 amxc_var_for_each(path, paths) {
281 const char* str_path = amxc_var_constcast(cstring_t, path);
282 int len = strlen(str_path);
283 if(strncmp(str_path, obj_path, len) == 0) {
300 amxd_object_t*
object = NULL;
303 amxc_string_t file_name;
304 amxc_string_init(&file_name, 0);
307 amxc_string_t* path = amxc_string_from_llist_it(it);
308 amxc_string_setf(&file_name,
"%2.2d_%s", index, amxc_string_get(path, 0));
309 amxc_string_trimr(&file_name,
isdot);
311 object = amxd_dm_findf(
storage.
dm,
"%s", amxc_string_get(path, 0));
313 amxc_string_delete(&path);
316 amxc_string_clean(&file_name);
322 const amxc_var_t*
const data,
323 UNUSED
void*
const priv) {
324 amxd_object_t*
object = amxd_dm_signal_get_object(
storage.
dm, data);
326 uint32_t save_delay = amxc_var_dyncast(uint32_t, GETP_ARG(&parser->config,
AMXRT_COPT_DELAY));
327 bool save_needed =
false;
329 if((strcmp(sig_name,
"dm:instance-added") == 0) ||
330 (strcmp(sig_name,
"dm:instance-removed") == 0)) {
331 uint32_t index = GET_UINT32(data,
"index");
332 amxd_object_t* instance = amxd_object_get_instance(
object, NULL, index);
333 object = instance != NULL? instance: object;
334 if(amxd_object_is_attr_set(
object, amxd_oattr_persistent)) {
337 }
else if(strcmp(sig_name,
"dm:object-changed") == 0) {
338 if(amxd_object_is_attr_set(
object, amxd_oattr_persistent)) {
345 if(amxd_object_is_attr_set(
object, amxd_oattr_persistent)) {
358 save_delay = save_delay == 0 ? 30000 : save_delay;
371 amxp_slot_connect(&dm->sigmngr,
"dm:instance-removed", NULL,
amxrt_save_changed, NULL);
378 when_true((storage_type == NULL) || (*storage_type == 0), exit);
379 when_true(strcmp(storage_type,
"odl") == 0, exit);
387 UNUSED
const amxc_var_t*
const data,
388 UNUSED
void*
const priv) {
401 if(amxp_dir_make(directory, 0777) != 0) {
410 amxc_var_set(
bool, save_opt,
false);
438 char* directory = NULL;
440 when_null(parser, exit);
447 rv = amxp_dir_owned_make(directory, 0777, uid, gid);
#define AMXRT_COPT_STORAGE
#define AMXRT_COPT_ON_CHANGED
#define AMXRT_COPT_EVENTS
#define AMXRT_COPT_STORAGE_DIR
#define AMXRT_COPT_DEFAULTS
#define AMXRT_COPT_DIRECTORY
#define AMXRT_COPT_OBJECTS
#define AMXRT_COPT_INIT_DELAY
PRIVATE void amxrt_print_message(const char *fmt,...)
PRIVATE void amxrt_print_error(const char *fmt,...)
static int amxrt_dm_save_object(amxo_parser_t *parser, amxd_object_t *object, const char *dir, const char *name)
static int amxrt_dm_load(amxd_dm_t *dm, amxo_parser_t *parser)
static int amxrt_odl_save_load_init(amxd_dm_t *dm, amxo_parser_t *parser)
static bool amxrt_save_check_tree(amxd_object_t *object)
static odl_storage_t storage
struct _odl_storage odl_storage_t
static void amxrt_save_add_path(const char *path)
static bool amxrt_save_check_paths(amxo_parser_t *parser, amxd_object_t *object)
static void amxrt_timed_save(UNUSED amxp_timer_t *const timer, UNUSED void *data)
static int amxrt_dm_save(amxd_dm_t *dm, amxo_parser_t *parser)
static void amxrt_save_subscribe(amxd_dm_t *dm)
static void amxrt_save_changed(const char *const sig_name, const amxc_var_t *const data, UNUSED void *const priv)
static char * amxrt_get_directory(amxo_parser_t *parser)
static amxc_var_t * amxrt_get_save_objects(amxo_parser_t *parser)
static bool amxrt_is_odl_storage_enabled(amxo_parser_t *parser)
static void amxrt_odl_save_load_cleanup(amxd_dm_t *dm, amxo_parser_t *parser)
int amxrt_dm_create_dir(amxo_parser_t *parser, uid_t uid, gid_t gid)
static bool amxrt_save_check_persistent_params(amxd_object_t *object, const amxc_var_t *data)
static void amxrt_monitor_changes(UNUSED const char *const sig_name, UNUSED const amxc_var_t *const data, UNUSED void *const priv)
int amxrt_dm_save_load_main(int reason, amxd_dm_t *dm, amxo_parser_t *parser)
The data model auto load and save module.
amxp_timer_t * save_timer