mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 02:37:10 +00:00 
			
		
		
		
	Build out "multi" version of realtime config (directory and realtime extensions will need this)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@4324 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
		
							
								
								
									
										18
									
								
								config.c
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								config.c
									
									
									
									
									
								
							| @@ -54,6 +54,12 @@ void ast_destroy_realtime(struct ast_variable *v) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void ast_category_destroy(struct ast_category *cat) | ||||
| { | ||||
| 	ast_destroy_realtime(cat->root); | ||||
| 	free(cat); | ||||
| } | ||||
|  | ||||
| void ast_destroy(struct ast_config *ast) | ||||
| { | ||||
| 	struct ast_category *cat, *catn; | ||||
| @@ -591,6 +597,18 @@ struct ast_config *ast_load(char *configfile) | ||||
| 	return __ast_load(configfile, NULL, &tmpc, &last, 0); | ||||
| } | ||||
|  | ||||
| void ast_category_append(struct ast_config *config, struct ast_category *cat) | ||||
| { | ||||
| 	struct ast_category *prev = NULL; | ||||
| 	cat->next = NULL; | ||||
| 	if (config->root) { | ||||
| 		prev = config->root; | ||||
| 		while(prev->next) prev = prev->next; | ||||
| 		prev->next = cat; | ||||
| 	} else | ||||
| 		config->root = cat; | ||||
| } | ||||
|  | ||||
| char *ast_category_browse(struct ast_config *config, char *prev) | ||||
| {	 | ||||
| 	struct ast_category *cat; | ||||
|   | ||||
| @@ -52,6 +52,8 @@ int ast_save(char *filename, struct ast_config *cfg, char *generator); | ||||
| struct ast_config *ast_new_config(void); | ||||
| struct ast_category *ast_new_category(char *name); | ||||
| struct ast_variable *ast_new_variable(char *name,char *value); | ||||
| void ast_category_append(struct ast_config *config, struct ast_category *cat); | ||||
| void ast_category_destroy(struct ast_category *cat); | ||||
| int ast_cust_config_register(struct ast_config_reg *new); | ||||
| int ast_cust_config_deregister(struct ast_config_reg *new); | ||||
| int register_config_cli(void); | ||||
|   | ||||
| @@ -167,6 +167,159 @@ static struct ast_variable *realtime_odbc(const char *database, const char *tabl | ||||
| 	return var; | ||||
| } | ||||
|  | ||||
| static struct ast_config *realtime_multi_odbc(const char *database, const char *table, va_list ap) | ||||
| { | ||||
| 	odbc_obj *obj; | ||||
| 	SQLHSTMT stmt; | ||||
| 	char sql[1024]; | ||||
| 	char coltitle[256]; | ||||
| 	char rowdata[2048]; | ||||
| 	char *op; | ||||
| 	const char *newparam, *newval; | ||||
| 	char *stringp; | ||||
| 	char *chunk; | ||||
| 	SQLSMALLINT collen; | ||||
| 	int res; | ||||
| 	int x; | ||||
| 	struct ast_variable *var=NULL, *prev=NULL; | ||||
| 	struct ast_config *cfg=NULL; | ||||
| 	struct ast_category *cat=NULL; | ||||
| 	SQLLEN rowcount=0; | ||||
| 	SQLULEN colsize; | ||||
| 	SQLSMALLINT colcount=0; | ||||
| 	SQLSMALLINT datatype; | ||||
| 	SQLSMALLINT decimaldigits; | ||||
| 	SQLSMALLINT nullable; | ||||
| 	va_list aq; | ||||
| 	 | ||||
| 	va_copy(aq, ap); | ||||
| 	 | ||||
| 	 | ||||
| 	if (!table) | ||||
| 		return NULL; | ||||
|  | ||||
| 	obj = fetch_odbc_obj(database); | ||||
| 	if (!obj) | ||||
| 		return NULL; | ||||
|  | ||||
| 	res = SQLAllocHandle (SQL_HANDLE_STMT, obj->con, &stmt); | ||||
| 	if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { | ||||
| 		ast_log(LOG_WARNING, "SQL Alloc Handle failed!\n"); | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	newparam = va_arg(aq, const char *); | ||||
| 	if (!newparam)  { | ||||
| 		SQLFreeHandle (SQL_HANDLE_STMT, stmt); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 	newval = va_arg(aq, const char *); | ||||
| 	if (!strchr(newparam, ' ')) op = " ="; else op = ""; | ||||
| 	snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE %s%s ?", table, newparam, op); | ||||
| 	while((newparam = va_arg(aq, const char *))) { | ||||
| 		if (!strchr(newparam, ' ')) op = " ="; else op = ""; | ||||
| 		snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " AND %s%s ?", newparam, op); | ||||
| 		newval = va_arg(aq, const char *); | ||||
| 	} | ||||
| 	va_end(aq); | ||||
| 	res = SQLPrepare(stmt, sql, SQL_NTS); | ||||
| 	if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { | ||||
| 		ast_log(LOG_WARNING, "SQL Prepare failed![%s]\n", sql); | ||||
| 		SQLFreeHandle (SQL_HANDLE_STMT, stmt); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 	 | ||||
| 	/* Now bind the parameters */ | ||||
| 	x = 1; | ||||
|  | ||||
| 	while((newparam = va_arg(ap, const char *))) { | ||||
| 		newval = va_arg(ap, const char *); | ||||
| 		SQLBindParameter(stmt, x++, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(newval), 0, (void *)newval, 0, NULL); | ||||
| 	} | ||||
| 		 | ||||
| 	res = SQLExecute(stmt); | ||||
|  | ||||
| 	if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { | ||||
| 		ast_log(LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql); | ||||
| 		SQLFreeHandle (SQL_HANDLE_STMT, stmt); | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	res = SQLRowCount(stmt, &rowcount); | ||||
| 	if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { | ||||
| 		ast_log(LOG_WARNING, "SQL Row Count error!\n[%s]\n\n", sql); | ||||
| 		SQLFreeHandle (SQL_HANDLE_STMT, stmt); | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	res = SQLNumResultCols(stmt, &colcount); | ||||
| 	if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { | ||||
| 		ast_log(LOG_WARNING, "SQL Column Count error!\n[%s]\n\n", sql); | ||||
| 		SQLFreeHandle (SQL_HANDLE_STMT, stmt); | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	while (rowcount) { | ||||
| 		var = NULL; | ||||
| 		prev = NULL; | ||||
| 		res = SQLFetch(stmt); | ||||
| 		if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { | ||||
| 			ast_log(LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql); | ||||
| 			continue; | ||||
| 		} | ||||
| 		for (x=0;x<colcount;x++) { | ||||
| 			rowdata[0] = '\0'; | ||||
| 			collen = sizeof(coltitle); | ||||
| 			res = SQLDescribeCol(stmt, x + 1, coltitle, sizeof(coltitle), &collen,  | ||||
| 						&datatype, &colsize, &decimaldigits, &nullable); | ||||
| 			if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { | ||||
| 				ast_log(LOG_WARNING, "SQL Describe Column error!\n[%s]\n\n", sql); | ||||
| 				if (var) | ||||
| 					ast_destroy_realtime(var); | ||||
| 				continue; | ||||
| 			} | ||||
| 			res = SQLGetData(stmt, x + 1, SQL_CHAR, rowdata, sizeof(rowdata), NULL); | ||||
| 			if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { | ||||
| 				ast_log(LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql); | ||||
| 				if (var) | ||||
| 					ast_destroy_realtime(var); | ||||
| 				continue; | ||||
| 			} | ||||
| 			stringp = rowdata; | ||||
| 			while(stringp) { | ||||
| 				chunk = strsep(&stringp, ";"); | ||||
| 				if (chunk && !ast_strlen_zero(ast_strip(chunk))) { | ||||
| 					if (prev) { | ||||
| 						prev->next = ast_new_variable(coltitle, chunk); | ||||
| 						if (prev->next) | ||||
| 							prev = prev->next; | ||||
| 					} else  | ||||
| 						prev = var = ast_new_variable(coltitle, chunk); | ||||
| 					 | ||||
| 				} | ||||
| 			} | ||||
| 			if (var) { | ||||
| 				cat = ast_new_category(""); | ||||
| 				if (cat) { | ||||
| 					cat->root = var; | ||||
| 					if (!cfg)  | ||||
| 						cfg = ast_new_config(); | ||||
| 					if (cfg) | ||||
| 						ast_category_append(cfg, cat); | ||||
| 					else  | ||||
| 						ast_category_destroy(cat); | ||||
| 				} else { | ||||
| 					ast_log(LOG_WARNING, "Out of memory!\n"); | ||||
| 					ast_destroy_realtime(var); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	SQLFreeHandle (SQL_HANDLE_STMT, stmt); | ||||
| 	return cfg; | ||||
| } | ||||
|  | ||||
| static int update_odbc(const char *database, const char *table, const char *keyfield, const char *lookup, va_list ap) | ||||
| { | ||||
| 	odbc_obj *obj; | ||||
| @@ -383,6 +536,7 @@ int load_module (void) | ||||
| 	strncpy(reg1.name, "odbc", sizeof(reg1.name) - 1); | ||||
| 	reg1.static_func = config_odbc; | ||||
| 	reg1.realtime_func = realtime_odbc; | ||||
| 	reg1.realtime_multi_func = realtime_multi_odbc; | ||||
| 	reg1.update_func = update_odbc; | ||||
| 	ast_cust_config_register (®1); | ||||
| 	if (option_verbose) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user