Pelles C forum
C language => Tips & tricks => Topic started by: TimoVJL on July 17, 2019, 09:39:07 AM
-
An interesting system:
http://sqlrelay.sourceforge.net/index.html
https://sourceforge.net/projects/sqlrelay/
Has anyone tested it ?
I have problems with that ODBC driver, when using SQLDriverConnect() with non DSN connection strings.
It will be fixed in next version 1.6 :)
Have anyone tried it with oracle 11/12 ?
It has own client library, so you can do this//#include <sqlrelay/sqlrclientwrapper.h>
#include <stdio.h>
#include <stdint.h>
#pragma comment(lib, "libsqlrclientwrapper.lib")
#define SQLRCLIENT_DLLSPEC __declspec(dllimport)
typedef struct sqlrconnection *sqlrcon;
typedef struct sqlrcursor *sqlrcur;
SQLRCLIENT_DLLSPEC sqlrcon sqlrcon_alloc(const char *server, uint16_t port, const char *socket, const char *user, const char *password, int32_t retrytime, int32_t tries);
SQLRCLIENT_DLLSPEC void sqlrcon_free(sqlrcon sqlrconref);
SQLRCLIENT_DLLSPEC sqlrcur sqlrcur_alloc(sqlrcon sqlrconref);
SQLRCLIENT_DLLSPEC void sqlrcur_free(sqlrcur sqlrcurref);
SQLRCLIENT_DLLSPEC int sqlrcur_sendQuery(sqlrcur sqlrcurref, const char *query);
SQLRCLIENT_DLLSPEC const char *sqlrcur_errorMessage(sqlrcur sqlrcurref);
SQLRCLIENT_DLLSPEC void sqlrcon_endSession(sqlrcon sqlrconref);
SQLRCLIENT_DLLSPEC uint32_t sqlrcur_colCount(sqlrcur sqlrcurref);
SQLRCLIENT_DLLSPEC uint64_t sqlrcur_rowCount(sqlrcur sqlrcurref);
SQLRCLIENT_DLLSPEC const char * const *sqlrcur_getRow(sqlrcur sqlrcurref, uint64_t row);
int __cdecl main(void)
{
sqlrcon con = sqlrcon_alloc("localhost", 9000, 0, "test", "test", 0, 1);
sqlrcur cur = sqlrcur_alloc(con);
if (!sqlrcur_sendQuery(cur, "SELECT * FROM test"))
{
printf("%s\n", sqlrcur_errorMessage(cur));
sqlrcon_endSession(con);
} else {
sqlrcon_endSession(con);
for (uint64_t row = 0; row < sqlrcur_rowCount(cur); row++)
{
char **rowarray = (char **)sqlrcur_getRow(cur, row);
for (uint64_t col = 0; col < sqlrcur_colCount(cur); col++)
printf("%s,", rowarray[col]);
printf("\n");
}
}
sqlrcur_free(cur);
sqlrcon_free(con);
return 0;
}
x64 dllslibrudiments.dll 475 648
libsqlrclient.dll 163 840
libsqlrclientwrapper.dll 26 112
ODBC drivers are small, 318 / 408 kB :)
Actual database drivers are in server side.
simple install from current dir as admin:odbcconf.exe /A {INSTALLDRIVER "SQL Relay|Driver=%~dp0libsqlrodbc.dll|Setup=%~dp0libsqlrodbc.dll|API Level=2|DriverODBCVer=03.00|FileUsage=0"}
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <sql.h>
#include <sqlext.h>
//#include "ODBC_Lib.h"
#pragma comment(lib, "user32.lib")
//#pragma comment(lib, "odbc32.lib")
#pragma comment(lib, "libsqlrodbc.lib")
typedef struct _ODBCCONN {
SQLHENV hEnv;
SQLHDBC hDbc;
SQLHSTMT hStmt;
} ODBCCONN, *PODBCCONN;
void ODBC_ErrMsg(char *szErr)
{
MessageBox(0, szErr, 0, MB_OK | MB_ICONERROR);
}
void ODBC_DisplayError(SQLHANDLE hHandle, SWORD HandleType, char *Module)
{
long nError;
SQLSMALLINT recno = 1;
SQLRETURN rc;
SWORD RetLen;
SQLCHAR szSQLState[80];
SQLCHAR szMsg[255];
char szBuf[512];
do
{
szBuf[0] = 0;
rc = SQLGetDiagRec(HandleType, hHandle, recno++, szSQLState, &nError, szMsg, sizeof(szMsg), &RetLen);
if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO) {
wsprintf(szBuf, "state: %s\nerror: %d\n%s", szSQLState, nError, szMsg);
MessageBox(0, szBuf, Module, MB_OK | MB_ICONERROR);
}
} while (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO);
}
BOOL ODBC_Open(ODBCCONN *conn, char *szCon, HWND hWnd)
{
SQLHENV hEnv;
SQLHDBC hDbc;
SQLRETURN rc;
SQLCHAR szOutConn[1024];
SQLSMALLINT nOutConn;
if (!conn) return FALSE;
conn->hEnv = NULL;
conn->hDbc = NULL;
conn->hStmt = NULL;
//i = 5;
// Allocate environment handle
rc = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &hEnv);
if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO)
{
conn->hEnv = hEnv;
// Set the ODBC version environment attribute
rc = SQLSetEnvAttr(hEnv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER *)SQL_OV_ODBC3, 0);
if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO)
{ // Allocate connection handle
rc = SQLAllocHandle(SQL_HANDLE_DBC, hEnv, &hDbc);
if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO)
{
conn->hDbc = hDbc;
// Set connection timeout to 10 seconds
SQLSetConnectAttr(hDbc, SQL_ATTR_CONNECTION_TIMEOUT, (SQLPOINTER)10, SQL_IS_UINTEGER);
// Set login timeout to 10 seconds
SQLSetConnectAttr(hDbc, SQL_ATTR_LOGIN_TIMEOUT, (SQLPOINTER)10, 0);
// SQL_DRIVER_COMPLETE SQL_DRIVER_PROMPT
// Connect to data source
if (szCon && *szCon)
rc = SQLDriverConnect(hDbc, hWnd, (SQLCHAR *)szCon, SQL_NTS,
szOutConn, sizeof(szOutConn), &nOutConn, SQL_DRIVER_COMPLETE);
else
rc = SQLDriverConnect(hDbc, hWnd, (SQLCHAR *)szCon, SQL_NTS,
szOutConn, sizeof(szOutConn), &nOutConn, SQL_DRIVER_PROMPT);
if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO)
{
//rc = SQLAllocHandle(SQL_HANDLE_STMT, conn->hDbc, &conn->hStmt);
//if (rc == SQL_SUCCESS) {}
return TRUE;
} else ODBC_DisplayError(hDbc, SQL_HANDLE_DBC, "SQLDriverConnect");
}
}
}
return FALSE;
}
BOOL ODBC_Close(ODBCCONN *conn)
{
if (!conn) return FALSE;
if (conn->hStmt) { //! Free statement handle
SQLFreeHandle(SQL_HANDLE_STMT, conn->hStmt);
conn->hStmt = NULL;
}
if (conn->hDbc) { //! Free connection handle
SQLDisconnect(conn->hDbc);
SQLFreeConnect(conn->hDbc);
conn->hDbc = NULL;
}
if (conn->hEnv) { //! Free environment handle
SQLFreeEnv(conn->hEnv);
conn->hEnv = NULL;
}
return TRUE;
}
int __cdecl main(void)
{
char szTmp[255];
ODBCCONN conn, *pConn = &conn;
//if (ODBC_Open(&conn, 0, GetDesktopWindow())) { // crash
//if (ODBC_Open(&conn, "sqlrelay16", GetDesktopWindow())) { // fail
if (ODBC_Open(&conn, "Driver={SQL Relay};Server=localhost;Port=9000;Database=test;User=test;Password=test;LazyConnect=0;Debug=1;", GetDesktopWindow())) {
SQLRETURN rc;
//rc = SQLSetConnectOption(conn.hDbc, SQL_CURSOR_TYPE, SQL_CURSOR_DYNAMIC);
//printf("\trc: %d\n", rc);
rc = SQLGetInfo(conn.hDbc, SQL_DATABASE_NAME, (SQLPOINTER)szTmp,sizeof(szTmp), NULL);
printf("\trc: %d, '%s'\n", rc, szTmp);
ODBC_Close(&conn);
}
return 0;
}