r18271 - gnucash/trunk/src - Fix bug 392357: Allow port specification for a database connection. For both mysql and pgsql,

Phil Longstaff plongstaff at code.gnucash.org
Sat Aug 22 16:17:37 EDT 2009


Author: plongstaff
Date: 2009-08-22 16:17:37 -0400 (Sat, 22 Aug 2009)
New Revision: 18271
Trac: http://svn.gnucash.org/trac/changeset/18271

Modified:
   gnucash/trunk/src/backend/dbi/gnc-backend-dbi.c
   gnucash/trunk/src/gnome-utils/gnc-main-window.c
   gnucash/trunk/src/gnome-utils/gnc-plugin-file-history.c
Log:
Fix bug 392357: Allow port specification for a database connection.  For both mysql and pgsql,
the port number can be specified after the host, separated by a colon.  The URI spec is:

    mysql://hostname[:port]:dbname:username:password

where [:port] indicates that it is optional.


Modified: gnucash/trunk/src/backend/dbi/gnc-backend-dbi.c
===================================================================
--- gnucash/trunk/src/backend/dbi/gnc-backend-dbi.c	2009-08-22 19:09:39 UTC (rev 18270)
+++ gnucash/trunk/src/backend/dbi/gnc-backend-dbi.c	2009-08-22 20:17:37 UTC (rev 18271)
@@ -331,9 +331,11 @@
     GncDbiBackend *be = (GncDbiBackend*)qbe;
 	gchar* dsn = NULL;
 	gchar* host;
+	gchar* port = NULL;
 	gchar* dbname;
     gchar* username;
     gchar* password;
+	gint portnum;
 	gint result;
 	gboolean success = FALSE;
 
@@ -343,17 +345,29 @@
 
     ENTER (" ");
 
-	/* Split the book-id (format host:dbname:username:password) */
+	/* Split the book-id (format host:dbname:username:password or
+	   host:port:dbname:username:password) */
 	dsn = g_strdup( book_id );
 	for( host = dsn; *host != '/'; host++ ) {}
 	host += 2;
 	for( dbname = host; *dbname != ':'; dbname++ ) {}
 	*dbname++ = '\0';
+	if( *dbname >= '0' && *dbname <= '9' ) {
+	    port = dbname;
+	    for( ; *dbname != ':'; dbname++ ) {}
+		*dbname++ = '\0';
+	}
 	for( username = dbname; *username != ':'; username++ ) {}
 	*username++ = '\0';
 	for( password = username; *password != ':'; password++ ) {}
 	*password++ = '\0';
 
+	if( port != NULL && *port != '\0' ) {
+		portnum = atoi( port );
+	} else {
+		portnum = 0;
+	}
+
 	// Try to connect to the db.  If it doesn't exist and the create_if_nonexistent
 	// flag is TRUE, we'll need to connect to the 'mysql' db and execute the
 	// CREATE DATABASE ddl statement there.
@@ -367,7 +381,7 @@
 		goto exit;
 	}
 	dbi_conn_error_handler( be->conn, mysql_error_fn, be );
-	if( !set_standard_connection_options( qbe, be->conn, host, 0, dbname, username, password ) ) {
+	if( !set_standard_connection_options( qbe, be->conn, host, portnum, dbname, username, password ) ) {
 		goto exit;
 	}
 	be->exists = TRUE;
@@ -469,10 +483,12 @@
 	gint result;
 	gchar* dsn;
 	gchar* host;
+	gchar* port = NULL;
 	gchar* dbname;
     gchar* username;
     gchar* password;
 	gboolean success;
+	gint portnum;
 
 	g_return_if_fail( qbe != NULL );
 	g_return_if_fail( session != NULL );
@@ -480,17 +496,29 @@
 
     ENTER (" ");
 
-	/* Split the book-id (format host:dbname:username:password) */
+	/* Split the book-id (format host:dbname:username:password or
+	   host:port:dbname:username:password) */
 	dsn = g_strdup( book_id );
 	for( host = dsn; *host != '/'; host++ ) {}
 	host += 2;
 	for( dbname = host; *dbname != ':'; dbname++ ) {}
 	*dbname++ = '\0';
+	if( *dbname >= '0' && *dbname <= '9' ) {
+	    port = dbname;
+	    for( ; *dbname != ':'; dbname++ ) {}
+		*dbname++ = '\0';
+	}
 	for( username = dbname; *username != ':'; username++ ) {}
 	*username++ = '\0';
 	for( password = username; *password != ':'; password++ ) {}
 	*password++ = '\0';
 
+	if( port != NULL && *port != '\0' ) {
+		portnum = atoi( port );
+	} else {
+		portnum = PGSQL_DEFAULT_PORT;
+	}
+
 	// Try to connect to the db.  If it doesn't exist and the create_if_nonexistent
 	// flag is TRUE, we'll need to connect to the 'postgres' db and execute the
 	// CREATE DATABASE ddl statement there.
@@ -504,7 +532,7 @@
 		goto exit;
 	}
 	dbi_conn_error_handler( be->conn, pgsql_error_fn, be );
-	if( !set_standard_connection_options( qbe, be->conn, host, PGSQL_DEFAULT_PORT, dbname, username, password ) ) {
+	if( !set_standard_connection_options( qbe, be->conn, host, portnum, dbname, username, password ) ) {
 		goto exit;
 	}
 	be->exists = TRUE;

Modified: gnucash/trunk/src/gnome-utils/gnc-main-window.c
===================================================================
--- gnucash/trunk/src/gnome-utils/gnc-main-window.c	2009-08-22 19:09:39 UTC (rev 18270)
+++ gnucash/trunk/src/gnome-utils/gnc-main-window.c	2009-08-22 20:17:37 UTC (rev 18271)
@@ -1269,24 +1269,27 @@
 	  if (c == ':') num_colons++;
 	}
 
-    if (num_colons != 4) {
+    if (num_colons < 4) {
       /* The Gnome HIG 2.0 recommends only the file name (no path) be used. (p15) */
       ptr = g_utf8_strrchr(filename, -1, G_DIR_SEPARATOR);
       if (ptr != NULL)
         filename = g_strdup(g_utf8_next_char(ptr));
 	} else {
 	  const gchar* src = filename;
+	  gboolean has_explicit_port = (num_colons == 5);
 
 	  filename = g_strdup(filename);
 	  ptr = filename;
 	  num_colons = 0;
 
-	  /* Loop and copy chars, converting username and password (after 3rd ':') to
-	  asterisks. */
+	  /* Loop and copy chars, converting username and password (after 3rd ':' (4th if there's
+	     an explicit port number) to asterisks. */
 	  for( ; *src; src = g_utf8_next_char(src)) {
 		gunichar unichar;
 
-	    if (num_colons < 3 || *src == ':') {
+		if (*src == ':' ||
+			(!has_explicit_port && num_colons < 3) ||
+			(has_explicit_port && num_colons < 4)) {
 	      unichar = g_utf8_get_char(src);
 		} else {
 		  unichar = '*';

Modified: gnucash/trunk/src/gnome-utils/gnc-plugin-file-history.c
===================================================================
--- gnucash/trunk/src/gnome-utils/gnc-plugin-file-history.c	2009-08-22 19:09:39 UTC (rev 18270)
+++ gnucash/trunk/src/gnome-utils/gnc-plugin-file-history.c	2009-08-22 20:17:37 UTC (rev 18271)
@@ -294,12 +294,23 @@
 	if (g_ascii_strncasecmp(filename, "mysql://", 8) == 0 ||
 		g_ascii_strncasecmp(filename, "postgres://", 11) == 0 ) {
 	  gint num_colons = 0;
+	  gboolean has_explicit_port;
 
+	  /* Count the number of colons to see if there is an explicit port number or not */
+	  for (src = filename; *src; src = g_utf8_next_char(src)) {
+	    gunichar c = g_utf8_get_char(src);
+	    if (c == ':') num_colons++;
+	  }
+	  has_explicit_port = (num_colons == 5);
+	  num_colons = 0;
+
 	  /* Loop for all chars and copy from 'src' to 'dst'.  While doing this,
-	     convert username and password (after 3rd ':') to asterisks. */
+	     convert username and password (after 2nd ':', 3rd if explicit port) to asterisks. */
 	  src = filename;
 	  for( ; *src; src = g_utf8_next_char(src)) {
-	    if (num_colons < 3 || *src == ':') {
+		if (*src == ':' ||
+			(!has_explicit_port && num_colons < 3) ||
+			(has_explicit_port && num_colons < 4)) {
 	      unichar = g_utf8_get_char(src);
 		} else {
 		  unichar = '*';



More information about the gnucash-changes mailing list