[asterisk-commits] cel pgsql: Add support for setting schema (asterisk[master])

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed May 13 15:17:19 CDT 2015


Joshua Colp has submitted this change and it was merged.

Change subject: cel_pgsql: Add support for setting schema
......................................................................


cel_pgsql: Add support for setting schema

Add feature to set optional schema parameter on configuration file via
'schema' setting.

Fix query to get columns from table while considering schema. If in
the database there exists two tables with same name in distinct schemas
it will return an error when inserting record.

ASTERISK-24967 #close

Change-Id: I691fd2cbc277fcba10e615f5884f8de5d8152f2c
---
M CHANGES
M cel/cel_pgsql.c
M configs/samples/cel_pgsql.conf.sample
3 files changed, 58 insertions(+), 8 deletions(-)

Approvals:
  Ashley Sanders: Looks good to me, but someone else must approve
  Joshua Colp: Looks good to me, approved; Verified



diff --git a/CHANGES b/CHANGES
index 1753be6..8a9727a 100644
--- a/CHANGES
+++ b/CHANGES
@@ -153,6 +153,10 @@
  * Added a new option, 'usegmtime', which causes timestamps in CEL events
    to be logged in GMT.
 
+ * Added support to set schema where located the table cel. This settings is
+   configurable for cel_pgsql via the 'schema' in configuration file
+   cel_pgsql.conf.
+
 ------------------------------------------------------------------------------
 --- Functionality changes from Asterisk 13.3.0 to Asterisk 13.4.0 ------------
 ------------------------------------------------------------------------------
diff --git a/cel/cel_pgsql.c b/cel/cel_pgsql.c
index 2d7f0df..2bcee6e 100644
--- a/cel/cel_pgsql.c
+++ b/cel/cel_pgsql.c
@@ -60,6 +60,8 @@
 
 #define PGSQL_BACKEND_NAME "CEL PGSQL backend"
 
+#define PGSQL_MIN_VERSION_SCHEMA 70300
+
 static char *config = "cel_pgsql.conf";
 
 static char *pghostname;
@@ -69,6 +71,7 @@
 static char *pgappname;
 static char *pgdbport;
 static char *table;
+static char *schema;
 
 static int connected = 0;
 static int maxsize = 512, maxsize2 = 512;
@@ -418,6 +421,10 @@
 		ast_free(table);
 		table = NULL;
 	}
+	if (schema) {
+		ast_free(schema);
+		schema = NULL;
+	}
 	while ((current = AST_RWLIST_REMOVE_HEAD(&psql_columns, list))) {
 		ast_free(current);
 	}
@@ -521,6 +528,16 @@
 	} else {
 		usegmtime = 0;
 	}
+	if (!(tmp = ast_variable_retrieve(cfg, "global", "schema"))) {
+		tmp = "";
+	}
+	if (schema) {
+		ast_free(schema);
+	}
+	if (!(schema = ast_strdup(tmp))) {
+		ast_log(LOG_WARNING,"PostgreSQL Ran out of memory copying schema info\n");
+		return AST_MODULE_LOAD_DECLINE;
+	}
 	if (option_debug) {
 		if (ast_strlen_zero(pghostname)) {
 			ast_debug(3, "cel_pgsql: using default unix socket\n");
@@ -538,23 +555,50 @@
 
 	pgsql_reconnect();
 	if (PQstatus(conn) != CONNECTION_BAD) {
-		char sqlcmd[512];
-		char *fname, *ftype, *flen, *fnotnull, *fdef;
-		char *tableptr;
-		int i, rows;
+		char sqlcmd[768];
+		char *fname, *ftype, *flen, *fnotnull, *fdef, *tablename, *tmp_tablename;
+		int i, rows, version;
 
 		ast_debug(1, "Successfully connected to PostgreSQL database.\n");
 		connected = 1;
 
+		version = PQserverVersion(conn);
 		/* Remove any schema name from the table */
-		if ((tableptr = strrchr(table, '.'))) {
-			tableptr++;
+		if ((tmp_tablename = strrchr(table, '.'))) {
+			tmp_tablename++;
 		} else {
-			tableptr = table;
+			tmp_tablename = table;
 		}
+		tablename = ast_alloca(strlen(tmp_tablename) * 2 + 1);
+		PQescapeStringConn(conn, tablename, tmp_tablename, strlen(tmp_tablename), NULL);
+		if (version >= PGSQL_MIN_VERSION_SCHEMA) {
+			char *schemaname;
+			int lenschema;
+			lenschema = strlen(schema);
+			schemaname = ast_alloca(lenschema * 2 + 1);
+			PQescapeStringConn(conn, schemaname, schema, lenschema, NULL);
 
+			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,
+				lenschema == 0 ? "" : "'", lenschema == 0 ? "current_schema()" : schemaname, lenschema == 0 ? "" : "'");
+		} else {
+			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", tablename);
+		}
 		/* 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);
diff --git a/configs/samples/cel_pgsql.conf.sample b/configs/samples/cel_pgsql.conf.sample
index 30c789e..13fe069 100644
--- a/configs/samples/cel_pgsql.conf.sample
+++ b/configs/samples/cel_pgsql.conf.sample
@@ -68,4 +68,6 @@
 ;password=password
 ;user=postgres
 ;table=cel		;SQL table where CEL's will be inserted
+;schema=public ;Schema where CEL's table is located.  Optional parameter.
+               ;If schema support is present the default value used will be current_schema().
 ;appname=asterisk   ; Postgres application_name support (optional). Whitespace not allowed.

-- 
To view, visit https://gerrit.asterisk.org/120
To unsubscribe, visit https://gerrit.asterisk.org/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I691fd2cbc277fcba10e615f5884f8de5d8152f2c
Gerrit-PatchSet: 8
Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-Owner: Rodrigo Ramirez Norambuena <decipher.hk at gmail.com>
Gerrit-Reviewer: Ashley Sanders <asanders at digium.com>
Gerrit-Reviewer: Joshua Colp <jcolp at digium.com>
Gerrit-Reviewer: Mark Michelson <mmichelson at digium.com>
Gerrit-Reviewer: Matt Jordan <mjordan at digium.com>
Gerrit-Reviewer: Rodrigo Ramirez Norambuena <decipher.hk at gmail.com>



More information about the asterisk-commits mailing list