#include #include #include #include #include #include #include static int schedule_load_single(MDB_txn *mdb_txn, MDB_dbi mdb_dbi, db_key_schedule_e key_schedule, uint8_t relay_num, uint8_t weekday, MDB_val *value) { int err; size_t key_size = sizeof(db_key_schedule_e) + (2 * sizeof(uint8_t)); uint8_t *key_data = malloc(key_size); uint8_t *key_data_writer = key_data; memmove(key_data_writer, &relay_num, sizeof(uint8_t)); key_data_writer += sizeof(uint8_t); memmove(key_data_writer, &weekday, sizeof(uint8_t)); key_data_writer += sizeof(uint8_t); memmove(key_data_writer, &key_schedule, sizeof(db_key_schedule_e)); MDB_val key; key.mv_size = key_size; key.mv_data = key_data; if((err = mdb_get(mdb_txn, mdb_dbi, &key, value)) != 0) { LOG_ERROR("mdb_get error %s\n", mdb_strerror(err)); mdb_txn_abort(mdb_txn); free(key_data); return 1; } free(key_data); return 0; } schedule_t* schedule_load(MDB_env *mdb_env, uint8_t relay_num, uint8_t weekday) { int err; MDB_txn *mdb_txn; MDB_dbi mdb_dbi; schedule_t *new_schedule; uuid_t off_id; memset(off_id, 0, sizeof(uuid_t)); memcpy(off_id, "off", 3); if((err = mdb_txn_begin(mdb_env, NULL, MDB_RDONLY, &mdb_txn)) != 0) { LOG_ERROR("mdb_txn_begin error %s\n", mdb_strerror(err)); return schedule_create(off_id, weekday, 0, NULL); } if((err = mdb_dbi_open(mdb_txn, "schedules", 0, &mdb_dbi)) != 0) { switch(err) { case MDB_NOTFOUND: LOG_INFO("no schedule db found in db. returning new one (no schedules db)\n"); mdb_txn_abort(mdb_txn); break; default: LOG_ERROR("mdb_txn_begin error %s\n", mdb_strerror(err)); } return schedule_create(off_id, weekday, 0, NULL); } MDB_val value; if((err = schedule_load_single(mdb_txn, mdb_dbi, DB_KEY_SCHEDULE_ID, relay_num, weekday, &value)) != 0) { LOG_INFO("no schedule for relay %d and weekday %d found in db. returning new one\n", relay_num, weekday); mdb_txn_abort(mdb_txn); // transaction is read only return schedule_create(off_id, weekday, 0, NULL); } uuid_t *schedule_id = (uuid_t*)value.mv_data; if((err = schedule_load_single(mdb_txn, mdb_dbi, DB_KEY_SCHEDULE_PERIODS, relay_num, weekday, &value)) != 0) { LOG_INFO("no schedule for relay %d and weekday %d found in db. returning new one\n", relay_num, weekday); mdb_txn_abort(mdb_txn); // transaction is read only return schedule_create(off_id, weekday, 0, NULL); } uint16_t schedule_periods_length = ((uint16_t*)value.mv_data)[0]; uint16_t *schedule_periods = ((uint16_t*)value.mv_data) + 1; new_schedule = schedule_create(*schedule_id, weekday, schedule_periods_length, schedule_periods); mdb_txn_abort(mdb_txn); // transaction is read only return new_schedule; }