2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Asterisk  - -  An  open  source  telephony  toolkit . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Copyright  ( C )  2011 ,  Terry  Wilson 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Terry  Wilson  < twilson @ digium . com > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  See  http : //www.asterisk.org for more information about
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  the  Asterisk  project .  Please  do  not  directly  contact 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  any  of  the  maintainers  of  this  project  for  assistance ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  the  project  provides  a  web  site ,  mailing  lists  and  IRC 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  channels  for  your  use . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  This  program  is  free  software ,  distributed  under  the  terms  of 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  the  GNU  General  Public  License  Version  2.  See  the  LICENSE  file 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  at  the  top  of  the  source  tree . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! \file
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  SQLite  3  configuration  engine 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ author \ verbatim  Terry  Wilson  < twilson @ digium . com >  \ endverbatim 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  This  is  a  realtime  configuration  engine  for  the  SQLite  3  Database 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ ingroup  resources 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-10-14 21:44:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*! \li \ref res_config_sqlite3.c uses the configuration file \ref res_config_sqlite3.conf
  
						 
					
						
							
								
									
										
										
										
											2012-10-01 23:24:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ addtogroup  configuration_file  Configuration  Files 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-12-22 09:23:22 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
									
										
										
										
											2012-10-01 23:24:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ page  res_config_sqlite3 . conf  res_config_sqlite3 . conf 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ verbinclude  res_config_sqlite3 . conf . sample 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*** MODULEINFO
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									< depend > sqlite3 < / depend > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									< support_level > core < / support_level > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * * */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <sqlite3.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/module.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/config.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/paths.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/astobj2.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/lock.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/utils.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/app.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*** DOCUMENTATION
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * * */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-16 09:38:06 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  has_explicit_like_escaping ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								static  struct  ast_config  * realtime_sqlite3_load ( const  char  * database ,  const  char  * table ,  const  char  * configfile ,  struct  ast_config  * config ,  struct  ast_flags  flags ,  const  char  * suggested_include_file ,  const  char  * who_asked ) ;  
						 
					
						
							
								
									
										
										
										
											2013-04-27 12:01:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  struct  ast_variable  * realtime_sqlite3 ( const  char  * database ,  const  char  * table ,  const  struct  ast_variable  * fields ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  ast_config  * realtime_sqlite3_multi ( const  char  * database ,  const  char  * table ,  const  struct  ast_variable  * fields ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  realtime_sqlite3_update ( const  char  * database ,  const  char  * table ,  const  char  * keyfield ,  const  char  * entity ,  const  struct  ast_variable  * fields ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  realtime_sqlite3_update2 ( const  char  * database ,  const  char  * table ,  const  struct  ast_variable  * lookup_fields ,  const  struct  ast_variable  * update_fields ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  realtime_sqlite3_store ( const  char  * database ,  const  char  * table ,  const  struct  ast_variable  * fields ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  realtime_sqlite3_destroy ( const  char  * database ,  const  char  * table ,  const  char  * keyfield ,  const  char  * entity ,  const  struct  ast_variable  * fields ) ;  
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								static  int  realtime_sqlite3_require ( const  char  * database ,  const  char  * table ,  va_list  ap ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  realtime_sqlite3_unload ( const  char  * database ,  const  char  * table ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								struct  ast_config_engine  sqlite3_config_engine  =  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. name  =  " sqlite3 " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. load_func  =  realtime_sqlite3_load , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. realtime_func  =  realtime_sqlite3 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. realtime_multi_func  =  realtime_sqlite3_multi , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. update_func  =  realtime_sqlite3_update , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. update2_func  =  realtime_sqlite3_update2 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. store_func  =  realtime_sqlite3_store , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. destroy_func  =  realtime_sqlite3_destroy , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. require_func  =  realtime_sqlite3_require , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. unload_func  =  realtime_sqlite3_unload , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								enum  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									REALTIME_SQLITE3_REQ_WARN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									REALTIME_SQLITE3_REQ_CLOSE , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									REALTIME_SQLITE3_REQ_CHAR , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								struct  realtime_sqlite3_db  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_DECLARE_STRING_FIELDS ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AST_STRING_FIELD ( name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AST_STRING_FIELD ( filename ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sqlite3  * handle ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pthread_t  syncthread ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_cond_t  cond ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  requirements : 2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  dirty : 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  debug : 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  exiting : 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  wakeup : 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-23 13:58:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									unsigned  int  has_batch_thread : 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									unsigned  int  batch ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-23 18:07:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  busy_timeout ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								struct  ao2_container  * databases ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define DB_BUCKETS 7 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								AST_MUTEX_DEFINE_STATIC ( config_lock ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* We need a separate buffer for each field we might use concurrently */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								AST_THREADSTORAGE ( escape_table_buf ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								AST_THREADSTORAGE ( escape_column_buf ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								AST_THREADSTORAGE ( escape_value_buf ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-16 06:46:04 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								typedef  int  ( * callback_t ) ( void * ,  int ,  char  * * ,  char  * * ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  realtime_sqlite3_exec_query_with_handle ( struct  realtime_sqlite3_db  * ,  const  char  * ,  callback_t ,  void  * ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  realtime_sqlite3_exec_query ( const  char  * ,  const  char  * ,  callback_t ,  void  * ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  realtime_sqlite3_exec_update_with_handle ( struct  realtime_sqlite3_db  * ,  const  char  * ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  realtime_sqlite3_exec_update ( const  char  * ,  const  char  * ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								void  db_start_batch ( struct  realtime_sqlite3_db  * db ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  db_stop_batch ( struct  realtime_sqlite3_db  * db ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  inline  const  char  * sqlite3_escape_string_helper ( struct  ast_threadstorage  * ts ,  const  char  * param )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									size_t  maxlen  =  strlen ( param )  *  2  +  sizeof ( " \" \" " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* It doesn't appear that sqlite3_snprintf will do more than double the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  length  of  a  string  with  % q  as  an  option .  % Q  could  double  and  possibly 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  add  two  quotes ,  and  convert  NULL  pointers  to  the  word  " NULL " ,  but  we 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  don ' t  allow  those  anyway .  Just  going  to  use  % q  for  now .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_str  * buf  =  ast_str_thread_get ( ts ,  maxlen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  q  =  ts  = =  & escape_value_buf  ?  ' \' '  :  ' " ' ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-16 15:14:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									char  * tmp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_str_size ( buf )  <  maxlen )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* realloc if buf is too small */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_str_make_space ( & buf ,  maxlen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									tmp  =  ast_str_buffer ( buf ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_str_reset ( buf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									* tmp + +  =  q ;  /* Initial quote */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( ( * tmp + +  =  * param + + ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Did we just copy a quote? Then double it. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( * ( tmp  -  1 )  = =  q )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											* tmp + +  =  q ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									* tmp  =  ' \0 ' ;  /* Terminate past NULL from copy */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									* ( tmp  -  1 )  =  q ;  /* Replace original NULL with the quote */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_str_update ( buf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ast_str_buffer ( buf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  inline  const  char  * sqlite3_escape_table ( const  char  * param )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  sqlite3_escape_string_helper ( & escape_table_buf ,  param ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  inline  const  char  * sqlite3_escape_column ( const  char  * param )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  sqlite3_escape_string_helper ( & escape_column_buf ,  param ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* Not inlining this function because it uses strdupa and I don't know if the compiler would be dumb */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  const  char  * sqlite3_escape_column_op ( const  char  * param )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									size_t  maxlen  =  strlen ( param )  *  2  +  sizeof ( " \" \"  = " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_str  * buf  =  ast_str_thread_get ( & escape_column_buf ,  maxlen ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-16 15:14:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									char  * tmp ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									int  space  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-02-16 15:14:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ast_str_size ( buf )  <  maxlen )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* realloc if buf is too small */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_str_make_space ( & buf ,  maxlen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									tmp  =  ast_str_buffer ( buf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									ast_str_reset ( buf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									* tmp + +  =  ' " ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( ( * tmp + +  =  * param + + ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* If we have seen a space, don't double quotes. XXX If we ever make the column/op field
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  available  to  users  via  an  API ,  we  will  definitely  need  to  avoid  allowing  special 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  characters  like  ' ; '  in  the  data  past  the  space  as  it  will  be  unquoted  data  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( space )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( * ( tmp  -  1 )  = =  '   ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											* ( tmp  -  1 )  =  ' " ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											* tmp + +  =  '   ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											space  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( * ( tmp  -  1 )  = =  ' " ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											* tmp + +  =  ' " ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! space )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										strcpy ( tmp  -  1 ,  " \"  = " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_str_update ( buf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ast_str_buffer ( buf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  inline  const  char  * sqlite3_escape_value ( const  char  * param )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  sqlite3_escape_string_helper ( & escape_value_buf ,  param ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  db_hash_fn ( const  void  * obj ,  const  int  flags )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  struct  realtime_sqlite3_db  * db  =  obj ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ast_str_hash ( flags  &  OBJ_KEY  ?  ( const  char  * )  obj  :  db - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  db_cmp_fn ( void  * obj ,  void  * arg ,  int  flags )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  realtime_sqlite3_db  * db  =  obj ,  * other  =  arg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  char  * name  =  arg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ! strcasecmp ( db - > name ,  flags  &  OBJ_KEY  ?  name  :  other - > name )  ?  CMP_MATCH  |  CMP_STOP  :  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  db_destructor ( void  * obj )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  realtime_sqlite3_db  * db  =  obj ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_debug ( 1 ,  " Destroying db: %s \n " ,  db - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_string_field_free_memory ( db ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									db_stop_batch ( db ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( db - > handle )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ao2_lock ( db ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										sqlite3_close ( db - > handle ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ao2_unlock ( db ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  realtime_sqlite3_db  * find_database ( const  char  * database )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ao2_find ( databases ,  database ,  OBJ_KEY ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  unref_db ( struct  realtime_sqlite3_db  * * db )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ao2_ref ( * db ,  - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									* db  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  stop_batch_cb ( void  * obj ,  void  * arg ,  int  flags )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  realtime_sqlite3_db  * db  =  obj ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									db_stop_batch ( db ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  CMP_MATCH ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  mark_dirty_cb ( void  * obj ,  void  * arg ,  int  flags )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  realtime_sqlite3_db  * db  =  obj ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									db - > dirty  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  CMP_MATCH ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  mark_all_databases_dirty ( void )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ao2_callback ( databases ,  OBJ_MULTIPLE  |  OBJ_NODATA ,  mark_dirty_cb ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  is_dirty_cb ( void  * obj ,  void  * arg ,  int  flags )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  realtime_sqlite3_db  * db  =  obj ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( db - > dirty )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										db_stop_batch ( db ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  CMP_MATCH ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  unlink_dirty_databases ( void )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ao2_callback ( databases ,  OBJ_MULTIPLE  |  OBJ_NODATA  |  OBJ_UNLINK ,  is_dirty_cb ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  str_to_requirements ( const  char  * data )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! strcasecmp ( data ,  " createclose " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  REALTIME_SQLITE3_REQ_CLOSE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( ! strcasecmp ( data ,  " createchar " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  REALTIME_SQLITE3_REQ_CHAR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* default */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  REALTIME_SQLITE3_REQ_WARN ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! \note Since this is called while a query is executing, we should already hold the db lock */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  trace_cb ( void  * arg ,  const  char  * sql )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  realtime_sqlite3_db  * db  =  arg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_debug ( 3 ,  " DB: %s SQL: %s \n " ,  db - > name ,  sql ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! \brief Wrap commands in transactions increased write performance */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  * db_sync_thread ( void  * data )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  realtime_sqlite3_db  * db  =  data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ao2_lock ( db ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-16 06:46:04 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									realtime_sqlite3_exec_query_with_handle ( db ,  " BEGIN TRANSACTION " ,  NULL ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									for  ( ; ; )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! db - > wakeup )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_cond_wait ( & db - > cond ,  ao2_object_get_lockaddr ( db ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										db - > wakeup  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-16 06:46:04 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( realtime_sqlite3_exec_query_with_handle ( db ,  " COMMIT " ,  NULL ,  NULL )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											realtime_sqlite3_exec_query_with_handle ( db ,  " ROLLBACK " ,  NULL ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( db - > exiting )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ao2_unlock ( db ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-16 06:46:04 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										realtime_sqlite3_exec_query_with_handle ( db ,  " BEGIN TRANSACTION " ,  NULL ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										ao2_unlock ( db ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										usleep ( 1000  *  db - > batch ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ao2_lock ( db ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unref_db ( & db ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! \brief Open a database and appropriately set debugging on the db handle */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  db_open ( struct  realtime_sqlite3_db  * db )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ao2_lock ( db ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( sqlite3_open ( db - > filename ,  & db - > handle )  ! =  SQLITE_OK )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Could not open %s: %s \n " ,  db - > filename ,  sqlite3_errmsg ( db - > handle ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ao2_unlock ( db ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-23 18:07:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									sqlite3_busy_timeout ( db - > handle ,  db - > busy_timeout ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( db - > debug )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										sqlite3_trace ( db - > handle ,  trace_cb ,  db ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										sqlite3_trace ( db - > handle ,  NULL ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ao2_unlock ( db ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  db_sync ( struct  realtime_sqlite3_db  * db )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									db - > wakeup  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_cond_signal ( & db - > cond ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  db_start_batch ( struct  realtime_sqlite3_db  * db )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( db - > batch )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_cond_init ( & db - > cond ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ao2_ref ( db ,  + 1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-23 13:58:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										db - > has_batch_thread  =  ! ast_pthread_create_background ( & db - > syncthread ,  NULL ,  db_sync_thread ,  db ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  db_stop_batch ( struct  realtime_sqlite3_db  * db )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2019-07-23 13:58:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( db - > has_batch_thread )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										db - > has_batch_thread  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										db - > exiting  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										db_sync ( db ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pthread_join ( db - > syncthread ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! \brief Create a db object based on a config category
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ note  Opening  the  db  handle  and  linking  to  databases  must  be  handled  outside  of  this  function 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  realtime_sqlite3_db  * new_realtime_sqlite3_db ( struct  ast_config  * config ,  const  char  * cat )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_variable  * var ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  realtime_sqlite3_db  * db ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( db  =  ao2_alloc ( sizeof ( * db ) ,  db_destructor ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_string_field_init ( db ,  64 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										unref_db ( & db ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Set defaults */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									db - > requirements  =  REALTIME_SQLITE3_REQ_WARN ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									db - > batch  =  100 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_string_field_set ( db ,  name ,  cat ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-23 18:07:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									db - > busy_timeout  =  1000 ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( var  =  ast_variable_browse ( config ,  cat ) ;  var ;  var  =  var - > next )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! strcasecmp ( var - > name ,  " dbfile " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_string_field_set ( db ,  filename ,  var - > value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strcasecmp ( var - > name ,  " requirements " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											db - > requirements  =  str_to_requirements ( var - > value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strcasecmp ( var - > name ,  " batch " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_app_parse_timelen ( var - > value ,  ( int  * )  & db - > batch ,  TIMELEN_MILLISECONDS ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strcasecmp ( var - > name ,  " debug " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											db - > debug  =  ast_true ( var - > value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-23 18:07:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  if  ( ! strcasecmp ( var - > name ,  " busy_timeout " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ast_parse_arg ( var - > value ,  PARSE_INT32 | PARSE_DEFAULT ,  & ( db - > busy_timeout ) ,  1000 )  ! =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " Invalid busy_timeout value '%s' at res_config_sqlite3.conf:%d. Using 1000 instead. \n " ,  var - > value ,  var - > lineno ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_strlen_zero ( db - > filename ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Must specify dbfile in res_config_sqlite3.conf \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										unref_db ( & db ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  db ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! \brief Update an existing db object based on config data
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  db  The  database  object  to  update 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  config  The  configuration  data  with  which  to  update  the  db 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  cat  The  config  category  ( which  becomes  db - > name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  update_realtime_sqlite3_db ( struct  realtime_sqlite3_db  * db ,  struct  ast_config  * config ,  const  char  * cat )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  realtime_sqlite3_db  * new ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( new  =  new_realtime_sqlite3_db ( config ,  cat ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Copy fields that don't need anything special done on change */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									db - > requirements  =  new - > requirements ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Handle changes that require immediate behavior modification */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( db - > debug  ! =  new - > debug )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( db - > debug )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											sqlite3_trace ( db - > handle ,  NULL ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											sqlite3_trace ( db - > handle ,  trace_cb ,  db ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										db - > debug  =  new - > debug ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( strcmp ( db - > filename ,  new - > filename ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										sqlite3_close ( db - > handle ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_string_field_set ( db ,  filename ,  new - > filename ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										db_open ( db ) ;  /* Also handles setting appropriate debug on new handle */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-05-23 18:07:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( db - > busy_timeout  ! =  new - > busy_timeout )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										db - > busy_timeout  =  new - > busy_timeout ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										sqlite3_busy_timeout ( db - > handle ,  db - > busy_timeout ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  ( db - > batch  ! =  new - > batch )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( db - > batch  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											db - > batch  =  new - > batch ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											db_start_batch ( db ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( new - > batch  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											db - > batch  =  new - > batch ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											db_stop_batch ( db ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										db - > batch  =  new - > batch ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									db - > dirty  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unref_db ( & new ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! \brief Create a varlist from a single sqlite3 result row */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  row_to_varlist ( void  * arg ,  int  num_columns ,  char  * * values ,  char  * * columns )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_variable  * * head  =  arg ,  * tail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_variable  * new ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( new  =  ast_variable_new ( columns [ 0 ] ,  S_OR ( values [ 0 ] ,  " " ) ,  " " ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  SQLITE_ABORT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									* head  =  tail  =  new ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( i  =  1 ;  i  <  num_columns ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! ( new  =  ast_variable_new ( columns [ i ] ,  S_OR ( values [ i ] ,  " " ) ,  " " ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_variables_destroy ( * head ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											* head  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  SQLITE_ABORT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										tail - > next  =  new ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										tail  =  new ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! \brief Callback for creating an ast_config from a successive sqlite3 result rows */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  append_row_to_cfg ( void  * arg ,  int  num_columns ,  char  * * values ,  char  * * columns )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_config  * cfg  =  arg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_category  * cat ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-21 09:56:54 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cat  =  ast_category_new_anonymous ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! cat )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  SQLITE_ABORT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( i  =  0 ;  i  <  num_columns ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  ast_variable  * var ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! ( var  =  ast_variable_new ( columns [ i ] ,  S_OR ( values [ i ] ,  " " ) ,  " " ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_ERROR ,  " Could not create new variable for '%s: %s', throwing away list \n " ,  columns [ i ] ,  values [ i ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_variable_append ( cat ,  var ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_category_append ( cfg ,  cat ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Structure  sent  to  the  SQLite  3  callback  function  for  static  configuration . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ see  static_realtime_cb ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								struct  cfg_entry_args  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_config  * cfg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_category  * cat ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  * cat_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_flags  flags ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  char  * who_asked ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-16 06:46:04 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Structure  passed  to  row  counting  SQLite  callback . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								struct  row_counter_args  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									callback_t  wrapped_callback ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									void  * wrapped_arg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  row_count ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ internal 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  SQLite3  callback  that  counts  rows  of  a  result  set . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ details 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  This  is  used  to  decorate  existing  callbacks  so  that  we  can  count  the  number 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  of  rows  returned  from  a  SELECT  statement  and  still  process  each  row 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  independently . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-19 09:54:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ param  arg  user  data  pointer  passed  in  via  sqlite3_exec ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-16 06:46:04 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ param  num_columns  number  of  columns  in  the  result 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  values  array  of  pointers  to  column  values 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  columns  array  of  pointers  of  to  column  names 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ return  the  return  value  of  the  wrapped  callback ,  or  0  if  no  wrapped  callback 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *          is  provided . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  row_counter_wrapper ( void  * arg ,  int  num_columns ,  char  * * values ,  char  * * columns )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  row_counter_args  * wrapped  =  arg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									wrapped - > row_count + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( wrapped - > wrapped_callback )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  wrapped - > wrapped_callback ( wrapped - > wrapped_arg ,  num_columns ,  values ,  columns ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ internal 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Execute  a  SQL  SELECT  statement  using  a  database  handle 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  db  the  database  handle  to  use  for  the  query 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  sql  the  SQL  statement  to  execute 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  callback  a  user  defined  callback  that  will  be  called  for  each  row  of 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *         the  result  set 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  arg  data  to  be  passed  to  the  user  defined  callback 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ return  if  successful ,  the  number  of  rows  returned  from  the  provided  SELECT 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *          statement .  - 1  on  failure . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  realtime_sqlite3_exec_query_with_handle ( struct  realtime_sqlite3_db  * db ,  const  char  * sql ,  callback_t  callback ,  void  * arg )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  * errmsg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  row_counter_args  wrapper  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										. wrapped_callback  =  callback , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										. wrapped_arg  =  arg , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										. row_count  =  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ao2_lock ( db ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( sqlite3_exec ( db - > handle ,  sql ,  row_counter_wrapper ,  & wrapper ,  & errmsg )  ! =  SQLITE_OK )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Could not execute '%s': %s \n " ,  sql ,  errmsg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										sqlite3_free ( errmsg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ao2_unlock ( db ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  res  = =  0  ?  wrapper . row_count  :  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ internal 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Execute  a  SQL  SELECT  statement  on  the  specified  database 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  database  the  name  of  the  database  to  query 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  sql  the  SQL  statement  to  execute 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  callback  a  user  defined  callback  that  will  be  called  for  each  row  of 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *         the  result  set 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  arg  data  to  be  passed  to  the  user  defined  callback 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ return  if  successful ,  the  number  of  rows  returned  from  the  provided  SELECT 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *          statement .  - 1  on  failure . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  realtime_sqlite3_exec_query ( const  char  * database ,  const  char  * sql ,  callback_t  callback ,  void  * arg )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  realtime_sqlite3_db  * db ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( db  =  find_database ( database ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Could not find database: %s \n " ,  database ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									res  =  realtime_sqlite3_exec_query_with_handle ( db ,  sql ,  callback ,  arg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ao2_ref ( db ,  - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ internal 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Execute  a  SQL  INSERT / UPDATE / DELETE  statement  using  a  database  handle 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-16 06:46:04 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ note  A  database  sync  operation  is  always  performed  after  a  statement 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *        is  executed . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  db  the  database  handle  to  use  for  the  query 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  sql  the  SQL  statement  to  execute 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ return  if  successful ,  the  number  of  rows  modified  by  the  provided  SQL 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *          statement .  - 1  on  failure . 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-16 06:46:04 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  realtime_sqlite3_exec_update_with_handle ( struct  realtime_sqlite3_db  * db ,  const  char  * sql )  
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  * errmsg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ao2_lock ( db ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-16 06:46:04 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( sqlite3_exec ( db - > handle ,  sql ,  NULL ,  NULL ,  & errmsg )  ! =  SQLITE_OK )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Could not execute '%s': %s \n " ,  sql ,  errmsg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										sqlite3_free ( errmsg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  sqlite3_changes ( db - > handle ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ao2_unlock ( db ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-16 06:46:04 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									db_sync ( db ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-16 06:46:04 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ internal 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Execute  a  SQL  INSERT / UPDATE / DELETE  statement  using  a  database  handle 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ note  A  database  sync  operation  is  always  performed  after  a  statement 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *        is  executed . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  database  the  name  of  the  database  to  query 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  sql  the  SQL  statement  to  execute 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-16 06:46:04 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ return  if  successful ,  the  number  of  rows  modified  by  the  provided  SQL 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *          statement .  - 1  on  failure . 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-16 06:46:04 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  realtime_sqlite3_exec_update ( const  char  * database ,  const  char  * sql )  
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  realtime_sqlite3_db  * db ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( db  =  find_database ( database ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Could not find database: %s \n " ,  database ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-16 06:46:04 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									res  =  realtime_sqlite3_exec_update_with_handle ( db ,  sql ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									ao2_ref ( db ,  - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! \note It is important that the COL_* enum matches the order of the columns selected in static_sql */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  const  char  * static_sql  =  " SELECT category, var_name, var_val FROM  \" %q \"  WHERE filename = %Q AND commented = 0 ORDER BY cat_metric ASC, var_metric ASC " ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								enum  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									COL_CATEGORY , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									COL_VAR_NAME , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									COL_VAR_VAL , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									COL_COLUMNS , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  static_realtime_cb ( void  * arg ,  int  num_columns ,  char  * * values ,  char  * * columns )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  cfg_entry_args  * args  =  arg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_variable  * var ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! strcmp ( values [ COL_VAR_NAME ] ,  " #include " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  ast_config  * cfg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										char  * val ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										val  =  values [ COL_VAR_VAL ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! ( cfg  =  ast_config_internal_load ( val ,  args - > cfg ,  args - > flags ,  " " ,  args - > who_asked ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_WARNING ,  " Unable to include %s \n " ,  val ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  SQLITE_ABORT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											args - > cfg  =  cfg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! args - > cat_name  | |  strcmp ( args - > cat_name ,  values [ COL_CATEGORY ] ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-21 09:56:54 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										args - > cat  =  ast_category_new_dynamic ( values [ COL_CATEGORY ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! args - > cat )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  SQLITE_ABORT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_free ( args - > cat_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! ( args - > cat_name  =  ast_strdup ( values [ COL_CATEGORY ] ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_category_destroy ( args - > cat ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  SQLITE_ABORT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_category_append ( args - > cfg ,  args - > cat ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( var  =  ast_variable_new ( values [ COL_VAR_NAME ] ,  values [ COL_VAR_VAL ] ,  " " ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-06 18:19:03 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Unable to allocate variable \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  SQLITE_ABORT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_variable_append ( args - > cat ,  var ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! \brief Realtime callback for static realtime
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ return  ast_config  on  success ,  NULL  on  failure 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  ast_config  * realtime_sqlite3_load ( const  char  * database ,  const  char  * table ,  const  char  * configfile ,  struct  ast_config  * config ,  struct  ast_flags  flags ,  const  char  * suggested_include_file ,  const  char  * who_asked )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  * sql ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  cfg_entry_args  args ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_strlen_zero ( table ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Must have a table to query! \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( sql  =  sqlite3_mprintf ( static_sql ,  table ,  configfile ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Couldn't allocate query \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									args . cfg  =  config ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									args . cat  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									args . cat_name  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									args . flags  =  flags ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									args . who_asked  =  who_asked ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-16 06:46:04 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									realtime_sqlite3_exec_query ( database ,  sql ,  static_realtime_cb ,  & args ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sqlite3_free ( sql ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  config ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-16 09:38:06 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define IS_SQL_LIKE_CLAUSE(x) ((x) && ast_ends_with(x, " LIKE")) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*! \brief Helper function for single and multi-row realtime load functions */  
						 
					
						
							
								
									
										
										
										
											2013-04-27 12:01:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  realtime_sqlite3_helper ( const  char  * database ,  const  char  * table ,  const  struct  ast_variable  * fields ,  int  is_multi ,  void  * arg )  
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_str  * sql ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-27 12:01:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									const  struct  ast_variable  * field ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									int  first  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_strlen_zero ( table ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Must have a table to query! \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( sql  =  ast_str_create ( 128 ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-04-27 12:01:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  ( field  =  fields ;  field ;  field  =  field - > next )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  ( first )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_str_set ( & sql ,  0 ,  " SELECT * FROM %s WHERE %s %s " ,  sqlite3_escape_table ( table ) , 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-27 12:01:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												    sqlite3_escape_column_op ( field - > name ) ,  sqlite3_escape_value ( field - > value ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											first  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-27 12:01:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_str_append ( & sql ,  0 ,  "  AND %s %s " ,  sqlite3_escape_column_op ( field - > name ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													sqlite3_escape_value ( field - > value ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-16 09:38:06 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( has_explicit_like_escaping  & &  IS_SQL_LIKE_CLAUSE ( field - > name ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  The  realtime  framework  is  going  to  pre - escape  these 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  for  us  with  a  backslash .  We  just  need  to  make  sure 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  to  tell  SQLite  about  it 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_str_append ( & sql ,  0 ,  "  ESCAPE ' \\ ' " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! is_multi )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_str_append ( & sql ,  0 ,  " %s " ,  "  LIMIT 1 " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-16 06:46:04 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( realtime_sqlite3_exec_query ( database ,  ast_str_buffer ( sql ) ,  is_multi  ?  append_row_to_cfg  :  row_to_varlist ,  arg )  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										ast_free ( sql ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_free ( sql ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! \brief Realtime callback for a single row query
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ return  ast_variable  list  for  single  result  on  success ,  NULL  on  empty / failure 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-27 12:01:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  struct  ast_variable  * realtime_sqlite3 ( const  char  * database ,  const  char  * table ,  const  struct  ast_variable  * fields )  
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_variable  * result_row  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-04-27 12:01:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									realtime_sqlite3_helper ( database ,  table ,  fields ,  0 ,  & result_row ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  result_row ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! \brief Realtime callback for a multi-row query
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ return  ast_config  containing  possibly  many  results  on  success ,  NULL  on  empty / failure 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-27 12:01:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  struct  ast_config  * realtime_sqlite3_multi ( const  char  * database ,  const  char  * table ,  const  struct  ast_variable  * fields )  
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_config  * cfg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( cfg  =  ast_config_new ( ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-04-27 12:01:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( realtime_sqlite3_helper ( database ,  table ,  fields ,  1 ,  cfg ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										ast_config_destroy ( cfg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  cfg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! \brief Realtime callback for updating a row based on a single criteria
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ return  Number  of  rows  affected  or  - 1  on  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-27 12:01:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  realtime_sqlite3_update ( const  char  * database ,  const  char  * table ,  const  char  * keyfield ,  const  char  * entity ,  const  struct  ast_variable  * fields )  
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_str  * sql ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-27 12:01:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									const  struct  ast_variable  * field ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									int  first  =  1 ,  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_strlen_zero ( table ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Must have a table to query! \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( sql  =  ast_str_create ( 128 ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-04-27 12:01:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  ( field  =  fields ;  field ;  field  =  field - > next )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  ( first )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_str_set ( & sql ,  0 ,  " UPDATE %s SET %s = %s " , 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-27 12:01:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													sqlite3_escape_table ( table ) ,  sqlite3_escape_column ( field - > name ) ,  sqlite3_escape_value ( field - > value ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											first  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-27 12:01:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_str_append ( & sql ,  0 ,  " , %s = %s " ,  sqlite3_escape_column ( field - > name ) ,  sqlite3_escape_value ( field - > value ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_str_append ( & sql ,  0 ,  "  WHERE %s %s " ,  sqlite3_escape_column_op ( keyfield ) ,  sqlite3_escape_value ( entity ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-16 06:46:04 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									res  =  realtime_sqlite3_exec_update ( database ,  ast_str_buffer ( sql ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									ast_free ( sql ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! \brief Realtime callback for updating a row based on multiple criteria
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ return  Number  of  rows  affected  or  - 1  on  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-27 12:01:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  realtime_sqlite3_update2 ( const  char  * database ,  const  char  * table ,  const  struct  ast_variable  * lookup_fields ,  const  struct  ast_variable  * update_fields )  
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_str  * sql ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_str  * where_clause ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-27 12:01:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									const  struct  ast_variable  * field ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									int  first  =  1 ,  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_strlen_zero ( table ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Must have a table to query! \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( sql  =  ast_str_create ( 128 ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( where_clause  =  ast_str_create ( 128 ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_free ( sql ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-04-27 12:01:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  ( field  =  lookup_fields ;  field ;  field  =  field - > next )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  ( first )  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-27 12:01:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_str_set ( & where_clause ,  0 ,  "  WHERE %s %s " ,  sqlite3_escape_column_op ( field - > name ) ,  sqlite3_escape_value ( field - > value ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											first  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-27 12:01:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_str_append ( & where_clause ,  0 ,  "  AND %s %s " ,  sqlite3_escape_column_op ( field - > name ) ,  sqlite3_escape_value ( field - > value ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									first  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-27 12:01:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  ( field  =  update_fields ;  field ;  field  =  field - > next )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  ( first )  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-27 12:01:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_str_set ( & sql ,  0 ,  " UPDATE %s SET %s = %s " ,  sqlite3_escape_table ( table ) ,  sqlite3_escape_column ( field - > name ) ,  sqlite3_escape_value ( field - > value ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											first  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-27 12:01:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_str_append ( & sql ,  0 ,  " , %s = %s " ,  sqlite3_escape_column ( field - > name ) ,  sqlite3_escape_value ( field - > value ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_str_append ( & sql ,  0 ,  " %s " ,  ast_str_buffer ( where_clause ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-16 06:46:04 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									res  =  realtime_sqlite3_exec_update ( database ,  ast_str_buffer ( sql ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_free ( sql ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_free ( where_clause ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! \brief Realtime callback for inserting a row
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ return  Number  of  rows  affected  or  - 1  on  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-27 12:01:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  realtime_sqlite3_store ( const  char  * database ,  const  char  * table ,  const  struct  ast_variable  * fields )  
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_str  * sql ,  * values ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-27 12:01:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									const  struct  ast_variable  * field ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									int  first  =  1 ,  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_strlen_zero ( table ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Must have a table to query! \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( sql  =  ast_str_create ( 128 ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( values  =  ast_str_create ( 128 ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_free ( sql ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-04-27 12:01:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  ( field  =  fields ;  field ;  field  =  field - > next )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  ( first )  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-27 12:01:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_str_set ( & sql ,  0 ,  " INSERT INTO %s (%s " ,  sqlite3_escape_table ( table ) ,  sqlite3_escape_column ( field - > name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_str_set ( & values ,  0 ,  " ) VALUES (%s " ,  sqlite3_escape_value ( field - > value ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											first  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-27 12:01:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_str_append ( & sql ,  0 ,  " , %s " ,  sqlite3_escape_column ( field - > name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_str_append ( & values ,  0 ,  " , %s " ,  sqlite3_escape_value ( field - > value ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_str_append ( & sql ,  0 ,  " %s) " ,  ast_str_buffer ( values ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-16 06:46:04 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									res  =  realtime_sqlite3_exec_update ( database ,  ast_str_buffer ( sql ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_free ( sql ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_free ( values ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! \brief Realtime callback for deleting a row
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ return  Number  of  rows  affected  or  - 1  on  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-27 12:01:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  realtime_sqlite3_destroy ( const  char  * database ,  const  char  * table ,  const  char  * keyfield ,  const  char  * entity ,  const  struct  ast_variable  * fields )  
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_str  * sql ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-27 12:01:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									const  struct  ast_variable  * field ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									int  first  =  1 ,  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_strlen_zero ( table ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Must have a table to query! \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( sql  =  ast_str_create ( 128 ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-04-27 12:01:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  ( field  =  fields ;  field ;  field  =  field - > next )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  ( first )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_str_set ( & sql ,  0 ,  " DELETE FROM %s WHERE %s %s " ,  sqlite3_escape_table ( table ) , 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-27 12:01:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													sqlite3_escape_column_op ( field - > name ) ,  sqlite3_escape_value ( field - > value ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											first  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-04-27 12:01:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_str_append ( & sql ,  0 ,  "  AND %s %s " ,  sqlite3_escape_column_op ( field - > name ) ,  sqlite3_escape_value ( field - > value ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-16 06:46:04 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									res  =  realtime_sqlite3_exec_update ( database ,  ast_str_buffer ( sql ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_free ( sql ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! \brief Convert Asterisk realtime types to SQLite 3 types
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ note  SQLite  3  has  NULL ,  INTEGER ,  REAL ,  TEXT ,  and  BLOB  types .  Any  column  other  than 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  an  INTEGER  PRIMARY  KEY  will  actually  store  any  kind  of  data  due  to  its  dynamic 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  typing .  When  we  create  columns ,  we ' ll  go  ahead  and  use  these  base  types  instead 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  of  messing  with  column  widths ,  etc .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  const  char  * get_sqlite_column_type ( int  type )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch ( type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  RQ_INTEGER1  : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  RQ_UINTEGER1  : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  RQ_INTEGER2  : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  RQ_UINTEGER2  : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  RQ_INTEGER3  : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  RQ_UINTEGER3  : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  RQ_INTEGER4  : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  RQ_UINTEGER4  : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  RQ_INTEGER8  : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  " INTEGER " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  RQ_UINTEGER8  :  /* SQLite3 stores INTEGER as signed 8-byte */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  RQ_CHAR  : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  RQ_DATE  : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  RQ_DATETIME  : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  " TEXT " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  RQ_FLOAT  : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  " REAL " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default  : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  " TEXT " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  " TEXT " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! \brief Create a table if ast_realtime_require shows that we are configured to handle the data
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  handle_missing_table ( struct  realtime_sqlite3_db  * db ,  const  char  * table ,  va_list  ap )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  char  * column ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  type ,  first  =  1 ,  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									size_t  sz ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_str  * sql ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( sql  =  ast_str_create ( 128 ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-16 06:46:04 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									while  ( ( column  =  va_arg ( ap ,  typeof ( column ) ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										type  =  va_arg ( ap ,  typeof ( type ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										sz  =  va_arg ( ap ,  typeof ( sz ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  ( first )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_str_set ( & sql ,  0 ,  " CREATE TABLE IF NOT EXISTS %s (%s %s " ,  sqlite3_escape_table ( table ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													sqlite3_escape_column ( column ) ,  get_sqlite_column_type ( type ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											first  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_str_append ( & sql ,  0 ,  " , %s %s " ,  sqlite3_escape_column ( column ) ,  get_sqlite_column_type ( type ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_str_append ( & sql ,  0 ,  " ) " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-16 06:46:04 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									res  =  realtime_sqlite3_exec_update_with_handle ( db ,  ast_str_buffer ( sql ) )  <  0  ?  - 1  :  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									ast_free ( sql ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! \brief If ast_realtime_require sends info about a column we don't have, create it
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  handle_missing_column ( struct  realtime_sqlite3_db  * db ,  const  char  * table ,  const  char  * column ,  int  type ,  size_t  sz )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  * sql ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  char  * sqltype  =  get_sqlite_column_type ( type ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( db - > requirements  = =  REALTIME_SQLITE3_REQ_WARN )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Missing column '%s' of type '%s' in %s.%s \n " ,  column ,  sqltype ,  db - > name ,  table ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( db - > requirements  = =  REALTIME_SQLITE3_REQ_CHAR )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										sqltype  =  " TEXT " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( sql  =  sqlite3_mprintf ( " ALTER TABLE  \" %q \"  ADD COLUMN  \" %q \"  %s " ,  table ,  column ,  sqltype ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-16 06:46:04 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! ( res  =  ( realtime_sqlite3_exec_update_with_handle ( db ,  sql )  <  0  ?  - 1  :  0 ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_NOTICE ,  " Creating column '%s' type %s for table %s \n " ,  column ,  sqltype ,  table ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sqlite3_free ( sql ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  str_hash_fn ( const  void  * obj ,  const  int  flags )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ast_str_hash ( ( const  char  * )  obj ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  str_cmp_fn ( void  * obj ,  void  * arg ,  int  flags )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ! strcasecmp ( ( const  char  * )  obj ,  ( const  char  * )  arg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! \brief Callback for creating a hash of column names for comparison in realtime_sqlite3_require
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  add_column_name ( void  * arg ,  int  num_columns ,  char  * * values ,  char  * * columns )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  * column ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ao2_container  * cnames  =  arg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( column  =  ao2_alloc ( strlen ( values [ 1 ] )  +  1 ,  NULL ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									strcpy ( column ,  values [ 1 ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ao2_link ( cnames ,  column ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ao2_ref ( column ,  - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! \brief Callback for ast_realtime_require
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  0  Required  fields  met  specified  standards 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  - 1  One  or  more  fields  was  missing  or  insufficient 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  realtime_sqlite3_require ( const  char  * database ,  const  char  * table ,  va_list  ap )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  char  * column ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  * sql ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									size_t  sz ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ao2_container  * columns ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  realtime_sqlite3_db  * db ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* SQLite3 columns are dynamically typed, with type affinity. Built-in functions will
 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-20 12:14:54 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 *  return  the  results  as  char  *  anyway .  The  only  field  that  cannot  contain  text 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									 *  data  is  an  INTEGER  PRIMARY  KEY ,  which  must  be  a  64 - bit  signed  integer .  So ,  for 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  the  purposes  here  we  really  only  care  whether  the  column  exists  and  not  what  its 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  type  or  length  is .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_strlen_zero ( table ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Must have a table to query! \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( db  =  find_database ( database ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-11-19 15:10:02 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									columns  =  ao2_container_alloc_hash ( AO2_ALLOC_OPT_LOCK_MUTEX ,  0 ,  31 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										str_hash_fn ,  NULL ,  str_cmp_fn ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! columns )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										unref_db ( & db ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( sql  =  sqlite3_mprintf ( " PRAGMA table_info( \" %q \" ) " ,  table ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										unref_db ( & db ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ao2_ref ( columns ,  - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-16 06:46:04 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ( res  =  realtime_sqlite3_exec_query_with_handle ( db ,  sql ,  add_column_name ,  columns ) )  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										unref_db ( & db ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ao2_ref ( columns ,  - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										sqlite3_free ( sql ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( res  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Table does not exist */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										sqlite3_free ( sql ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  handle_missing_table ( db ,  table ,  ap ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ao2_ref ( columns ,  - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										unref_db ( & db ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sqlite3_free ( sql ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-16 06:46:04 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									while  ( ( column  =  va_arg ( ap ,  typeof ( column ) ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										char  * found ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-16 06:46:04 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										type  =  va_arg ( ap ,  typeof ( type ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										sz  =  va_arg ( ap ,  typeof ( sz ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  ( ! ( found  =  ao2_find ( columns ,  column ,  OBJ_POINTER  |  OBJ_UNLINK ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( handle_missing_column ( db ,  table ,  column ,  type ,  sz ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												unref_db ( & db ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ao2_ref ( columns ,  - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ao2_ref ( found ,  - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ao2_ref ( columns ,  - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unref_db ( & db ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! \brief Callback for clearing any cached info
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ note  We  don ' t  currently  cache  anything 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  0  If  any  cache  was  purged 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  - 1  If  no  cache  was  found 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  realtime_sqlite3_unload ( const  char  * database ,  const  char  * table )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* We currently do no caching */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! \brief Parse the res_config_sqlite3 config file
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  parse_config ( int  reload )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_config  * config ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_flags  config_flags  =  {  CONFIG_FLAG_NOREALTIME  |  ( reload  ?  CONFIG_FLAG_FILEUNCHANGED  :  0 )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									static  const  char  * config_filename  =  " res_config_sqlite3.conf " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									config  =  ast_config_load ( config_filename ,  config_flags ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( config  = =  CONFIG_STATUS_FILEUNCHANGED )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " %s was unchanged, skipping parsing \n " ,  config_filename ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_mutex_lock ( & config_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( config  = =  CONFIG_STATUS_FILEMISSING  | |  config  = =  CONFIG_STATUS_FILEINVALID )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " %s config file '%s' \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											config  = =  CONFIG_STATUS_FILEMISSING  ?  " Missing "  :  " Invalid " ,  config_filename ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-15 12:55:19 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_mutex_unlock ( & config_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										const  char  * cat ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  realtime_sqlite3_db  * db ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										mark_all_databases_dirty ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  ( cat  =  ast_category_browse ( config ,  NULL ) ;  cat ;  cat  =  ast_category_browse ( config ,  cat ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! strcasecmp ( cat ,  " general " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! ( db  =  find_database ( cat ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( ! ( db  =  new_realtime_sqlite3_db ( config ,  cat ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_log ( LOG_WARNING ,  " Could not allocate new db for '%s' - skipping. \n " ,  cat ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( db_open ( db ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													unref_db ( & db ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												db_start_batch ( db ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ao2_link ( databases ,  db ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												unref_db ( & db ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else   { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( update_realtime_sqlite3_db ( db ,  config ,  cat ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													unref_db ( & db ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												unref_db ( & db ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										unlink_dirty_databases ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_mutex_unlock ( & config_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_config_destroy ( config ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  reload ( void )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									parse_config ( 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  unload_module ( void )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_mutex_lock ( & config_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ao2_callback ( databases ,  OBJ_MULTIPLE  |  OBJ_NODATA  |  OBJ_UNLINK ,  stop_batch_cb ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ao2_ref ( databases ,  - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									databases  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_config_engine_deregister ( & sqlite3_config_engine ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_mutex_unlock ( & config_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-16 09:38:06 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  discover_sqlite3_caps ( void )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  So  we  cheat  a  little  bit  here .  SQLite3  added  support  for  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  ' ESCAPE '  keyword  in  3.1 .0 .  They  added  SQLITE_VERSION_NUMBER 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  in  3.1 .2 .  So  if  we  run  into  3.1 .0  or  3.1 .1  in  the  wild ,  we 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  just  treat  it  like  <  3.1 .0 . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  For  reference :  3.1 .0 ,  3.1 .1 ,  and  3.1 .2  were  all  released 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  within  30  days  of  each  other  in  Jan / Feb  2005 ,  so  I  don ' t 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  imagine  we ' ll  be  finding  something  pre - 3.1 .2  that  often  in 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  practice . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# if defined(SQLITE_VERSION_NUMBER) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									has_explicit_like_escaping  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# else 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									has_explicit_like_escaping  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_debug ( 3 ,  " SQLite3 has 'LIKE ... ESCAPE ...' support? %s \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											has_explicit_like_escaping  ?  " Yes "  :  " No " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-10-01 23:24:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Load  the  module 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Module  loading  including  tests  for  configuration  or  dependencies . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  This  function  can  return  AST_MODULE_LOAD_FAILURE ,  AST_MODULE_LOAD_DECLINE , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  or  AST_MODULE_LOAD_SUCCESS .  If  a  dependency  or  environment  variable  fails 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-22 09:23:22 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  tests  return  AST_MODULE_LOAD_FAILURE .  If  the  module  can  not  load  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  configuration  file  or  other  non - critical  problem  return 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-01 23:24:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  AST_MODULE_LOAD_DECLINE .  On  success  return  AST_MODULE_LOAD_SUCCESS . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								static  int  load_module ( void )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2017-02-16 09:38:06 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									discover_sqlite3_caps ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-11-19 15:10:02 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									databases  =  ao2_container_alloc_hash ( AO2_ALLOC_OPT_LOCK_MUTEX ,  0 ,  DB_BUCKETS , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										db_hash_fn ,  NULL ,  db_cmp_fn ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! databases )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-11 10:07:39 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  AST_MODULE_LOAD_DECLINE ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( parse_config ( 0 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ao2_ref ( databases ,  - 1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-11 10:07:39 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  AST_MODULE_LOAD_DECLINE ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( ast_config_engine_register ( & sqlite3_config_engine ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " The config API must have changed, this shouldn't happen. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ao2_ref ( databases ,  - 1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-11 10:07:39 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  AST_MODULE_LOAD_DECLINE ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  AST_MODULE_LOAD_SUCCESS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								AST_MODULE_INFO ( ASTERISK_GPL_KEY ,  AST_MODFLAG_LOAD_ORDER ,  " SQLite 3 realtime config engine " ,  
						 
					
						
							
								
									
										
										
										
											2014-07-25 16:47:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									. support_level  =  AST_MODULE_SUPPORT_CORE , 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									. load  =  load_module , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. unload  =  unload_module , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. reload  =  reload , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. load_pri  =  AST_MODPRI_REALTIME_DRIVER , 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-16 22:11:42 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									. requires  =  " extconfig " , 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								) ;