[asterisk-commits] tilghman: branch 1.6.1 r222310 - in /branches/1.6.1: ./ cdr/ res/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Oct 6 14:34:50 CDT 2009


Author: tilghman
Date: Tue Oct  6 14:34:48 2009
New Revision: 222310

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=222310
Log:
Recorded merge of revisions 222309 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/trunk

........
  r222309 | tilghman | 2009-10-06 14:31:39 -0500 (Tue, 06 Oct 2009) | 10 lines
  
  Change schema query to involve the use of an optional schema parameter.
  This change is done in such a way as to allow the driver to continue to
  function with older databases which don't have these features.
  (closes issue #16000)
   Reported by: jamicque
   Patches: 
         20091002__issue16000.diff.txt uploaded by tilghman (license 14)
         20091002__issue16000__1.6.1.diff.txt uploaded by tilghman (license 14)
   Tested by: jamicque
........

Modified:
    branches/1.6.1/   (props changed)
    branches/1.6.1/cdr/cdr_pgsql.c
    branches/1.6.1/res/res_config_pgsql.c

Propchange: branches/1.6.1/
------------------------------------------------------------------------------
Binary property 'trunk-merged' - no diff available.

Modified: branches/1.6.1/cdr/cdr_pgsql.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.6.1/cdr/cdr_pgsql.c?view=diff&rev=222310&r1=222309&r2=222310
==============================================================================
--- branches/1.6.1/cdr/cdr_pgsql.c (original)
+++ branches/1.6.1/cdr/cdr_pgsql.c Tue Oct  6 14:34:48 2009
@@ -474,22 +474,58 @@
 
 	conn = PQsetdbLogin(pghostname, pgdbport, NULL, NULL, pgdbname, pgdbuser, pgpassword);
 	if (PQstatus(conn) != CONNECTION_BAD) {
-		char sqlcmd[512];
+		char sqlcmd[768];
 		char *fname, *ftype, *flen, *fnotnull, *fdef;
-		char *tableptr;
-		int i, rows;
+		int i, rows, version;
 		ast_debug(1, "Successfully connected to PostgreSQL database.\n");
 		connected = 1;
-
-		/* Remove any schema name from the table */
-		if ((tableptr = strrchr(table, '.'))) {
-			tableptr++;
+		version = PQserverVersion(conn);
+
+		if (version >= 70300) {
+			char *schemaname, *tablename;
+			if (strchr(table, '.')) {
+				schemaname = ast_strdupa(table);
+				tablename = strchr(schemaname, '.');
+				*tablename++ = '\0';
+			} else {
+				schemaname = "";
+				tablename = table;
+			}
+
+			/* Escape special characters in schemaname */
+			if (strchr(schemaname, '\\') || strchr(schemaname, '\'')) {
+				char *tmp = schemaname, *ptr;
+
+				ptr = schemaname = alloca(strlen(tmp) * 2 + 1);
+				for (; *tmp; tmp++) {
+					if (strchr("\\'", *tmp)) {
+						*ptr++ = *tmp;
+					}
+					*ptr++ = *tmp;
+				}
+				*ptr = '\0';
+			}
+			/* Escape special characters in tablename */
+			if (strchr(tablename, '\\') || strchr(tablename, '\'')) {
+				char *tmp = tablename, *ptr;
+
+				ptr = tablename = alloca(strlen(tmp) * 2 + 1);
+				for (; *tmp; tmp++) {
+					if (strchr("\\'", *tmp)) {
+						*ptr++ = *tmp;
+					}
+					*ptr++ = *tmp;
+				}
+				*ptr = '\0';
+			}
+
+			snprintf(sqlcmd, sizeof(sqlcmd), "SELECT a.attname, t.typname, a.attlen, a.attnotnull, d.adsrc, a.atttypmod FROM (((pg_catalog.pg_class c INNER JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace AND c.relname = '%s' AND n.nspname = %s%s%s) INNER JOIN pg_catalog.pg_attribute a ON (NOT a.attisdropped) AND a.attnum > 0 AND a.attrelid = c.oid) INNER JOIN pg_catalog.pg_type t ON t.oid = a.atttypid) LEFT OUTER JOIN pg_attrdef d ON a.atthasdef AND d.adrelid = a.attrelid AND d.adnum = a.attnum ORDER BY n.nspname, c.relname, attnum",
+				tablename,
+				ast_strlen_zero(schemaname) ? "" : "'", ast_strlen_zero(schemaname) ? "current_schema()" : schemaname, ast_strlen_zero(schemaname) ? "" : "'");
 		} else {
-			tableptr = table;
-		}
-
+			snprintf(sqlcmd, sizeof(sqlcmd), "SELECT a.attname, t.typname, a.attlen, a.attnotnull, d.adsrc, a.atttypmod FROM pg_class c, pg_type t, pg_attribute a LEFT OUTER JOIN pg_attrdef d ON a.atthasdef AND d.adrelid = a.attrelid AND d.adnum = a.attnum WHERE c.oid = a.attrelid AND a.atttypid = t.oid AND (a.attnum > 0) AND c.relname = '%s' ORDER BY c.relname, attnum", table);
+		}
 		/* Query the columns */
-		snprintf(sqlcmd, sizeof(sqlcmd), "select a.attname, t.typname, a.attlen, a.attnotnull, d.adsrc from pg_class c, pg_type t, pg_attribute a left outer join pg_attrdef d on a.atthasdef and d.adrelid = a.attrelid and d.adnum = a.attnum where c.oid = a.attrelid and a.atttypid = t.oid and (a.attnum > 0) and c.relname = '%s' order by c.relname, attnum", tableptr);
 		result = PQexec(conn, sqlcmd);
 		if (PQresultStatus(result) != PGRES_TUPLES_OK) {
 			pgerror = PQresultErrorMessage(result);
@@ -506,6 +542,10 @@
 			flen = PQgetvalue(result, i, 2);
 			fnotnull = PQgetvalue(result, i, 3);
 			fdef = PQgetvalue(result, i, 4);
+			if (atoi(flen) == -1) {
+				/* For varchar columns, the maximum length is encoded in a different field */
+				flen = PQgetvalue(result, i, 5);
+			}
 			ast_verb(4, "Found column '%s' of type '%s'\n", fname, ftype);
 			cur = ast_calloc(1, sizeof(*cur) + strlen(fname) + strlen(ftype) + 2);
 			if (cur) {

Modified: branches/1.6.1/res/res_config_pgsql.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.6.1/res/res_config_pgsql.c?view=diff&rev=222310&r1=222309&r2=222310
==============================================================================
--- branches/1.6.1/res/res_config_pgsql.c (original)
+++ branches/1.6.1/res/res_config_pgsql.c Tue Oct  6 14:34:48 2009
@@ -46,6 +46,8 @@
 #define RES_CONFIG_PGSQL_CONF "res_pgsql.conf"
 
 PGconn *pgsqlConn = NULL;
+static int version;
+#define has_schema_support	(version > 70300 ? 1 : 0)
 
 #define MAX_DB_OPTION_SIZE 64
 
@@ -99,7 +101,7 @@
 	ast_free(table);
 }
 
-static struct tables *find_table(const char *tablename)
+static struct tables *find_table(const char *orig_tablename)
 {
 	struct columns *column;
 	struct tables *table;
@@ -111,7 +113,7 @@
 
 	AST_LIST_LOCK(&psql_tables);
 	AST_LIST_TRAVERSE(&psql_tables, table, list) {
-		if (!strcasecmp(table->name, tablename)) {
+		if (!strcasecmp(table->name, orig_tablename)) {
 			ast_debug(1, "Found table in cache; now locking\n");
 			ast_mutex_lock(&table->lock);
 			ast_debug(1, "Lock cached table; now returning\n");
@@ -120,10 +122,69 @@
 		}
 	}
 
-	ast_debug(1, "Table '%s' not found in cache, querying now\n", tablename);
+	ast_debug(1, "Table '%s' not found in cache, querying now\n", orig_tablename);
 
 	/* Not found, scan the table */
-	ast_str_set(&sql, 0, "SELECT a.attname, t.typname, a.attlen, a.attnotnull, d.adsrc, a.atttypmod FROM pg_class c, pg_type t, pg_attribute a LEFT OUTER JOIN pg_attrdef d ON a.atthasdef AND d.adrelid = a.attrelid AND d.adnum = a.attnum WHERE c.oid = a.attrelid AND a.atttypid = t.oid AND (a.attnum > 0) AND c.relname = '%s' ORDER BY c.relname, attnum", tablename);
+	if (has_schema_support) {
+		char *schemaname, *tablename;
+		if (strchr(orig_tablename, '.')) {
+			schemaname = ast_strdupa(orig_tablename);
+			tablename = strchr(schemaname, '.');
+			*tablename++ = '\0';
+		} else {
+			schemaname = "";
+			tablename = ast_strdupa(orig_tablename);
+		}
+
+		/* Escape special characters in schemaname */
+		if (strchr(schemaname, '\\') || strchr(schemaname, '\'')) {
+			char *tmp = schemaname, *ptr;
+
+			ptr = schemaname = alloca(strlen(tmp) * 2 + 1);
+			for (; *tmp; tmp++) {
+				if (strchr("\\'", *tmp)) {
+					*ptr++ = *tmp;
+				}
+				*ptr++ = *tmp;
+			}
+			*ptr = '\0';
+		}
+		/* Escape special characters in tablename */
+		if (strchr(tablename, '\\') || strchr(tablename, '\'')) {
+			char *tmp = tablename, *ptr;
+
+			ptr = tablename = alloca(strlen(tmp) * 2 + 1);
+			for (; *tmp; tmp++) {
+				if (strchr("\\'", *tmp)) {
+					*ptr++ = *tmp;
+				}
+				*ptr++ = *tmp;
+			}
+			*ptr = '\0';
+		}
+
+		ast_str_set(&sql, 0, "SELECT a.attname, t.typname, a.attlen, a.attnotnull, d.adsrc, a.atttypmod FROM (((pg_catalog.pg_class c INNER JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace AND c.relname = '%s' AND n.nspname = %s%s%s) INNER JOIN pg_catalog.pg_attribute a ON (NOT a.attisdropped) AND a.attnum > 0 AND a.attrelid = c.oid) INNER JOIN pg_catalog.pg_type t ON t.oid = a.atttypid) LEFT OUTER JOIN pg_attrdef d ON a.atthasdef AND d.adrelid = a.attrelid AND d.adnum = a.attnum ORDER BY n.nspname, c.relname, attnum",
+			tablename,
+			ast_strlen_zero(schemaname) ? "" : "'", ast_strlen_zero(schemaname) ? "current_schema()" : schemaname, ast_strlen_zero(schemaname) ? "" : "'");
+	} else {
+		/* Escape special characters in tablename */
+		if (strchr(orig_tablename, '\\') || strchr(orig_tablename, '\'')) {
+			const char *tmp = orig_tablename;
+			char *ptr;
+
+			orig_tablename = ptr = alloca(strlen(tmp) * 2 + 1);
+			for (; *tmp; tmp++) {
+				if (strchr("\\'", *tmp)) {
+					*ptr++ = *tmp;
+				}
+				*ptr++ = *tmp;
+			}
+			*ptr = '\0';
+		}
+
+		ast_str_set(&sql, 0, "SELECT a.attname, t.typname, a.attlen, a.attnotnull, d.adsrc, a.atttypmod FROM pg_class c, pg_type t, pg_attribute a LEFT OUTER JOIN pg_attrdef d ON a.atthasdef AND d.adrelid = a.attrelid AND d.adnum = a.attnum WHERE c.oid = a.attrelid AND a.atttypid = t.oid AND (a.attnum > 0) AND c.relname = '%s' ORDER BY c.relname, attnum", orig_tablename);
+	}
+
 	result = PQexec(pgsqlConn, sql->str);
 	ast_debug(1, "Query of table structure complete.  Now retrieving results.\n");
 	if (PQresultStatus(result) != PGRES_TUPLES_OK) {
@@ -134,12 +195,12 @@
 		return NULL;
 	}
 
-	if (!(table = ast_calloc(1, sizeof(*table) + strlen(tablename) + 1))) {
+	if (!(table = ast_calloc(1, sizeof(*table) + strlen(orig_tablename) + 1))) {
 		ast_log(LOG_ERROR, "Unable to allocate memory for new table structure\n");
 		AST_LIST_UNLOCK(&psql_tables);
 		return NULL;
 	}
-	strcpy(table->name, tablename); /* SAFE */
+	strcpy(table->name, orig_tablename); /* SAFE */
 	ast_mutex_init(&table->lock);
 	AST_LIST_HEAD_INIT_NOLOCK(&table->columns);
 	
@@ -153,7 +214,7 @@
 		ast_verb(4, "Found column '%s' of type '%s'\n", fname, ftype);
 
 		if (!(column = ast_calloc(1, sizeof(*column) + strlen(fname) + strlen(ftype) + 2))) {
-			ast_log(LOG_ERROR, "Unable to allocate column element for %s, %s\n", tablename, fname);
+			ast_log(LOG_ERROR, "Unable to allocate column element for %s, %s\n", orig_tablename, fname);
 			destroy_table(table);
 			AST_LIST_UNLOCK(&psql_tables);
 			return NULL;
@@ -1292,6 +1353,7 @@
 		if (pgsqlConn && PQstatus(pgsqlConn) == CONNECTION_OK) {
 			ast_debug(1, "PostgreSQL RealTime: Successfully connected to database.\n");
 			connect_time = time(NULL);
+			version = PQserverVersion(pgsqlConn);
 			return 1;
 		} else {
 			ast_log(LOG_ERROR,




More information about the asterisk-commits mailing list