[Kexi-devel] koffice/kexi/kexidb

Jaroslaw Staniek js at iidea.pl
Tue Feb 28 21:59:26 CET 2006


SVN commit 514614 by staniek:

PostgreSQL Driver
- fixed escaping binary data (octal values are used for special characters)

CCMAIL:kexi-devel at kde.org



 M  +41 -10    driver.cpp  
 M  +7 -4      driver.h  
 M  +5 -0      driver_p.h  
 M  +1 -1      drivers/mySQL/mysqldriver.cpp  
 M  +1 -1      drivers/pqxx/pqxxdriver.cpp  
 M  +1 -1      drivers/sqlite/sqlitedriver.cpp  


--- trunk/koffice/kexi/kexidb/driver.cpp #514613:514614
@@ -334,26 +334,57 @@
 	}
 }
 
-QString Driver::escapeBLOBInternal(const QByteArray& array, bool use0x) const
+#define BLOB_ESCAPING_TYPE_USE_X     0 //!< escaping like X'abcd0', used by sqlite
+#define BLOB_ESCAPING_TYPE_USE_0x    1 //!< escaping like 0xabcd0, used by mysql
+#define BLOB_ESCAPING_TYPE_USE_OCTAL 2 //!< escaping like 'abcd\\000', used by pgsql
+
+QString Driver::escapeBLOBInternal(const QByteArray& array, int type) const
 {
 	const int size = array.size();
 	int escaped_length = size*2 + 2/*0x or X'*/;
-	if (!use0x)
+	if (type == BLOB_ESCAPING_TYPE_USE_X)
 		escaped_length += 1; //last char: '
 	QString str;
 	str.reserve(escaped_length);
 	if (str.capacity() < (uint)escaped_length) {
-		KexiDBWarn << "MySqlDriver::escapeBLOB(): no enough memory (cannot allocate "<< escaped_length<<" chars)" << endl;
+		KexiDBWarn << "KexiDB::Driver::escapeBLOB(): no enough memory (cannot allocate "<< \
+			escaped_length<<" chars)" << endl;
 		return QString::fromLatin1("NULL");
 	}
-	str = use0x ? QString::fromLatin1("0x") : QString::fromLatin1("X'");
-	int new_length = 2; //after X'
-	for (int i = 0; i < size; i++) {
-		unsigned char val = array[i];
-		str[new_length++] = (val/16) < 10 ? ('0'+(val/16)) : ('A'+(val/16)-10);
-		str[new_length++] = (val%16) < 10 ? ('0'+(val%16)) : ('A'+(val%16)-10);
+	if (type == BLOB_ESCAPING_TYPE_USE_X)
+		str = QString::fromLatin1("X'");
+	else if (type == BLOB_ESCAPING_TYPE_USE_0x)
+		str = QString::fromLatin1("0x");
+	else if (type == BLOB_ESCAPING_TYPE_USE_OCTAL)
+		str = QString::fromLatin1("'");
+	
+	int new_length = str.length(); //after X' or 0x, etc.
+	if (type == BLOB_ESCAPING_TYPE_USE_OCTAL) {
+		// only escape nonprintable characters as in Table 8-7:
+		// http://www.postgresql.org/docs/8.1/interactive/datatype-binary.html
+		// i.e. escape for bytes: < 32, >= 127, 39 ('), 92(\). 
+		for (int i = 0; i < size; i++) {
+			const unsigned char val = array[i];
+			if (val<32 || val>=127 || val==39 || val==92) {
+				str[new_length++] = '\\';
+				str[new_length++] = '\\';
+				str[new_length++] = '0' + val/64;
+				str[new_length++] = '0' + (val % 64) / 8;
+				str[new_length++] = '0' + val % 8;
+			}
+			else {
+				str[new_length++] = val;
+			}
+		}
 	}
-	if (!use0x)
+	else {
+		for (int i = 0; i < size; i++) {
+			const unsigned char val = array[i];
+			str[new_length++] = (val/16) < 10 ? ('0'+(val/16)) : ('A'+(val/16)-10);
+			str[new_length++] = (val%16) < 10 ? ('0'+(val%16)) : ('A'+(val%16)-10);
+		}
+	}
+	if (type == BLOB_ESCAPING_TYPE_USE_X || type == BLOB_ESCAPING_TYPE_USE_OCTAL)
 		str[new_length++] = '\'';
 	return str;
 }
--- trunk/koffice/kexi/kexidb/driver.h #514613:514614
@@ -326,10 +326,13 @@
 		 eventually delete it. Better use Connection destructor. */
 		Connection* removeConnection( Connection *conn );
 
-		/*! Helper, used in escapeBLOB(). If \a use0x is true, \a array is encoded as 0xABCD,
-		 else \a array is encoded as X'ABCD'. For example, MySQL>=3 supports the former 
-		 and SQlite supports the latter. */
-		QString escapeBLOBInternal(const QByteArray& array, bool use0x) const;
+		/*! Helper, used in escapeBLOB(). 
+		 * use \a type == BLOB_ESCAPING_TYPE_USE_X to get escaping like X'ABCD0' (used by sqlite)
+		 * use \a type == BLOB_ESCAPING_TYPE_USE_0x to get escaping like 0xABCD0 (used by mysql)
+		 * use \a type == BLOB_ESCAPING_TYPE_USE_OCTAL to get escaping like '\\253\\315\\000' 
+		     (used by pgsql)
+		*/
+		QString escapeBLOBInternal(const QByteArray& array, int type) const;
 
 	friend class Connection;
 	friend class Cursor;
--- trunk/koffice/kexi/kexidb/driver_p.h #514613:514614
@@ -234,6 +234,11 @@
 	friend class DriverManagerInternal;
 };
 
+// escaping types for Driver::escapeBLOBInternal()
+#define BLOB_ESCAPING_TYPE_USE_X     0 //!< escaping like X'abcd0', used by sqlite
+#define BLOB_ESCAPING_TYPE_USE_0x    1 //!< escaping like 0xabcd0, used by mysql
+#define BLOB_ESCAPING_TYPE_USE_OCTAL 2 //!< escaping like 'abcd\\000', used by pgsql
+
 }
 
 //! Driver's static version information (implementation), 
--- trunk/koffice/kexi/kexidb/drivers/mySQL/mysqldriver.cpp #514613:514614
@@ -181,7 +181,7 @@
 
 QString MySqlDriver::escapeBLOB(const QByteArray& array) const
 {
-	return escapeBLOBInternal(array, true /*use0x*/);
+	return escapeBLOBInternal(array, BLOB_ESCAPING_TYPE_USE_0x);
 }
 
 QCString MySqlDriver::escapeString(const QCString& str) const
--- trunk/koffice/kexi/kexidb/drivers/pqxx/pqxxdriver.cpp #514613:514614
@@ -158,7 +158,7 @@
 //
 QString pqxxSqlDriver::escapeBLOB(const QByteArray& array) const
 {
-	return escapeBLOBInternal(array, false /* use X'ABCD' */);
+	return escapeBLOBInternal(array, BLOB_ESCAPING_TYPE_USE_OCTAL);
 }
 
 
--- trunk/koffice/kexi/kexidb/drivers/sqlite/sqlitedriver.cpp #514613:514614
@@ -128,7 +128,7 @@
 
 QString SQLiteDriver::escapeBLOB(const QByteArray& array) const
 {
-	return escapeBLOBInternal(array, false /* use X'ABCD' */);
+	return escapeBLOBInternal(array, BLOB_ESCAPING_TYPE_USE_X);
 }
 
 QString SQLiteDriver::drv_escapeIdentifier( const QString& str) const


More information about the Kexi-devel mailing list