List:Commits« Previous MessageNext Message »
From:jbalint Date:October 12 2006 4:36am
Subject:Connector/ODBC 5 commit: r597 - in trunk/SDK/Installer: Library Tests
View as plain text  
Modified:
   trunk/SDK/Installer/Library/MYODBCIns.cpp
   trunk/SDK/Installer/Tests/MYODBCInsTest.cpp
Log:
Fixed the parser to handle the delimiter at the end correctly.
Added tests for parsing routines.

Modified: trunk/SDK/Installer/Library/MYODBCIns.cpp
===================================================================
--- trunk/SDK/Installer/Library/MYODBCIns.cpp	2006-10-12 04:19:07 UTC (rev 596)
+++ trunk/SDK/Installer/Library/MYODBCIns.cpp	2006-10-12 04:36:43 UTC (rev 597)
@@ -161,8 +161,10 @@
     int         nAnchorChar     = 0;
     int         nScanChar       = 0;
     QString     stringKeyword;
+    QString     stringValue;
     QChar       cEqual( '=' );
     QChar       cBraceOpen( '{' );
+    QChar       cBraceClose( '}' );
 
     /* short circuit if we have not been given stuff to parse */
     if ( stringKeywordValues.isEmpty() )
@@ -218,8 +220,20 @@
                 /* end of value? */
                 if ( nState == PARSE_STATE_VALUE )
                 {
-                    if ( !isDelim( stringKeywordValues, nScanChar, &nDelim ) )
+                    /* more chars if it's not the last char or delimiter */
+                    if ( nScanChar + 1 < stringKeywordValues.length() && 
+                            !isDelim( stringKeywordValues, nScanChar, &nDelim ) )
                         break;
+
+                    /*
+                        increment nScanChar if this is the last char and not a delimiter
+                        so mid() is given the right length
+                    */
+                    if( nScanChar + 1 == stringKeywordValues.length() &&
+                            !isDelim( stringKeywordValues, nScanChar, &nDelim ) )
+                        nScanChar++;
+
+                    stringValue = stringKeywordValues.mid( nAnchorChar, nScanChar -
nAnchorChar );
                 }
                 else if ( nState == PARSE_STATE_VALUE_BRACED )
                 {
@@ -229,47 +243,28 @@
                         MYODBCDbgReturn3( "%d", false );
                     }
 
-                    if ( stringKeywordValues[nScanChar] != QChar( '}' ) )
+                    if ( stringKeywordValues[nScanChar] != cBraceClose )
                         break;
 
-                    nScanChar++;
+                    stringValue = stringKeywordValues.mid( nAnchorChar, nScanChar -
nAnchorChar );
+
+                    /* Skip the brace, unless it's the last char */
+                    if ( nScanChar < stringKeywordValues.length() )
+                        nScanChar++;
                 }
-// printf( "[PAH][%s][%d] (%s)=(%s) nAnchorChar=%d nScanChar=%d\n", __FILE__, __LINE__,
stringKeyword.toAscii().data(), stringKeywordValues.mid( nAnchorChar, nScanChar -
nAnchorChar ).toAscii().data(), nAnchorChar, nScanChar );
 
                 /* we now have a keyword/value pair */
 
                 /*
                     \internal ODBC Rule
 
-                    If the DSN and DRIVER keywords are included in the same connection
string, 
-                    the Driver Manager and the driver use whichever keyword appears
first.                     
-
-                    \note
-
-                    This is for SQLDriverConnect().
-
-                    We assume we are processing for a ConfigDSN(), not a connection
string, when
-                    we are using DELIM_NULL. This is a bit of trickery - sorry.
-                */
-                if ( nDelim != MYODBCIns::DELIM_NULL )
-                {
-                    if ( stringKeyword == "DSN" &&
!(*phashKeywordValues)["DRIVER"].isNull() )
-                        break;
-
-                    if ( stringKeyword == "DRIVER" &&
!(*phashKeywordValues)["DSN"].isNull() )
-                        break;
-                }
-
-                /*
-                    \internal ODBC Rule
-
                     If any keywords are repeated in the connection string, the driver
uses the value 
                     associated with the first occurrence of the keyword. 
                 */
                 if ( phashKeywordValues->contains( stringKeyword ) )
                     break;
 
-                phashKeywordValues->insert( stringKeyword, stringKeywordValues.mid(
nAnchorChar, nScanChar - nAnchorChar ) );
+                phashKeywordValues->insert( stringKeyword, stringValue );
                 stringKeyword = QString::null;
                 break;
             default:
@@ -277,14 +272,15 @@
                 MYODBCDbgReturn3( "%d", false );
         }
 
+        /* have we advanced to end of string */
+        if ( nScanChar + 1 >= stringKeywordValues.length() ||
+                isDelimKeywordValues( stringKeywordValues, nScanChar, nDelim ) )
+            break;
+
         /* terminated a name/value pair */
         if ( isDelimKeywordValue( stringKeywordValues[nScanChar], &nDelim ) )
             nState = PARSE_STATE_NAME_START;
 
-        /* have we advanced to end of string */
-        if ( isDelimKeywordValues( stringKeywordValues, nScanChar, nDelim ) )
-            break;
-
         nScanChar++;
 
     } /* while scan */

Modified: trunk/SDK/Installer/Tests/MYODBCInsTest.cpp
===================================================================
--- trunk/SDK/Installer/Tests/MYODBCInsTest.cpp	2006-10-12 04:19:07 UTC (rev 596)
+++ trunk/SDK/Installer/Tests/MYODBCInsTest.cpp	2006-10-12 04:36:43 UTC (rev 597)
@@ -32,6 +32,7 @@
     QFile fileDebugOut;
 
 private slots:
+    void slotAttributeParsing();
     void slotDataSource();
     void slotDriverConnect();
     void slotRegisterDriver();
@@ -63,6 +64,88 @@
     fileDebugOut.close();
 }
 
+/*
+   	Test the MYODBCIns::getKeywordValues parsing of connect strings.
+*/
+#define INS_VAL_TEST(a,b) QCOMPARE( attrVals.value(a), QString::fromAscii(b))
+void MYODBCInsTest::slotAttributeParsing()
+{
+	/* semi-delimited, end on delimiter, no braces */
+    WCHAR *attrs = L"DSN=NorthwindMyODBC5;UID=myodbctest;PWD=myodbctest;";
+    QHash<QString, QString> attrVals;
+
+    if ( !MYODBCIns::getKeywordValues( &attrVals, 
+            QString::fromUtf16( attrs ), MYODBCIns::DELIM_SEMI ) )
+        QFAIL( "getKeywordValues failed" );
+
+	INS_VAL_TEST("DSN", "NorthwindMyODBC5");
+    INS_VAL_TEST("UID", "myodbctest");
+    INS_VAL_TEST("PWD", "myodbctest");
+
+	attrVals.clear();
+
+	/* semi-delimited, end on value, no braces */
+    attrs = L"DSN=NorthwindMyODBC5;UID=myodbctest;PWD=myodbctest";
+
+    if ( !MYODBCIns::getKeywordValues( &attrVals, 
+            QString::fromUtf16( attrs ), MYODBCIns::DELIM_SEMI ) )
+        QFAIL( "getKeywordValues failed" );
+
+	INS_VAL_TEST("DSN", "NorthwindMyODBC5");
+    INS_VAL_TEST("UID", "myodbctest");
+    INS_VAL_TEST("PWD", "myodbctest");
+
+	attrVals.clear();
+
+    /* semi-delimited, end on delimiter, with braces */
+    attrs = L"DSN={NorthwindMyODBC5};UID={myodbctest};PWD={myodbctest};";
+
+    if ( !MYODBCIns::getKeywordValues( &attrVals, 
+            QString::fromUtf16( attrs ), MYODBCIns::DELIM_SEMI ) )
+        QFAIL( "getKeywordValues failed" );
+
+	INS_VAL_TEST("DSN", "NorthwindMyODBC5");
+    INS_VAL_TEST("UID", "myodbctest");
+    INS_VAL_TEST("PWD", "myodbctest");
+
+	attrVals.clear();
+
+    /* semi-delimited, end on brace, with braces */
+    attrs = L"DSN={NorthwindMyODBC5};UID={myodbctest};PWD={myodbctest}";
+
+    if ( !MYODBCIns::getKeywordValues( &attrVals, 
+            QString::fromUtf16( attrs ), MYODBCIns::DELIM_SEMI ) )
+        QFAIL( "getKeywordValues failed" );
+
+	INS_VAL_TEST("DSN", "NorthwindMyODBC5");
+    INS_VAL_TEST("UID", "myodbctest");
+    INS_VAL_TEST("PWD", "myodbctest");
+
+	attrVals.clear();
+
+	/* test error condition, left-open brace */
+    attrs = L"DSN={NorthwindMyODBC5;UID={myodbctest};PWD={myodbctest}";
+
+    if ( MYODBCIns::getKeywordValues( &attrVals, 
+            QString::fromUtf16( attrs ), MYODBCIns::DELIM_SEMI ) )
+        QFAIL( "getKeywordValues succeeded unexpectedly" );
+
+	attrVals.clear();
+
+	/* test redundant attributes */
+    attrs = L"DSN=dsn1;DSN=dsn2;PWD={myodbctest}";
+
+    if ( !MYODBCIns::getKeywordValues( &attrVals, 
+            QString::fromUtf16( attrs ), MYODBCIns::DELIM_SEMI ) )
+        QFAIL( "getKeywordValues failed" );
+
+	INS_VAL_TEST("DSN", "dsn1");
+    INS_VAL_TEST("PWD", "myodbctest");
+
+	attrVals.clear();
+
+}
+
 void MYODBCInsTest::slotDataSource()
 {
     QHash<QString,QString>  hashKeywordValues;
@@ -139,9 +222,10 @@
 
         if ( !driverconnect.setAttributes( "DRIVER=My Driver;DSN=MyDSN;DATABASE=MyDB" ) )
             QFAIL( "Failed to parse connection string driver" );
-        QCOMPARE( driverconnect.getDSN(), QString() );
+        QCOMPARE( driverconnect.getDSN(), QString( "MyDSN" ) );
         QCOMPARE( driverconnect.getDRIVER(), QString( "My Driver" ) );
-        QCOMPARE( driverconnect.getAttributes(), QString( "DRIVER=My
Driver;DATABASE=MyDB" ) );
+        QCOMPARE( driverconnect.getAttributes(),
+        		QString( "DRIVER=My Driver;DATABASE=MyDB;DSN=MyDSN" ) );
     }
 }
 

Thread
Connector/ODBC 5 commit: r597 - in trunk/SDK/Installer: Library Testsjbalint12 Oct