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 . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Please  follow  coding  guidelines 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  http : //svn.digium.com/view/asterisk/trunk/doc/CODING-GUIDELINES
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! \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 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ 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" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								ASTERISK_FILE_VERSION ( __FILE__ ,  " $Revision$ " )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# 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
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * * */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								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 ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  ast_variable  * realtime_sqlite3 ( const  char  * database ,  const  char  * table ,  va_list  ap ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  ast_config  * realtime_sqlite3_multi ( const  char  * database ,  const  char  * table ,  va_list  ap ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  realtime_sqlite3_update ( const  char  * database ,  const  char  * table ,  const  char  * keyfield ,  const  char  * entity ,  va_list  ap ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  realtime_sqlite3_update2 ( const  char  * database ,  const  char  * table ,  va_list  ap ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  realtime_sqlite3_store ( const  char  * database ,  const  char  * table ,  va_list  ap ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  realtime_sqlite3_destroy ( const  char  * database ,  const  char  * table ,  const  char  * keyfield ,  const  char  * entity ,  va_list  ap ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  batch ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								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 ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  realtime_sqlite3_execute_handle ( struct  realtime_sqlite3_db  * db ,  const  char  * sql ,  int  ( * callback ) ( void * ,  int ,  char  * * ,  char  * * ) ,  void  * arg ,  int  sync ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								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  * tmp  =  ast_str_buffer ( buf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  q  =  ts  = =  & escape_value_buf  ?  ' \' '  :  ' " ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  * tmp  =  ast_str_buffer ( buf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  space  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									realtime_sqlite3_execute_handle ( db ,  " BEGIN TRANSACTION " ,  NULL ,  NULL ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( ; ; )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! db - > wakeup )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_cond_wait ( & db - > cond ,  ao2_object_get_lockaddr ( db ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										db - > wakeup  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( realtime_sqlite3_execute_handle ( db ,  " COMMIT " ,  NULL ,  NULL ,  0 )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											realtime_sqlite3_execute_handle ( db ,  " ROLLBACK " ,  NULL ,  NULL ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( db - > exiting )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ao2_unlock ( db ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										realtime_sqlite3_execute_handle ( db ,  " BEGIN TRANSACTION " ,  NULL ,  NULL ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_pthread_create_background ( & db - > syncthread ,  NULL ,  db_sync_thread ,  db ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  db_stop_batch ( struct  realtime_sqlite3_db  * db )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( db - > batch )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										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 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( cat  =  ast_category_new ( " " ,  " " ,  99999 ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! Exeute an SQL statement given the database object
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  - 1  ERROR 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  >  - 1  Number  of  rows  changed 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  realtime_sqlite3_execute_handle ( struct  realtime_sqlite3_db  * db ,  const  char  * sql ,  int  ( * callback ) ( void * ,  int ,  char  * * ,  char  * * ) ,  void  * arg ,  int  sync )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  * errmsg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ao2_lock ( db ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( sqlite3_exec ( db - > handle ,  sql ,  callback ,  arg ,  & errmsg )  ! =  SQLITE_OK )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										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 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( sync )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										db_sync ( db ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! Exeute an SQL statement give the database name
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  - 1  ERROR 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  >  - 1  Number  of  rows  changed 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  realtime_sqlite3_execute ( const  char  * database ,  const  char  * sql ,  int  ( * callback ) ( void * ,  int ,  char  * * ,  char  * * ) ,  void  * arg ,  int  sync )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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_execute_handle ( db ,  sql ,  callback ,  arg ,  sync ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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 ] ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! ( args - > cat  =  ast_category_new ( values [ COL_CATEGORY ] ,  " " ,  99999 ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_WARNING ,  " Unable to allocate category \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									realtime_sqlite3_execute ( database ,  sql ,  static_realtime_cb ,  & args ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sqlite3_free ( sql ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  config ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! \brief Helper function for single and multi-row realtime load functions */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  realtime_sqlite3_helper ( const  char  * database ,  const  char  * table ,  va_list  ap ,  int  is_multi ,  void  * arg )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_str  * sql ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  char  * param ,  * value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( ( param  =  va_arg ( ap ,  const  char  * ) )  & &  ( value  =  va_arg ( ap ,  const  char  * ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( first )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_str_set ( & sql ,  0 ,  " SELECT * FROM %s WHERE %s %s " ,  sqlite3_escape_table ( table ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													sqlite3_escape_column_op ( param ) ,  sqlite3_escape_value ( value ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											first  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_str_append ( & sql ,  0 ,  "  AND %s %s " ,  sqlite3_escape_column_op ( param ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													sqlite3_escape_value ( value ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! is_multi )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_str_append ( & sql ,  0 ,  " %s " ,  "  LIMIT 1 " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( realtime_sqlite3_execute ( database ,  ast_str_buffer ( sql ) ,  is_multi  ?  append_row_to_cfg  :  row_to_varlist ,  arg ,  0 )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										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 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  ast_variable  * realtime_sqlite3 ( const  char  * database ,  const  char  * table ,  va_list  ap )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_variable  * result_row  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									realtime_sqlite3_helper ( database ,  table ,  ap ,  0 ,  & result_row ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  result_row ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! \brief Realtime callback for a multi-row query
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ return  ast_config  containing  possibly  many  results  on  success ,  NULL  on  empty / failure 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  ast_config  * realtime_sqlite3_multi ( const  char  * database ,  const  char  * table ,  va_list  ap )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_config  * cfg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( cfg  =  ast_config_new ( ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( realtime_sqlite3_helper ( database ,  table ,  ap ,  1 ,  cfg ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										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 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  realtime_sqlite3_update ( const  char  * database ,  const  char  * table ,  const  char  * keyfield ,  const  char  * entity ,  va_list  ap )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_str  * sql ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  char  * key ,  * value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( ( key  =  va_arg ( ap ,  const  char  * ) )  & &  ( value  =  va_arg ( ap ,  const  char  * ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( first )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_str_set ( & sql ,  0 ,  " UPDATE %s SET %s = %s " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													sqlite3_escape_table ( table ) ,  sqlite3_escape_column ( key ) ,  sqlite3_escape_value ( value ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											first  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_str_append ( & sql ,  0 ,  " , %s = %s " ,  sqlite3_escape_column ( key ) ,  sqlite3_escape_value ( value ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_str_append ( & sql ,  0 ,  "  WHERE %s %s " ,  sqlite3_escape_column_op ( keyfield ) ,  sqlite3_escape_value ( entity ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									res  =  realtime_sqlite3_execute ( database ,  ast_str_buffer ( sql ) ,  NULL ,  NULL ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  realtime_sqlite3_update2 ( const  char  * database ,  const  char  * table ,  va_list  ap )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_str  * sql ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_str  * where_clause ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  char  * key ,  * value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( ( key  =  va_arg ( ap ,  const  char  * ) )  & &  ( value  =  va_arg ( ap ,  const  char  * ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( first )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_str_set ( & where_clause ,  0 ,  "  WHERE %s %s " ,  sqlite3_escape_column_op ( key ) ,  sqlite3_escape_value ( value ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											first  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_str_append ( & where_clause ,  0 ,  "  AND %s %s " ,  sqlite3_escape_column_op ( key ) ,  sqlite3_escape_value ( value ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									first  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( ( key  =  va_arg ( ap ,  const  char  * ) )  & &  ( value  =  va_arg ( ap ,  const  char  * ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( first )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_str_set ( & sql ,  0 ,  " UPDATE %s SET %s = %s " ,  sqlite3_escape_table ( table ) ,  sqlite3_escape_column ( key ) ,  sqlite3_escape_value ( value ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											first  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_str_append ( & sql ,  0 ,  " , %s = %s " ,  sqlite3_escape_column ( key ) ,  sqlite3_escape_value ( value ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_str_append ( & sql ,  0 ,  " %s " ,  ast_str_buffer ( where_clause ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									res  =  realtime_sqlite3_execute ( database ,  ast_str_buffer ( sql ) ,  NULL ,  NULL ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  realtime_sqlite3_store ( const  char  * database ,  const  char  * table ,  va_list  ap )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_str  * sql ,  * values ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  char  * column ,  * value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( ( column  =  va_arg ( ap ,  const  char  * ) )  & &  ( value  =  va_arg ( ap ,  const  char  * ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( first )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_str_set ( & sql ,  0 ,  " INSERT INTO %s (%s " ,  sqlite3_escape_table ( table ) ,  sqlite3_escape_column ( column ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_str_set ( & values ,  0 ,  " ) VALUES (%s " ,  sqlite3_escape_value ( value ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											first  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_str_append ( & sql ,  0 ,  " , %s " ,  sqlite3_escape_column ( column ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_str_append ( & values ,  0 ,  " , %s " ,  sqlite3_escape_value ( value ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_str_append ( & sql ,  0 ,  " %s) " ,  ast_str_buffer ( values ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									res  =  realtime_sqlite3_execute ( database ,  ast_str_buffer ( sql ) ,  NULL ,  NULL ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_free ( sql ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_free ( values ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! \brief Realtime callback for deleting a row
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ return  Number  of  rows  affected  or  - 1  on  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  realtime_sqlite3_destroy ( const  char  * database ,  const  char  * table ,  const  char  * keyfield ,  const  char  * entity ,  va_list  ap )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_str  * sql ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  char  * param ,  * value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( ( param  =  va_arg ( ap ,  const  char  * ) )  & &  ( value  =  va_arg ( ap ,  const  char  * ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( first )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_str_set ( & sql ,  0 ,  " DELETE FROM %s WHERE %s %s " ,  sqlite3_escape_table ( table ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													sqlite3_escape_column_op ( param ) ,  sqlite3_escape_value ( value ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											first  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_str_append ( & sql ,  0 ,  "  AND %s %s " ,  sqlite3_escape_column_op ( param ) ,  sqlite3_escape_value ( value ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									res  =  realtime_sqlite3_execute ( database ,  ast_str_buffer ( sql ) ,  NULL ,  NULL ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( ( column  =  va_arg ( ap ,  typeof ( column ) ) )  & &  ( type  =  va_arg ( ap ,  typeof ( type ) ) )  & &  ( sz  =  va_arg ( ap ,  typeof ( sz ) ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										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 ,  " ) " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									res  =  realtime_sqlite3_execute_handle ( db ,  ast_str_buffer ( sql ) ,  NULL ,  NULL ,  1 )  <  0  ?  - 1  :  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-04-17 18:57:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! ( res  =  ( realtime_sqlite3_execute_handle ( db ,  sql ,  NULL ,  NULL ,  1 )  <  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
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  return  the  results  as  char  *  anyway .  The  only  field  that  that  cannot  contain  text 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( columns  =  ao2_container_alloc ( 31 ,  str_hash_fn ,  str_cmp_fn ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										unref_db ( & db ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( sql  =  sqlite3_mprintf ( " PRAGMA table_info( \" %q \" ) " ,  table ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										unref_db ( & db ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ao2_ref ( columns ,  - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( res  =  realtime_sqlite3_execute_handle ( db ,  sql ,  add_column_name ,  columns ,  0 ) )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										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 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( ( column  =  va_arg ( ap ,  typeof ( column ) ) )  & &  ( type  =  va_arg ( ap ,  typeof ( type ) ) )  & &  ( sz  =  va_arg ( ap ,  typeof ( sz ) ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										char  * found ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										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 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  tests  return  AST_MODULE_LOAD_FAILURE .  If  the  module  can  not  load  the  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  configuration  file  or  other  non - critical  problem  return  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  AST_MODULE_LOAD_DECLINE .  On  success  return  AST_MODULE_LOAD_SUCCESS . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-11 17:09:36 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								static  int  load_module ( void )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( ( databases  =  ao2_container_alloc ( DB_BUCKETS ,  db_hash_fn ,  db_cmp_fn ) ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  AST_MODULE_LOAD_FAILURE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( parse_config ( 0 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ao2_ref ( databases ,  - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  AST_MODULE_LOAD_FAILURE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  AST_MODULE_LOAD_FAILURE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  AST_MODULE_LOAD_SUCCESS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								AST_MODULE_INFO ( ASTERISK_GPL_KEY ,  AST_MODFLAG_LOAD_ORDER ,  " SQLite 3 realtime config engine " ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. load  =  load_module , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. unload  =  unload_module , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. reload  =  reload , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. load_pri  =  AST_MODPRI_REALTIME_DRIVER , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								) ;