add: more basic macro stuff
add: more efficient relay loading (only ids)
This commit is contained in:
		
							parent
							
								
									f67b7e9e0f
								
							
						
					
					
						commit
						0103b0b2ff
					
				
					 7 changed files with 555 additions and 7 deletions
				
			
		| 
						 | 
					@ -36,7 +36,6 @@ void
 | 
				
			||||||
cache_invalidate_relay(int relay_id, int status_relay);
 | 
					cache_invalidate_relay(int relay_id, int status_relay);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
cache_put_json_controller(int controller_id, char *controller_json);
 | 
					cache_put_json_controller(int controller_id, char *controller_json);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -47,6 +46,16 @@ void
 | 
				
			||||||
cache_invalidate_controller(int controller_id);
 | 
					cache_invalidate_controller(int controller_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cache_put_json_macro(int macro_id, char *macro_json);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char*
 | 
				
			||||||
 | 
					cache_get_json_macro(int macro_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cache_invalidate_macro(int macro_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
cache_invalidate_tagged(int tag_id);
 | 
					cache_invalidate_tagged(int tag_id);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,4 +10,7 @@ junction_relay_schedule_remove_for_relay(int relay_id);
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
junction_relay_schedule_insert_weekdays(int relay_id, int *schedule_ids);
 | 
					junction_relay_schedule_insert_weekdays(int relay_id, int *schedule_ids);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int*
 | 
				
			||||||
 | 
					junction_relay_schedule_get_relay_ids_with_schedule(int schedule_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* CORE_MODELS_JUNCTION_RELAY_SCHEDULE_H */
 | 
					#endif /* CORE_MODELS_JUNCTION_RELAY_SCHEDULE_H */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										45
									
								
								include/models/macro.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								include/models/macro.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,45 @@
 | 
				
			||||||
 | 
					#ifndef CORE_MACRO_H
 | 
				
			||||||
 | 
					#define CORE_MACRO_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <uuid/uuid.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <cJSON.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <constants.h>
 | 
				
			||||||
 | 
					#include <models/period.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int id;
 | 
				
			||||||
 | 
					    uuid_t uid;
 | 
				
			||||||
 | 
					    char name[MAX_NAME_LENGTH + 1];
 | 
				
			||||||
 | 
					} macro_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					macro_save(macro_t *macro);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					macro_remove(macro_t *macro);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					macro_free(macro_t *macro);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					macro_free_list(macro_t **macro);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cJSON*
 | 
				
			||||||
 | 
					macro_to_json(macro_t *macro);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					macro_free_list(macro_t **macros_list);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					macro_t*
 | 
				
			||||||
 | 
					macro_get_by_id(int id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					macro_t*
 | 
				
			||||||
 | 
					macro_get_by_uid(uuid_t uid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					macro_t**
 | 
				
			||||||
 | 
					macro_get_all();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* CORE_MACRO_H */
 | 
				
			||||||
							
								
								
									
										37
									
								
								src/cache.c
									
										
									
									
									
								
							
							
						
						
									
										37
									
								
								src/cache.c
									
										
									
									
									
								
							| 
						 | 
					@ -2,6 +2,7 @@
 | 
				
			||||||
#include <logger.h>
 | 
					#include <logger.h>
 | 
				
			||||||
#include <sql/cache.h>
 | 
					#include <sql/cache.h>
 | 
				
			||||||
#include <models/junction_tag.h>
 | 
					#include <models/junction_tag.h>
 | 
				
			||||||
 | 
					#include <models/junction_relay_schedule.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
sqlite3 *cache_database;
 | 
					sqlite3 *cache_database;
 | 
				
			||||||
| 
						 | 
					@ -134,14 +135,14 @@ cache_invalidate_schedule(int schedule_id)
 | 
				
			||||||
    sprintf(key, "schedule_json:%d", schedule_id);
 | 
					    sprintf(key, "schedule_json:%d", schedule_id);
 | 
				
			||||||
    cache_invalidate(key);
 | 
					    cache_invalidate(key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    relay_t **relays = relay_get_with_schedule(schedule_id);
 | 
					    int *relay_ids = junction_relay_schedule_get_relay_ids_with_schedule(schedule_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for(int i = 0; relays[i] != NULL; ++i)
 | 
					    for(int i = 0; relay_ids[i] != 0; ++i)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        cache_invalidate_relay(relays[i]->id, -1);
 | 
					        cache_invalidate_relay(relay_ids[i], -1);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    relay_free_list(relays);
 | 
					    free(relay_ids);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -208,6 +209,34 @@ cache_invalidate_controller(int controller_id)
 | 
				
			||||||
    cache_invalidate(key);
 | 
					    cache_invalidate(key);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cache_put_json_macro(int macro_id, char *macro_json)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    char key[32];
 | 
				
			||||||
 | 
					    sprintf(key, "macro_json:%d", macro_id);
 | 
				
			||||||
 | 
					    cache_insert_value(key, macro_json);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char*
 | 
				
			||||||
 | 
					cache_get_json_macro(int macro_id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    char key[32];
 | 
				
			||||||
 | 
					    sprintf(key, "macro_json:%d", macro_id);
 | 
				
			||||||
 | 
					    return cache_get_value(key);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cache_invalidate_macro(int macro_id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    char key[32];
 | 
				
			||||||
 | 
					    sprintf(key, "macro_json:%d", macro_id);
 | 
				
			||||||
 | 
					    cache_invalidate(key);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
cache_invalidate_tagged(int tag_id)
 | 
					cache_invalidate_tagged(int tag_id)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -87,3 +87,14 @@ junction_relay_schedule_remove_for_relay(int relay_id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return rc == SQLITE_DONE;
 | 
					    return rc == SQLITE_DONE;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int*
 | 
				
			||||||
 | 
					junction_relay_schedule_get_relay_ids_with_schedule(int schedule_id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    sqlite3_stmt *stmt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sqlite3_prepare_v2(global_database, "SELECT relay_id FROM junction_relay_schedule WHERE schedule_id=?1;", -1, &stmt, NULL);
 | 
				
			||||||
 | 
					    sqlite3_bind_int(stmt, 1, schedule_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return database_helper_get_ids(stmt);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										451
									
								
								src/models/macro.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										451
									
								
								src/models/macro.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,451 @@
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <sqlite3.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <cache.h>
 | 
				
			||||||
 | 
					#include <cJSON.h>
 | 
				
			||||||
 | 
					#include <logger.h>
 | 
				
			||||||
 | 
					#include <database.h>
 | 
				
			||||||
 | 
					#include <models/macro.h>
 | 
				
			||||||
 | 
					#include <models/junction_macro.h>
 | 
				
			||||||
 | 
					#include <models/schedule.h>
 | 
				
			||||||
 | 
					#include <models/tag.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					db_update_insert(macro_t *macro, sqlite3_stmt *stmt)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    LOGGER_DEBUG("saving macro '%s' into database (id: %d)\n", macro->name, macro->id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int rc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sqlite3_bind_int(stmt, 1, macro->id);
 | 
				
			||||||
 | 
					    sqlite3_bind_blob(stmt, 2, macro->uid, sizeof(uuid_t), SQLITE_STATIC);
 | 
				
			||||||
 | 
					    sqlite3_bind_text(stmt, 3, macro->name, -1, SQLITE_STATIC);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    rc = sqlite3_step(stmt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sqlite3_finalize(stmt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    free(periods_blob);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return rc != SQLITE_DONE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static macro_t*
 | 
				
			||||||
 | 
					macro_db_select_mapper(sqlite3_stmt *stmt)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    const uint16_t *periods_blob;
 | 
				
			||||||
 | 
					    macro_t *new_macro = malloc(sizeof(macro_t));
 | 
				
			||||||
 | 
					    for(int i = 0; i < sqlite3_column_count(stmt); i++)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        const char *name = sqlite3_column_name(stmt, i);
 | 
				
			||||||
 | 
					        switch(name[0])
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            case 'i': // id
 | 
				
			||||||
 | 
					                new_macro->id = sqlite3_column_int(stmt, i);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case 'n': // name
 | 
				
			||||||
 | 
					                strncpy(new_macro->name, (const char*)sqlite3_column_text(stmt, i), MAX_NAME_LENGTH);
 | 
				
			||||||
 | 
					                new_macro->name[MAX_NAME_LENGTH] = '\0';
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case 'u': // uid
 | 
				
			||||||
 | 
					                uuid_copy(new_macro->uid, (const unsigned char*)sqlite3_column_blob(stmt, i));
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            default: // ignore columns not implemented
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return new_macro;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static macro_t**
 | 
				
			||||||
 | 
					macro_db_select(sqlite3_stmt *stmt)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    macro_t **all_macros = malloc(sizeof(macro_t*));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int row = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for(;;)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        int s;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        s = sqlite3_step(stmt);
 | 
				
			||||||
 | 
					        if (s == SQLITE_ROW)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            macro_t *new_macro = macro_db_select_mapper(stmt);
 | 
				
			||||||
 | 
					            row++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            all_macros = (macro_t**)realloc(all_macros, sizeof(macro_t*) * (row + 1));
 | 
				
			||||||
 | 
					            all_macros[row - 1] = new_macro;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if(s == SQLITE_DONE)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                LOGGER_ERR("error selecting macros from database: %s\n", sqlite3_errstr(s));
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    sqlite3_finalize(stmt);
 | 
				
			||||||
 | 
					    all_macros[row] = NULL;
 | 
				
			||||||
 | 
					    return all_macros;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					macro_save(macro_t *macro)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int opened_transaction = database_transaction_begin();
 | 
				
			||||||
 | 
					     
 | 
				
			||||||
 | 
					    sqlite3_stmt *stmt;
 | 
				
			||||||
 | 
					    if(macro->id)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        sqlite3_prepare_v2(global_database, "UPDATE macros SET uid = ?2, name = ?3, periods = ?4 WHERE id=?1;", -1, &stmt, NULL);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        sqlite3_prepare_v2(global_database, "INSERT INTO macros(uid, name, periods) values (?2, ?3, ?4);", -1, &stmt, NULL);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int result = db_update_insert(macro, stmt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(result)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if(macro->id)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            LOGGER_ERR("error inserting data: %s\n", sqlite3_errmsg(global_database));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            LOGGER_ERR("error updating data: %s\n", sqlite3_errmsg(global_database));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(opened_transaction)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            database_transaction_rollback();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if(!macro->id)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            macro->id = sqlite3_last_insert_rowid(global_database);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(opened_transaction)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            database_transaction_commit();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cache_invalidate_macro(macro->id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					macro_remove(macro_t *macro)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    sqlite3_stmt *stmt;
 | 
				
			||||||
 | 
					    if(!macro->id)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sqlite3_prepare_v2(global_database, "DELETE FROM macros WHERE id=?1;", -1, &stmt, NULL);
 | 
				
			||||||
 | 
					    sqlite3_bind_int(stmt, 1, macro->id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int rc = sqlite3_step(stmt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sqlite3_finalize(stmt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return rc != SQLITE_DONE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					macro_is_protected(macro_t *macro)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uuid_t tmp_uuid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memset(tmp_uuid, 0, sizeof(uuid_t));
 | 
				
			||||||
 | 
					    memcpy(tmp_uuid, "off", 3);
 | 
				
			||||||
 | 
					    if(uuid_compare(macro->uid, tmp_uuid) == 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memset(tmp_uuid, 0, sizeof(uuid_t));
 | 
				
			||||||
 | 
					    memcpy(tmp_uuid, "on", 2);
 | 
				
			||||||
 | 
					    if(uuid_compare(macro->uid, tmp_uuid) == 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					macro_free(macro_t *macro)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    free(macro->periods);
 | 
				
			||||||
 | 
					    free(macro);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					macro_free_list(macro_t **macros)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    for(int i = 0; macros[i] != NULL; ++i)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        macro_free(macros[i]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    free(macros);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint16_t*
 | 
				
			||||||
 | 
					macro_periods_to_blob(macro_t *macro)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint16_t *blob = malloc(sizeof(uint16_t) * ((macro->periods_count * 2) + 1));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    blob[0] = macro->periods_count;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for(int i = 0; i < macro->periods_count; i++)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        blob[(i * 2) + 1] = macro->periods[i].start;
 | 
				
			||||||
 | 
					        blob[(i * 2) + 2] = macro->periods[i].end;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return blob;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cJSON*
 | 
				
			||||||
 | 
					macro_to_json(macro_t *macro)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    cJSON *json;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    char *cached = cache_get_json_macro(macro->id);
 | 
				
			||||||
 | 
					    if(cached)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        json = cJSON_CreateRaw(cached);
 | 
				
			||||||
 | 
					        free(cached);
 | 
				
			||||||
 | 
					        return json;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    char uuid_str[UUID_STR_LEN];
 | 
				
			||||||
 | 
					    macro_uid_unparse(macro->uid, uuid_str);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    LOGGER_DEBUG("JSONifying macro %s\n", uuid_str);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    json = cJSON_CreateObject();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cJSON *json_name = cJSON_CreateString(macro->name);
 | 
				
			||||||
 | 
					    if(json_name == NULL)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        cJSON_Delete(json);
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    cJSON_AddItemToObject(json, "name", json_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cJSON *json_id = cJSON_CreateString(uuid_str);
 | 
				
			||||||
 | 
					    if(json_name == NULL)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        cJSON_Delete(json);
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    cJSON_AddItemToObject(json, "id", json_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cJSON *json_tags = cJSON_CreateArray();
 | 
				
			||||||
 | 
					    int *tags_ids = junction_tag_get_tags_for_macro_id(macro->id);
 | 
				
			||||||
 | 
					    if(tags_ids != NULL)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        for(int i = 0; tags_ids[i] != 0; ++i)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            char *tag = tag_get_tag(tags_ids[i]);
 | 
				
			||||||
 | 
					            if(tag == NULL)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                continue;   
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            cJSON *json_tag = cJSON_CreateString(tag);
 | 
				
			||||||
 | 
					            if (json_tag == NULL)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                LOGGER_DEBUG("failed to add tag from string '%s'\n", tag);
 | 
				
			||||||
 | 
					                free(tag);
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            cJSON_AddItemToArray(json_tags, json_tag);
 | 
				
			||||||
 | 
					            free(tag);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        free(tags_ids);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    cJSON_AddItemToObject(json, "tags", json_tags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    char *json_str = cJSON_Print(json);
 | 
				
			||||||
 | 
					    cache_put_json_macro(macro->id, json_str);
 | 
				
			||||||
 | 
					    cJSON_Delete(json);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    json = cJSON_CreateRaw(json_str);
 | 
				
			||||||
 | 
					    free(json_str);
 | 
				
			||||||
 | 
					    return json;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					macro_t*
 | 
				
			||||||
 | 
					macro_get_by_id_or_off(int id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    sqlite3_stmt *stmt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sqlite3_prepare_v2(global_database, "SELECT * FROM macros WHERE id = ?1;", -1, &stmt, NULL);
 | 
				
			||||||
 | 
					    sqlite3_bind_int(stmt, 1, id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    macro_t **sql_result = macro_db_select(stmt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    macro_t *result = sql_result[0];
 | 
				
			||||||
 | 
					    free(sql_result);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(result)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return result;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    uuid_t tmp_uuid;
 | 
				
			||||||
 | 
					    memset(tmp_uuid, 0, sizeof(uuid_t));
 | 
				
			||||||
 | 
					    memcpy(tmp_uuid, "off", 3);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return macro_get_by_uid(tmp_uuid);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					macro_t*
 | 
				
			||||||
 | 
					macro_get_by_id(int id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    LOGGER_DEBUG("getting macro [id=%d] from database\n", id);
 | 
				
			||||||
 | 
					    sqlite3_stmt *stmt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sqlite3_prepare_v2(global_database, "SELECT * FROM macros WHERE id = ?1;", -1, &stmt, NULL);
 | 
				
			||||||
 | 
					    sqlite3_bind_int(stmt, 1, id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    macro_t **sql_result = macro_db_select(stmt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    macro_t *result = sql_result[0];
 | 
				
			||||||
 | 
					    free(sql_result);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					macro_t*
 | 
				
			||||||
 | 
					macro_get_by_uid_or_off(uuid_t uid)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    char uuid_str[UUID_STR_LEN];
 | 
				
			||||||
 | 
					    macro_uid_unparse(uid, uuid_str);
 | 
				
			||||||
 | 
					    LOGGER_DEBUG("getting macro [uid=%s] or off from database\n", uuid_str);
 | 
				
			||||||
 | 
					    sqlite3_stmt *stmt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sqlite3_prepare_v2(global_database, "SELECT * FROM macros WHERE uid = ?1;", -1, &stmt, NULL);
 | 
				
			||||||
 | 
					    sqlite3_bind_blob(stmt, 1, uid, sizeof(uuid_t), SQLITE_STATIC);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    macro_t **sql_result = macro_db_select(stmt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    macro_t *result = sql_result[0];
 | 
				
			||||||
 | 
					    free(sql_result);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(result)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return result;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    uuid_t tmp_uuid;
 | 
				
			||||||
 | 
					    memset(tmp_uuid, 0, sizeof(uuid_t));
 | 
				
			||||||
 | 
					    memcpy(tmp_uuid, "off", 3);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return macro_get_by_uid(tmp_uuid);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					macro_t*
 | 
				
			||||||
 | 
					macro_get_by_uid(uuid_t uid)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    char uuid_str[UUID_STR_LEN];
 | 
				
			||||||
 | 
					    macro_uid_unparse(uid, uuid_str);
 | 
				
			||||||
 | 
					    LOGGER_DEBUG("getting macro [uid=%s] from database\n", uuid_str);
 | 
				
			||||||
 | 
					    sqlite3_stmt *stmt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sqlite3_prepare_v2(global_database, "SELECT * FROM macros WHERE uid = ?1;", -1, &stmt, NULL);
 | 
				
			||||||
 | 
					    sqlite3_bind_blob(stmt, 1, uid, sizeof(uuid_t), SQLITE_STATIC);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    macro_t **sql_result = macro_db_select(stmt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    macro_t *result = sql_result[0];
 | 
				
			||||||
 | 
					    free(sql_result);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					macro_t**
 | 
				
			||||||
 | 
					macro_get_relay_weekdays(int relay_id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    LOGGER_DEBUG("getting macros [relay_id=%d] from database\n", relay_id);
 | 
				
			||||||
 | 
					    sqlite3_stmt *stmt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sqlite3_prepare_v2(global_database, "SELECT macros.* FROM macros INNER JOIN junction_relay_macro ON macros.id == junction_relay_macro.macro_id WHERE junction_relay_macro.relay_id = ?1 ORDER BY junction_relay_macro.weekday ASC", -1, &stmt, NULL);
 | 
				
			||||||
 | 
					    sqlite3_bind_int(stmt, 1, relay_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return macro_db_select(stmt);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					macro_t**
 | 
				
			||||||
 | 
					macro_get_all()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    LOGGER_DEBUG("getting all macros from database\n");
 | 
				
			||||||
 | 
					    sqlite3_stmt *stmt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sqlite3_prepare_v2(global_database, "SELECT * FROM macros;", -1, &stmt, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return macro_db_select(stmt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					macro_uid_parse(const char *uid_str, uuid_t result)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if(strcmp("off", uid_str) == 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        memset(result, 0, sizeof(uuid_t));
 | 
				
			||||||
 | 
					        memcpy(result, "off", 3);
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if(strcmp("on", uid_str) == 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        memset(result, 0, sizeof(uuid_t));
 | 
				
			||||||
 | 
					        memcpy(result, "on", 2);
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(uuid_parse(uid_str, result))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					macro_uid_unparse(const uuid_t uid, char *result)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uuid_t tmp_uuid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memset(tmp_uuid, 0, sizeof(uuid_t));
 | 
				
			||||||
 | 
					    memcpy(tmp_uuid, "off", 3);
 | 
				
			||||||
 | 
					    if(uuid_compare(uid, tmp_uuid) == 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        strcpy(result, "off");
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memset(tmp_uuid, 0, sizeof(uuid_t));
 | 
				
			||||||
 | 
					    memcpy(tmp_uuid, "on", 2);
 | 
				
			||||||
 | 
					    if(uuid_compare(uid, tmp_uuid) == 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        strcpy(result, "on");
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uuid_unparse(uid, result);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -46,8 +46,8 @@ schedule_db_select_mapper(sqlite3_stmt *stmt)
 | 
				
			||||||
                new_schedule->id = sqlite3_column_int(stmt, i);
 | 
					                new_schedule->id = sqlite3_column_int(stmt, i);
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case 'n': // name
 | 
					            case 'n': // name
 | 
				
			||||||
                strncpy(new_schedule->name, (const char*)sqlite3_column_text(stmt, i), 127);
 | 
					                strncpy(new_schedule->name, (const char*)sqlite3_column_text(stmt, i), MAX_NAME_LENGTH);
 | 
				
			||||||
                new_schedule->name[127] = '\0';
 | 
					                new_schedule->name[MAX_NAME_LENGTH] = '\0';
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case 'p': // periods
 | 
					            case 'p': // periods
 | 
				
			||||||
                periods_blob = sqlite3_column_blob(stmt, i);
 | 
					                periods_blob = sqlite3_column_blob(stmt, i);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue