[Freeswitch-branches] [commit] r3836 - freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr

Freeswitch SVN mishehu at freeswitch.org
Tue Dec 26 22:45:27 EST 2006


Author: mishehu
Date: Tue Dec 26 22:45:26 2006
New Revision: 3836

Modified:
   freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/README
   freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/csvcdr.cpp
   freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/sqlitecdr.cpp
   freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/sqlitecdr.h
   freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/xmlcdr.cpp

Log:
SqliteCDR compiles and appears to behave as expected.  Welcome it to the list of CDR backends.

Modified: freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/README
==============================================================================
--- freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/README	(original)
+++ freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/README	Tue Dec 26 22:45:26 2006
@@ -82,6 +82,14 @@
 		<param name="chanvars_supp" value=""/> value is a comma separated list of supplemental channel variables to log.  Can be a wildcard (*) (optional)
 		<param name="chanvars_supp_repeat_fixed" value=""/> value is 0 for no, 1 for yes, and determines whether or not to repeat any of the fixed channel variables as key / value pairs in the chanvars table.
 		<param name="timezone" value=""/> value is utc for utc time, local for localtime.  If not specified or incorrectly specified, localtime is assumed.
+				
+Class:	SqliteCDR, located in sqlitecdr.h and sqlitecdr.cpp
+		This class uses the Sqlite3 library as included with FreeSWITCH's core.  Sqlite is not strict in its handling of column types, and in theory you can toss any sort of data at any sort of column.  That being said, this logger was designed to at least attempt to match the column types to the type of data being sent to it.  It will warn you if the schema does not match what chanvars_fixed types you specify, but it will not fail on them.  However, due to the use of prepared statements, it is likely that you will have unexpected results if you mismatch your chanvars_fixed logging to db schema.  The is the first SQL logger to automatically create the db schema and even update it on its own.
+Configuration: Section <sqlitecdr>
+		<param name="path" value=""/> value is the path to the database to open or create  (required)
+		<param name="chanvars_fixed" value=""/> Is a comma separated list of key=type pairs.  Types are x for decimal, s for string (varchar), d for double, i for integer, t for tiny.  If no type is provided, it defaults that column to string (varchar).  It cannot accept wildcards (*).  You must have a matching column of matching type in the main freeswitchcdr table. The logger will attempt to automatically update the schema, but it cannot if a column by that name already exists.(optional)
+		<param name="chanvars_supp" value=""/> value is a comma separated list of supplemental channel variables to log.  Can be a wildcard (*) (optional)
+		<param name="chanvars_supp_repeat_fixed" value=""/> value is 0 for no, 1 for yes, and determines whether or not to repeat any of the fixed channel variables as key / value pairs in the chanvars table.
 		
 FAQ:
 

Modified: freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/csvcdr.cpp
==============================================================================
--- freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/csvcdr.cpp	(original)
+++ freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/csvcdr.cpp	Tue Dec 26 22:45:26 2006
@@ -179,7 +179,7 @@
 			if(outputfile.good())
 			{
 				activated = 1;
-				switch_console_printf(SWITCH_CHANNEL_LOG,"CsvCDR activated, log rotation will occur at or after %d MB",(filesize_limit/1024/1024));
+				switch_console_printf(SWITCH_CHANNEL_LOG,"CsvCDR activated, log rotation will occur at or after %d MB\n",(filesize_limit/1024/1024));
 			}
 		}
 		else
@@ -329,7 +329,7 @@
 	chanvars_fixed_list.clear();
 	chanvars_supp_list.clear();
 	connectionstate = 0;
-	switch_console_printf(SWITCH_CHANNEL_LOG,"Shutting down CsvCDR...  Done!");	
+	switch_console_printf(SWITCH_CHANNEL_LOG,"Shutting down CsvCDR...  Done!\n");	
 }
 
 AUTO_REGISTER_BASECDR(CsvCDR);

Modified: freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/sqlitecdr.cpp
==============================================================================
--- freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/sqlitecdr.cpp	(original)
+++ freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/sqlitecdr.cpp	Tue Dec 26 22:45:26 2006
@@ -200,7 +200,7 @@
 			
 				if(sql_rc == SQLITE_OK)
 				{
-					for(int i = 0; i < nrows; i++)
+					for(int i = 0; i < ((nrow+1)*ncol); i++)
 					{
 						std::string tablename = result[i];
 						if(tablename == "freeswitchcdr" || tablename == "chanvars")
@@ -212,14 +212,14 @@
 				else
 					switch_console_printf(SWITCH_CHANNEL_LOG,"There was an error in executing query %s: The error was %s.\n",sql_query_check_tables,errormessage);
 				
-				switch_core_db_free_table(&result);
+				switch_core_db_free_table(result);
 			
 				if(!temp_sql_tables["freeswitchcdr"])
 				{
 					switch_console_printf(SWITCH_CHANNEL_LOG,"Creating the freeswitchcdr table in the SQLite mod_cdr database file.\n");
 					// Must create the missing freeswitchcdr table.
 					char sql_query_create_freeswitchcdr[] = "CREATE TABLE freeswitchcdr (\n"
-						"callid INTEGER AUTOINCREMENT PRIMARY KEY,\n"
+						"callid INTEGER PRIMARY KEY AUTOINCREMENT,\n"
 						"callstartdate INTEGER NOT NULL,\n"
 						"callanswerdate INTEGER NOT NULL,\n"
 						"calltransferdate INTEGER NOT NULL,\n"
@@ -239,8 +239,8 @@
 						"lastapp TEXT default \"\",\n"
 						"lastdata TEXT default \"\",\n"
 						"billusec INTEGER default 0,\n"
-						"disposition INTEGER default 0,\n" /* 0 = Busy or Unanswered, 1 = Answered */
-						"hangupcause INTEGER default 0\n",
+						"disposition INTEGER default 0,\n"
+						"hangupcause INTEGER default 0,\n"
 						"amaflags INTEGER default 0\n"
 						");\n";
 						
@@ -251,8 +251,8 @@
 				{
 					switch_console_printf(SWITCH_CHANNEL_LOG,"Creating the chanvars table in the SQLite mod_cdr database file.\n");
 					// Must create the missing chanvars table.
-					sql_query_create_chanvars[] = "CREATE TABLE chanvars (\n"
-						"callid INTEGER default 0,\n""
+					char sql_query_create_chanvars[] = "CREATE TABLE chanvars (\n"
+						"callid INTEGER default 0,\n"
 						"varname TEXT NOT NULL,\n"
 						"varvalue TEXT default \"\"\n"
 						");\n";
@@ -264,19 +264,23 @@
 				{
 					// Now to check if the freeswitchcdr schema matches
 					std::map<std::string,std::string> freeswitchcdr_columns;
-					char sql_query_get_schema_of_freeswitchcdr[] = "SELECT * FROM SQLITE_MASTER WHERE name=\"freeswitchcdr\"";
+					char sql_query_get_schema_of_freeswitchcdr[] = "SELECT sql FROM SQLITE_MASTER WHERE name=\"freeswitchcdr\"";
 					char **result2;
 					nrow = 0;
 					ncol = 0;
 					char *errormessage2;
-					sql_rc = switch_core_db_get_table(db,sql_query_get_schema_of_freeswitchcdr,&result2,&nrow,&ncol,&errormessage);
+					sql_rc = switch_core_db_get_table(db,sql_query_get_schema_of_freeswitchcdr,&result2,&nrow,&ncol,&errormessage2);
 					
 					if(sql_rc == SQLITE_OK)
 					{
-						for(int i = 0; i < nrows; i++)
+						for(int k = 0; k < nrow; k++)
 						{
-							std::string resultstring = result2[i][4];
-							std::string::size_type j = resultstring.find('(',i);
+							// Warning - this is slightly ugly for string parsing
+							std::string resultstring = result2[1];
+							std::string::size_type j = resultstring.find('(',0);
+							j = resultstring.find('\n',j);
+							
+							std::string::size_type h = 0;
 							
 							std::string tempstring1,tempstring2;
 							
@@ -285,15 +289,29 @@
 								j = resultstring.find(' ',i);
 								if(j > 0)
 								{
-									tempstring = resultstring.substr(i,(j-i));
+									if(j == i)
+									{
+										i++;
+										j = resultstring.find(' ',(i));
+									}
+									
+									tempstring1 = resultstring.substr(i,(j-i));
 									i = j+1;
 									j =resultstring.find(',',i);
+									
+									h = resultstring.find(' ',i);
 									if(j == std::string::npos)
 										tempstring2 = resultstring.substr(i,(resultstring.size() - i));
+									else if(j > h)
+										tempstring2 = resultstring.substr(i,(h-i));
 									else
 										tempstring2 = resultstring.substr(i,(j-i));
 								
 									freeswitchcdr_columns[tempstring1] = tempstring2;
+									// switch_console_printf(SWITCH_CHANNEL_LOG,"tempstring1 = %s, tempstring2 = %s\n",tempstring1.c_str(),tempstring2.c_str());
+									if(resultstring.find('\n',j+1) == (j+1))
+										j++;
+									i = j+1;
 								}
 								else
 									switch_console_printf(SWITCH_CHANNEL_LOG,"There has been a parsing problem with the freeswitchcdr schema.\n");
@@ -301,7 +319,7 @@
 						}
 					}
 					
-					switch_core_db_free_table(&result2);
+					switch_core_db_free_table(result2);
 					
 					// Now to actually compare what we have in the config against the db schema
 					std::map<std::string,std::string> freeswitchcdr_add_columns;
@@ -315,7 +333,8 @@
 							case CDR_TINY:
 								if(freeswitchcdr_columns.find(*iItr) != freeswitchcdr_columns.end())
 								{
-									if(freeswitchcdr_columns[*iItr] != "INTEGER")
+									//switch_console_printf(SWITCH_CHANNEL_LOG,"freeswitchcdr_columns[%s] == %s.\n",iItr->c_str(),freeswitchcdr_columns[*iItr].c_str());
+									if(freeswitchcdr_columns[*iItr].find("INTEGER",0) == std::string::npos)
 										switch_console_printf(SWITCH_CHANNEL_LOG,"WARNING: SqliteCDR freeswitchcdr table column type mismatch: Column \"%s\" is not of an INTEGER type.  This is not necessarily fatal, but may result in unexpected behavior.\n",iItr->c_str());
 								}
 								else
@@ -324,7 +343,7 @@
 							case CDR_DOUBLE:
 								if(freeswitchcdr_columns.find(*iItr) != freeswitchcdr_columns.end())
 								{
-									if(freeswitchcdr_columns[*iItr] != "REAL")
+									if(freeswitchcdr_columns[*iItr].find("REAL",0) == std::string::npos)
 										switch_console_printf(SWITCH_CHANNEL_LOG,"WARNING: SqliteCDR freeswitchcdr table column type mismatch: Column \"%s\" is not of a REAL type.  This is not necessarily fatal, but may result in unexpected behavior.\n",iItr->c_str());
 								}
 								else
@@ -334,21 +353,21 @@
 							case CDR_STRING:
 								if(freeswitchcdr_columns.find(*iItr) != freeswitchcdr_columns.end())
 								{
-									if(freeswitchcdr_columns[*iItr] != "TEXT")
+									if(freeswitchcdr_columns[*iItr].find("TEXT",0) == std::string::npos)
 										switch_console_printf(SWITCH_CHANNEL_LOG,"WARNING: SqliteCDR freeswitchcdr table column type mismatch: Column \"%s\" is not of a TEXT type.  This is not necessarily fatal, but may result in unexpected behavior.\n",iItr->c_str());
 								}
 								else
 									freeswitchcdr_add_columns[*iItr] = "TEXT";
 								break;
 							default:
-								switch_console_printf("Oh bother, I should not have fallen into this hole in the switch/case statement.  Please notify the author.\n");
+								switch_console_printf(SWITCH_CHANNEL_LOG,"Oh bother, I should not have fallen into this hole in the switch/case statement.  Please notify the author.\n");
 						}
 					}
 					
 					if(freeswitchcdr_add_columns.size())
 					{
 						switch_console_printf(SWITCH_CHANNEL_LOG,"Updating the freeswitchcdr table schema.\n");
-						std::string tempsql_freeswitchcdr_alter_table = "ALTER TABLE freeswithcdr ADD ";
+						std::string tempsql_freeswitchcdr_alter_table = "ALTER TABLE freeswitchcdr ADD ";
 						std::map<std::string, std::string>::iterator iItr, iEnd;
 						for(iItr = freeswitchcdr_add_columns.begin(), iEnd = freeswitchcdr_add_columns.end(); iItr != iEnd; iItr++)
 						{
@@ -356,6 +375,7 @@
 							sql_query_freeswitchcdr_alter_table.append(iItr->first);
 							sql_query_freeswitchcdr_alter_table.append(" ");
 							sql_query_freeswitchcdr_alter_table.append(iItr->second);
+							switch_console_printf(SWITCH_CHANNEL_LOG,"Updating the freeswitchcdr table with the following SQL command: %s.\n",sql_query_freeswitchcdr_alter_table.c_str());
 							switch_core_db_exec(db, sql_query_freeswitchcdr_alter_table.c_str(), NULL, NULL, NULL);
 						}
 					}
@@ -391,11 +411,12 @@
 {
 	int column = 1;
 	switch_core_db_step(stmt_begin);
+	switch_core_db_reset(stmt_begin);
 	switch_core_db_bind_int64(stmt, column++, (sqlite_int64) callstartdate);
 	switch_core_db_bind_int64(stmt, column++, (sqlite_int64) callanswerdate);
 	switch_core_db_bind_int64(stmt, column++, (sqlite_int64) calltransferdate);
 	switch_core_db_bind_int64(stmt, column++, (sqlite_int64) callenddate);
-	switch_core_db_bind_int(stmt, column++, (sqlite_int) originated);
+	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);
@@ -410,9 +431,55 @@
 	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_int(stmt, column++, (sqlite_int) disposition);
-	switch_core_db_bind_int(stmt, column++, (sqlite_int) hangupcause);
-	switch_core_db_bind_int(stmt, column++, (sqlite_int) amaflags);
+	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);
+	
+	if(chanvars_fixed.size())
+	{
+		std::list< std::pair<std::string,std::string> >::iterator iItr, iEnd;
+		int count = 0;
+		for(iItr = chanvars_fixed.begin(), iEnd = chanvars_fixed.end(); iItr != iEnd; iItr++, count++)
+		{
+			switch(chanvars_fixed_types[count])
+			{
+				case CDR_INTEGER:
+				case CDR_TINY:
+				{
+					int x;
+					if(iItr->second.size() > 0)
+					{
+						std::istringstream istring(iItr->second);
+						istring >> x;
+					}
+					else
+						x = 0;
+					switch_core_db_bind_int(stmt,column++,x);
+					break;
+				}
+				case CDR_DOUBLE:
+				{
+					double x = 0;
+					if(iItr->second.size() > 0)
+					{
+						std::istringstream istring(iItr->second);
+						istring >> x;
+					}
+					switch_core_db_bind_double(stmt,column++,x);
+					break;
+				}
+				case CDR_DECIMAL:
+				case CDR_STRING:
+				{
+					switch_core_db_bind_text(stmt,column++,iItr->second.c_str(),-1,SQLITE_STATIC);
+					break;
+				}
+				default:
+					switch_console_printf(SWITCH_CHANNEL_LOG,"Oh bother, I should not have fallen into this hole in the switch/case statement.  Please notify the author.\n");
+			}
+		}
+	}
+	
 	int sql_rc = switch_core_db_step(stmt);
 	if(sql_rc != SQLITE_DONE)
 	{
@@ -422,6 +489,8 @@
 			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));
 	}
 	
+	sql_rc = switch_core_db_reset(stmt);
+	
 	if(logchanvars && chanvars_supp.size())
 	{
 		sqlite_int64 rowid = switch_core_db_last_insert_rowid(db);
@@ -429,22 +498,24 @@
 		std::map<std::string,std::string>::iterator iItr, iEnd;
 		for(iItr = chanvars_supp.begin(), iEnd = chanvars_supp.end(); iItr != iEnd; iItr++)
 		{
-			switch_core_db_bind_int64(stmt_chanvars, column++, rowid);
-			switch_core_db_bind_text(stmt_chanvars, column++, iItr->first.c_str(),-1,SQLITE_STATIC);
-			switch_core_db_bind_text(stmt_chanvars, column++, iItr->second.c_str(),-1,SQLITE_STATIC);
-		}
-		
-		int sql_rc = switch_core_db_step(stmt_chanvars);
-		if(sql_rc != SQLITE_DONE)
-		{
-			if(sql_rc == SQLITE_BUSY)
-				sql_rc = switch_core_db_step(stmt_chanvars);
-			else if (sql_rc == SQLITE_ERROR || sql_rc == SQLITE_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));
+			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);
+			int sql_rc = switch_core_db_step(stmt_chanvars);
+			if(sql_rc != SQLITE_DONE)
+			{
+				if(sql_rc == SQLITE_BUSY)
+					sql_rc = switch_core_db_step(stmt_chanvars);
+				else if (sql_rc == SQLITE_ERROR || sql_rc == SQLITE_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));
+			}
+			
+			switch_core_db_reset(stmt_chanvars);
 		}
 	}
 	
 	switch_core_db_step(stmt_commit);
+	switch_core_db_reset(stmt_commit);
 	
 	return 1;
 }
@@ -465,6 +536,12 @@
 	tmp_sql_query.clear();
 }
 
+std::string SqliteCDR::get_display_name()
+{
+	return display_name;
+}
+
+
 
 AUTO_REGISTER_BASECDR(SqliteCDR);
 

Modified: freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/sqlitecdr.h
==============================================================================
--- freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/sqlitecdr.h	(original)
+++ freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/sqlitecdr.h	Tue Dec 26 22:45:26 2006
@@ -59,7 +59,7 @@
 		static std::string tmp_sql_query; // Object must exist to bind the statement, this used for generating the sql
 		static char sql_query_chanvars[100];
 		static std::string db_filename;
-		static switch_core_db *db;
+		static switch_core_db_t *db;
 		static switch_core_db_stmt_t *stmt;
 		static switch_core_db_stmt_t *stmt_chanvars;
 		static switch_core_db_stmt_t *stmt_begin;

Modified: freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/xmlcdr.cpp
==============================================================================
--- freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/xmlcdr.cpp	(original)
+++ freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/xmlcdr.cpp	Tue Dec 26 22:45:26 2006
@@ -171,7 +171,7 @@
 		switch_console_printf(SWITCH_CHANNEL_LOG, "XmlCDR::process_record():  Unable to open file  %s to commit the call record to.  Invalid path name, invalid permissions, or no space available?\n",outputfile_name.c_str());
 	else
 	{
-		switch_console_printf(SWITCH_CHANNEL_LOG, "XmlCDR::process_record():  Preping the CDR to %s.\n",outputfile_name.c_str());
+		//switch_console_printf(SWITCH_CHANNEL_LOG, "XmlCDR::process_record():  Preping the CDR to %s.\n",outputfile_name.c_str());
 		// Format the call record and proceed from here...
 		outputfile << "<?xml version=\"1.0\"?>" << std::endl;
 		outputfile << "<document type=\"freeswitch-cdr/xml\">" << std::endl;
@@ -213,7 +213,7 @@
 		}
 		outputfile << "\t</chanvars>" << std::endl << "</document>" << std::endl << std::endl;
 
-		switch_console_printf(SWITCH_CHANNEL_LOG, "XmlCDR::process_record():  Dumping the CDR to %s.\n",outputfile_name.c_str());
+		//switch_console_printf(SWITCH_CHANNEL_LOG, "XmlCDR::process_record():  Dumping the CDR to %s.\n",outputfile_name.c_str());
 		retval = 1;
 	}
 	



More information about the Freeswitch-branches mailing list