List:Commits« Previous MessageNext Message »
From:jwinstead Date:August 23 2007 7:32pm
Subject:Connector/ODBC 3.51 commit: r678 - in branches/guffert: driver test
View as plain text  
Modified:
   branches/guffert/driver/ansi.c
   branches/guffert/driver/driver.def
   branches/guffert/driver/driver.h
   branches/guffert/driver/results.c
   branches/guffert/driver/unicode.c
   branches/guffert/test/my_unicode.c
Log:
Implement SQLDescribeColW


Modified: branches/guffert/driver/ansi.c
===================================================================
--- branches/guffert/driver/ansi.c	2007-08-23 15:01:43 UTC (rev 677)
+++ branches/guffert/driver/ansi.c	2007-08-23 17:32:29 UTC (rev 678)
@@ -170,6 +170,61 @@
 
 
 SQLRETURN SQL_API
+SQLDescribeCol(SQLHSTMT hstmt, SQLUSMALLINT column,
+               SQLCHAR *name, SQLSMALLINT name_max, SQLSMALLINT *name_len,
+               SQLSMALLINT *type, SQLULEN *size, SQLSMALLINT *scale,
+               SQLSMALLINT *nullable)
+{
+  STMT *stmt= (STMT *)hstmt;
+  SQLCHAR *value= NULL;
+  SQLINTEGER len= SQL_NTS;
+  SQLSMALLINT free_value;
+  uint errors;
+
+  SQLRETURN rc= MySQLDescribeCol(hstmt, column, &value, &free_value, type,
+                                 size, scale, nullable);
+
+  if (free_value == -1)
+  {
+    set_mem_error(&stmt->dbc->mysql);
+    return handle_connection_error(stmt);
+  }
+
+  if (value)
+  {
+    SQLCHAR *old_value= value;
+    if (stmt->dbc->ansi_charset_info->number !=
+        stmt->dbc->cxn_charset_info->number)
+    {
+      value= sqlchar_as_sqlchar(stmt->dbc->cxn_charset_info,
+                                stmt->dbc->ansi_charset_info,
+                                value, &len, &errors);
+      if (free_value)
+        x_free(old_value);
+      free_value= TRUE;
+    }
+    else
+      len= strlen((char *)value);
+
+    if (len > name_max - 1)
+      rc= set_error(stmt, MYERR_01004, NULL, 0);
+
+    if (name && name_max > 1)
+      strmake((char *)name, (char *)value, name_max - 1);
+    ((char *)name)[name_max]= '\0';
+
+    if (name_len)
+      *name_len= len;
+
+    if (free_value)
+      x_free(value);
+  }
+
+  return rc;
+}
+
+
+SQLRETURN SQL_API
 SQLDriverConnect(SQLHDBC hdbc, SQLHWND hwnd, SQLCHAR *in, SQLSMALLINT in_len,
                  SQLCHAR *out, SQLSMALLINT out_max, SQLSMALLINT *out_len,
                  SQLUSMALLINT completion)
@@ -452,16 +507,6 @@
 //SQLDataSources
 
 
-SQLRETURN SQL_API
-SQLDescribeCol(SQLHSTMT hstmt, SQLUSMALLINT column,
-               SQLCHAR *name, SQLSMALLINT name_max, SQLSMALLINT *name_len,
-               SQLSMALLINT *type, SQLULEN *def, SQLSMALLINT *scale,
-               SQLSMALLINT *nullable)
-{
-  NOT_IMPLEMENTED;
-}
-
-
 //SQLDrivers
 
 

Modified: branches/guffert/driver/driver.def
===================================================================
--- branches/guffert/driver/driver.def	2007-08-23 15:01:43 UTC (rev 677)
+++ branches/guffert/driver/driver.def	2007-08-23 17:32:29 UTC (rev 678)
@@ -110,6 +110,7 @@
 SQLColAttributesW
 SQLCloseCursor
 SQLConnectW
+SQLDescribeColW
 SQLDriverConnectW
 SQLExecDirectW
 SQLGetStmtAttrW

Modified: branches/guffert/driver/driver.h
===================================================================
--- branches/guffert/driver/driver.h	2007-08-23 15:01:43 UTC (rev 677)
+++ branches/guffert/driver/driver.h	2007-08-23 17:32:29 UTC (rev 678)
@@ -408,6 +408,10 @@
 SQLRETURN SQL_API MySQLConnect(SQLHDBC hdbc, SQLCHAR *szDSN, SQLSMALLINT cbDSN,
                                SQLCHAR *szUID, SQLSMALLINT cbUID,
                                SQLCHAR *szAuth, SQLSMALLINT cbAuth);
+SQLRETURN SQL_API MySQLDescribeCol(SQLHSTMT hstmt, SQLUSMALLINT column,
+                                   SQLCHAR **name, SQLSMALLINT *need_free,
+                                   SQLSMALLINT *type, SQLULEN *def,
+                                   SQLSMALLINT *scale, SQLSMALLINT *nullable);
 SQLRETURN SQL_API MySQLDriverConnect(SQLHDBC hdbc, SQLHWND hwnd,
                                      SQLCHAR *in, SQLSMALLINT in_len,
                                      SQLCHAR *out, SQLSMALLINT out_max,

Modified: branches/guffert/driver/results.c
===================================================================
--- branches/guffert/driver/results.c	2007-08-23 15:01:43 UTC (rev 677)
+++ branches/guffert/driver/results.c	2007-08-23 17:32:29 UTC (rev 678)
@@ -494,64 +494,68 @@
     return SQL_SUCCESS;
 }
 
-/*
-  @type    : ODBC 1.0 API
-  @purpose : returns the result column name, type, column size, decimal
-  digits, and nullabilityfor one column in the result set
+
+/**
+  Get some basic properties of a column.
+
+  @param[in]  hstmt      Statement handle
+  @param[in]  column     Column number (starting with 1)
+  @param[out] name       Pointer to column name
+  @param[out] need_free  Whether the column name needs to be freed.
+  @param[out] type       Column SQL type
+  @param[out] size       Column size
+  @param[out] scale      Scale
+  @param[out] nullable   Whether the column is nullable
 */
-
-SQLRETURN SQL_API SQLDescribeCol( SQLHSTMT          hstmt, 
-                                  SQLUSMALLINT      icol,
-                                  SQLCHAR FAR *     szColName,
-                                  SQLSMALLINT       cbColNameMax,
-                                  SQLSMALLINT FAR * pcbColName,
-                                  SQLSMALLINT FAR * pfSqlType,
-                                  SQLULEN *         pnColumnSize,
-                                  SQLSMALLINT FAR * pibScale,
-                                  SQLSMALLINT FAR * pfNullable )
+SQLRETURN SQL_API
+MySQLDescribeCol(SQLHSTMT hstmt, SQLUSMALLINT column,
+                 SQLCHAR **name, SQLSMALLINT *need_free, SQLSMALLINT *type,
+                 SQLULEN *size, SQLSMALLINT *scale, SQLSMALLINT *nullable)
 {
-    SQLRETURN error;
-    MYSQL_FIELD *field;
-    STMT FAR *stmt= (STMT FAR*) hstmt;
+  SQLRETURN error;
+  MYSQL_FIELD *field;
+  STMT *stmt= (STMT *)hstmt;
 
-    if ( (error= check_result(stmt)) != SQL_SUCCESS )
-        return error;
-    if ( ! stmt->result )
-        return set_stmt_error(stmt,"07005","No result set",0);
+  if ((error= check_result(stmt)) != SQL_SUCCESS)
+    return error;
+  if (!stmt->result)
+    return set_stmt_error(stmt, "07005", "No result set", 0);
 
-    mysql_field_seek(stmt->result,icol-1);
-    if ( !(field= mysql_fetch_field(stmt->result)) )
-        return set_error(stmt,MYERR_S1002,"Invalid column number",0);
+  mysql_field_seek(stmt->result, column - 1);
+  if (!(field= mysql_fetch_field(stmt->result)))
+    return set_error(stmt, MYERR_S1002, "Invalid column number", 0);
 
-    if (pfSqlType)
-      *pfSqlType= get_sql_data_type(stmt, field, NULL);
-    if (pnColumnSize)
-      *pnColumnSize= get_column_size(stmt, field, FALSE);
-    if (pibScale)
-      *pibScale= max(0, get_decimal_digits(stmt, field));
-    if ( pfNullable )
-        *pfNullable= (((field->flags & (NOT_NULL_FLAG)) ==
-                       NOT_NULL_FLAG) ?
-                      SQL_NO_NULLS :
-                      SQL_NULLABLE);
+  if (type)
+    *type= get_sql_data_type(stmt, field, NULL);
+  if (size)
+    *size= get_column_size(stmt, field, FALSE);
+  if (scale)
+    *scale= max(0, get_decimal_digits(stmt, field));
+  if (nullable)
+    *nullable= ((field->flags & NOT_NULL_FLAG) ? SQL_NO_NULLS : SQL_NULLABLE);
 
-    if ( stmt->dbc->flag & FLAG_FULL_COLUMN_NAMES && field->table )
+  *need_free= 0;
+
+  if (stmt->dbc->flag & FLAG_FULL_COLUMN_NAMES && field->table)
+  {
+    char *tmp= my_malloc(strlen(field->name) + strlen(field->table) + 2,
+                         MYF(0));
+    if (!tmp)
     {
-        char *tmp= my_malloc(strlen(field->name)+strlen(field->table)+2,
-                             MYF(MY_WME));
-        SQLRETURN error;
-        if ( !tmp )
-        {
-            return set_error(stmt,MYERR_S1001,NULL,4001);
-        }
-        strxmov(tmp,field->table,".",field->name,NullS);
-        error= copy_str_data(SQL_HANDLE_STMT, stmt, szColName,
-                             cbColNameMax, pcbColName, tmp);
-        my_free((gptr) tmp,MYF(0));
-        return error;
+      *need_free= -1;
+      *name= NULL;
     }
-    return copy_str_data(SQL_HANDLE_STMT, stmt, szColName, cbColNameMax,
-                         pcbColName, field->name);
+    else
+    {
+      strxmov(tmp, field->table, ".", field->name, NullS);
+      *name= tmp;
+      *need_free= 1;
+    }
+  }
+  else
+    *name= field->name;
+
+  return SQL_SUCCESS;
 }
 
 

Modified: branches/guffert/driver/unicode.c
===================================================================
--- branches/guffert/driver/unicode.c	2007-08-23 15:01:43 UTC (rev 677)
+++ branches/guffert/driver/unicode.c	2007-08-23 17:32:29 UTC (rev 678)
@@ -419,6 +419,63 @@
 
 
 SQLRETURN SQL_API
+SQLDescribeColW(SQLHSTMT hstmt, SQLUSMALLINT column,
+                SQLWCHAR *name, SQLSMALLINT name_max, SQLSMALLINT *name_len,
+                SQLSMALLINT *type, SQLULEN *size, SQLSMALLINT *scale,
+                SQLSMALLINT *nullable)
+{
+  STMT *stmt= (STMT *)hstmt;
+  SQLCHAR *value= NULL;
+  SQLWCHAR *wvalue= NULL;
+  SQLINTEGER len= SQL_NTS;
+  SQLSMALLINT free_value;
+  uint errors;
+
+  SQLRETURN rc= MySQLDescribeCol(hstmt, column, &value, &free_value, type,
+                                 size, scale, nullable);
+
+  if (free_value == -1)
+  {
+    set_mem_error(&stmt->dbc->mysql);
+    return handle_connection_error(stmt);
+  }
+
+  if (value)
+  {
+    wvalue= sqlchar_as_sqlwchar(stmt->dbc->cxn_charset_info, value, &len,
+                                &errors);
+    if (!wvalue)
+    {
+      if (free_value)
+        x_free(value);
+      set_mem_error(&stmt->dbc->mysql);
+      return handle_connection_error(stmt);
+    }
+
+    if (len > name_max - 1)
+      rc= set_error(stmt, MYERR_01004, NULL, 0);
+
+    if (name_len)
+      *name_len= len;
+
+    if (name_max > 0)
+    {
+      len= min(len, name_max - 1);
+      (void)memcpy((char *)name, (const char *)wvalue,
+                   len * sizeof(SQLWCHAR));
+      ((SQLWCHAR *)name)[len]= 0;
+    }
+
+    if (free_value)
+      x_free(value);
+    x_free(wvalue);
+  }
+
+  return rc;
+}
+
+
+SQLRETURN SQL_API
 SQLExecDirectW(SQLHSTMT hstmt, SQLWCHAR *str, SQLINTEGER str_len)
 {
   int error;
@@ -670,16 +727,6 @@
 //SQLDataSourcesW
 
 
-SQLRETURN SQL_API
-SQLDescribeColW(SQLHSTMT hstmt, SQLUSMALLINT column,
-                SQLWCHAR *name, SQLSMALLINT name_max, SQLSMALLINT *name_len,
-                SQLSMALLINT *type, SQLULEN *def, SQLSMALLINT *scale,
-                SQLSMALLINT *nullable)
-{
-  NOT_IMPLEMENTED;
-}
-
-
 //SQLDriversW
 
 

Modified: branches/guffert/test/my_unicode.c
===================================================================
--- branches/guffert/test/my_unicode.c	2007-08-23 15:01:43 UTC (rev 677)
+++ branches/guffert/test/my_unicode.c	2007-08-23 17:32:29 UTC (rev 678)
@@ -470,8 +470,9 @@
   is_num(len, 3);
   is_wstr(sqlwchar_to_wchar_t(wbuff), L"a\u00e3g", 4);
 
-  ok_stmt(hstmt1, SQLColAttributeW(hstmt1, 1, SQL_DESC_BASE_TABLE_NAME,
-                                   wbuff, 5, &len, NULL));
+  expect_stmt(hstmt1, SQLColAttributeW(hstmt1, 1, SQL_DESC_BASE_TABLE_NAME,
+                                       wbuff, 5, &len, NULL),
+              SQL_SUCCESS_WITH_INFO);
   is_num(len, 11);
   is_wstr(sqlwchar_to_wchar_t(wbuff), L"t_co", 5);
 
@@ -491,6 +492,50 @@
 }
 
 
+DECLARE_TEST(sqldescribecol)
+{
+  HDBC hdbc1;
+  HSTMT hstmt1;
+  SQLWCHAR wbuff[40];
+  SQLSMALLINT len;
+
+  ok_env(henv, SQLAllocConnect(henv, &hdbc1));
+  ok_con(hdbc1, SQLConnectW(hdbc1, W(L"myodbc3"), SQL_NTS, W(L"root"), SQL_NTS,
+                            W(L""), SQL_NTS));
+
+  ok_con(hdbc1, SQLAllocStmt(hdbc1, &hstmt1));
+
+  ok_sql(hstmt1, "DROP TABLE IF EXISTS t_desc");
+  ok_stmt(hstmt1, SQLExecDirectW(hstmt1,
+                                 W(L"CREATE TABLE t_desc (a\u00e3g INT)"),
+                                 SQL_NTS));
+
+  ok_sql(hstmt1, "SELECT * FROM t_desc");
+
+  ok_stmt(hstmt1, SQLDescribeColW(hstmt1, 1, wbuff,
+                                  sizeof(wbuff) / sizeof(wbuff[0]), &len,
+                                  NULL, NULL, NULL, NULL));
+  is_num(len, 3);
+  is_wstr(sqlwchar_to_wchar_t(wbuff), L"a\u00e3g", 4);
+
+  expect_stmt(hstmt1, SQLDescribeColW(hstmt1, 1, wbuff, 3, &len,
+                                      NULL, NULL, NULL, NULL),
+              SQL_SUCCESS_WITH_INFO);
+  is_num(len, 3);
+  is_wstr(sqlwchar_to_wchar_t(wbuff), L"a\u00e3", 3);
+
+  ok_stmt(hstmt1, SQLFreeStmt(hstmt1, SQL_CLOSE));
+
+  ok_sql(hstmt1, "DROP TABLE IF EXISTS t_desc");
+
+  ok_stmt(hstmt1, SQLFreeStmt(hstmt1, SQL_DROP));
+  ok_con(hdbc1, SQLDisconnect(hdbc1));
+  ok_con(hdbc1, SQLFreeConnect(hdbc1));
+
+  return OK;
+}
+
+
 BEGIN_TESTS
   ADD_TEST(sqlconnect)
   ADD_TEST(sqlprepare)
@@ -501,6 +546,7 @@
   ADD_TEST(sqlsetcursorname)
   ADD_TEST(sqlgetcursorname)
   ADD_TEST(sqlcolattribute)
+  ADD_TEST(sqldescribecol)
 END_TESTS
 
 

Thread
Connector/ODBC 3.51 commit: r678 - in branches/guffert: driver testjwinstead23 Aug