| // @@@ START COPYRIGHT @@@ | |
| // | |
| // Licensed to the Apache Software Foundation (ASF) under one | |
| // or more contributor license agreements. See the NOTICE file | |
| // distributed with this work for additional information | |
| // regarding copyright ownership. The ASF licenses this file | |
| // to you under the Apache License, Version 2.0 (the | |
| // "License"); you may not use this file except in compliance | |
| // with the License. You may obtain a copy of the License at | |
| // | |
| // http://www.apache.org/licenses/LICENSE-2.0 | |
| // | |
| // Unless required by applicable law or agreed to in writing, | |
| // software distributed under the License is distributed on an | |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
| // KIND, either express or implied. See the License for the | |
| // specific language governing permissions and limitations | |
| // under the License. | |
| // | |
| // @@@ END COPYRIGHT @@@ | |
| #ifdef __linux | |
| #include <unistd.h> | |
| #else | |
| #include <windows.h> | |
| #include <tchar.h> | |
| #endif | |
| //#include <stdarg.h> | |
| #include <stdio.h> | |
| #include <string.h> | |
| #include <stdlib.h> | |
| #include <assert.h> | |
| #include <sql.h> | |
| #include <sqlext.h> | |
| SQLHENV henv ; | |
| SQLHDBC hdbc ; | |
| SQLHSTMT hstmt ; | |
| SQLHWND hWnd ; | |
| #define MAX_SQLSTRING_LEN 1000 | |
| #define STATE_SIZE 6 | |
| #define MAX_CONNECT_STRING 256 | |
| #define TRUE 1 | |
| #define FALSE 0 | |
| #define ARGS "d:u:p:" | |
| const char *SqlRetText( int rc ) | |
| { | |
| static char buffer[80] ; | |
| switch ( rc ) | |
| { | |
| case SQL_SUCCESS: return( "SQL_SUCCESS" ) ; | |
| case SQL_SUCCESS_WITH_INFO: return( "SQL_SUCCESS_WITH_INFO" ) ; | |
| case SQL_NO_DATA: return( "SQL_NO_DATA" ) ; | |
| case SQL_ERROR: return( "SQL_ERROR" ) ; | |
| case SQL_INVALID_HANDLE: return( "SQL_INVALID_HANDLE" ) ; | |
| case SQL_STILL_EXECUTING: return( "SQL_STILL_EXECUTING" ) ; | |
| case SQL_NEED_DATA: return( "SQL_NEED_DATA" ) ; | |
| } | |
| sprintf( buffer, "SQL Error %d", rc ) ; | |
| return( buffer ) ; | |
| } | |
| void CleanUp() | |
| { | |
| printf( "\nConnect Test FAILED!!!\n" ) ; | |
| if ( hstmt != SQL_NULL_HANDLE ) | |
| SQLFreeHandle( SQL_HANDLE_STMT,hstmt ) ; | |
| if( hdbc != SQL_NULL_HANDLE ) | |
| { | |
| SQLDisconnect( hdbc ) ; | |
| SQLFreeHandle( SQL_HANDLE_DBC, hdbc ) ; | |
| } | |
| if ( henv != SQL_NULL_HANDLE ) | |
| SQLFreeHandle( SQL_HANDLE_ENV, henv ) ; | |
| exit( EXIT_FAILURE ) ; | |
| } | |
| void LogDiagnostics( const char *sqlFunction | |
| , SQLRETURN rc | |
| , bool exitOnError=true | |
| ) | |
| { | |
| SQLRETURN diagRC = SQL_SUCCESS ; | |
| SQLSMALLINT recordNumber ; | |
| SQLINTEGER nativeError ; | |
| SQLCHAR messageText[SQL_MAX_MESSAGE_LENGTH] ; | |
| SQLCHAR sqlState[6] ; | |
| int diagsPrinted = 0 ; | |
| bool printedErrorLogHeader = false ; | |
| printf( "Function %s returned %s\n" | |
| , sqlFunction | |
| , SqlRetText( rc ) | |
| ) ; | |
| /* Log any henv Diagnostics */ | |
| recordNumber = 1 ; | |
| do | |
| { | |
| diagRC = SQLGetDiagRec( SQL_HANDLE_ENV | |
| , henv | |
| , recordNumber | |
| , sqlState | |
| , &nativeError | |
| , messageText | |
| , sizeof(messageText) | |
| , NULL | |
| ) ; | |
| if ( diagRC==SQL_SUCCESS ) | |
| { | |
| if( ! printedErrorLogHeader ) | |
| { | |
| printf( "Diagnostics associated with environment handle:\n" ) ; | |
| printedErrorLogHeader = true ; | |
| } | |
| printf( "\n\tSQL Diag %d\n\tNative Error: %ld\n\tSQL State: %s\n\tMessage: %s\n" | |
| , recordNumber | |
| , nativeError | |
| , sqlState | |
| , messageText | |
| ) ; | |
| } | |
| recordNumber++ ; | |
| } while ( diagRC==SQL_SUCCESS ) ; | |
| /* Log any hdbc Diagnostics */ | |
| recordNumber = 1 ; | |
| printedErrorLogHeader = false ; | |
| do | |
| { | |
| diagRC = SQLGetDiagRec( SQL_HANDLE_DBC | |
| , hdbc | |
| , recordNumber | |
| , sqlState | |
| , &nativeError | |
| , messageText | |
| , sizeof(messageText) | |
| , NULL | |
| ) ; | |
| if ( diagRC==SQL_SUCCESS ) | |
| { | |
| if( !printedErrorLogHeader ) | |
| { | |
| printf( "Diagnostics associated with connection handle:\n" ) ; | |
| printedErrorLogHeader = true ; | |
| } | |
| printf( "\n\tSQL Diag %d\n\tNative Error: %ld\n\tSQL State: %s\n\tMessage: %s\n" | |
| , recordNumber | |
| , nativeError | |
| , sqlState | |
| , messageText | |
| ) ; | |
| } | |
| recordNumber++ ; | |
| } while (diagRC==SQL_SUCCESS) ; | |
| /* Log any hstmt Diagnostics */ | |
| recordNumber = 1 ; | |
| printedErrorLogHeader = false ; | |
| do | |
| { | |
| diagRC = SQLGetDiagRec( SQL_HANDLE_STMT | |
| , hstmt | |
| , recordNumber | |
| , sqlState | |
| , &nativeError | |
| , messageText | |
| , sizeof(messageText) | |
| , NULL | |
| ) ; | |
| if (diagRC == SQL_SUCCESS ) | |
| { | |
| if ( !printedErrorLogHeader ) | |
| { | |
| printf( "Diagnostics associated with statmement handle:\n" ) ; | |
| printedErrorLogHeader = true ; | |
| } | |
| printf( "\n\tSQL Diag %d\n\tNative Error: %ld\n\tSQL State: %s\n\tMessage: %s\n" | |
| , recordNumber | |
| , nativeError | |
| , sqlState | |
| , messageText | |
| ) ; | |
| } | |
| recordNumber++ ; | |
| } while ( diagRC==SQL_SUCCESS ) ; | |
| if ( exitOnError && rc != SQL_SUCCESS_WITH_INFO ) | |
| CleanUp() ; | |
| } | |
| // Main Program | |
| int main (int argc, char *argv[]) | |
| { | |
| unsigned char dsnName[20] ; | |
| unsigned char user[20] ; | |
| unsigned char password[20] ; | |
| SQLRETURN returnCode ; | |
| bool testPassed = true ; | |
| SQLCHAR InConnStr[MAX_CONNECT_STRING] ; | |
| SQLCHAR OutConnStr[MAX_CONNECT_STRING] ; | |
| SQLSMALLINT ConnStrLength ; | |
| int errflag = 0 ; | |
| //optarg = NULL ; | |
| if ( argc != 4 ) | |
| errflag++ ; | |
| if ( !errflag ) | |
| { | |
| strcpy ( (char *) dsnName, argv[1] ) ; | |
| strcpy ( (char *) user, argv[2] ) ; | |
| strcpy ( (char *) password, argv[3] ) ; | |
| } | |
| if ( errflag ) | |
| { | |
| printf( "Command line error.\n" ) ; | |
| printf( "Usage: %s <datasource> <userid> <password>\n", argv[0] ) ; | |
| return FALSE ; | |
| } | |
| // Initialize handles to NULL | |
| henv = SQL_NULL_HANDLE ; | |
| hstmt = SQL_NULL_HANDLE ; | |
| hdbc = SQL_NULL_HANDLE ; | |
| // Allocate Environment Handle | |
| returnCode = SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv ) ; | |
| if ( ! SQL_SUCCEEDED( returnCode ) ) | |
| LogDiagnostics( "SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv )" | |
| , returnCode | |
| ) ; | |
| // Set ODBC version to 3.0 | |
| returnCode = SQLSetEnvAttr( henv, SQL_ATTR_ODBC_VERSION, (void*) SQL_OV_ODBC3, 0 ) ; | |
| if ( ! SQL_SUCCEEDED( returnCode ) ) | |
| LogDiagnostics( "SQLSetEnvAttr( henv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0 )" | |
| , returnCode | |
| , false | |
| ) ; | |
| // Allocate Connection handle | |
| returnCode = SQLAllocHandle( SQL_HANDLE_DBC, henv, &hdbc ) ; | |
| if ( ! SQL_SUCCEEDED( returnCode ) ) | |
| LogDiagnostics( "SQLAllocHandle( SQL_HANDLE_DBC, henv, &hdbc )", returnCode ) ; | |
| // Connect to the database | |
| sprintf( (char*) InConnStr | |
| , "DSN=%s;UID=%s;PWD=%s;%c" | |
| , (char*) dsnName | |
| , (char*) user | |
| , (char*) password | |
| , '\0' | |
| ) ; | |
| printf( "Using Connect String: %s\n", InConnStr ) ; | |
| returnCode = SQLDriverConnect( hdbc | |
| , hWnd | |
| , InConnStr | |
| , SQL_NTS | |
| , OutConnStr | |
| , sizeof( OutConnStr ) | |
| , &ConnStrLength | |
| , SQL_DRIVER_NOPROMPT | |
| ) ; | |
| if ( ! SQL_SUCCEEDED( returnCode ) ) | |
| LogDiagnostics( "SQLDriverConnect", returnCode ) ; | |
| printf( "Successfully connected using SQLDriverConnect.\n" ) ; | |
| // Allocate Statement handle | |
| returnCode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt) ; | |
| if ( ! SQL_SUCCEEDED( returnCode ) ) | |
| LogDiagnostics( "SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt )", returnCode ) ; | |
| printf( "Drop sample table if it exists...\n" ) ; | |
| // Drop the test table if it exists | |
| // DROP IF EXISTS TASKS ; | |
| returnCode = SQLExecDirect(hstmt, (SQLCHAR*) "DROP TABLE IF EXISTS TASKS", SQL_NTS ) ; | |
| if ( ! SQL_SUCCEEDED( returnCode ) ) | |
| LogDiagnostics( "SQLExecDirect of DROP", returnCode ) ; | |
| printf( "Creating sample table TASKS...\n" ) ; | |
| // Create a test table in default schema | |
| // CREATE TABLE TASKS (ID INT NOT NULL, TASK VARCHAR(10), LAST_UPDATE TIMESTAMP, PRIMARY KEY (C1)) ; | |
| returnCode = | |
| SQLExecDirect | |
| ( hstmt | |
| , (SQLCHAR*) "CREATE TABLE TASKS (ID INT NOT NULL, TASK CHAR(20), COMPLETED DATE, PRIMARY KEY (ID))" | |
| , SQL_NTS | |
| ) ; | |
| if ( ! SQL_SUCCEEDED( returnCode ) ) | |
| LogDiagnostics( "SQLExecDirect of CREATE", returnCode ) ; | |
| printf( "Table TASKS created using SQLExecDirect.\n" ) ; | |
| printf( "Inserting data using SQLBindParameter, SQLPrepare, SQLExecute\n" ) ; | |
| // Insert few rows into test table using bound parameters | |
| // INSERT INTO TASKS VALUES (?, ?, ?) ; | |
| SQLINTEGER intID ; | |
| SQLLEN cbID = 0, cbTask = SQL_NTS, cbCompleted = 0 ; | |
| SQLCHAR strTask[200] ; | |
| SQL_DATE_STRUCT dsCompleted ; | |
| returnCode = SQLBindParameter( hstmt | |
| , 1 | |
| , SQL_PARAM_INPUT | |
| , SQL_C_SHORT | |
| , SQL_INTEGER | |
| , 0 | |
| , 0 | |
| , &intID | |
| , 0 | |
| , &cbID | |
| ) ; | |
| if ( ! SQL_SUCCEEDED( returnCode ) ) | |
| LogDiagnostics( "SQLBindParameter 1", returnCode ) ; | |
| returnCode = SQLBindParameter( hstmt | |
| , 2 | |
| , SQL_PARAM_INPUT | |
| , SQL_C_CHAR | |
| , SQL_CHAR | |
| , 0 | |
| , 0 | |
| , &strTask | |
| , 0 | |
| , &cbTask | |
| ) ; | |
| if ( ! SQL_SUCCEEDED( returnCode ) ) | |
| LogDiagnostics( "SQLBindParameter 2", returnCode ) ; | |
| returnCode = SQLBindParameter( hstmt | |
| , 3 | |
| , SQL_PARAM_INPUT | |
| , SQL_C_TYPE_DATE | |
| , SQL_DATE | |
| , sizeof(dsCompleted) | |
| , 0 | |
| , &dsCompleted | |
| , 0 | |
| , &cbCompleted | |
| ) ; | |
| if ( ! SQL_SUCCEEDED( returnCode ) ) | |
| LogDiagnostics( "SQLBindParameter 3", returnCode ) ; | |
| returnCode = SQLPrepare( hstmt | |
| , (SQLCHAR*) "INSERT INTO TASKS VALUES (?, ?, ?)" | |
| , SQL_NTS | |
| ) ; | |
| if ( ! SQL_SUCCEEDED( returnCode ) ) | |
| LogDiagnostics( "SQLPrepare of INSERT", returnCode ) ; | |
| intID = 1000 ; | |
| strcpy ( (char*) strTask, "CREATE REPORTS" ) ; | |
| dsCompleted.year = 2014 ; | |
| dsCompleted.month = 3 ; | |
| dsCompleted.day = 22 ; | |
| returnCode = SQLExecute( hstmt ) ; | |
| if ( ! SQL_SUCCEEDED( returnCode ) ) | |
| LogDiagnostics( "SQLExecute", returnCode ) ; | |
| printf( "Data inserted.\n" ) ; | |
| // Select rows from test table and fetch the data | |
| // SELECT * from TASKS WHERE TASK LIKE '%REPORT%' | |
| printf( "Fetching data using SQLExecDirect, SQLFetch, SQLGetData\n" ) ; | |
| returnCode = SQLExecDirect( hstmt | |
| , (SQLCHAR*) "SELECT ID, TASK, COMPLETED FROM TASKS" | |
| , SQL_NTS | |
| ) ; | |
| if ( ! SQL_SUCCEEDED( returnCode ) ) | |
| LogDiagnostics( "SQLExecDirect of SELECT", returnCode ) ; | |
| //loop thru resultset | |
| while ( TRUE ) | |
| { | |
| returnCode = SQLFetch( hstmt ) ; | |
| if ( returnCode == SQL_ERROR || returnCode == SQL_SUCCESS_WITH_INFO ) | |
| { | |
| LogDiagnostics( "SQLFetch", returnCode ) ; | |
| } | |
| if ( returnCode == SQL_SUCCESS || returnCode == SQL_SUCCESS_WITH_INFO ) | |
| { | |
| SQLGetData( hstmt, 1, SQL_C_SHORT, &intID, 0, &cbID ) ; | |
| SQLGetData( hstmt, 2, SQL_C_CHAR, strTask, 20, &cbTask ) ; | |
| SQLGetData( hstmt | |
| , 3 | |
| , SQL_C_TYPE_DATE | |
| , &dsCompleted | |
| , sizeof( dsCompleted ) | |
| , &cbCompleted | |
| ) ; | |
| printf( "Data selected: %d %s %d-%d-%d\n" | |
| , intID | |
| , strTask | |
| , dsCompleted.year | |
| , dsCompleted.month | |
| , dsCompleted.day | |
| ) ; | |
| } | |
| else | |
| break ; | |
| } | |
| // Free Statement handle | |
| returnCode = SQLFreeHandle( SQL_HANDLE_STMT, hstmt ) ; | |
| if ( ! SQL_SUCCEEDED( returnCode ) ) | |
| LogDiagnostics( "SQLFreeHandle( SQL_HANDLE_STMT, hstmt )", returnCode ) ; | |
| hstmt = SQL_NULL_HANDLE ; | |
| // Disconnect | |
| returnCode = SQLDisconnect(hdbc) ; | |
| if ( ! SQL_SUCCEEDED( returnCode ) ) | |
| LogDiagnostics( "SQLDisconnect( hdbc )", returnCode ) ; | |
| // Free Connection handle | |
| returnCode = SQLFreeHandle( SQL_HANDLE_DBC, hdbc ) ; | |
| if ( ! SQL_SUCCEEDED( returnCode ) ) | |
| LogDiagnostics( "SQLFreeHandle( SQL_HANDLE_DBC, hdbc )", returnCode ) ; | |
| hdbc = SQL_NULL_HANDLE ; | |
| // Free Environment handle | |
| returnCode = SQLFreeHandle( SQL_HANDLE_ENV, henv ) ; | |
| if ( ! SQL_SUCCEEDED( returnCode ) ) | |
| LogDiagnostics( "SQLFreeHandle( SQL_HANDLE_ENV, henv )", returnCode ) ; | |
| henv = SQL_NULL_HANDLE ; | |
| printf( "Basic SQL ODBC Test Passed!\n" ) ; | |
| exit( EXIT_SUCCESS ) ; | |
| } |