From 499fba1651a97493f04319468f6988de5101f581 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Sat, 10 Mar 2007 21:57:02 +0000 Subject: [PATCH] fix sqlite cdr build with new sqlite wrapper in the core, exposing all the necessary functions. Add sqlite cdr to the windows build. git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@4505 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- src/include/switch_core_db.h | 187 ++++++++++++++++++ src/mod/event_handlers/mod_cdr/mod_cdr.vcproj | 8 + src/mod/event_handlers/mod_cdr/sqlitecdr.cpp | 62 +++--- src/switch_core_db.c | 40 ++++ 4 files changed, 266 insertions(+), 31 deletions(-) diff --git a/src/include/switch_core_db.h b/src/include/switch_core_db.h index be700d73c4..063a42b63d 100644 --- a/src/include/switch_core_db.h +++ b/src/include/switch_core_db.h @@ -59,6 +59,22 @@ typedef struct sqlite3_stmt switch_core_db_stmt_t; typedef int (*switch_core_db_callback_func_t)(void *pArg, int argc, char **argv, char **columnNames); +/* +** These are special value for the destructor that is passed in as the +** final argument to routines like switch_core_db_result_blob(). If the destructor +** argument is SWITCH_CORE_DB_STATIC, it means that the content pointer is constant +** and will never change. It does not need to be destroyed. The +** SWITCH_CORE_DB_TRANSIENT value means that the content will likely change in +** the near future and that the db should make its own private copy of +** the content before returning. +** +** The typedef is necessary to work around problems in certain +** C++ compilers. +*/ +typedef void (*switch_core_db_destructor_type_t)(void*); +#define SWITCH_CORE_DB_STATIC ((switch_core_db_destructor_type_t)0) +#define SWITCH_CORE_DB_TRANSIENT ((switch_core_db_destructor_type_t)-1) + /** * A function to close the database. * @@ -278,6 +294,177 @@ SWITCH_DECLARE(int) switch_core_db_prepare(switch_core_db_t *db, */ SWITCH_DECLARE(int) switch_core_db_step(switch_core_db_stmt_t *stmt); +/** + * The switch_core_db_reset() function is called to reset a compiled SQL + * statement obtained by a previous call to switch_core_db_prepare() + * back to it's initial state, ready to be re-executed. + * Any SQL statement variables that had values bound to them using + * the switch_core_db_bind_*() API retain their values. + */ +SWITCH_DECLARE(int) switch_core_db_reset(switch_core_db_stmt_t *pStmt); + +/** + * In the SQL strings input to switch_core_db_prepare(), + * one or more literals can be replace by parameters "?" or ":AAA" or + * "$VVV" where AAA is an identifer and VVV is a variable name according + * to the syntax rules of the TCL programming language. + * The value of these parameters (also called "host parameter names") can + * be set using the routines listed below. + * + * In every case, the first parameter is a pointer to the sqlite3_stmt + * structure returned from switch_core_db_prepare(). The second parameter is the + * index of the parameter. The first parameter as an index of 1. For + * named parameters (":AAA" or "$VVV") you can use + * switch_core_db_bind_parameter_index() to get the correct index value given + * the parameters name. If the same named parameter occurs more than + * once, it is assigned the same index each time. + * + * The switch_core_db_bind_* routine must be called before switch_core_db_step() after + * an switch_core_db_prepare() or sqlite3_reset(). Unbound parameterss are + * interpreted as NULL. + */ +SWITCH_DECLARE(int) switch_core_db_bind_int(switch_core_db_stmt_t *pStmt, int i, int iValue); + +/** + * In the SQL strings input to switch_core_db_prepare(), + * one or more literals can be replace by parameters "?" or ":AAA" or + * "$VVV" where AAA is an identifer and VVV is a variable name according + * to the syntax rules of the TCL programming language. + * The value of these parameters (also called "host parameter names") can + * be set using the routines listed below. + * + * In every case, the first parameter is a pointer to the sqlite3_stmt + * structure returned from switch_core_db_prepare(). The second parameter is the + * index of the parameter. The first parameter as an index of 1. For + * named parameters (":AAA" or "$VVV") you can use + * switch_core_db_bind_parameter_index() to get the correct index value given + * the parameters name. If the same named parameter occurs more than + * once, it is assigned the same index each time. + * + * The switch_core_db_bind_* routine must be called before switch_core_db_step() after + * an switch_core_db_prepare() or sqlite3_reset(). Unbound parameterss are + * interpreted as NULL. + */ +SWITCH_DECLARE(int) switch_core_db_bind_int64(switch_core_db_stmt_t *pStmt, int i, int64_t iValue); + +/** + * In the SQL strings input to switch_core_db_prepare(), + * one or more literals can be replace by parameters "?" or ":AAA" or + * "$VVV" where AAA is an identifer and VVV is a variable name according + * to the syntax rules of the TCL programming language. + * The value of these parameters (also called "host parameter names") can + * be set using the routines listed below. + * + * In every case, the first parameter is a pointer to the sqlite3_stmt + * structure returned from switch_core_db_prepare(). The second parameter is the + * index of the parameter. The first parameter as an index of 1. For + * named parameters (":AAA" or "$VVV") you can use + * switch_core_db_bind_parameter_index() to get the correct index value given + * the parameters name. If the same named parameter occurs more than + * once, it is assigned the same index each time. + * + * The fifth parameter to switch_core_db_bind_blob(), switch_core_db_bind_text(), and + * switch_core_db_bind_text16() is a destructor used to dispose of the BLOB or + * text after SQLite has finished with it. If the fifth argument is the + * special value SQLITE_STATIC, then the library assumes that the information + * is in static, unmanaged space and does not need to be freed. If the + * fifth argument has the value SQLITE_TRANSIENT, then SQLite makes its + * own private copy of the data. + * + * The switch_core_db_bind_* routine must be called before switch_core_db_step() after + * an switch_core_db_prepare() or sqlite3_reset(). Unbound parameterss are + * interpreted as NULL. + */ +SWITCH_DECLARE(int) switch_core_db_bind_text(switch_core_db_stmt_t *pStmt, int i, const char *zData, int nData, switch_core_db_destructor_type_t xDel); + +/** + * In the SQL strings input to switch_core_db_prepare(), + * one or more literals can be replace by parameters "?" or ":AAA" or + * "$VVV" where AAA is an identifer and VVV is a variable name according + * to the syntax rules of the TCL programming language. + * The value of these parameters (also called "host parameter names") can + * be set using the routines listed below. + * + * In every case, the first parameter is a pointer to the sqlite3_stmt + * structure returned from switch_core_db_prepare(). The second parameter is the + * index of the parameter. The first parameter as an index of 1. For + * named parameters (":AAA" or "$VVV") you can use + * sqlite3_bind_parameter_index() to get the correct index value given + * the parameters name. If the same named parameter occurs more than + * once, it is assigned the same index each time. + * + * The sqlite3_bind_* routine must be called before switch_core_db_step() after + * an switch_core_db_prepare() or switch_core_db_reset(). Unbound parameterss are + * interpreted as NULL. + */ +SWITCH_DECLARE(int) switch_core_db_bind_double(switch_core_db_stmt_t *pStmt, int i, double dValue); + +/** + * Each entry in a table has a unique integer key. (The key is + * the value of the INTEGER PRIMARY KEY column if there is such a column, + * otherwise the key is generated at random. The unique key is always + * available as the ROWID, OID, or _ROWID_ column.) The following routine + * returns the integer key of the most recent insert in the database. + * + * This function is similar to the mysql_insert_id() function from MySQL. + */ +SWITCH_DECLARE(int64_t) switch_core_db_last_insert_rowid(switch_core_db_t *db); + +/** + * This next routine is really just a wrapper around switch_core_db_exec(). + * Instead of invoking a user-supplied callback for each row of the + * result, this routine remembers each row of the result in memory + * obtained from malloc(), then returns all of the result after the + * query has finished. + * + * As an example, suppose the query result where this table: + * + * Name | Age + * ----------------------- + * Alice | 43 + * Bob | 28 + * Cindy | 21 + * + * If the 3rd argument were &azResult then after the function returns + * azResult will contain the following data: + * + * azResult[0] = "Name"; + * azResult[1] = "Age"; + * azResult[2] = "Alice"; + * azResult[3] = "43"; + * azResult[4] = "Bob"; + * azResult[5] = "28"; + * azResult[6] = "Cindy"; + * azResult[7] = "21"; + * + * Notice that there is an extra row of data containing the column + * headers. But the *nrow return value is still 3. *ncolumn is + * set to 2. In general, the number of values inserted into azResult + * will be ((*nrow) + 1)*(*ncolumn). + * + * After the calling function has finished using the result, it should + * pass the result data pointer to switch_core_db_free_table() in order to + * release the memory that was malloc-ed. Because of the way the + * malloc() happens, the calling function must not try to call + * free() directly. Only switch_core_db_free_table() is able to release + * the memory properly and safely. + * + * The return value of this routine is the same as from switch_core_db_exec(). + */ +SWITCH_DECLARE(int) switch_core_db_get_table( + switch_core_db_t *db, /* An open database */ + const char *sql, /* SQL to be executed */ + char ***resultp, /* Result written to a char *[] that this points to */ + int *nrow, /* Number of result rows written here */ + int *ncolumn, /* Number of result columns written here */ + char **errmsg /* Error msg written here */ +); + +/** + * Call this routine to free the memory that sqlite3_get_table() allocated. + */ +SWITCH_DECLARE(void) switch_core_db_free_table(char **result); + /** * Call this routine to free the memory that switch_core_db_get_table() allocated. */ diff --git a/src/mod/event_handlers/mod_cdr/mod_cdr.vcproj b/src/mod/event_handlers/mod_cdr/mod_cdr.vcproj index 756cc89b16..13b40dbc79 100644 --- a/src/mod/event_handlers/mod_cdr/mod_cdr.vcproj +++ b/src/mod/event_handlers/mod_cdr/mod_cdr.vcproj @@ -396,6 +396,10 @@ RelativePath=".\pddcdr.cpp" > + + @@ -430,6 +434,10 @@ RelativePath=".\pddcdr.h" > + + diff --git a/src/mod/event_handlers/mod_cdr/sqlitecdr.cpp b/src/mod/event_handlers/mod_cdr/sqlitecdr.cpp index 396f7c94b8..71630ac9d3 100644 --- a/src/mod/event_handlers/mod_cdr/sqlitecdr.cpp +++ b/src/mod/event_handlers/mod_cdr/sqlitecdr.cpp @@ -190,7 +190,7 @@ void SqliteCDR::connect(switch_xml_t& cfg, switch_xml_t& xml, switch_xml_t& sett int sql_rc = switch_core_db_open(db_filename.c_str(),&db); - if(sql_rc != SQLITE_OK) + if(sql_rc != SWITCH_CORE_DB_OK) { switch_console_printf(SWITCH_CHANNEL_LOG,"There was an error opening database filename %s. The error was: %s. SqliteCDR logging has been disabled until the problem is resolved and modcdr_reload is initiated.\n",db_filename.c_str(),switch_core_db_errmsg(db)); activated = 0; @@ -211,7 +211,7 @@ void SqliteCDR::connect(switch_xml_t& cfg, switch_xml_t& xml, switch_xml_t& sett temp_sql_tables["freeswitchcdr"] = 0; temp_sql_tables["chanvars"] = 0; - if(sql_rc == SQLITE_OK) + if(sql_rc == SWITCH_CORE_DB_OK) { for(int i = 0; i < ((nrow+1)*ncol); i++) { @@ -284,7 +284,7 @@ void SqliteCDR::connect(switch_xml_t& cfg, switch_xml_t& xml, switch_xml_t& sett char *errormessage2; sql_rc = switch_core_db_get_table(db,sql_query_get_schema_of_freeswitchcdr,&result2,&nrow,&ncol,&errormessage2); - if(sql_rc == SQLITE_OK) + if(sql_rc == SWITCH_CORE_DB_OK) { for(int k = 0; k < nrow; k++) { @@ -451,25 +451,25 @@ bool SqliteCDR::process_record() int column = 1; switch_core_db_step(stmt_begin); switch_core_db_reset(stmt_begin); - switch_core_db_bind_int64(stmt, column++, (sqlite_int64) sqlite_callstartdate); - switch_core_db_bind_int64(stmt, column++, (sqlite_int64) sqlite_callanswerdate); - switch_core_db_bind_int64(stmt, column++, (sqlite_int64) sqlite_calltransferdate); - switch_core_db_bind_int64(stmt, column++, (sqlite_int64) sqlite_callenddate); + switch_core_db_bind_int64(stmt, column++, sqlite_callstartdate); + switch_core_db_bind_int64(stmt, column++, sqlite_callanswerdate); + switch_core_db_bind_int64(stmt, column++, sqlite_calltransferdate); + switch_core_db_bind_int64(stmt, column++, sqlite_callenddate); switch_core_db_bind_int(stmt, column++, (int) originated); - switch_core_db_bind_text(stmt, column++, clid,-1,SQLITE_STATIC); - switch_core_db_bind_text(stmt, column++, src,-1,SQLITE_STATIC); - switch_core_db_bind_text(stmt, column++, dst,-1,SQLITE_STATIC); - switch_core_db_bind_text(stmt, column++, ani,-1,SQLITE_STATIC); - switch_core_db_bind_text(stmt, column++, aniii,-1,SQLITE_STATIC); - switch_core_db_bind_text(stmt, column++, dialplan,-1,SQLITE_STATIC); - switch_core_db_bind_text(stmt, column++, myuuid,36,SQLITE_STATIC); - switch_core_db_bind_text(stmt, column++, destuuid,36,SQLITE_STATIC); - switch_core_db_bind_text(stmt, column++, srcchannel,-1,SQLITE_STATIC); - switch_core_db_bind_text(stmt, column++, dstchannel,-1,SQLITE_STATIC); - switch_core_db_bind_text(stmt, column++, network_addr,-1,SQLITE_STATIC); - switch_core_db_bind_text(stmt, column++, lastapp,-1,SQLITE_STATIC); - switch_core_db_bind_text(stmt, column++, lastdata,-1,SQLITE_STATIC); - switch_core_db_bind_int64(stmt, column++, (sqlite_int64) billusec); + switch_core_db_bind_text(stmt, column++, clid,-1,SWITCH_CORE_DB_STATIC); + switch_core_db_bind_text(stmt, column++, src,-1,SWITCH_CORE_DB_STATIC); + switch_core_db_bind_text(stmt, column++, dst,-1,SWITCH_CORE_DB_STATIC); + switch_core_db_bind_text(stmt, column++, ani,-1,SWITCH_CORE_DB_STATIC); + switch_core_db_bind_text(stmt, column++, aniii,-1,SWITCH_CORE_DB_STATIC); + switch_core_db_bind_text(stmt, column++, dialplan,-1,SWITCH_CORE_DB_STATIC); + switch_core_db_bind_text(stmt, column++, myuuid,36,SWITCH_CORE_DB_STATIC); + switch_core_db_bind_text(stmt, column++, destuuid,36,SWITCH_CORE_DB_STATIC); + switch_core_db_bind_text(stmt, column++, srcchannel,-1,SWITCH_CORE_DB_STATIC); + switch_core_db_bind_text(stmt, column++, dstchannel,-1,SWITCH_CORE_DB_STATIC); + switch_core_db_bind_text(stmt, column++, network_addr,-1,SWITCH_CORE_DB_STATIC); + switch_core_db_bind_text(stmt, column++, lastapp,-1,SWITCH_CORE_DB_STATIC); + switch_core_db_bind_text(stmt, column++, lastdata,-1,SWITCH_CORE_DB_STATIC); + switch_core_db_bind_int64(stmt, column++, billusec); switch_core_db_bind_int(stmt, column++, disposition); switch_core_db_bind_int(stmt, column++, (int) hangupcause); switch_core_db_bind_int(stmt, column++, amaflags); @@ -510,7 +510,7 @@ bool SqliteCDR::process_record() case CDR_DECIMAL: case CDR_STRING: { - switch_core_db_bind_text(stmt,column++,iItr->second.c_str(),-1,SQLITE_STATIC); + switch_core_db_bind_text(stmt,column++,iItr->second.c_str(),-1,SWITCH_CORE_DB_STATIC); break; } default: @@ -520,11 +520,11 @@ bool SqliteCDR::process_record() } int sql_rc = switch_core_db_step(stmt); - if(sql_rc != SQLITE_DONE) + if(sql_rc != SWITCH_CORE_DB_DONE) { - if(sql_rc == SQLITE_BUSY) + if(sql_rc == SWITCH_CORE_DB_BUSY) sql_rc = switch_core_db_step(stmt); - else if (sql_rc == SQLITE_ERROR || sql_rc == SQLITE_MISUSE) + else if (sql_rc == SWITCH_CORE_DB_ERROR || sql_rc == SWITCH_CORE_DB_MISUSE) switch_console_printf(SWITCH_CHANNEL_LOG,"There was an error executing switch_core_db_step on SqliteCDR::stmt. The error was: %s\n",switch_core_db_errmsg(db)); } @@ -532,20 +532,20 @@ bool SqliteCDR::process_record() if(logchanvars && chanvars_supp.size()) { - sqlite_int64 rowid = switch_core_db_last_insert_rowid(db); + int64_t rowid = switch_core_db_last_insert_rowid(db); int column2 = 1; std::map::iterator iItr, iEnd; for(iItr = chanvars_supp.begin(), iEnd = chanvars_supp.end(); iItr != iEnd; iItr++) { switch_core_db_bind_int64(stmt_chanvars, column2++, rowid); - switch_core_db_bind_text(stmt_chanvars, column2++, iItr->first.c_str(),-1,SQLITE_STATIC); - switch_core_db_bind_text(stmt_chanvars, column2++, iItr->second.c_str(),-1,SQLITE_STATIC); + switch_core_db_bind_text(stmt_chanvars, column2++, iItr->first.c_str(),-1,SWITCH_CORE_DB_STATIC); + switch_core_db_bind_text(stmt_chanvars, column2++, iItr->second.c_str(),-1,SWITCH_CORE_DB_STATIC); int sql_rc = switch_core_db_step(stmt_chanvars); - if(sql_rc != SQLITE_DONE) + if(sql_rc != SWITCH_CORE_DB_DONE) { - if(sql_rc == SQLITE_BUSY) + if(sql_rc == SWITCH_CORE_DB_BUSY) sql_rc = switch_core_db_step(stmt_chanvars); - else if (sql_rc == SQLITE_ERROR || sql_rc == SQLITE_MISUSE) + else if (sql_rc == SWITCH_CORE_DB_ERROR || sql_rc == SWITCH_CORE_DB_MISUSE) switch_console_printf(SWITCH_CHANNEL_LOG,"There was an error executing switch_core_db_step on SqliteCDR::stmt_chanvars. The error was: %s\n",switch_core_db_errmsg(db)); } diff --git a/src/switch_core_db.c b/src/switch_core_db.c index 0a60065c34..1d83ec7a8c 100644 --- a/src/switch_core_db.c +++ b/src/switch_core_db.c @@ -91,6 +91,46 @@ SWITCH_DECLARE(int) switch_core_db_step(switch_core_db_stmt_t *stmt) return sqlite3_step(stmt); } +SWITCH_DECLARE(int) switch_core_db_reset(switch_core_db_stmt_t *pStmt) +{ + return sqlite3_reset(pStmt); +} + +SWITCH_DECLARE(int) switch_core_db_bind_int(switch_core_db_stmt_t *pStmt, int i, int iValue) +{ + return sqlite3_bind_int(pStmt, i, iValue); +} + +SWITCH_DECLARE(int) switch_core_db_bind_int64(switch_core_db_stmt_t *pStmt, int i, int64_t iValue) +{ + return sqlite3_bind_int64(pStmt, i, iValue); +} + +SWITCH_DECLARE(int) switch_core_db_bind_text(switch_core_db_stmt_t *pStmt, int i, const char *zData, int nData, switch_core_db_destructor_type_t xDel) +{ + return sqlite3_bind_text(pStmt, i, zData, nData, xDel); +} + +SWITCH_DECLARE(int) switch_core_db_bind_double(switch_core_db_stmt_t *pStmt, int i, double dValue) +{ + return sqlite3_bind_double(pStmt, i, dValue); +} + +SWITCH_DECLARE(int64_t) switch_core_db_last_insert_rowid(switch_core_db_t *db) +{ + return sqlite3_last_insert_rowid(db); +} + +SWITCH_DECLARE(int) switch_core_db_get_table(switch_core_db_t *db, const char *sql, char ***resultp, int *nrow, int *ncolumn, char **errmsg) +{ + return sqlite3_get_table(db, sql, resultp, nrow, ncolumn, errmsg); +} + +SWITCH_DECLARE(void) switch_core_db_free_table(char **result) +{ + sqlite3_free_table(result); +} + SWITCH_DECLARE(void) switch_core_db_free(char *z) { sqlite3_free(z);