List:Commits« Previous MessageNext Message »
From:pharvey Date:June 28 2006 11:01am
Subject:Connector/ODBC 5 commit: r411 - in trunk: MYODBCDriver/MYODBCDriverLib MYSQLPlus/MYSQLPlusLib
View as plain text  
Modified:
   trunk/MYODBCDriver/MYODBCDriverLib/SQLGetFunctions.cpp
   trunk/MYSQLPlus/MYSQLPlusLib/MResultPlus.cpp
   trunk/MYSQLPlus/MYSQLPlusLib/MResultPlus.h
   trunk/MYSQLPlus/MYSQLPlusLib/MStatement.cpp
Log:
added support for SQLPrimaryKeys (no testing on it yet)

Modified: trunk/MYODBCDriver/MYODBCDriverLib/SQLGetFunctions.cpp
===================================================================
--- trunk/MYODBCDriver/MYODBCDriverLib/SQLGetFunctions.cpp	2006-06-28 08:46:11 UTC (rev
410)
+++ trunk/MYODBCDriver/MYODBCDriverLib/SQLGetFunctions.cpp	2006-06-28 11:01:40 UTC (rev
411)
@@ -110,7 +110,7 @@
     SQL_API_SQLNATIVESQL,
     SQL_API_SQLNUMPARAMS,
 /*  SQL_API_SQLPARAMOPTIONS,        Dep */
-/*  SQL_API_SQLPRIMARYKEYS,             */
+    SQL_API_SQLPRIMARYKEYS,
 /*  SQL_API_SQLPROCEDURECOLUMNS,        */
 /*  SQL_API_SQLPROCEDURES,              */
 /*  SQL_API_SQLSETPOS,                  */

Modified: trunk/MYSQLPlus/MYSQLPlusLib/MResultPlus.cpp
===================================================================
--- trunk/MYSQLPlus/MYSQLPlusLib/MResultPlus.cpp	2006-06-28 08:46:11 UTC (rev 410)
+++ trunk/MYSQLPlus/MYSQLPlusLib/MResultPlus.cpp	2006-06-28 11:01:40 UTC (rev 411)
@@ -687,6 +687,87 @@
     MYODBCDbgReturn( nReturn );
 }
 
+SQLRETURN MResultPlus::doPrimaryKeys( const QString &stringCatalog, const QString
&stringSchema, const QString &stringTable )
+{
+    MYODBCDbgEnter();
+
+    SQLRETURN nReturn;
+
+    /* create empty resultset */
+    MDescriptor *pDescriptor;
+
+    doClear();
+    getDiagnostic()->setRowCount( 0 );
+
+    pDescriptor = getImpRowDesc();
+    pDescriptor->doAppend( SQL_VARCHAR, "TABLE_CAT", SQL_NULLABLE );
+    pDescriptor->doAppend( SQL_VARCHAR, "TABLE_SCHEM", SQL_NULLABLE );
+    pDescriptor->doAppend( SQL_VARCHAR, "TABLE_NAME", SQL_NO_NULLS );
+    pDescriptor->doAppend( SQL_VARCHAR, "COLUMN_NAME", SQL_NO_NULLS );
+    pDescriptor->doAppend( SQL_SMALLINT, "KEY_SEQ", SQL_NO_NULLS );
+    pDescriptor->doAppend( SQL_VARCHAR, "PK_NAME", SQL_NULLABLE );
+
+    /* load result set */
+    {
+        QString     stringStatement;
+        MYSQL_RES * pResult = NULL;
+        MYSQL_ROW   pRow;
+
+        MYODBCDbgEnter();
+
+        stringStatement = "SELECT COLUMN_NAME, SEQ_IN_INDEX "
+                          "FROM   INFORMATION_SCHEMA.STATISTICS "
+                          "WHERE  TABLE_SCHEMA='" + stringCatalog + "' AND TABLE_NAME='"
+ stringTable + "' AND INDEX_NAME='PRIMARY' "
+                          "ORDER BY SEQ_IN_INDEX ";
+
+        if ( mysql_query( getMySQL(), stringStatement.toUtf8().data() ) )
+            MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY000,
mysql_errno( getMySQL() ), mysql_error( getMySQL() ) ) );
+
+        pResult = mysql_use_result( getMySQL() );
+        if ( !pResult )
+            MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY000,
mysql_errno( getMySQL() ), mysql_error( getMySQL() ) ) );
+
+        while ( pRow = mysql_fetch_row( pResult ) )
+        {
+            doAppendPrimaryKeys( stringCatalog,
+                                 stringSchema,
+                                 stringTable,
+                                 pRow[0],
+                                 pRow[1],
+                                 "PRIMARY" );
+        }
+
+        mysql_free_result( pResult ); 
+    }
+
+    /*!
+        \internal ODBC RULE
+
+        When SQLExecute, SQLExecDirect, SQLBulkOperations, SQLSetPos, or SQLMoreResults
is called, the SQL_DIAG_ROW_COUNT 
+        field of the diagnostic data structure is set to the row count, and the row count
is cached in an implementation-dependent 
+        way. SQLRowCount returns the cached row count value. The cached row count value
is valid until the statement handle is set 
+        back to the prepared or allocated state, the statement is reexecuted, or
SQLCloseCursor is called. Note that if a function 
+        has been called since the SQL_DIAG_ROW_COUNT field was set, the value returned by
SQLRowCount might be different from the 
+        value in the SQL_DIAG_ROW_COUNT field because the SQL_DIAG_ROW_COUNT field is
reset to 0 by any function call.                
+
+        \internal MYODBC RULE
+
+        Wet set SQL_DIAG_ROW_COUNT when any result set is requested - for example we also
set SQL_DIAG_ROW_COUNT for catalog
+        functions.
+    */
+    qulonglong nRows = -1;
+    if ( !SQL_SUCCEEDED( getRows( &nRows ) ) )
+        getDiagnostic()->setRowCount( -1 );
+    else
+        getDiagnostic()->setRowCount( nRows );
+
+    /* we should be at last record so next will make us eof and a subsequent next will be
first record */
+    setState( STATE_EXECUTED );
+    doNext();
+
+    MYODBCDbgReturn( SQL_SUCCESS );
+}
+
 SQLRETURN MResultPlus::doSpecialColumns( SQLSMALLINT nIdentifierType, const QString
&stringCatalog, const QString &stringSchema, const QString &stringTable,
SQLSMALLINT nScope, SQLSMALLINT nNullable )
 {
     MYODBCDbgEnter();
@@ -2018,3 +2099,25 @@
     MYODBCDbgReturn( SQL_SUCCESS );
 }
 
+SQLRETURN MResultPlus::doAppendPrimaryKeys( const QVariant &variantCatalog,
+                                            const QVariant &variantSchema,
+                                            const QVariant &variantTable,
+                                            const QVariant &variantColumn,
+                                            const QVariant &variantSequence,
+                                            const QVariant &variantKeyName )
+{                                      
+    MYODBCDbgEnter();
+
+    doAppend();
+    /* 1 based - setData will make it 0 based */
+    setData( 1, variantCatalog );
+    setData( 2, variantSchema );
+    setData( 3, variantTable );
+    setData( 4, variantColumn );
+    setData( 5, variantSequence );
+    setData( 6, variantKeyName );
+
+    MYODBCDbgReturn( SQL_SUCCESS );
+}
+
+

Modified: trunk/MYSQLPlus/MYSQLPlusLib/MResultPlus.h
===================================================================
--- trunk/MYSQLPlus/MYSQLPlusLib/MResultPlus.h	2006-06-28 08:46:11 UTC (rev 410)
+++ trunk/MYSQLPlus/MYSQLPlusLib/MResultPlus.h	2006-06-28 11:01:40 UTC (rev 411)
@@ -72,6 +72,7 @@
 
     SQLRETURN doTables( const QString &stringCatalogFilter, const QString
&stringSchemaFilter, const QString &stringTableFilter, const QString
&stringTableTypeFilter );
     SQLRETURN doColumns( const QString &stringCatalogFilter, const QString
&stringSchemaFilter, const QString &stringTableFilter, const QString
&stringColumnFilter );
+    SQLRETURN doPrimaryKeys( const QString &stringCatalog, const QString
&stringSchema, const QString &stringTable );
     SQLRETURN doSpecialColumns( SQLSMALLINT nIdentifierType, const QString
&stringCatalog, const QString &stringSchema, const QString &stringTable,
SQLSMALLINT nScope, SQLSMALLINT nNullable );
 
     /* isers */
@@ -193,6 +194,12 @@
                                       const QVariant &variantBufferLength,
                                       const QVariant &variantDecimalDigits,
                                       const QVariant &variantPseudoColumn );
+    SQLRETURN doAppendPrimaryKeys( const QVariant &variantCatalog,
+                                   const QVariant &variantSchema,
+                                   const QVariant &variantTable,
+                                   const QVariant &variantColumn,
+                                   const QVariant &variantSequence,
+                                   const QVariant &variantKeyName );
 };
 
 #endif

Modified: trunk/MYSQLPlus/MYSQLPlusLib/MStatement.cpp
===================================================================
--- trunk/MYSQLPlus/MYSQLPlusLib/MStatement.cpp	2006-06-28 08:46:11 UTC (rev 410)
+++ trunk/MYSQLPlus/MYSQLPlusLib/MStatement.cpp	2006-06-28 11:01:40 UTC (rev 411)
@@ -2839,7 +2839,7 @@
     MYODBCDbgReturn( nReturn );
 }
 
-SQLRETURN MStatement::doPrimaryKeys( SQLWCHAR *psCatalogName, SQLSMALLINT nNameLength1,
SQLWCHAR *psSchemaName, SQLSMALLINT nNameLength2, SQLWCHAR *psTableName, SQLSMALLINT
nNameLength3 )
+SQLRETURN MStatement::doPrimaryKeys( SQLWCHAR *psCatalog, SQLSMALLINT nLength1, SQLWCHAR
*psSchema, SQLSMALLINT nLength2, SQLWCHAR *psTable, SQLSMALLINT nLength3 )
 {
     MYODBCDbgEnter();
 
@@ -2850,7 +2850,207 @@
     */
     getDiagnostic()->doClear();
 
-    MYODBCDbgReturn( SQL_ERROR );
+    /*!
+        \internal ODBC RULE (DM)
+
+        A cursor was open on the StatementHandle, and SQLFetch or 
+        SQLFetchScroll had been called.
+    */
+    if ( getState() == STATE_S6 )
+        MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_24000 ) );
+
+    /*!
+        \internal ODBC RULE (DM)
+
+        A cursor was open on the StatementHandle, but SQLFetch or SQLFetchScroll 
+        had not been called.
+    */
+    if ( getState() == STATE_S5 )
+        MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_24000 ) );
+
+    /*!
+        \internal ODBC RULE (DM)
+
+        An asynchronously executing function was called for the 
+        StatementHandle and was still executing when this function 
+        was called.
+    */
+    if ( isAsyncInProgress() )
+        MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY010 ) );
+
+    /*!
+        \internal ODBC RULE (DM)
+
+        SQLExecute, SQLExecDirect, SQLBulkOperations, or SQLSetPos was 
+        called for the StatementHandle and returned SQL_NEED_DATA. 
+        This function was called before data was sent for all 
+        data-at-execution parameters or columns.
+    */
+    if ( isDataNeeded() )
+        MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY010 ) );
+
+    /*!
+        \internal ODBC RULE (DM)
+
+        The value of one of the length arguments was less than 0 but 
+        not equal to SQL_NTS.
+    */
+    if ( nLength1 < 0 && nLength1 != SQL_NTS )
+        MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY090 ) );
+    if ( nLength2 < 0 && nLength2 != SQL_NTS )
+        MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY090 ) );
+    if ( nLength3 < 0 && nLength3 != SQL_NTS )
+        MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY090 ) );
+
+    /*!
+        \internal ODBC RULE (DM)
+
+        The value of one of the name length arguments exceeded the maximum length 
+        value for the corresponding name.
+    */
+    if ( nLength1 > getConnection()->getInfoMaxCatalogNameLen() )
+        MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY090 ) );
+    if ( nLength2 > getConnection()->getInfoMaxSchemaNameLen() )
+        MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY090 ) );
+    if ( nLength3 > getConnection()->getInfoMaxTableNameLen() )
+        MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY090 ) );
+
+    /* do it */
+    QString stringCatalog;
+    QString stringSchema;
+    QString stringTable;
+
+    if ( psCatalog && nLength1 != 0 )
+        stringCatalog = QString::fromUtf16( psCatalog, ( nLength1 == SQL_NTS ? -1 :
nLength1 ) );
+    if ( psSchema && nLength2 != 0  )
+        stringSchema = QString::fromUtf16( psSchema, ( nLength2 == SQL_NTS ? -1 :
nLength2 ) );
+    if ( psTable && nLength3 != 0  )
+        stringTable = QString::fromUtf16( psTable, ( nLength3 == SQL_NTS ? -1 : nLength3
) );
+
+    if ( getMetadataID() == SQL_TRUE )
+    {
+        SQLRETURN nReturn;
+
+        /*!
+            \internal ODBC RULE
+
+            Setting an identifier argument to a null pointer returns SQL_ERROR and
SQLSTATE HY009 (Invalid use of null 
+            pointer), unless the argument is a catalog name and catalogs are not
supported.
+
+            The SQL_ATTR_METADATA_ID statement attribute was set to SQL_TRUE, the
CatalogName 
+            argument was a null pointer, and the SQL_CATALOG_NAME InfoType returns that
catalog 
+            names are supported.
+        */
+        if ( !psSchema || !psTable || ( getConnection()->getInfoCatalogName() == "Y"
&& !psCatalog  ) )
+            MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY009 ) );
+
+        /*!
+            \internal ODBC RULE
+
+            If a string in an identifier argument is quoted, the driver removes leading
and trailing blanks and treats 
+            literally the string within the quotation marks. If the string is not quoted,
the driver removes trailing 
+            blanks and folds the string to uppercase. 
+        */
+        nReturn = doIdentifierArgumentMakeNice( stringCatalog );
+        if ( !SQL_SUCCEEDED( nReturn ) )
+            MYODBCDbgReturn( nReturn );
+        nReturn = doIdentifierArgumentMakeNice( stringSchema );
+        if ( !SQL_SUCCEEDED( nReturn ) )
+            MYODBCDbgReturn( nReturn );
+        nReturn = doIdentifierArgumentMakeNice( stringTable );
+        if ( !SQL_SUCCEEDED( nReturn ) )
+            MYODBCDbgReturn( nReturn );
+
+        /*!
+            \internal MYODBC RULE
+
+            We do not want empty strings to get through (we know they are going to fail).
+        */
+        if ( stringCatalog.isEmpty() )
+            stringCatalog = getConnection()->getCurrentCatalog();
+        if ( stringTable.isEmpty() )
+            MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY009 ) );
+    }
+    else
+    {
+        /*!
+            \internal ODBC RULE
+
+            When a catalog function string argument is an ordinary argument, it is
treated as a literal string. An 
+            ordinary argument accepts neither a string search pattern nor a list of
values. The case of an ordinary 
+            argument is significant, and quote characters in the string are taken
literally.
+        */
+        /*!
+            \internal ODBC RULE
+
+            If an ordinary argument is set to a null pointer and the argument is a
required argument, the function 
+            returns SQL_ERROR and SQLSTATE HY009 (Invalid use of null pointer). If an
ordinary argument is set to a 
+            null pointer and the argument is not a required argument, the argument's
behavior is driver-dependent. 
+
+            TableName is required.
+
+            \internal MYODBC RULE
+
+            An empty catalog is set to current catalog.
+        */
+        if ( stringTable.isEmpty() )
+            MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY009 ) );
+        if ( stringCatalog.isEmpty() )
+            stringCatalog = getConnection()->getCurrentCatalog();
+    }
+
+    /*!
+        \internal ODBC RULE
+
+        A catalog was specified, and the driver or data source does not support catalogs.
+
+        \internal MYODBC RULE 
+
+        We can continue if value is; NULL or "".
+    */
+    if ( getConnection()->getInfoCatalogUsage() == 0 &&
!stringCatalog.isEmpty() )
+        MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HYC00 ) );
+
+    /*!
+        \internal ODBC RULE
+
+        A schema was specified, and the driver or data source does not support schema.
+
+        \internal MYODBC RULE 
+
+        We can continue if value is; NULL or "".
+    */
+    if ( getConnection()->getInfoSchemaUsage() == 0 && !stringSchema.isEmpty()
)
+        MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HYC00 ) );
+
+    /*!
+        \internal MYODBC RULE
+
+        We undo any prepare - no worries.
+    */
+    SQLRETURN nReturn;
+    if ( getState() > STATE_S1 )
+    {
+        nReturn = doStateRollBack( STATE_S1 );
+        if ( !SQL_SUCCEEDED( nReturn ) )
+            MYODBCDbgReturn( nReturn );
+    }
+
+    /* generate result */
+    MResultPlus *pResult = new MResultPlus( this );
+
+    nReturn = pResult->doPrimaryKeys( stringCatalog, stringSchema, stringTable );
+    if ( !SQL_SUCCEEDED( nReturn ) )
+    {
+        delete pResult;
+        MYODBCDbgReturn( nReturn );
+    }
+
+    setImplicitPrepare( true );
+    this->pResult = pResult;
+    setState( STATE_S5 );
+
+    MYODBCDbgReturn( nReturn );
 }
 
 SQLRETURN MStatement::doProcedureColumns( SQLWCHAR *psCatalogName, SQLSMALLINT
nNameLength1, SQLWCHAR *psSchemaName, SQLSMALLINT nNameLength2, SQLWCHAR *psProcName,
SQLSMALLINT nNameLength3, SQLWCHAR *psColumnName, SQLSMALLINT nNameLength4 )
@@ -3249,6 +3449,16 @@
         nReturn = doIdentifierArgumentMakeNice( stringTable );
         if ( !SQL_SUCCEEDED( nReturn ) )
             MYODBCDbgReturn( nReturn );
+
+        /*!
+            \internal MYODBC RULE
+
+            We do not want empty strings to get through (we know they are going to fail).
+        */
+        if ( stringCatalog.isEmpty() )
+            stringCatalog = getConnection()->getCurrentCatalog();
+        if ( stringTable.isEmpty() )
+            MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY009 ) );
     }
     else
     {

Thread
Connector/ODBC 5 commit: r411 - in trunk: MYODBCDriver/MYODBCDriverLib MYSQLPlus/MYSQLPlusLibpharvey28 Jun