提交 958e48d2 authored 作者: Thomas Mueller's avatar Thomas Mueller

--no commit message

--no commit message
上级 43214cca
# Project: h2odbcUninstall
# Makefile created by Dev-C++ 4.9.9.2
CPP = g++.exe
CC = gcc.exe
WINDRES = windres.exe
RES = ../../bin/odbcTemp/h2odbcUninstall_private.res
OBJ = ../../bin/odbcTemp/uninstall.o $(RES)
LINKOBJ = ../../bin/odbcTemp/uninstall.o $(RES)
LIBS = -L"C:/Dev-Cpp/lib" -mwindows C:/Dev-Cpp/lib/libodbccp32.a C:/Dev-Cpp/lib/libodbc32.a
INCS = -I"C:/Dev-Cpp/include"
CXXINCS = -I"C:/Dev-Cpp/lib/gcc/mingw32/3.4.2/include" -I"C:/Dev-Cpp/include/c++/3.4.2/backward" -I"C:/Dev-Cpp/include/c++/3.4.2/mingw32" -I"C:/Dev-Cpp/include/c++/3.4.2" -I"C:/Dev-Cpp/include"
BIN = ../../bin/odbc/h2odbcUninstall.exe
CXXFLAGS = $(CXXINCS)
CFLAGS = $(INCS)
RM = rm -f
.PHONY: all all-before all-after clean clean-custom
all: all-before ../../bin/odbc/h2odbcUninstall.exe all-after
clean: clean-custom
${RM} $(OBJ) $(BIN)
$(BIN): $(OBJ)
$(CPP) $(LINKOBJ) -o "..\..\bin\odbc\h2odbcUninstall.exe" $(LIBS)
../../bin/odbcTemp/uninstall.o: uninstall/uninstall.cpp
$(CPP) -c uninstall/uninstall.cpp -o ../../bin/odbcTemp/uninstall.o $(CXXFLAGS)
../../bin/odbcTemp/h2odbcUninstall_private.res: h2odbcUninstall_private.rc
$(WINDRES) -i h2odbcUninstall_private.rc --input-format=rc -o ../../bin/odbcTemp/h2odbcUninstall_private.res -O coff
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
*/
#include "h2odbc.h"
typedef struct {
char name[MAX_STRING_LEN+1];
char url[MAX_STRING_LEN+1];
char user[MAX_STRING_LEN+1];
char password[MAX_STRING_LEN+1];
} DNSConfiguration;
BOOL INSTAPI ConfigDriver(HWND hwndParent,
WORD fRequest, LPCSTR lpszDriver,
LPCSTR lpszArgs, LPSTR lpszMsg,
WORD cbMsgMax, WORD *pcbMsgOut) {
trace("ConfigDriver");
switch(fRequest) {
case ODBC_INSTALL_DRIVER:
case ODBC_CONFIG_DRIVER:
case ODBC_REMOVE_DRIVER:
return TRUE;
}
return FALSE;
}
LONG CALLBACK ConfigDlgProc(HWND hdlg,WORD wMsg,WPARAM wParam,LPARAM lParam) {
DNSConfiguration* config;
switch (wMsg) {
case WM_INITDIALOG:
config=(DNSConfiguration*)lParam;
SetDlgItemText(hdlg,IDC_NAME,config->name);
SetDlgItemText(hdlg,IDC_URL,config->url);
SetDlgItemText(hdlg,IDC_USER,config->user);
SetDlgItemText(hdlg,IDC_PASSWORD,config->password);
SetWindowLong(hdlg, GWL_USERDATA, (LONG) lParam );
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDOK:
config=(DNSConfiguration*)GetWindowLong(hdlg,GWL_USERDATA);
GetDlgItemText(hdlg,IDC_NAME,config->name,MAX_STRING_LEN);
GetDlgItemText(hdlg,IDC_URL,config->url,MAX_STRING_LEN);
GetDlgItemText(hdlg,IDC_USER,config->user,MAX_STRING_LEN);
GetDlgItemText(hdlg,IDC_PASSWORD,config->password,MAX_STRING_LEN);
EndDialog(hdlg, wParam);
return TRUE;
case IDCANCEL:
EndDialog(hdlg, wParam);
return TRUE;
}
break;
}
return FALSE;
}
BOOL INSTAPI ConfigDSN(HWND hwndParent,
WORD fRequest, LPCSTR lpszDriver,
LPCSTR lpszAttributes) {
trace("ConfigDSN");
char* begin=strstr(lpszAttributes,"DSN=");
int len=0;
char name[MAX_STRING_LEN+1];
name[0]=0;
DNSConfiguration configuration;
configuration.name[0]=0;
configuration.url[0]=0;
configuration.user[0]=0;
configuration.password[0]=0;
if(begin) {
trace(" begin");
begin+=4;
char* end=strstr(begin,";");
int len;
if(end==NULL) {
len=strlen(begin);
} else {
len=end-begin;
}
if(len>MAX_STRING_LEN) {
len=MAX_STRING_LEN;
}
strncpy(name, begin, len+1);
strncpy(configuration.name, begin, len+1);
}
if(fRequest==ODBC_REMOVE_DSN) {
trace(" ODBC_REMOVE_DSN");
return SQLRemoveDSNFromIni(name);
}
if(fRequest==ODBC_CONFIG_DSN) {
trace(" ODBC_CONFIG_DSN");
SQLGetPrivateProfileString(
name,
"URL", "", configuration.url, MAX_STRING_LEN,
"ODBC.INI");
SQLGetPrivateProfileString(
name,
"User", "", configuration.user, MAX_STRING_LEN,
"ODBC.INI");
SQLGetPrivateProfileString(
name,
"Password", "", configuration.password, MAX_STRING_LEN,
"ODBC.INI");
} else if(fRequest==ODBC_ADD_DSN) {
// ok
trace(" ODBC_ADD_DSN");
} else {
// error
trace(" ?");
return FALSE;
}
HMODULE module = GetModuleHandle("h2odbc");
if(hwndParent) {
int result=DialogBoxParam(module,
MAKEINTRESOURCE(IDD_CONFIG),
hwndParent,
(DLGPROC)ConfigDlgProc,
(LPARAM)&configuration);
if(result != IDOK) {
trace(" result != IDOK, %d lastError=%d", result, GetLastError());
return TRUE;
}
}
trace(" SQLRemoveDSNFromIni...");
SQLRemoveDSNFromIni(name);
SQLWriteDSNToIni(configuration.name,lpszDriver);
SQLWritePrivateProfileString(
configuration.name, "URL", configuration.url,
"ODBC.INI");
SQLWritePrivateProfileString(
configuration.name, "User", configuration.user,
"ODBC.INI");
SQLWritePrivateProfileString(
configuration.name, "Password", configuration.password,
"ODBC.INI");
// TODO: temp hack (because m_dll is 0?)
// SQLRemoveDSNFromIni(name);
// SQLWriteDSNToIni("Test",lpszDriver);
// SQLWritePrivateProfileString(
// configuration.name, "URL", "jdbc:h2:localhost:9082",
// "ODBC.INI");
// SQLWritePrivateProfileString(
// configuration.name, "User", "sa",
// "ODBC.INI");
// SQLWritePrivateProfileString(
// configuration.name, "Password", "123",
// "ODBC.INI");
trace(" return TRUE");
return TRUE;
}
LIBRARY h2odbc
EXPORTS
DllMain
ConfigDriver
ConfigDSN
SQLAllocHandle
SQLBindCol
SQLBindParameter
SQLCancel
SQLCloseCursor
SQLColAttribute
SQLColumns
SQLConnect
SQLCopyDesc
SQLDescribeCol
SQLDriverConnect
SQLDisconnect
SQLEndTran
SQLExecDirect
SQLExecute
SQLFetch
SQLFetchScroll
SQLFreeHandle
SQLFreeStmt
SQLGetConnectAttr
SQLGetCursorName
SQLGetData
SQLGetDescField
SQLGetDescRec
SQLGetDiagField
SQLGetDiagRec
SQLGetEnvAttr
SQLGetInfo
SQLGetStmtAttr
SQLGetTypeInfo
SQLNumResultCols
SQLNativeSql
SQLNumParams
SQLParamData
SQLPrepare
SQLPutData
SQLRowCount
SQLSetConnectAttr
SQLSetCursorName
SQLSetDescField
SQLSetDescRec
SQLSetEnvAttr
SQLSetStmtAttr
SQLSpecialColumns
SQLStatistics
SQLTables
差异被折叠。
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
*/
#include "h2odbc.h"
HINSTANCE m_dll = 0;
/*
static FILE* m_logfile=NULL;
void trace(char* message,...) {
if(m_logfile==NULL) {
m_logfile=fopen("C:\\h2odbc.log","a+");
}
va_list valist;
va_start(valist,message);
vfprintf(m_logfile,message, valist);
fprintf(m_logfile,"\r\n");
va_end(valist);
fflush(m_logfile);
}
*/
bool initialized = false;
bool traceOn = false;
#define BUFFER_SIZE 1024
char tracePath[BUFFER_SIZE+1];
void initTrace() {
if(initialized) {
return;
}
char* key = "Software\\H2\\ODBC";
HKEY hk;
DWORD dwDisp;
if (RegCreateKeyEx(HKEY_CURRENT_USER, key,
0, NULL, REG_OPTION_NON_VOLATILE,
KEY_WRITE, NULL, &hk, &dwDisp) != ERROR_SUCCESS) {
return;
}
if (RegOpenKeyEx(HKEY_CURRENT_USER, key, 0, KEY_QUERY_VALUE, &hk) != ERROR_SUCCESS) {
initialized = true;
return;
}
DWORD bufferSize = BUFFER_SIZE;
if(RegQueryValueEx(hk, "LogFile", NULL, NULL, (BYTE*)tracePath, &bufferSize) != ERROR_SUCCESS) {
RegCloseKey(hk);
initialized = true;
return;
}
tracePath[bufferSize] = 0;
RegCloseKey(hk);
traceOn = bufferSize > 0;
initialized = true;
}
void trace(char* message,...) {
initTrace();
if(!traceOn) {
return;
}
FILE* log = fopen(tracePath,"a+");
va_list valist;
va_start(valist,message);
vfprintf(log,message, valist);
fprintf(log,"\r\n");
va_end(valist);
fflush(log);
fclose(log);
}
int WINAPI DllMain(HINSTANCE hInst,DWORD fdwReason,PVOID pvReserved) {
if(fdwReason==DLL_PROCESS_ATTACH) {
m_dll=hInst;
}
return 1;
}
int _export FAR PASCAL libmain(HANDLE hModule,short cbHeapSize,
SQLCHAR FAR *lszCmdLine) {
trace("libmain");
m_dll = (HINSTANCE) hModule;
return TRUE;
}
void Connection::appendStatement() {
Statement* s=new Statement(this);
m_stats.push_back(s);
}
void Connection::removeStatement(int i) {
delete m_stats[i];
m_stats.erase(m_stats.begin()+i);
}
void Connection::open(string name, string user, string password) {
trace("Connection::open");
m_name=name;
m_user=user;
m_password=password;
trace("url=%s user=%s", (char*)m_name.data(), (char*)m_user.data());
string prefix = "jdbc:h2:odbc://";
if(strncmp((char*)name.data(), (char*)prefix.data(), prefix.length()) != 0) {
trace("url does not start with prefix");
m_state == C_CLOSED;
return;
}
string server = name.substr(prefix.length());
trace("server %s", (char*)server.data());
int dbnameIdx = server.find('/');
if(dbnameIdx <= 0) {
trace("url does not contain '/'");
setError("Wrong URL format");
m_state == C_CLOSED;
return;
}
string dbname = server.substr(dbnameIdx+1);
trace("dbname %s", dbname.data());
server = server.substr(0, dbnameIdx);
int portIdx = server.find(':');
trace("portIdx %d", portIdx);
int port = 9082;
if(portIdx != 0) {
string portString = server.substr(portIdx+1);
trace("portString %s", (char*)portString.data());
port = atoi((char*)portString.data());
trace("port %d", port);
server = server.substr(0, portIdx);
trace("server %s", server.data());
}
m_socket = new Socket(server.data(), port);
if(m_socket->isClosed()) {
setError(E_08001); // unable to establish
m_state == C_CLOSED;
return;
}
m_socket->writeByte('C');
m_socket->writeString(dbname.data())->writeString(m_user.data())->writeString(m_password.data());
int result = m_socket->readByte();
if(result=='O') {
trace("ok!");
m_state == C_OPEN;
} else {
trace("error");
setError(E_08004); // rejected
m_state == C_CLOSED;
}
}
void Connection::setAutoCommit(bool autocommit) {
if(autocommit != m_autoCommit) {
m_socket->writeByte('A');
m_socket->writeByte(autocommit ? '1' : '0');
m_autoCommit=autocommit;
}
}
void Connection::commit() {
m_socket->writeByte('A');
m_socket->writeByte('C');
}
void Connection::rollback() {
m_socket->writeByte('A');
m_socket->writeByte('R');
}
void Connection::close() {
if(m_state == C_OPEN) {
m_socket->close();
m_state=C_CLOSED;
}
}
string Connection::getNativeSQL(const char* sql) {
Socket* s = m_socket;
s->writeByte('M');
s->writeByte('N');
s->writeString(sql);
string native = s->readString();
return native;
}
Environment* Environment::cast(void* pointer) {
if(pointer==0) {
return 0;
}
Environment* env=(Environment*)pointer;
if(env->m_magic!=MAGIC_ENVIRONMENT) {
return 0;
}
return env;
}
Connection* Connection::cast(void* pointer) {
if(pointer==0) {
return 0;
}
Connection* conn=(Connection*)pointer;
if(conn->m_magic!=MAGIC_CONNECTION) {
return 0;
}
return conn;
}
Connection::Connection(Environment* e) {
m_magic = MAGIC_CONNECTION;
m_environment = e;
m_state = C_INIT;
m_error = 0;
}
Connection::~Connection() {
if(m_magic==MAGIC_CONNECTION) {
m_magic=0;
} else {
trace("~Connection %d",m_magic);
return;
}
}
Environment::Environment() {
m_magic=MAGIC_ENVIRONMENT;
}
Environment::~Environment() {
if(m_magic==MAGIC_ENVIRONMENT) {
m_magic=0;
} else {
trace("~Environment %d",m_magic);
return;
}
}
Connection* Environment::createConnection() {
m_openConnections++;
return new Connection(this);
}
void Environment::closeConnection(Connection* conn) {
delete conn;
m_openConnections--;
}
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
*/
#include "h2odbc.h"
char convertBuffer[512];
Descriptor* Descriptor::cast(void* pointer) {
if(pointer==0) {
return 0;
}
Descriptor* desc=Descriptor::cast(pointer);
if(desc->m_magic!=MAGIC_DESCRIPTOR) {
return 0;
}
return desc;
}
Descriptor::Descriptor(Connection* c) {
init();
m_connection = c;
m_type = DT_SHARED;
}
Descriptor::Descriptor() {
init();
m_type = DT_DEFAULT;
}
void Descriptor::init() {
m_magic = MAGIC_DESCRIPTOR;
m_state = D_ACTIVE;
m_arraySize = 0;
m_statusPointer = 0;
m_rowsProcessedPointer = 0;
m_rowWiseBinding = false;
m_rowSize = 0;
m_id = 0;
m_count = 0;
m_error = 0;
}
void Descriptor::setBindingType(bool rowWiseBinding, int rowSize) {
m_rowWiseBinding = rowWiseBinding;
m_rowSize = rowSize;
}
Descriptor::~Descriptor() {
if(m_magic==MAGIC_DESCRIPTOR) {
m_magic=0;
} else {
trace("~Descriptor %d",m_magic);
return;
}
for(int i=0;i<m_records.size();i++) {
delete m_records[i];
m_records[i]=0;
}
}
void Descriptor::readData(int i, Socket* s) {
m_records[i]->readData(s);
}
DescriptorRecord* DescriptorRecord::cast(void* pointer) {
if(pointer==0) {
return 0;
}
DescriptorRecord* rec=(DescriptorRecord*)pointer;
if(rec->m_magic!=MAGIC_DESCRIPTOR_RECORD) {
return 0;
}
return rec;
}
void DescriptorRecord::sendParameterValue(Socket* s) {
int length = m_targetBufferLength;
if(m_statusPointer != 0) {
if(*m_statusPointer == SQL_NULL_DATA) {
s->writeInt(0);
trace(" write null");
return;
} else if(*m_statusPointer == SQL_NTS) {
trace(" len=max");
length = m_targetBufferLength;
} else if(*m_statusPointer == SQL_DEFAULT_PARAM) {
trace(" len=SQL_DEFAULT_PARAM TODO");
length = m_targetBufferLength;
} else if(*m_statusPointer == SQL_DATA_AT_EXEC) {
trace(" len=SQL_DATA_AT_EXEC TODO");
length = m_targetBufferLength;
} else {
length = *m_statusPointer;
trace(" len = %d", length);
}
}
if(m_pointer == 0) {
trace(" pointer==0 TODO");
s->writeInt(0);
return;
}
switch(m_cDataType) {
case SQL_C_SHORT: {
SQLSMALLINT i = *((SQLSMALLINT*)m_pointer);
trace(" write smallInt %d", i);
s->writeInt(SQL_INTEGER);
s->writeInt(i);
break;
}
case SQL_C_LONG: {
SQLINTEGER i = *((SQLINTEGER*)m_pointer);
trace(" write int %d", i);
s->writeInt(SQL_INTEGER);
s->writeInt(i);
break;
}
case SQL_C_CHAR: {
if(length < 0) {
trace(" write String with buffer %d TODO", length);
s->writeInt(0);
} else {
char buff[length+1];
strncpy(buff, (char*)m_pointer, length);
buff[length] = 0;
trace(" write string %s", buff);
s->writeInt(SQL_VARCHAR);
s->writeString(buff);
}
break;
}
default:
trace(" unsupported data type %d", m_cDataType);
}
}
const char* DescriptorRecord::getPrefix() {
return getSuffix();
}
const char* DescriptorRecord::getSuffix() {
switch(m_sqlDataType) {
case SQL_VARCHAR:
case SQL_TYPE_DATE:
case SQL_TYPE_TIME:
case SQL_TYPE_TIMESTAMP:
return ",";
case SQL_DECIMAL:
case SQL_NUMERIC:
case SQL_BIT:
case SQL_TINYINT:
case SQL_SMALLINT:
case SQL_INTEGER:
case SQL_BIGINT:
case SQL_REAL:
case SQL_FLOAT:
case SQL_DOUBLE:
default:
return "";
}
}
int DescriptorRecord::getLength() {
switch(m_sqlDataType) {
case SQL_VARCHAR:
return 255;
case SQL_DECIMAL:
case SQL_NUMERIC:
return 100;
case SQL_BIT:
return 1;
case SQL_TINYINT:
return 3;
case SQL_SMALLINT:
return 5;
case SQL_INTEGER:
return 10;
case SQL_BIGINT:
return 20;
case SQL_REAL:
return 7;
case SQL_FLOAT:
case SQL_DOUBLE:
return 15;
case SQL_TYPE_DATE:
return 10;
case SQL_TYPE_TIME:
return 8;
case SQL_TYPE_TIMESTAMP:
return 40;
default:
return 255;
}
}
void DescriptorRecord::copyData(DescriptorRecord* ar) {
if(m_wasNull) {
ar->setNull();
} else {
switch(ar->m_cDataType) {
case SQL_C_CHAR:
trace(" SQL_CHAR / SQL_VARCHAR");
returnString((SQLCHAR*)ar->m_pointer, ar->m_targetBufferLength, ar->m_statusPointer, getString());
break;
case SQL_C_SLONG:
case SQL_C_ULONG:
trace(" SQL_INTEGER");
returnInt(ar->m_pointer, ar->m_statusPointer, getInt());
break;
case SQL_C_SSHORT:
trace(" SQL_SMALLINT");
returnSmall((SQLSMALLINT*)ar->m_pointer, ar->m_statusPointer, getInt());
break;
default:
trace(" ard not set");
}
}
}
void DescriptorRecord::setNull() {
if(m_statusPointer != 0) {
*m_statusPointer = SQL_NULL_DATA;
}
}
void DescriptorRecord::readData(Socket* s) {
m_wasNull = false;
switch(m_sqlDataType) {
case 0: {
trace(" read null");
m_wasNull = true;
m_dataInt = 0;
break;
}
case SQL_SMALLINT: {
trace(" read smallInt");
m_wasNull = s->readBool();
if(m_wasNull) {
m_dataInt = 0;
} else {
m_dataInt = s->readInt();
}
break;
}
case SQL_INTEGER: {
trace(" read int");
m_wasNull = s->readBool();
if(m_wasNull) {
m_dataInt = 0;
} else {
m_dataInt = s->readInt();
}
break;
}
case SQL_VARCHAR: {
m_dataString = s->readString();
trace(" read string=%s", (char*)m_dataString.data());
break;
}
default:
trace(" unsupported data type %d", (char*)m_dataString.data());
}
}
void DescriptorRecord::readMeta(Socket* s) {
m_sqlDataType = s->readInt();
m_tableName = s->readString();
m_name = s->readString();
m_columnName = m_name;
m_precision = s->readInt();
m_scale = s->readInt();
m_displaySize = s->readInt();
trace(" %s", m_name.data());
}
char* DescriptorRecord::getString() {
switch(m_sqlDataType) {
case SQL_VARCHAR:
trace(" getString s=%s", (char*)m_dataString.data());
return (char*)m_dataString.data();
case SQL_SMALLINT:
case SQL_INTEGER: {
itoa(m_dataInt, convertBuffer, 10);
trace(" getString int %s", convertBuffer);
return convertBuffer;
}
case 0:
trace(" getString null");
return 0;
default:
trace("unsupported type=%d", m_sqlDataType);
}
return "";
}
int DescriptorRecord::getInt() {
switch(m_sqlDataType) {
case SQL_VARCHAR:
return atoi(m_dataString.data());
case SQL_SMALLINT:
case SQL_INTEGER: {
return m_dataInt;
}
case 0:
return 0;
default:
trace("unsupported type=%d", m_sqlDataType);
return 0;
}
}
bool DescriptorRecord::hasFixedPrecisionScale() {
switch(m_sqlDataType) {
case SQL_VARCHAR:
case SQL_INTEGER:
case SQL_SMALLINT:
case 0:
return false;
default:
trace("unsupported type=%d", m_sqlDataType);
return false;
}
}
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
*/
#include "h2odbc.h"
Statement::Statement(Connection* c) {
m_magic=MAGIC_STATEMENT;
m_connection=c;
m_appRow=&m_appRowDefault;
m_impRow=&m_impRowDefault;
m_appParam=&m_appParamDefault;
m_impParam=&m_impParamDefault;
m_columnCount = 0;
m_updateCount = 0;
m_resultSetId = -1;
m_preparedId = 0;
m_rowId = 0;
m_hasResultSet = false;
m_parameterCount = 0;
m_useBookmarks = false;
m_error = 0;
}
Statement::~Statement() {
if(m_magic==MAGIC_STATEMENT) {
m_magic=0;
} else {
trace("~Statement %d",m_magic);
return;
}
}
Statement* Statement::cast(void* pointer) {
if(pointer==0) {
return 0;
}
Statement* stat=(Statement*)pointer;
if(stat->m_magic!=MAGIC_STATEMENT) {
return 0;
}
return stat;
}
void Statement::processResultSet(Socket* s) {
m_rowId = 0;
m_updateCount = 0;
m_state = S_EXECUTED;
m_hasResultSet = true;
m_resultSetId = s->readInt();
m_columnCount = s->readInt();
trace(" ResultSet id=%d cols=%d", m_resultSetId, m_columnCount);
m_impRow->clearRecords();
m_appRow->clearRecords();
for(int i=0; i<m_columnCount; i++) {
DescriptorRecord* rec = new DescriptorRecord(m_impRow);
rec->readMeta(s);
m_impRow->addRecord(rec);
rec = new DescriptorRecord(m_appRow);
m_appRow->addRecord(rec);
}
trace(" imp=%d app=%d", m_impRow->getRecordCount(), m_appRow->getRecordCount());
}
void Statement::getMetaTables(char* catalog, char* schema, char* table, char* tabletypes) {
Socket* s = m_connection->getSocket();
s->writeByte('M');
s->writeByte('T');
s->writeString(catalog);
s->writeString(schema);
s->writeString(table);
s->writeString(tabletypes);
processResultSet(s);
}
void Statement::getMetaBestRowIdentifier(char* catalog, char* schema, char* table, int scope, bool nullable) {
Socket* s = m_connection->getSocket();
s->writeByte('M');
s->writeByte('B');
s->writeString(catalog);
s->writeString(schema);
s->writeString(table);
s->writeInt(scope);
s->writeBool(nullable);
processResultSet(s);
}
void Statement::getMetaVersionColumns(char* catalog, char* schema, char* table) {
Socket* s = m_connection->getSocket();
s->writeByte('M');
s->writeByte('V');
s->writeString(catalog);
s->writeString(schema);
s->writeString(table);
processResultSet(s);
}
void Statement::getMetaIndexInfo(char* catalog, char* schema, char* table, bool unique, bool approximate) {
Socket* s = m_connection->getSocket();
s->writeByte('M');
s->writeByte('I');
s->writeString(catalog);
s->writeString(schema);
s->writeString(table);
s->writeBool(unique);
s->writeBool(approximate);
processResultSet(s);
}
void Statement::getMetaColumns(char* catalog, char* schema, char* table, char* column) {
Socket* s = m_connection->getSocket();
s->writeByte('M');
s->writeByte('C');
s->writeString(catalog);
s->writeString(schema);
s->writeString(table);
s->writeString(column);
processResultSet(s);
}
void Statement::getMetaTypeInfoAll() {
Socket* s = m_connection->getSocket();
s->writeByte('M');
s->writeByte('D');
s->writeByte('A');
processResultSet(s);
}
void Statement::getMetaTypeInfo(int sqlType) {
Socket* s = m_connection->getSocket();
s->writeByte('M');
s->writeByte('D');
s->writeByte('T');
s->writeInt(sqlType);
processResultSet(s);
}
const char* Statement::getSQL() {
return m_sql.data();
}
bool Statement::prepare(char* sql) {
Socket* s = m_connection->getSocket();
m_state = S_PREPARED;
s->writeByte('P');
s->writeString(sql);
m_sql = sql;
int result = s->readByte();
if(result=='E') {
m_parameterCount = 0;
m_state = S_CLOSED;
setError(E_42000);
return false;
} else if(result=='O') {
m_preparedId = s->readInt();
m_parameterCount = s->readInt();
m_impParam->clearRecords();
m_appParam->clearRecords();
trace(" prepared %d params=%d", m_preparedId, m_parameterCount);
}
return true;
}
void Statement::addParameter() {
m_impParam->addRecord(new DescriptorRecord(m_impParam));
m_appParam->addRecord(new DescriptorRecord(m_appParam));
}
bool Statement::executePrepared() {
Socket* s = m_connection->getSocket();
s->writeByte('Q');
s->writeInt(m_preparedId);
trace(" executePrepared %d", m_preparedId);
Descriptor* desc = getAppParamDesc();
for(int i=0; i<m_parameterCount; i++) {
s->writeByte('1');
s->writeInt(i);
DescriptorRecord* rec = desc->getRecord(i);
rec->sendParameterValue(s);
}
// end of parameters
s->writeByte('0');
int result = s->readByte();
// TODO: this is copied source code from execute!
m_state = S_EXECUTED;
m_rowId = 0;
m_resultSetId = 0;
m_columnCount = 0;
m_updateCount = 0;
if(result=='E') {
m_state = S_CLOSED;
setError(E_42000);
return false;
} else if(result=='R') {
processResultSet(s);
} else if(result=='U') {
m_state = S_EXECUTED;
m_hasResultSet = false;
m_updateCount = s->readInt();
}
return true;
}
bool Statement::execute(char* sql) {
Socket* s = m_connection->getSocket();
s->writeByte('E');
s->writeString(sql);
m_sql = sql;
int result = s->readByte();
m_state = S_EXECUTED;
m_rowId = 0;
m_resultSetId = 0;
m_columnCount = 0;
m_updateCount = 0;
m_parameterCount = 0;
if(result=='E') {
m_state = S_CLOSED;
// TODO set correct error
setError(E_42000);
return false;
} else if(result=='R') {
processResultSet(s);
} else if(result=='U') {
m_state = S_EXECUTED;
m_hasResultSet = false;
m_updateCount = s->readInt();
} else if(result=='O') {
m_preparedId = s->readInt();
m_parameterCount = s->readInt();
trace(" executeDirect prepared %d params=%d", m_preparedId, m_parameterCount);
return executePrepared();
}
return true;
}
bool Statement::next() {
if(!m_hasResultSet) {
return false;
}
m_rowId++;
Socket* s = m_connection->getSocket();
s->writeByte('G');
s->writeInt(m_resultSetId);
int result = s->readByte();
trace(" next %c", result);
if(result=='E') {
m_state = S_CLOSED;
return false;
} else if(result == '1') {
for(int i=0; i<m_columnCount; i++) {
m_impRow->readData(i, s);
m_impRow->getRecord(i)->copyData(m_appRow->getRecord(i));
}
trace(" setStatus");
m_impRow->setStatus(SQL_ROW_SUCCESS);
trace(" setRowsProcessed");
m_impRow->setRowsProcessed(1);
return true;
} else {
m_impRow->setStatus(SQL_ROW_NOROW);
m_impRow->setRowsProcessed(0);
return false;
}
return m_resultSetId == 0;
}
void Statement::closeCursor() {
if(m_resultSetId >= 0) {
Socket* s = m_connection->getSocket();
s->writeByte('F');
s->writeInt(m_resultSetId);
m_resultSetId = -1;
}
m_state=S_CLOSED;
}
Descriptor* Statement::getAppRowDesc() {
return m_appRow;
}
Descriptor* Statement::getImpRowDesc() {
return m_impRow;
}
Descriptor* Statement::getAppParamDesc() {
return m_appParam;
}
Descriptor* Statement::getImpParamDesc() {
return m_impParam;
}
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
*/
#define IDD_CONFIG 101
#define IDI_ICON 102
#define IDC_URL 1000
#define IDC_NAME 1001
#define IDC_USER 1002
#define IDC_PASSWORD 1003
#include "resource.h"
#include <windows.h>
#include <afxres.h>
IDD_CONFIG DIALOG DISCARDABLE 0, 0, 251, 119
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Database Driver Configuration"
FONT 8, "MS Sans Serif"
BEGIN
EDITTEXT IDC_NAME,81,7,163,14,ES_AUTOHSCROLL
EDITTEXT IDC_URL,81,34,163,14,ES_AUTOHSCROLL
EDITTEXT IDC_USER,81,50,163,14,ES_AUTOHSCROLL
EDITTEXT IDC_PASSWORD,81,66,163,14,ES_PASSWORD | ES_AUTOHSCROLL
DEFPUSHBUTTON "OK",IDOK,137,98,50,14
PUSHBUTTON "Cancel",IDCANCEL,194,98,50,14
LTEXT "Database URL:", IDC_STATIC,7,37,72,8
LTEXT "Data Source Name:",IDC_STATIC,7,10,70,8
LTEXT "User Name:",IDC_STATIC,7,53,71,8
LTEXT "Password:",IDC_STATIC,7,69,71,8
CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ | SS_SUNKEN |
WS_GROUP,7,87,237,1
CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ | SS_SUNKEN |
WS_GROUP,7,27,236,1
END
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
*/
#include "h2odbc.h"
bool m_socket_init = false;
Socket::Socket(const char* host,int port) {
if(!m_socket_init) {
initSockets();
m_socket_init = true;
}
m_socket=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
if(m_socket==INVALID_SOCKET) {
setError("socket");
return;
}
// check if it's an IP number (because that's simpler)
// could be also IPv6 or something, if Winsocks supports that
// also supported is 0x4.0x3.0x2.0x10
SOCKADDR_IN sin;
memset((void*)&sin,0,sizeof(sin));
sin.sin_family=AF_INET;
sin.sin_port=htons(port);
long addr=inet_addr(host);
if(addr=!INADDR_NONE) {
sin.sin_addr.s_addr=addr;
} else {
// ok then it's hopefully a host name
HOSTENT* hostent;
hostent=gethostbyname(host);
if(hostent==NULL) {
setError("gethostbyname");
return;
}
// take the first ip address
memcpy(
&sin.sin_addr,
hostent->h_addr_list[0],
hostent->h_length);
}
int result=connect(m_socket,(sockaddr*)&sin,sizeof(sin));
if(result==SOCKET_ERROR) {
setError("connect");
return;
}
}
void Socket::close() {
if(m_socket==0) {
return;
}
closesocket(m_socket);
m_socket=0;
}
int Socket::readByte() {
if(m_socket==0) {
return -1;
}
char buffer[1];
read(buffer,1);
// trace(" readByte=%c", buffer[0]);
return buffer[0];
}
int Socket::readInt() {
if(m_socket==0) {
return -1;
}
char buffer[4];
read(buffer, 4);
int x = ((buffer[0] & 0xff) << 24) | ((buffer[1] & 0xff) << 16) |
((buffer[2] & 0xff) << 8) | (buffer[3] & 0xff);
return x;
}
void Socket::read(char* buffer, int len) {
if(m_socket==0) {
return;
}
do {
int result=recv(m_socket,buffer,len,0);
if(result==0) {
// closed?
setError("recv");
return;
} else if(result==SOCKET_ERROR) {
setError("recv");
return;
}
len-=result;
buffer+=result;
} while(len>0);
}
Socket* Socket::writeString(const char* string) {
// trace(" writeString %s", string);
int len = strlen(string);
writeInt(len);
write(string, len);
return this;
}
string Socket::readString() {
if(m_socket==0) {
return "";
}
int len = readInt();
if(len<0) {
len = 0;
}
char buffer[len+1];
if(len==0) {
buffer[0]=0;
} else {
read(buffer, len);
buffer[len] = 0;
}
// trace(" readString len=%d s=%s", len, buffer);
return buffer;
}
Socket* Socket::writeByte(int byte) {
// trace(" writeByte %c", byte);
char buffer[1];
buffer[0]=byte;
write(buffer, 1);
return this;
}
Socket* Socket::writeBool(bool x) {
// trace(" writeBoox %d", x ? 1 : 0);
writeInt(x ? 1 : 0);
return this;
}
bool Socket::readBool() {
return readInt() == 1;
}
Socket* Socket::writeInt(int x) {
// trace(" writeInt=%d", x);
char buffer[4];
buffer[0] = (x >> 24) & 0xff;
buffer[1] = (x >> 16) & 0xff;
buffer[2] = (x >> 8) & 0xff;
buffer[3] = x & 0xff;
write(buffer, 4);
return this;
}
void Socket::write(const char* buffer, int len) {
if(m_socket==0) {
return;
}
do {
int result=send(m_socket,buffer,len,0);
if(result==SOCKET_ERROR) {
setError("send");
return;
}
len-=result;
buffer+=result;
} while(len>0);
}
void Socket::setError(char* where) {
m_socket=0;
int error=WSAGetLastError();
trace("Socket error %d in %s", error, where);
}
void initSockets() {
trace("initSockets");
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD( 1, 1 );
int err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
trace("No Winsock.dll");
return;
}
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 ) {
trace("No Winsock.dll v1.1");
WSACleanup( );
return;
}
}
差异被折叠。
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
*/
#include "h2odbc.h"
SQLRETURN SQLColAttribute (
SQLHSTMT StatementHandle,
SQLUSMALLINT ColumnNumber,
SQLUSMALLINT FieldIdentifier,
SQLPOINTER CharacterAttributePtr,
SQLSMALLINT BufferLength,
SQLSMALLINT* StringLengthPtr,
SQLPOINTER NumericAttributePtr) {
trace("SQLColAttribute col=%d", ColumnNumber);
Statement* stat=Statement::cast(StatementHandle);
if(stat==0) {
return SQL_INVALID_HANDLE;
}
stat->setError(0);
Descriptor* desc = stat->getImpRowDesc();
ColumnNumber--;
if(ColumnNumber > stat->getColumnCount()) {
trace(" columnCount=%d", stat->getColumnCount());
return SQL_ERROR;
}
DescriptorRecord* rec = desc->getRecord(ColumnNumber);
switch(FieldIdentifier) {
case SQL_DESC_AUTO_UNIQUE_VALUE:
trace(" SQL_DESC_AUTO_UNIQUE_VALUE");
returnInt(NumericAttributePtr, SQL_FALSE);
break;
case SQL_DESC_BASE_COLUMN_NAME:
trace(" SQL_DESC_BASE_COLUMN_NAME");
returnString((SQLCHAR*)CharacterAttributePtr, BufferLength, StringLengthPtr, "");
break;
case SQL_DESC_BASE_TABLE_NAME:
trace(" SQL_DESC_BASE_TABLE_NAME");
returnString((SQLCHAR*)CharacterAttributePtr, BufferLength, StringLengthPtr, "");
break;
case SQL_DESC_CASE_SENSITIVE:
trace(" SQL_DESC_CASE_SENSITIVE");
returnInt(NumericAttributePtr, SQL_TRUE);
break;
case SQL_DESC_CATALOG_NAME:
trace(" SQL_DESC_CATALOG_NAME");
returnString((SQLCHAR*)CharacterAttributePtr, BufferLength, StringLengthPtr, "");
break;
case SQL_DESC_CONCISE_TYPE:
trace(" SQL_DESC_CONCISE_TYPE");
returnInt(NumericAttributePtr, rec->getSqlDataType());
break;
case SQL_DESC_COUNT:
trace(" SQL_DESC_COUNT");
returnInt(NumericAttributePtr, stat->getColumnCount());
break;
case SQL_DESC_DISPLAY_SIZE:
trace(" SQL_DESC_DISPLAY_SIZE");
returnInt(NumericAttributePtr, rec->getDisplaySize());
break;
case SQL_DESC_FIXED_PREC_SCALE:
trace(" SQL_DESC_FIXED_PREC_SCALE");
returnInt(NumericAttributePtr, rec->hasFixedPrecisionScale() ? SQL_TRUE : SQL_FALSE);
break;
case SQL_DESC_LABEL:
trace(" SQL_DESC_LABEL");
returnString((SQLCHAR*)CharacterAttributePtr, BufferLength, StringLengthPtr, rec->getColumnName().data());
break;
case SQL_DESC_LENGTH:
trace(" SQL_DESC_LENGTH =%d", rec->getLength());
returnInt(NumericAttributePtr, rec->getLength());
break;
case SQL_DESC_LITERAL_PREFIX:
trace(" SQL_DESC_LITERAL_PREFIX %s", rec->getPrefix());
returnString((SQLCHAR*)CharacterAttributePtr, BufferLength, StringLengthPtr, rec->getPrefix());
break;
case SQL_DESC_LITERAL_SUFFIX:
trace(" SQL_DESC_LITERAL_SUFFIX %s", rec->getSuffix());
returnString((SQLCHAR*)CharacterAttributePtr, BufferLength, StringLengthPtr, rec->getSuffix());
break;
case SQL_DESC_LOCAL_TYPE_NAME:
trace(" SQL_DESC_LOCAL_TYPE_NAME TODO");
returnString((SQLCHAR*)CharacterAttributePtr, BufferLength, StringLengthPtr, "DataType");
break;
case SQL_DESC_NAME:
trace(" SQL_DESC_LOCAL_TYPE_NAME");
returnString((SQLCHAR*)CharacterAttributePtr, BufferLength, StringLengthPtr, rec->getColumnName().data());
break;
case SQL_DESC_NULLABLE:
trace(" SQL_DESC_NULLABLE TODO");
returnInt(NumericAttributePtr, SQL_NULLABLE_UNKNOWN);
break;
case SQL_DESC_NUM_PREC_RADIX:
trace(" SQL_DESC_NUM_PREC_RADIX TODO");
returnInt(NumericAttributePtr, 10);
break;
case SQL_DESC_OCTET_LENGTH:
trace(" SQL_DESC_OCTET_LENGTH TODO");
returnInt(NumericAttributePtr, 255);
break;
case SQL_DESC_PRECISION:
trace(" SQL_DESC_PRECISION");
returnInt(NumericAttributePtr, rec->getPrecision());
break;
case SQL_DESC_SCALE:
trace(" SQL_DESC_SCALE");
returnInt(NumericAttributePtr, rec->getScale());
break;
case SQL_DESC_SCHEMA_NAME:
trace(" SQL_DESC_SCHEMA_NAME");
returnString((SQLCHAR*)CharacterAttributePtr, BufferLength, StringLengthPtr, "");
break;
case SQL_DESC_SEARCHABLE:
trace(" SQL_DESC_SEARCHABLE");
returnInt(NumericAttributePtr, SQL_PRED_SEARCHABLE);
break;
case SQL_DESC_TABLE_NAME:
trace(" SQL_DESC_TABLE_NAME");
returnString((SQLCHAR*)CharacterAttributePtr, BufferLength, StringLengthPtr, rec->getTableName().data());
break;
case SQL_DESC_TYPE:
trace(" SQL_DESC_TYPE %d", rec->getSqlDataType());
returnInt(NumericAttributePtr, rec->getSqlDataType());
break;
case SQL_DESC_TYPE_NAME:
trace(" SQL_DESC_TYPE_NAME TODO");
returnString((SQLCHAR*)CharacterAttributePtr, BufferLength, StringLengthPtr, "VARCHAR");
break;
case SQL_DESC_UNNAMED:
trace(" SQL_DESC_UNNAMED TODO");
returnInt(NumericAttributePtr, SQL_NAMED);
break;
case SQL_DESC_UNSIGNED:
trace(" SQL_DESC_UNSIGNED");
returnInt(NumericAttributePtr, SQL_FALSE);
break;
case SQL_DESC_UPDATABLE:
trace(" SQL_DESC_UPDATABLE TODO");
returnInt(NumericAttributePtr, SQL_ATTR_READONLY);
break;
default:
trace(" FieldIdentifier=? %d TODO", FieldIdentifier);
stat->setError(E_HY091);
return SQL_ERROR;
}
return SQL_SUCCESS;
}
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
*/
#include "h2odbc.h"
SQLRETURN SQL_API SQLSetConnectAttr(SQLHDBC ConnectionHandle,
SQLINTEGER Attribute, SQLPOINTER Value,
SQLINTEGER StringLength) {
trace("SQLSetConnectAttr",(int)Value);
Connection* conn=Connection::cast(ConnectionHandle);
if(conn==0) {
return SQL_INVALID_HANDLE;
}
conn->setError(0);
SQLUINTEGER uint=(SQLUINTEGER)Value;
switch(Attribute) {
case SQL_ATTR_ACCESS_MODE:
trace(" SQL_ATTR_ACCESS_MODE");
if(uint==SQL_MODE_READ_ONLY) {
conn->setReadOnly(true);
}
break;
case SQL_ATTR_ASYNC_ENABLE:
trace(" SQL_ATTR_ASYNC_ENABLE (TODO not supported)");
conn->setError(E_HYC00);
return SQL_ERROR;
break;
case SQL_ATTR_ENABLE_AUTO_IPD:
trace(" SQL_ATTR_AUTO_IPD TODO");
conn->setError(E_HYC00);
return SQL_ERROR;
case SQL_ATTR_AUTO_IPD:
trace(" SQL_ATTR_AUTO_IPD TODO");
conn->setError(E_HYC00);
return SQL_ERROR;
case SQL_ATTR_AUTOCOMMIT:
trace(" SQL_ATTR_AUTOCOMMIT");
if(uint==SQL_AUTOCOMMIT_OFF) {
conn->setAutoCommit(false);
} else if(uint==SQL_AUTOCOMMIT_ON) {
conn->setAutoCommit(true);
}
break;
case SQL_ATTR_CONNECTION_DEAD:
trace(" SQL_ATTR_CONNECTION_DEAD TODO");
// read only
return SQL_ERROR;
case SQL_ATTR_CONNECTION_TIMEOUT:
trace(" SQL_ATTR_CONNECTION_TIMEOUT");
break;
case SQL_ATTR_CURRENT_CATALOG:
trace(" SQL_ATTR_CURRENT_CATALOG TODO");
break;
case SQL_ATTR_LOGIN_TIMEOUT:
trace(" SQL_ATTR_LOGIN_TIMEOUT");
break;
case SQL_ATTR_METADATA_ID:
trace(" SQL_ATTR_METADATA_ID");
break;
case SQL_ATTR_ODBC_CURSORS:
trace(" SQL_ATTR_ODBC_CURSORS");
if((SQLUINTEGER)Value != SQL_CUR_USE_ODBC) {
trace(" not SQL_CUR_USE_ODBC %d", (SQLUINTEGER)Value);
conn->setError(E_01S02);
return SQL_ERROR;
}
break;
case SQL_ATTR_PACKET_SIZE:
trace(" SQL_ATTR_PACKET_SIZE");
break;
case SQL_ATTR_QUIET_MODE:
trace(" SQL_ATTR_QUIET_MODE");
break;
case SQL_ATTR_TRACE:
trace(" SQL_ATTR_TRACE");
break;
case SQL_ATTR_TRACEFILE:
trace(" SQL_ATTR_TRACEFILE");
break;
case SQL_ATTR_TRANSLATE_LIB:
trace(" SQL_ATTR_TRANSLATE_LIB");
break;
case SQL_ATTR_TRANSLATE_OPTION:
trace(" SQL_ATTR_TRANSLATE_OPTION");
break;
case SQL_ATTR_TXN_ISOLATION:
trace(" SQL_ATTR_TXN_ISOLATION");
break;
default:
trace(" ? %d TODO",Attribute);
conn->setError(E_HY092);
return SQL_ERROR;
}
return SQL_SUCCESS;
}
SQLRETURN SQL_API SQLGetConnectAttr(SQLHDBC ConnectionHandle,
SQLINTEGER Attribute, SQLPOINTER Value,
SQLINTEGER BufferLength, SQLINTEGER *StringLength) {
trace("SQLGetConnectAttr");
Connection* conn=Connection::cast(ConnectionHandle);
if(conn==0) {
return SQL_INVALID_HANDLE;
}
conn->setError(0);
switch(Attribute) {
case SQL_ATTR_ACCESS_MODE:
trace(" SQL_ATTR_ACCESS_MODE");
if(conn->getReadOnly()) {
returnInt(Value,StringLength,SQL_MODE_READ_ONLY);
} else {
returnInt(Value,StringLength,SQL_MODE_READ_WRITE);
}
break;
case SQL_ATTR_ASYNC_ENABLE:
trace(" SQL_ATTR_ASYNC_ENABLE");
returnInt(Value, SQL_ASYNC_ENABLE_OFF);
break;
case SQL_ATTR_AUTO_IPD:
trace(" SQL_ATTR_AUTO_IPD");
returnInt(Value, SQL_FALSE);
break;
case SQL_ATTR_AUTOCOMMIT:
trace(" SQL_ATTR_AUTOCOMMIT");
if(conn->getAutoCommit()) {
returnInt(Value,StringLength,SQL_AUTOCOMMIT_ON);
} else {
returnInt(Value,StringLength,SQL_AUTOCOMMIT_OFF);
}
break;
case SQL_ATTR_CONNECTION_DEAD:
trace(" SQL_ATTR_CONNECTION_DEAD");
// TODO: should test if connection is active. now say it's active
returnInt(Value, SQL_CD_FALSE);
break;
case SQL_ATTR_CONNECTION_TIMEOUT:
trace(" SQL_ATTR_CONNECTION_TIMEOUT");
returnInt(Value, 0);
break;
case SQL_ATTR_CURRENT_CATALOG:
trace(" SQL_ATTR_CURRENT_CATALOG (temp:DATA)");
returnString(Value, BufferLength, StringLength, "DATA");
break;
case SQL_ATTR_LOGIN_TIMEOUT:
trace(" SQL_ATTR_LOGIN_TIMEOUT");
returnInt(Value, 0);
break;
case SQL_ATTR_METADATA_ID:
trace(" SQL_ATTR_METADATA_ID");
// TODO: how catalogs are treated. FALSE: catalog can contain patterns (%)
returnInt(Value, SQL_FALSE);
break;
case SQL_ATTR_ODBC_CURSORS:
trace(" SQL_ATTR_ODBC_CURSORS");
returnInt(Value, SQL_CUR_USE_IF_NEEDED);
break;
case SQL_ATTR_PACKET_SIZE:
trace(" SQL_ATTR_PACKET_SIZE");
// TODO should return correct packet size
returnInt(Value, 100);
break;
case SQL_ATTR_QUIET_MODE:
trace(" SQL_ATTR_QUIET_MODE");
// TODO should be a hwnd, 0 means no dialogs, other value means dialogs
returnInt(Value, 0);
break;
case SQL_ATTR_TRACE:
trace(" SQL_ATTR_TRACE");
// TODO should support tracing
returnInt(Value, SQL_OPT_TRACE_OFF);
break;
case SQL_ATTR_TRACEFILE:
trace(" SQL_ATTR_TRACEFILE TODO");
break;
case SQL_ATTR_TRANSLATE_LIB:
trace(" SQL_ATTR_TRANSLATE_LIB TODO");
break;
case SQL_ATTR_TRANSLATE_OPTION:
trace(" SQL_ATTR_TRANSLATE_OPTION TODO");
break;
case SQL_ATTR_TXN_ISOLATION:
trace(" SQL_ATTR_TXN_ISOLATION TODO");
break;
default:
conn->setError(E_HY092);
trace(" ? %d TODO", Attribute);
return SQL_ERROR;
}
conn->setError(0);
return SQL_SUCCESS;
}
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
*/
#include "h2odbc.h"
SQLRETURN SQL_API SQLGetDiagField(SQLSMALLINT HandleType, SQLHANDLE Handle,
SQLSMALLINT RecNumber, SQLSMALLINT DiagIdentifier,
SQLPOINTER DiagInfo, SQLSMALLINT BufferLength,
SQLSMALLINT* StringLength) {
trace("SQLGetDiagField");
if(RecNumber < 0) {
return SQL_ERROR;
}
if(RecNumber > 1) {
trace(" SQL_NO_DATA");
return SQL_NO_DATA;
}
switch(HandleType) {
case SQL_HANDLE_ENV: {
trace(" SQL_HANDLE_ENV TODO");
Environment* env=Environment::cast(Handle);
if(env==0) {
return SQL_INVALID_HANDLE;
}
return SQL_NO_DATA;
}
case SQL_HANDLE_DBC: {
trace(" SQL_HANDLE_DBC TODO");
Connection* conn=Connection::cast(Handle);
if(conn==0) {
return SQL_INVALID_HANDLE;
}
const char* error = conn->getError();
switch(DiagIdentifier) {
case SQL_DIAG_NUMBER:
trace(" SQL_DIAG_NUMBER %d", (error ? 1 : 0));
returnInt(DiagInfo, error ? 1 : 0);
break;
case SQL_DIAG_MESSAGE_TEXT:
trace(" SQL_DIAG_MESSAGE_TEXT");
if(error==0) {
return SQL_NO_DATA;
}
returnString((SQLCHAR*)DiagInfo, BufferLength, StringLength, error + 6);
break;
case SQL_DIAG_NATIVE:
trace(" SQL_DIAG_NATIVE");
if(error==0) {
return SQL_NO_DATA;
}
returnInt(DiagInfo, 0);
break;
case SQL_DIAG_SERVER_NAME:
trace(" SQL_DIAG_SERVER_NAME %s", conn->getDataSourceName().data());
returnString((SQLCHAR*)DiagInfo, BufferLength, StringLength, conn->getDataSourceName().data());
break;
case SQL_DIAG_SQLSTATE:
trace(" SQL_DIAG_SQLSTATE");
if(error==0) {
return SQL_NO_DATA;
}
returnString((SQLCHAR*)DiagInfo, max((int)BufferLength, 6), StringLength, error);
break;
case SQL_DIAG_SUBCLASS_ORIGIN:
trace(" SQL_DIAG_SUBCLASS_ORIGIN");
if(error==0) {
return SQL_NO_DATA;
}
returnString((SQLCHAR*)DiagInfo, BufferLength, StringLength, "ODBC 3.0");
break;
default:
trace(" ? %d", DiagIdentifier);
return SQL_ERROR;
}
return SQL_SUCCESS;
}
case SQL_HANDLE_STMT: {
trace(" SQL_HANDLE_STMT");
Statement* stat=Statement::cast(Handle);
if(stat==0) {
return SQL_INVALID_HANDLE;
}
char* error = stat->getError();
switch(DiagIdentifier) {
case SQL_DIAG_CURSOR_ROW_COUNT:
trace(" SQL_DIAG_CURSOR_ROW_COUNT");
returnInt(DiagInfo, 1);
break;
case SQL_DIAG_DYNAMIC_FUNCTION:
trace(" SQL_DIAG_DYNAMIC_FUNCTION");
returnString((SQLCHAR*)DiagInfo, BufferLength, StringLength, stat->getSQL());
break;
case SQL_DIAG_DYNAMIC_FUNCTION_CODE:
trace(" SQL_DIAG_DYNAMIC_FUNCTION_CODE");
returnInt(DiagInfo, SQL_DIAG_UNKNOWN_STATEMENT);
break;
case SQL_DIAG_NUMBER:
trace(" SQL_DIAG_NUMBER %d", (error ? 1 : 0));
returnInt(DiagInfo, error ? 1 : 0);
break;
case SQL_DIAG_RETURNCODE:
trace(" SQL_DIAG_RETURNCODE TODO");
break;
case SQL_DIAG_ROW_COUNT:
trace(" SQL_DIAG_ROW_COUNT");
returnInt(DiagInfo, stat->getUpdateCount());
break;
case SQL_DIAG_CLASS_ORIGIN:
trace(" SQL_DIAG_CLASS_ORIGIN TODO");
returnString((SQLCHAR*)DiagInfo, BufferLength, StringLength, "ISO 9075");
break;
case SQL_DIAG_COLUMN_NUMBER:
trace(" SQL_DIAG_COLUMN_NUMBER");
returnInt(DiagInfo, stat->getColumnCount());
break;
case SQL_DIAG_CONNECTION_NAME:
trace(" SQL_DIAG_CONNECTION_NAME");
returnString((SQLCHAR*)DiagInfo, BufferLength, StringLength, "");
break;
case SQL_DIAG_MESSAGE_TEXT:
trace(" SQL_DIAG_MESSAGE_TEXT");
if(error==0) {
return SQL_NO_DATA;
}
returnString((SQLCHAR*)DiagInfo, BufferLength, StringLength, error + 6);
break;
case SQL_DIAG_NATIVE:
trace(" SQL_DIAG_NATIVE");
if(error==0) {
return SQL_NO_DATA;
}
returnInt(DiagInfo, 0);
break;
case SQL_DIAG_ROW_NUMBER:
trace(" SQL_DIAG_ROW_NUMBER");
returnInt(DiagInfo, SQL_ROW_NUMBER_UNKNOWN);
break;
case SQL_DIAG_SERVER_NAME:
trace(" SQL_DIAG_SERVER_NAME");
returnString((SQLCHAR*)DiagInfo, BufferLength, StringLength, "");
break;
case SQL_DIAG_SQLSTATE:
trace(" SQL_DIAG_SQLSTATE");
if(error==0) {
return SQL_NO_DATA;
}
returnString((SQLCHAR*)DiagInfo, max((int)BufferLength, 6), StringLength, error);
break;
case SQL_DIAG_SUBCLASS_ORIGIN:
trace(" SQL_DIAG_SUBCLASS_ORIGIN");
if(error==0) {
return SQL_NO_DATA;
}
returnString((SQLCHAR*)DiagInfo, BufferLength, StringLength, "ODBC 3.0");
break;
default:
trace(" ? %d TODO", DiagIdentifier);
return SQL_ERROR;
}
return SQL_SUCCESS;;
}
case SQL_HANDLE_DESC: {
trace(" SQL_HANDLE_DESC");
Descriptor* desc=Descriptor::cast(Handle);
if(desc==0) {
return SQL_INVALID_HANDLE;
}
desc->setError(0);
return SQL_NO_DATA;
}
default:
trace(" ? %d",HandleType);
return SQL_INVALID_HANDLE;
}
}
SQLRETURN SQL_API SQLGetDiagRec(SQLSMALLINT HandleType, SQLHANDLE Handle,
SQLSMALLINT RecNumber, SQLCHAR *Sqlstate,
SQLINTEGER *NativeError, SQLCHAR *MessageText,
SQLSMALLINT BufferLength, SQLSMALLINT *TextLength) {
trace("SQLGetDiagRec %d",RecNumber);
if(RecNumber < 0) {
return SQL_ERROR;
}
if(RecNumber > 1) {
trace(" SQL_NO_DATA");
return SQL_NO_DATA;
}
if(BufferLength < 0) {
return SQL_ERROR;
}
char* error = 0;
switch(HandleType) {
case SQL_HANDLE_ENV: {
trace(" SQL_HANDLE_ENV");
Environment* env=Environment::cast(Handle);
if(env==0) {
trace(" SQL_INVALID_HANDLE");
return SQL_INVALID_HANDLE;
}
error = env->getError();
break;
}
case SQL_HANDLE_DBC: {
trace(" SQL_HANDLE_DBC");
Connection* conn=Connection::cast(Handle);
if(conn==0) {
trace(" SQL_INVALID_HANDLE");
return SQL_INVALID_HANDLE;
}
error = conn->getError();
break;
}
case SQL_HANDLE_STMT: {
trace(" SQL_HANDLE_STMT");
Statement* stat=Statement::cast(Handle);
if(stat==0) {
trace(" SQL_INVALID_HANDLE");
return SQL_INVALID_HANDLE;
}
error = stat->getError();
break;
}
case SQL_HANDLE_DESC: {
trace(" SQL_HANDLE_DESC");
Descriptor* desc=Descriptor::cast(Handle);
if(desc==0) {
trace(" SQL_INVALID_HANDLE");
return SQL_INVALID_HANDLE;
}
error = desc->getError();
break;
}
default:
trace(" ? %d TODO", HandleType);
return SQL_INVALID_HANDLE;
}
if(error == 0) {
trace(" SQL_NO_DATA");
return SQL_NO_DATA;
} else {
returnString(Sqlstate, 6, 0, error);
returnString(MessageText, BufferLength, TextLength, error + 6);
if(NativeError != 0) {
*NativeError = 0;
}
trace(" SQL_SUCCESS %s", MessageText);
return SQL_SUCCESS;
}
}
差异被折叠。
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
*/
#include "h2odbc.h"
SQLRETURN SQL_API SQLGetStmtAttr(SQLHSTMT StatementHandle,
SQLINTEGER Attribute, SQLPOINTER Value,
SQLINTEGER BufferLength, SQLINTEGER* StringLength) {
trace("SQLGetStmtAttr");
Statement* stat=Statement::cast(StatementHandle);
if(stat==0) {
return SQL_INVALID_HANDLE;
}
stat->setError(0);
switch(Attribute) {
case SQL_ATTR_APP_ROW_DESC:
trace(" SQL_ATTR_APP_ROW_DESC");
returnPointer(Value,stat->getAppRowDesc());
break;
case SQL_ATTR_APP_PARAM_DESC:
trace(" SQL_ATTR_APP_PARAM_DESC");
returnPointer(Value,stat->getAppParamDesc());
break;
case SQL_ATTR_IMP_ROW_DESC:
trace(" SQL_ATTR_IMP_ROW_DESC");
returnPointer(Value,stat->getImpRowDesc());
break;
case SQL_ATTR_IMP_PARAM_DESC:
trace(" SQL_ATTR_IMP_PARAM_DESC");
returnPointer(Value,stat->getImpParamDesc());
break;
case SQL_ATTR_QUERY_TIMEOUT:
trace(" SQL_ATTR_QUERY_TIMEOUT");
returnInt(Value,StringLength,0);
break;
case SQL_ATTR_ASYNC_ENABLE:
trace(" SQL_ATTR_ASYNC_ENABLE TODO");
break;
case SQL_ATTR_CONCURRENCY:
trace(" SQL_ATTR_CONCURRENCY");
returnInt(Value, SQL_CONCUR_READ_ONLY);
break;
case SQL_ATTR_CURSOR_SCROLLABLE:
trace(" SQL_ATTR_CURSOR_SCROLLABLE TODO");
break;
case SQL_ATTR_CURSOR_SENSITIVITY:
trace(" SQL_ATTR_CURSOR_SENSITIVITY");
returnInt(Value, SQL_INSENSITIVE);
break;
case SQL_ATTR_CURSOR_TYPE:
trace(" SQL_ATTR_CURSOR_TYPE");
returnInt(Value, SQL_CURSOR_FORWARD_ONLY);
break;
case SQL_ATTR_ENABLE_AUTO_IPD:
trace(" SQL_ATTR_ENABLE_AUTO_IPD TODO");
break;
case SQL_ATTR_FETCH_BOOKMARK_PTR:
trace(" SQL_ATTR_FETCH_BOOKMARK_PTR TODO");
break;
case SQL_ATTR_KEYSET_SIZE:
trace(" SQL_ATTR_KEYSET_SIZE TODO");
break;
case SQL_ATTR_MAX_LENGTH:
trace(" SQL_ATTR_MAX_LENGTH TODO");
break;
case SQL_ATTR_MAX_ROWS:
trace(" SQL_ATTR_MAX_ROWS TODO");
break;
case SQL_ATTR_METADATA_ID:
trace(" SQL_ATTR_METADATA_ID TODO");
break;
case SQL_ATTR_NOSCAN:
trace(" SQL_ATTR_NOSCAN TODO");
break;
case SQL_ATTR_PARAM_BIND_OFFSET_PTR:
trace(" SQL_ATTR_PARAM_BIND_OFFSET_PTR TODO");
break;
case SQL_ATTR_PARAM_BIND_TYPE:
trace(" SQL_ATTR_PARAM_BIND_TYPE TODO");
break;
case SQL_ATTR_PARAM_OPERATION_PTR:
trace(" SQL_ATTR_PARAM_OPERATION_PTR TODO");
break;
case SQL_ATTR_PARAM_STATUS_PTR:
trace(" SQL_ATTR_PARAM_STATUS_PTR TODO");
break;
case SQL_ATTR_PARAMS_PROCESSED_PTR:
trace(" SQL_ATTR_PARAMS_PROCESSED_PTR TODO");
break;
case SQL_ATTR_PARAMSET_SIZE:
trace(" SQL_ATTR_PARAMSET_SIZE TODO");
break;
case SQL_ATTR_RETRIEVE_DATA:
trace(" SQL_ATTR_RETRIEVE_DATA TODO");
break;
case SQL_ATTR_ROW_ARRAY_SIZE:
trace(" SQL_ATTR_ROW_ARRAY_SIZE TODO");
break;
case SQL_ATTR_ROW_BIND_OFFSET_PTR:
trace(" SQL_ATTR_ROW_BIND_OFFSET_PTR TODO");
break;
case SQL_ATTR_ROW_BIND_TYPE:
trace(" SQL_ATTR_ROW_BIND_TYPE TODO");
break;
case SQL_ATTR_ROW_NUMBER: {
trace(" SQL_ATTR_ROW_NUMBER");
returnInt(Value, stat->getRowId());
break;
}
case SQL_ATTR_ROW_OPERATION_PTR:
trace(" SQL_ATTR_ROW_OPERATION_PTR TODO");
break;
case SQL_ATTR_ROW_STATUS_PTR:
trace(" SQL_ATTR_ROW_STATUS_PTR");
returnInt(Value, (int)stat->getAppRowDesc()->getStatusPointer());
break;
case SQL_ATTR_ROWS_FETCHED_PTR:
trace(" SQL_ATTR_ROWS_FETCHED_PTR TODO");
break;
case SQL_ATTR_SIMULATE_CURSOR:
trace(" SQL_ATTR_SIMULATE_CURSOR TODO");
break;
case SQL_ATTR_USE_BOOKMARKS:
trace(" SQL_ATTR_USE_BOOKMARKS");
returnInt(Value, stat->getUseBookmarks() ? SQL_UB_VARIABLE : SQL_UB_OFF);
break;
default:
trace(" ? %d TODO",(int)Attribute);
return SQL_ERROR;
}
return SQL_SUCCESS;
}
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
*/
#include "h2odbc.h"
SQLRETURN SQL_API SQLColumns(SQLHSTMT StatementHandle,
SQLCHAR* CatalogName, SQLSMALLINT NameLength1,
SQLCHAR* SchemaName, SQLSMALLINT NameLength2,
SQLCHAR* TableName, SQLSMALLINT NameLength3,
SQLCHAR* ColumnName, SQLSMALLINT NameLength4) {
trace("SQLColumns");
Statement* stat=Statement::cast(StatementHandle);
if(stat==0) {
return SQL_INVALID_HANDLE;
}
stat->setError(0);
char catalog[512];
setString(catalog,sizeof(catalog),CatalogName,NameLength1);
char schema[512];
setString(schema,sizeof(schema),SchemaName,NameLength2);
char table[512];
setString(table,sizeof(table),TableName,NameLength3);
char column[512];
setString(column,sizeof(column),ColumnName,NameLength4);
trace(" catalog=%s schema=%s table=%s column=%s",catalog,schema,table,column);
stat->getMetaColumns(catalog, schema, table, column);
return SQL_SUCCESS;
}
SQLRETURN SQL_API SQLSpecialColumns(SQLHSTMT StatementHandle,
SQLUSMALLINT IdentifierType, SQLCHAR* CatalogName,
SQLSMALLINT NameLength1, SQLCHAR* SchemaName,
SQLSMALLINT NameLength2, SQLCHAR* TableName,
SQLSMALLINT NameLength3, SQLUSMALLINT Scope,
SQLUSMALLINT Nullable) {
trace("SQLSpecialColumns");
Statement* stat=Statement::cast(StatementHandle);
if(stat==0) {
return SQL_INVALID_HANDLE;
}
stat->setError(0);
char catalog[512];
setString(catalog,sizeof(catalog),CatalogName,NameLength1);
char schema[512];
setString(schema,sizeof(schema),SchemaName,NameLength2);
char table[512];
setString(table,sizeof(table),TableName,NameLength3);
switch(IdentifierType) {
case SQL_BEST_ROWID: {
trace(" SQL_BEST_ROWID");
bool nullable = Nullable == SQL_NULLABLE;
stat->getMetaBestRowIdentifier(catalog, schema, table, Scope, nullable);
break;
}
case SQL_ROWVER: {
trace(" SQL_ROWVER");
stat->getMetaVersionColumns(catalog, schema, table);
break;
}
default:
stat->setError(E_HY097);
return SQL_ERROR;
}
return SQL_SUCCESS;
}
SQLRETURN SQL_API SQLStatistics(SQLHSTMT StatementHandle,
SQLCHAR* CatalogName, SQLSMALLINT NameLength1,
SQLCHAR* SchemaName, SQLSMALLINT NameLength2,
SQLCHAR* TableName, SQLSMALLINT NameLength3,
SQLUSMALLINT Unique, SQLUSMALLINT Reserved) {
trace("SQLStatistics");
Statement* stat=Statement::cast(StatementHandle);
if(stat==0) {
return SQL_INVALID_HANDLE;
}
stat->setError(0);
char catalog[512];
setString(catalog,sizeof(catalog),CatalogName,NameLength1);
char schema[512];
setString(schema,sizeof(schema),SchemaName,NameLength2);
char table[512];
setString(table,sizeof(table),TableName,NameLength3);
bool unique = Unique == SQL_INDEX_UNIQUE;
bool approximate = Reserved == SQL_QUICK;
stat->getMetaIndexInfo(catalog, schema, table, unique, approximate);
return SQL_SUCCESS;
}
SQLRETURN SQL_API SQLTables(SQLHSTMT StatementHandle,
SQLCHAR* CatalogName, SQLSMALLINT NameLength1,
SQLCHAR* SchemaName, SQLSMALLINT NameLength2,
SQLCHAR* TableName, SQLSMALLINT NameLength3,
SQLCHAR* TableType, SQLSMALLINT NameLength4) {
trace("SQLTables");
Statement* stat=Statement::cast(StatementHandle);
if(stat==0) {
return SQL_INVALID_HANDLE;
}
stat->setError(0);
char catalog[512];
setString(catalog,sizeof(catalog),CatalogName,NameLength1);
char schema[512];
setString(schema,sizeof(schema),SchemaName,NameLength2);
char table[512];
setString(table,sizeof(table),TableName,NameLength3);
char tabletypes[512];
setString(tabletypes,sizeof(tabletypes),TableType,NameLength4);
trace(" catalog=%s schema=%s table=%s tabletypes=%s",catalog, schema, table, tabletypes);
stat->getMetaTables(catalog, schema, table, tabletypes);
return SQL_SUCCESS;
}
SQLRETURN SQL_API SQLGetTypeInfo(SQLHSTMT StatementHandle,
SQLSMALLINT DataType) {
trace("SQLGetTypeInfo");
Statement* stat=Statement::cast(StatementHandle);
if(stat==0) {
return SQL_INVALID_HANDLE;
}
stat->setError(0);
switch(DataType) {
case SQL_ALL_TYPES:
trace(" SQL_ALL_TYPES");
stat->getMetaTypeInfoAll();
break;
/*
case SQL_CHAR:
trace(" SQL_CHAR");
break;
case SQL_VARCHAR:
trace(" SQL_VARCHAR");
break;
case SQL_LONGVARCHAR:
trace(" SQL_LONGVARCHAR");
break;
case SQL_WCHAR:
trace(" SQL_WCHAR");
break;
case SQL_WVARCHAR:
trace(" SQL_WVARCHAR");
break;
case SQL_WLONGVARCHAR:
trace(" SQL_WLONGVARCHAR");
break;
case SQL_DECIMAL:
trace(" SQL_DECIMAL");
break;
case SQL_NUMERIC:
trace(" SQL_NUMERIC");
break;
case SQL_INTEGER:
trace(" SQL_INTEGER");
break;
case SQL_BINARY:
trace(" SQL_BINARY");
break;
case SQL_SMALLINT:
trace(" SQL_SMALLINT");
break;
case SQL_REAL:
trace(" SQL_REAL");
break;
case SQL_FLOAT:
trace(" SQL_FLOAT");
break;
case SQL_DOUBLE:
trace(" SQL_DOUBLE");
break;
case SQL_BIT:
trace(" SQL_BIT");
break;
case SQL_TINYINT:
trace(" SQL_TINYINT");
break;
case SQL_BIGINT:
trace(" SQL_BIGINT");
break;
case SQL_VARBINARY:
trace(" SQL_VARBINARY");
break;
case SQL_LONGVARBINARY:
trace(" SQL_LONGVARBINARY");
break;
case SQL_TYPE_DATE:
trace(" SQL_TYPE_DATE");
break;
case SQL_TYPE_TIME:
trace(" SQL_TYPE_TIME");
break;
case SQL_TYPE_TIMESTAMP:
trace(" SQL_TYPE_TIMESTAMP");
break;
case SQL_INTERVAL_MONTH:
case SQL_INTERVAL_YEAR:
case SQL_INTERVAL_YEAR_TO_MONTH:
case SQL_INTERVAL_DAY:
case SQL_INTERVAL_HOUR:
case SQL_INTERVAL_MINUTE:
case SQL_INTERVAL_SECOND:
case SQL_INTERVAL_DAY_TO_HOUR:
case SQL_INTERVAL_DAY_TO_MINUTE:
case SQL_INTERVAL_DAY_TO_SECOND:
case SQL_INTERVAL_HOUR_TO_MINUTE:
case SQL_INTERVAL_HOUR_TO_SECOND:
case SQL_INTERVAL_MINUTE_TO_SECOND:
trace(" SQL_INTERVAL_ %d",DataType);
break;
case SQL_GUID:
trace(" SQL_GUID");
break;
*/
default:
trace(" type=%d", DataType);
stat->getMetaTypeInfo(DataType);
break;
}
return SQL_SUCCESS;
}
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
*/
#include "h2odbc.h"
SQLRETURN SQL_API SQLSetStmtAttr(SQLHSTMT StatementHandle,
SQLINTEGER Attribute, SQLPOINTER Value,
SQLINTEGER StringLength) {
trace("SQLSetStmtAttr");
Statement* stat=Statement::cast(StatementHandle);
if(stat==0) {
return SQL_INVALID_HANDLE;
}
stat->setError(0);
switch(Attribute) {
case SQL_ATTR_APP_PARAM_DESC:
trace(" SQL_ATTR_APP_ROW_DESC TODO");
// todo
return SQL_ERROR;
case SQL_ATTR_APP_ROW_DESC:
trace(" SQL_ATTR_APP_ROW_DESC TODO");
// todo
return SQL_ERROR;
case SQL_ATTR_ASYNC_ENABLE:
trace(" SQL_ATTR_ASYNC_ENABLE TODO not supported");
// TODO should support that!
if((SQLUINTEGER)Value != SQL_ASYNC_ENABLE_OFF) {
stat->setError(E_01S02);
return SQL_SUCCESS_WITH_INFO;
}
break;
case SQL_ATTR_CONCURRENCY: {
trace(" SQL_ATTR_CONCURRENCY");
// option value can be changed
SQLUINTEGER type = (SQLUINTEGER)Value;
switch(type) {
case SQL_CONCUR_READ_ONLY:
trace(" SQL_CONCUR_READ_ONLY");
break;
case SQL_CONCUR_LOCK:
trace(" SQL_CONCUR_LOCK");
stat->setError(E_01S02);
return SQL_SUCCESS_WITH_INFO;
break;
case SQL_CONCUR_ROWVER:
trace(" SQL_CONCUR_ROWVER");
stat->setError(E_01S02);
return SQL_SUCCESS_WITH_INFO;
break;
case SQL_CONCUR_VALUES:
trace(" SQL_CONCUR_ROWVER");
stat->setError(E_01S02);
return SQL_SUCCESS_WITH_INFO;
break;
default:
trace(" =? %d TODO", type);
return SQL_ERROR;
}
break;
}
case SQL_ATTR_CURSOR_SCROLLABLE:
trace(" SQL_ATTR_CURSOR_SCROLLABLE TODO");
break;
case SQL_ATTR_CURSOR_SENSITIVITY: {
trace(" SQL_ATTR_CURSOR_SENSITIVITY TODO");
// it seems this must be supported!
SQLUINTEGER type = (SQLUINTEGER)Value;
switch(type) {
case SQL_UNSPECIFIED:
trace(" SQL_UNSPECIFIED");
break;
case SQL_INSENSITIVE:
trace(" SQL_INSENSITIVE");
stat->setError(E_01S02);
return SQL_SUCCESS_WITH_INFO;
break;
case SQL_SENSITIVE:
trace(" SQL_SENSITIVE");
stat->setError(E_01S02);
return SQL_SUCCESS_WITH_INFO;
break;
default:
trace(" =? %d TODO", type);
return SQL_ERROR;
}
break;
}
case SQL_ATTR_CURSOR_TYPE: {
trace(" SQL_ATTR_CURSOR_TYPE");
// option value can be changed
SQLUINTEGER type = (SQLUINTEGER)Value;
switch(type) {
case SQL_CURSOR_FORWARD_ONLY:
trace(" SQL_CURSOR_FORWARD_ONLY");
break;
case SQL_CURSOR_STATIC:
trace(" SQL_CURSOR_STATIC");
stat->setError(E_01S02);
return SQL_SUCCESS_WITH_INFO;
break;
case SQL_CURSOR_KEYSET_DRIVEN:
trace(" SQL_CURSOR_KEYSET_DRIVEN");
stat->setError(E_01S02);
return SQL_SUCCESS_WITH_INFO;
break;
case SQL_CURSOR_DYNAMIC:
trace(" SQL_CURSOR_DYNAMIC");
stat->setError(E_01S02);
return SQL_SUCCESS_WITH_INFO;
break;
default:
trace(" =? %d TODO", type);
return SQL_ERROR;
}
break;
}
case SQL_ATTR_IMP_PARAM_DESC:
trace(" SQL_ATTR_IMP_PARAM_DESC TODO");
return SQL_ERROR;
case SQL_ATTR_ROW_NUMBER:
trace(" SQL_ATTR_ROW_NUMBER TODO");
return SQL_ERROR;
case SQL_ATTR_IMP_ROW_DESC:
trace(" SQL_ATTR_IMP_ROW_DESC TODO");
return SQL_ERROR;
case SQL_ATTR_QUERY_TIMEOUT:
trace(" SQL_ATTR_QUERY_TIMEOUT");
// option value can be changed
if((SQLUINTEGER)Value != 0) {
stat->setError(E_01S02);
return SQL_SUCCESS_WITH_INFO;
}
break;
case SQL_ATTR_ENABLE_AUTO_IPD:
trace(" SQL_ATTR_ENABLE_AUTO_IPD TODO");
break;
case SQL_ATTR_FETCH_BOOKMARK_PTR:
trace(" SQL_ATTR_FETCH_BOOKMARK_PTR TODO");
break;
case SQL_ATTR_KEYSET_SIZE:
trace(" SQL_ATTR_KEYSET_SIZE");
// option value can be changed
if((SQLUINTEGER)Value != 0) {
stat->setError(E_01S02);
return SQL_SUCCESS_WITH_INFO;
}
break;
case SQL_ATTR_MAX_LENGTH:
trace(" SQL_ATTR_MAX_LENGTH %d", Value);
// option value can be changed
if((SQLUINTEGER)Value != 0) {
stat->setError(E_01S02);
return SQL_SUCCESS_WITH_INFO;
}
break;
case SQL_ATTR_MAX_ROWS:
trace(" SQL_ATTR_MAX_ROWS");
// option value can be changed
if((SQLUINTEGER)Value != 0) {
stat->setError(E_01S02);
return SQL_SUCCESS_WITH_INFO;
}
break;
case SQL_ATTR_METADATA_ID:
trace(" SQL_ATTR_METADATA_ID TODO");
break;
case SQL_ATTR_NOSCAN:
trace(" SQL_ATTR_NOSCAN TODO");
break;
case SQL_ATTR_PARAM_BIND_OFFSET_PTR:
trace(" SQL_ATTR_PARAM_BIND_OFFSET_PTR TODO");
break;
case SQL_ATTR_PARAM_BIND_TYPE:
trace(" SQL_ATTR_PARAM_BIND_TYPE TODO");
break;
case SQL_ATTR_PARAM_OPERATION_PTR:
trace(" SQL_ATTR_PARAM_OPERATION_PTR TODO");
break;
case SQL_ATTR_PARAM_STATUS_PTR:
trace(" SQL_ATTR_PARAM_STATUS_PTR TODO");
break;
case SQL_ATTR_PARAMS_PROCESSED_PTR:
trace(" SQL_ATTR_PARAMS_PROCESSED_PTR TODO");
break;
case SQL_ATTR_PARAMSET_SIZE:
trace(" SQL_ATTR_PARAMSET_SIZE TODO");
// TODO it seems all drivers must support arrays, but the MySQL driver doesn't support it
if((SQLUINTEGER)Value != 1) {
stat->setError(E_01S02);
return SQL_SUCCESS_WITH_INFO;
}
break;
case SQL_ATTR_RETRIEVE_DATA:
trace(" SQL_ATTR_RETRIEVE_DATA TODO");
break;
case SQL_ATTR_ROW_ARRAY_SIZE:
trace(" SQL_ATTR_ROW_ARRAY_SIZE");
// option value can be changed
if((SQLUINTEGER)Value != 1) {
stat->setError(E_01S02);
return SQL_SUCCESS_WITH_INFO;
}
break;
case SQL_ATTR_ROW_BIND_OFFSET_PTR:
trace(" SQL_ATTR_ROW_BIND_OFFSET_PTR TODO");
break;
case SQL_ATTR_ROW_BIND_TYPE:
trace(" SQL_ATTR_ROW_BIND_TYPE TODO");
if(Value == SQL_BIND_BY_COLUMN) {
// column wise binding
// SQL_BIND_BY_COLUMN = 0UL
trace(" SQL_BIND_BY_COLUMN TODO");
stat->getAppRowDesc()->setBindingType(false, 0);
} else {
// row wise binding
trace(" row wise binding size=%d", Value);
stat->getAppRowDesc()->setBindingType(true, (int)Value);
}
break;
case SQL_ATTR_ROW_OPERATION_PTR:
trace(" SQL_ATTR_ROW_OPERATION_PTR TODO");
break;
case SQL_ATTR_ROW_STATUS_PTR:
trace(" SQL_ATTR_ROW_STATUS_PTR");
stat->getAppRowDesc()->setStatusPointer((SQLUSMALLINT*)Value);
break;
case SQL_ATTR_ROWS_FETCHED_PTR:
trace(" SQL_ATTR_ROWS_FETCHED_PTR");
stat->getImpRowDesc()->setRowsProcessedPointer((SQLUINTEGER*)Value);
break;
case SQL_ATTR_SIMULATE_CURSOR: {
trace(" SQL_ATTR_SIMULATE_CURSOR");
// option value can be changed
if((SQLUINTEGER)Value != SQL_SC_NON_UNIQUE) {
stat->setError(E_01S02);
return SQL_SUCCESS_WITH_INFO;
}
break;
}
case SQL_ATTR_USE_BOOKMARKS: {
trace(" SQL_ATTR_USE_BOOKMARKS");
switch((int)Value) {
case SQL_UB_OFF:
trace(" SQL_UB_OFF");
stat->setUseBookmarks(false);
break;
case SQL_UB_FIXED:
trace(" SQL_UB_FIXED TODO");
break;
case SQL_UB_VARIABLE:
trace(" SQL_UB_VARIABLE");
stat->setUseBookmarks(true);
break;
default:
trace(" ? %d TODO", Value);
}
break;
}
default:
trace(" ? %d TODO",Attribute);
break;
}
return SQL_SUCCESS;
}
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
*/
#include "h2odbc.h"
void setString(char* dest, int dest_len, SQLCHAR* source, SQLSMALLINT source_len) {
if(dest==0 || dest_len==0) {
return;
}
if(source==0) {
*dest=0;
return;
}
int len;
if(source_len==SQL_NTS) {
len=strlen((char*)source);
} else {
len=(int)source_len;
}
if(dest_len<len) {
len=dest_len;
}
strncpy(dest, (char*)source, len);
dest[len]=0;
}
void returnString(SQLPOINTER dest, SQLINTEGER dest_len, SQLINTEGER* dest_pt, const char* source) {
if(dest_len==0) {
return;
}
char* s = (char*)source;
if(source==0) {
s="";
}
int len=strlen(s);
if(dest_len<len) {
len=dest_len;
}
if(dest_pt!=0) {
*dest_pt=len;
}
if(dest!=0) {
strncpy((char*)dest, s, len);
((char*)dest)[len]=0;
}
}
void returnString(SQLCHAR* dest, SQLSMALLINT dest_len, SQLSMALLINT* dest_pt, const char* source) {
if(dest_len==0) {
return;
}
char* s = (char*)source;
if(source==0) {
s="";
}
int len=strlen(s);
if(dest_len<len) {
len=dest_len;
}
if(dest_pt!=0) {
*dest_pt=len;
}
if(dest!=0) {
strncpy((char*)dest, s, len);
dest[len]=0;
}
}
void returnInt(SQLPOINTER InfoValue, SQLINTEGER* LengthPtr, SQLUINTEGER value) {
if(LengthPtr!=0) {
*LengthPtr=sizeof(SQLUINTEGER);
}
*((SQLUINTEGER*)InfoValue)=value;
}
void returnInt(SQLPOINTER NumericPtr, int value) {
if(NumericPtr != 0) {
*(SQLUINTEGER*)NumericPtr = value;
}
}
void returnInt(SQLSMALLINT* pointer, int value) {
if(pointer != 0) {
*pointer = value;
}
}
void returnInt(SQLPOINTER InfoValue, SQLSMALLINT* LengthPtr, SQLUINTEGER value) {
if(LengthPtr!=0) {
*LengthPtr=sizeof(SQLUINTEGER);
}
*((SQLUINTEGER*)InfoValue)=value;
}
void returnSmall(SQLPOINTER InfoValue, SQLINTEGER* LengthPtr, SQLUSMALLINT value) {
if(LengthPtr!=0) {
*LengthPtr=sizeof(SQLUSMALLINT);
}
*((SQLSMALLINT*)InfoValue)=value;
}
void returnSmall(SQLPOINTER InfoValue, SQLSMALLINT* LengthPtr, SQLUSMALLINT value) {
if(LengthPtr!=0) {
*LengthPtr=sizeof(SQLUSMALLINT);
}
*((SQLSMALLINT*)InfoValue)=value;
}
void returnPointer(SQLPOINTER pointer, void* value) {
if(pointer==0) {
return;
}
(*(void**)pointer)=value;
}
int getDefaultCType(int sqlType) {
switch (sqlType) {
case SQL_CHAR:
case SQL_VARCHAR:
case SQL_LONGVARCHAR:
case SQL_DECIMAL:
case SQL_NUMERIC:
case SQL_GUID:
return SQL_C_CHAR;
case SQL_WCHAR:
case SQL_WVARCHAR:
case SQL_WLONGVARCHAR:
return SQL_C_WCHAR;
case SQL_BIT:
return SQL_C_BIT;
case SQL_TINYINT:
return SQL_C_TINYINT;
case SQL_SMALLINT:
return SQL_C_SHORT;
case SQL_INTEGER:
return SQL_C_LONG;
case SQL_BIGINT:
return SQL_C_SBIGINT;
case SQL_REAL:
return SQL_C_FLOAT;
case SQL_FLOAT:
case SQL_DOUBLE:
return SQL_C_DOUBLE;
case SQL_BINARY:
case SQL_VARBINARY:
case SQL_LONGVARBINARY:
return SQL_C_BINARY;
case SQL_TYPE_DATE:
return SQL_C_DATE;
case SQL_TYPE_TIME:
return SQL_C_TIME;
case SQL_TYPE_TIMESTAMP:
return SQL_C_TIMESTAMP;
default:
trace(" unsupported translation from sqlType %d TODO", sqlType);
return SQL_C_CHAR;
}
}
差异被折叠。
差异被折叠。
[Project]
FileName=h2odbcSetup.dev
Name=h2odbcSetup
UnitCount=1
Type=0
Ver=1
ObjFiles=
Includes=
Libs=
PrivateResource=h2odbcSetup_private.rc
ResourceIncludes=
MakeIncludes=
Compiler=
CppCompiler=
Linker=C:/Dev-Cpp/lib/libodbccp32.a_@@_C:/Dev-Cpp/lib/libodbc32.a_@@_
IsCpp=1
Icon=h2odbcSetup.ico
ExeOutput=..\..\bin\odbc
ObjectOutput=..\..\bin\odbcTemp
OverrideOutput=0
OverrideOutputName=h2odbcSetup.exe
HostApplication=
Folders=
CommandLine=
UseCustomMakefile=0
CustomMakefile=
IncludeVersionInfo=0
SupportXPThemes=0
CompilerSet=0
CompilerSettings=0000000000000000000000
[Unit1]
FileName=setup\setup.cpp
CompileCpp=1
Folder=h2odbcSetup
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[VersionInfo]
Major=0
Minor=1
Release=1
Build=1
LanguageID=1033
CharsetID=1252
CompanyName=
FileVersion=
FileDescription=Developed using the Dev-C++ IDE
InternalName=
LegalCopyright=
LegalTrademarks=
OriginalFilename=
ProductName=
ProductVersion=
AutoIncBuildNr=0
差异被折叠。
/* THIS FILE WILL BE OVERWRITTEN BY DEV-C++ */
/* DO NOT EDIT! */
A ICON MOVEABLE PURE LOADONCALL DISCARDABLE "h2odbcSetup.ico"
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论