2019-07-22 20:06:13 +00:00
# include <cstdio>
# include <cstring>
# include <trantor/utils/Logger.h>
2019-07-29 20:02:38 +00:00
# include <sys/socket.h>
# include <unistd.h>
2020-02-23 19:06:14 +00:00
# include <uuid/uuid.h>
2019-07-22 20:06:13 +00:00
# include <helpers.h>
2020-04-18 19:29:52 +00:00
# include <binn.h>
# include <enums.h>
2019-07-22 20:06:13 +00:00
# include "controller_dbo.h"
# include "globals.h"
2019-07-29 20:02:38 +00:00
controller_dbo : : ~ controller_dbo ( )
{
2019-08-04 21:44:38 +00:00
if ( this - > relays )
{
relay_dbo : : free_list ( this - > relays ) ;
}
2019-07-29 20:02:38 +00:00
}
2019-07-22 20:06:13 +00:00
static bool controller_db_update_insert ( controller_dbo * controller , sqlite3_stmt * stmt )
{
int rc ;
2020-02-23 19:06:14 +00:00
sqlite3_bind_blob ( stmt , 1 , controller - > id , sizeof ( uuid_t ) , SQLITE_STATIC ) ;
2019-07-22 20:06:13 +00:00
sqlite3_bind_text ( stmt , 2 , controller - > name , - 1 , SQLITE_STATIC ) ;
sqlite3_bind_text ( stmt , 3 , controller - > ip , - 1 , SQLITE_STATIC ) ;
sqlite3_bind_int ( stmt , 4 , controller - > active ) ;
sqlite3_bind_int ( stmt , 5 , controller - > port ) ;
sqlite3_bind_int ( stmt , 6 , controller - > relay_count ) ;
2019-09-24 21:33:35 +00:00
sqlite3_bind_text ( stmt , 7 , controller - > tag , - 1 , SQLITE_STATIC ) ;
2019-07-22 20:06:13 +00:00
rc = sqlite3_step ( stmt ) ;
if ( rc ! = SQLITE_DONE )
{
printf ( " ERROR inserting data: %s \n " , sqlite3_errmsg ( globals : : db ) ) ;
return false ;
}
sqlite3_finalize ( stmt ) ;
return true ;
}
static controller_dbo *
controller_db_select_mapper ( sqlite3_stmt * stmt )
{
auto * new_controller = new controller_dbo ( ) ;
2020-01-02 20:55:42 +00:00
const char * new_tag ;
2019-07-22 20:06:13 +00:00
for ( int i = 0 ; i < sqlite3_column_count ( stmt ) ; i + + )
{
const char * name = sqlite3_column_name ( stmt , i ) ;
switch ( name [ 0 ] )
{
case ' a ' : // active
new_controller - > active = ( bool ) sqlite3_column_int ( stmt , i ) ;
break ;
case ' i ' :
switch ( name [ 1 ] )
{
case ' d ' : // id
2020-02-23 19:06:14 +00:00
uuid_copy ( new_controller - > id , ( const unsigned char * ) sqlite3_column_blob ( stmt , i ) ) ;
2019-07-22 20:06:13 +00:00
break ;
case ' p ' : // ip
strncpy ( new_controller - > ip , ( const char * ) sqlite3_column_text ( stmt , i ) , 16 ) ;
break ;
default : // ignore columns not implemented
break ;
}
break ;
case ' n ' : // name
strncpy ( new_controller - > name , ( const char * ) sqlite3_column_text ( stmt , i ) , 127 ) ;
break ;
case ' p ' : // port
new_controller - > port = sqlite3_column_int ( stmt , i ) ;
break ;
case ' r ' : // relay_count
new_controller - > relay_count = sqlite3_column_int ( stmt , i ) ;
break ;
2019-09-24 21:33:35 +00:00
case ' t ' : // tag
2020-01-02 20:55:42 +00:00
new_tag = ( const char * ) sqlite3_column_text ( stmt , i ) ;
new_controller - > tag [ 0 ] = ' \0 ' ;
if ( new_tag )
{
strncpy ( new_controller - > tag , ( const char * ) sqlite3_column_text ( stmt , i ) , 63 ) ;
}
2019-09-24 21:33:35 +00:00
break ;
2019-07-22 20:06:13 +00:00
default : // ignore columns not implemented
break ;
}
}
return new_controller ;
}
static controller_dbo * *
controller_db_select ( sqlite3_stmt * stmt )
{
auto * * all_controllers = ( controller_dbo * * ) malloc ( sizeof ( controller_dbo * ) ) ;
int row = 0 ;
while ( true )
{
int s ;
s = sqlite3_step ( stmt ) ;
if ( s = = SQLITE_ROW )
{
controller_dbo * new_controller = controller_db_select_mapper ( stmt ) ;
2020-02-23 19:06:14 +00:00
new_controller - > relays = relay_dbo : : get_by_simple ( " controller_id " , new_controller - > id , ( intptr_t ) & sqlite3_bind_blob , sizeof ( uuid_t ) ) ;
2019-07-22 20:06:13 +00:00
row + + ;
all_controllers = ( controller_dbo * * ) realloc ( all_controllers , sizeof ( controller_dbo * ) * ( row + 1 ) ) ;
all_controllers [ row - 1 ] = new_controller ;
}
else
{
if ( s = = SQLITE_DONE )
{
break ;
}
else
{
LOG_ERROR < < " Error Selecting controllers from database " ;
sqlite3_finalize ( stmt ) ;
return nullptr ;
}
}
}
sqlite3_finalize ( stmt ) ;
all_controllers [ row ] = nullptr ;
return all_controllers ;
}
bool
controller_dbo : : update ( )
{
sqlite3_stmt * stmt ;
2019-09-24 21:33:35 +00:00
sqlite3_prepare_v2 ( globals : : db , " UPDATE controllers set name = ?2, ip = ?3, active = ?4, port = ?5, relay_count = ?6, tag = ?7 WHERE id = ?1; " , - 1 , & stmt , nullptr ) ;
2019-07-22 20:06:13 +00:00
return controller_db_update_insert ( this , stmt ) ;
}
bool
controller_dbo : : insert ( )
{
sqlite3_stmt * stmt ;
2019-09-24 21:33:35 +00:00
sqlite3_prepare_v2 ( globals : : db , " INSERT INTO controllers(id, name, ip, active, port, relay_count, tag) values (?1, ?2, ?3, ?4, ?5, ?6, ?7); " , - 1 , & stmt , nullptr ) ;
2019-07-22 20:06:13 +00:00
return controller_db_update_insert ( this , stmt ) ;
}
bool
controller_dbo : : remove ( )
{
sqlite3_stmt * stmt ;
int rc ;
sqlite3_prepare_v2 ( globals : : db , " DELETE FROM controllers WHERE id=?1; " , - 1 , & stmt , nullptr ) ;
2020-02-23 19:06:14 +00:00
sqlite3_bind_blob ( stmt , 1 , this - > id , sizeof ( uuid_t ) , SQLITE_STATIC ) ;
2019-07-22 20:06:13 +00:00
rc = sqlite3_step ( stmt ) ;
sqlite3_finalize ( stmt ) ;
return rc = = SQLITE_DONE ;
}
Json : : Value
controller_dbo : : to_json ( )
{
2020-02-23 19:06:14 +00:00
char id_str [ 37 ] ;
uuid_unparse ( this - > id , id_str ) ;
2019-07-22 20:06:13 +00:00
Json : : Value controller_json ;
controller_json [ " name " ] = this - > name ;
2020-02-23 19:06:14 +00:00
controller_json [ " id " ] = id_str ;
2019-07-22 20:06:13 +00:00
controller_json [ " ip " ] = this - > ip ;
controller_json [ " relay_count " ] = this - > relay_count ;
controller_json [ " active " ] = this - > active ;
2019-09-24 21:33:35 +00:00
controller_json [ " tag " ] = this - > tag ;
2019-07-22 20:06:13 +00:00
2019-07-29 20:02:38 +00:00
controller_json [ " relays " ] = Json : : arrayValue ;
for ( int i = 0 ; this - > relays [ i ] ! = nullptr ; i + + )
{
controller_json [ " relays " ] . append ( this - > relays [ i ] - > to_json ( ) ) ;
}
2019-07-22 20:06:13 +00:00
return controller_json ;
}
controller_dbo * *
controller_dbo : : get_all ( )
{
sqlite3_stmt * stmt ;
sqlite3_prepare_v2 ( globals : : db , " SELECT * FROM controllers; " , - 1 , & stmt , nullptr ) ;
return controller_db_select ( stmt ) ;
}
controller_dbo * *
2020-02-23 19:06:14 +00:00
controller_dbo : : get_by_simple ( const char * key , const void * value , intptr_t bind_func , int bind_func_param )
2019-07-22 20:06:13 +00:00
{
helpers : : sql_filter_builder * filters [ 1 ] ;
helpers : : sql_filter_builder filter
{
key ,
value ,
bind_func ,
2020-02-23 19:06:14 +00:00
bind_func_param ,
2019-07-22 20:06:13 +00:00
" ; "
} ;
filters [ 0 ] = & filter ;
sqlite3_stmt * stmt = helpers : : create_sql_filtered_query ( " SELECT * FROM controllers WHERE " , filters ) ;
return controller_db_select ( stmt ) ;
}
controller_dbo * *
controller_dbo : : get_by ( helpers : : sql_filter_builder * * filters )
{
sqlite3_stmt * stmt = helpers : : create_sql_filtered_query ( " SELECT * FROM controllers WHERE " , filters ) ;
return controller_db_select ( stmt ) ;
}
2019-07-29 20:02:38 +00:00
bool
2020-04-18 19:29:52 +00:00
controller_dbo : : command ( binn * payload )
2019-07-29 20:02:38 +00:00
{
2020-04-18 19:29:52 +00:00
LOG_DEBUG < < " Commanding " < < binn_map_uint8 ( payload , COMMAND_MAPPING_CODE ) ;
int bytes_transferred ;
2019-08-04 21:44:38 +00:00
char port_str [ 6 ] ;
sprintf ( port_str , " %d " , this - > port ) ;
2019-07-29 20:02:38 +00:00
2020-04-18 19:29:52 +00:00
void * payload_ptr = binn_ptr ( payload ) ;
uint32_t payload_size = binn_size ( payload ) ;
int fd_controller = helpers : : open_tcp_connection ( this - > ip , port_str ) ;
2019-07-29 20:02:38 +00:00
2020-04-18 19:29:52 +00:00
if ( fd_controller = = - 1 )
2019-07-29 20:02:38 +00:00
{
2019-08-04 21:44:38 +00:00
LOG_ERROR < < " Can't open command socket " < < this - > ip < < " : " < < port_str ;
2019-07-29 20:02:38 +00:00
return false ;
}
2020-04-18 19:29:52 +00:00
if ( ( bytes_transferred = send ( fd_controller , & payload_size , sizeof ( payload_size ) , 0 ) ) < = 0 )
{
LOG_ERROR < < " error during sending size " ;
return false ;
}
if ( ( bytes_transferred = send ( fd_controller , payload_ptr , payload_size , 0 ) ) < = 0 )
{
LOG_ERROR < < " error during sending " ;
return false ;
}
close ( fd_controller ) ;
2019-07-29 20:02:38 +00:00
return true ;
}
2019-07-22 20:06:13 +00:00
void
controller_dbo : : free_list ( controller_dbo * * controllers_list )
{
for ( int i = 0 ; controllers_list [ i ] ! = nullptr ; i + + )
{
2019-07-29 20:02:38 +00:00
delete controllers_list [ i ] ;
2019-07-22 20:06:13 +00:00
}
free ( controllers_list ) ;
}