Files
@ 3d604507d726
Branch filter:
Location: DA/protocols/pmodbc.c
3d604507d726
4.2 KiB
text/x-csrc
Add pmodbc.c and add new protocol tests to vldb-protocols.py.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
#include <stdio.h>
#include <stdlib.h>
#include <sql.h>
#include <sqlext.h>
#include <string.h>
#include <assert.h>
// compilation: gcc -g pmodbc.c -lodbc -o pmodbc
static void list_drivers();
static void query_db(char* dsn, char* query, int csv);
void extract_error(char *fn, SQLHANDLE handle, SQLSMALLINT type);
int main(int argc, char** argv) {
if (argc < 4) {
printf("Incorrect number of arguments.\n\n");
printf("Arguments:\n");
printf("pmodbc [dsn] [query] [csv={0,1}]\n\n");
printf("DSN List:\n");
list_drivers();
} else {
query_db(argv[1], argv[2], *argv[3] == '1');
}
}
static void list_drivers() {
SQLHENV env;
char dsn[256];
char desc[256];
SQLSMALLINT dsn_ret;
SQLSMALLINT desc_ret;
SQLUSMALLINT direction;
SQLRETURN ret;
SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void *) SQL_OV_ODBC3, 0);
direction = SQL_FETCH_FIRST;
while(SQL_SUCCEEDED(ret = SQLDataSources(env, direction, dsn, sizeof(dsn), &dsn_ret, desc, sizeof(desc), &desc_ret))) {
direction = SQL_FETCH_NEXT;
printf("%s - %s\n", dsn, desc);
if (ret == SQL_SUCCESS_WITH_INFO) printf("\tdata truncation\n");
}
}
static void query_db(char* dsn_str, char* query, int csv) {
SQLHENV env;
SQLHDBC dbc;
SQLHSTMT stmt;
SQLRETURN ret; /* ODBC API return status */
SQLSMALLINT columns; /* number of columns in result-set */
int row = 0;
char dsn[1000];
snprintf(dsn, 1000, "DSN=%s;", dsn_str);
/* Allocate an environment handle */
SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
/* We want ODBC 3 support */
SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void *) SQL_OV_ODBC3, 0);
/* Allocate a connection handle */
ret = SQLAllocHandle(SQL_HANDLE_DBC, env, &dbc);
if (!SQL_SUCCEEDED(ret)) {
extract_error("SQLAllocHandle for dbc", env, SQL_HANDLE_ENV);
exit(1);
}
/* Connect to the DSN mydsn */
/* You will need to change mydsn to one you have created and tested */
SQLDriverConnect(dbc, NULL, dsn, SQL_NTS, NULL, 0, NULL, SQL_DRIVER_COMPLETE);
/* Allocate a statement handle */
SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt);
/* Retrieve a list of tables */
//SQLTables(stmt, NULL, 0, NULL, 0, NULL, 0, "TABLE", SQL_NTS);
ret = SQLExecDirect(stmt, query, SQL_NTS);
if (!SQL_SUCCEEDED(ret)) {
extract_error("SQLExecuteDirect for dbc", stmt, SQL_HANDLE_STMT);
exit(1);
}
/* How many columns are there */
SQLNumResultCols(stmt, &columns);
if (csv == 0) {
while (SQL_SUCCEEDED(ret = SQLFetch(stmt))) {
}
} else {
char csvbuf[1000];
/* Loop through the rows in the result-set */
while (SQL_SUCCEEDED(ret = SQLFetch(stmt))) {
SQLUSMALLINT i;
SQLLEN curlen = 0;
SQLLEN indicator;
/* Loop through the columns */
for (i = 1; i <= columns; i++) {
/* retrieve column data as a string */
ret = SQLGetData(stmt, i, SQL_C_CHAR, csvbuf + curlen, sizeof(csvbuf) - curlen, &indicator);
if (!SQL_SUCCEEDED(ret)) {
extract_error("SQLExecuteDirect for dbc", stmt, SQL_HANDLE_STMT);
exit(1);
}
curlen += indicator;
if (i != columns)
csvbuf[curlen++] = ',';
}
puts(csvbuf);
}
}
extract_error("SQLStmt for dbc", stmt, SQL_HANDLE_STMT);
exit(1);
}
void extract_error(char *fn, SQLHANDLE handle, SQLSMALLINT type)
{
SQLINTEGER i = 0;
SQLINTEGER native;
SQLCHAR state[ 7 ];
SQLCHAR text[256];
SQLSMALLINT len;
SQLRETURN ret;
fprintf(stderr,
"\n"
"The driver reported the following diagnostics whilst running "
"%s\n\n",
fn);
do
{
ret = SQLGetDiagRec(type, handle, ++i, state, &native, text,
sizeof(text), &len );
if (SQL_SUCCEEDED(ret))
printf("%s:%d:%d:%s\n", state, i, native, text);
}
while( ret == SQL_SUCCESS );
}
|