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 test | jwinstead | 23 Aug |