IM001 Driver does not support this function (ODBC) - sql

I'm building custom ODBC driver.
my main method:
int main(int argc, char** argv) {
SQLRETURN status;
//SQLHANDLE hEnv;
//SQLHANDLE hStmt;
SQLHENV hEnv;
SQLHDBC dbc = 0;
SQLHSTMT hStmt;
SQLCHAR ConnStrOut[1024];
SQLSMALLINT x;
// startup banner
//printf();
MessageBox(GetDesktopWindow(), "ODBC Client\n\n", "Driver", MB_OK);
// show query to be executed
printf("Query: %s\n", "SELECT VISITS FROM TRAFFIC");
// allocate ENVIRONMENT
status = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &hEnv);
// check for error
ODBC_CHK_ERROR(SQL_HANDLE_ENV, hEnv, status, "");
// set the ODBC version for behaviour expected
status = SQLSetEnvAttr(hEnv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3, 0);
CHECK_STATUS(status, (UCHAR*)"SQLSetEnvAttr", hEnv, SQL_HANDLE_ENV);
// check for error
ODBC_CHK_ERROR(SQL_HANDLE_ENV, hEnv, status, "");
// allocate CONNECTION
status = SQLAllocHandle(SQL_HANDLE_DBC, hEnv, &dbc);
// check for error
ODBC_CHK_ERROR(SQL_HANDLE_ENV, hEnv, status, "");
// ----------- real connection takes place at this point
status = SQLDriverConnect(dbc, GetDesktopWindow(),
(unsigned char*) "DSN=myDSN",
SQL_NTS, ConnStrOut, 1024, &x,
SQL_DRIVER_PROMPT);
if (SQL_SUCCEEDED(status)) {
printf("Connected\n");
printf("Returned connection string was:\n\t%s\n", ConnStrOut);
//SQLDisconnect(dbc);
}
Everything works well when I run main using my sample client.
However, when I try odbc testing tool odbcte32 or other odbc client(s) such as SqlDbx or QTODBC, once I try to establish connection using 'myDSN' (which is using my custom driver) I always get: [Microsoft][ODBC Driver Manager] Driver does not support this function
I've properly implemented SQLDriverConnect function to create OutConnectionString by reading key-value-pairs from User DSN that uses my compiled driver DLL.
I've defined skeletons for all odbc functions http://msdn.microsoft.com/en-us/library/windows/desktop/ms714562(v=vs.85).aspx
I compile my custom diver using minGW compiler (32-bit).
I have Windows 7 OS 64-bit but I'm running 32-bit ODBC test tool.
This is driving me crazy. I don't understand which specific function is not supported in my driver. Again, I have created skeletons for all needed functions. Here's the list:
SQLAllocConnect ,
SQLAllocEnv ,
SQLAllocStmt ,
SQLAllocHandle ,
SQLFreeConnect ,
SQLFreeEnv ,
SQLFreeStmt ,
SQLBindCol ,
SQLCancel ,
SQLConnect ,
SQLDescribeCol ,
SQLDisconnect ,
SQLExecDirect ,
SQLExecute ,
SQLExtendedFetch ,
SQLFetch ,
SQLGetCursorName ,
SQLNumResultCols ,
SQLPrepare ,
SQLRowCount ,
SQLSetCursorName ,
SQLColumns ,
SQLDriverConnect ,
SQLGetData ,
SQLGetInfo ,
SQLGetTypeInfo ,
SQLParamData ,
SQLPutData ,
SQLStatistics ,
SQLTables ,
SQLBrowseConnect ,
SQLColumnPrivileg,
SQLDescribeParam ,
SQLForeignKeys ,
SQLMoreResults ,
SQLNativeSql ,
SQLNumParams ,
SQLPrimaryKeys ,
SQLProcedureColum,
SQLProcedures ,
SQLSetPos ,
SQLTablePrivilege,
SQLBindParameter ,
SQLCloseCursor ,
SQLColAttribute ,
SQLCopyDesc ,
SQLEndTran ,
SQLFetchScroll ,
SQLFreeHandle ,
SQLGetConnectAttr,
SQLGetDescField ,
SQLGetDescRec ,
SQLGetDiagField ,
SQLGetDiagRec ,
SQLGetEnvAttr ,
SQLGetStmtAttr ,
SQLSetConnectAttr,
SQLSetDescField ,
SQLSetDescRec ,
SQLSetEnvAttr ,
SQLSetStmtAttr ,
SQLBulkOperations,
SQLSpecialColumns.
EDIT:
Figured it out. SQLDisconnect was defined incorrectly. Make sure all parameters that are passed are correct.
The right definition was:
RETCODE SQL_API SQLDisconnect(SQLHDBC pHandle) {
__CHK_HANDLE(pHandle, SQL_HANDLE_DBC, SQL_ERROR);
_SQLFreeDiag(_DIAGCONN(pHandle));
_SQLDisconnect((PGENODBCCONN) pHandle);
return (SQL_SUCCESS);
}
The way I figured it out:
create .def file (name it the same as your driver DLL file name, i.e. in my case it was axodbc.def), list all functions present in your driver in it, as following:
LIBRARY axodbc
DESCRIPTION "Driver 1 definitions"
EXPORTS
SQLAllocConnect
SQLAllocEnv
SQLAllocStmt
SQLAllocHandle
SQLFreeConnect
SQLFreeEnv
SQLFreeStmt
SQLBindCol
SQLCancel
SQLConnect
SQLDescribeCol
SQLExecDirect
SQLExecute
SQLDisconnect
SQLExtendedFetch
SQLFetch
SQLGetCursorName
SQLNumResultCols
SQLPrepare
SQLRowCount
SQLSetCursorName
SQLColumns
SQLDriverConnect
SQLGetData
SQLGetInfo
SQLGetTypeInfo
SQLParamData
SQLPutData
SQLStatistics
SQLTables
SQLBrowseConnect
SQLColumnPrivileges
SQLDescribeParam
SQLForeignKeys
SQLMoreResults
SQLNativeSql
SQLNumParams
SQLPrimaryKeys
SQLProcedureColumns
SQLProcedures
SQLSetPos
SQLTablePrivileges
SQLBindParameter
SQLCloseCursor
SQLColAttribute
SQLCopyDesc
SQLEndTran
SQLFetchScroll
SQLFreeHandle
SQLGetConnectAttr
SQLGetDescField
SQLGetDescRec
SQLGetDiagField
SQLGetDiagRec
SQLGetEnvAttr
SQLGetStmtAttr
SQLSetConnectAttr
SQLSetDescField
SQLSetDescRec
SQLSetEnvAttr
SQLSetStmtAttr
SQLBulkOperations
SQLSpecialColumns
Compile DLL (using mingw (g++)) and include your .def file, something like:
g++ -shared -o axodbc.dll axodbc.cpp connectionmanager.cpp diagnostics.cpp myresources.res axodbc.def -lodbc32 -lodbccp32
Compiler gave me an error at this point that SQLDisconnect was defined incorrectly

I don't SQLGetFunctions in that list. You can always enable ODBC tracing in the driver manager and it will show what ODBC calls are made and what the result was.

Related

Unable to update unidata from .NET

I've been attempting for the last couple of days to update unidata using sample code as a basis using .NET without success. I can read the database successfully and view the raw data within visual studio. The error reported back is a out of range error. The program is attempting to update the unit price of a purchase order.
Error:
{" Error on Socket Receive. Index was outside the bounds of the array.POD"}
[IBMU2.UODOTNET.UniFileException]: {" Error on Socket Receive. Index was outside the bounds of the array.POD"}
Data: {System.Collections.ListDictionaryInternal}
HelpLink: null
HResult: -2146232832
InnerException: null
Message: " Error on Socket Receive. Index was outside the bounds of the array.POD"
Source: "UniFile Class"
StackTrace: " at IBMU2.UODOTNET.UniFile.Write()\r\n at IBMU2.UODOTNET.UniFile.Write(String aRecordID, UniDynArray aRecordData)\r\n at ReadXlsToUnix.Form1.TestUpdate(String PO_LINE_SHIP, String price) in c:\Users\xxx\Documents\Visual Studio 2013\Projects\ReadXlsToUnix\ReadXlsToUnix\Form1.cs:line 330"
TargetSite: {Void Write()}
failing Test Code is:
private void TestUpdate(string PO_LINE_SHIP,string price)
{
UniFile pod =null;
UniSession uniSession =null;
//connection string
uniSession = UniObjects.OpenSession("unixMachine", "userid", Properties.Settings.Default.PWD, "TRAIN", "udcs");
//open file
pod = uniSession.CreateUniFile("POD");
//read data
pod.Read(PO_LINE_SHIP);
//locking strategy
pod.UniFileLockStrategy = 1;
pod.UniFileReleaseStrategy = 1;
if (pod.RecordID == ""){
pod.UnlockRecord();
}
//replace existing value with one entered by user
pod.Record.Replace(4, (string)uniSession.Iconv(price, "MD4"));
try
{
pod.Write(pod.RecordID,pod.Record); //RecordId and Record both show correctly hover/immediate window
//pod.Write() fails with same message
}
catch (Exception err)
{
MessageBox.Show("Error" + err);
}
pod.Close();
UniObjects.CloseSession(uniSession);
}
}
Running on HP UX 11.31 unidata 7.2 and using UODOTNET.dll 2.2.3.7377
Any help greatly appreciated.
This is the write record version and have also tried writefield functionality with same error.
Rajan - thanks for the update and link. I have tried unsuccessfully to read/update my unidata tables using the U2 Toolkit. I can however read/update a file I have created within the same account. Does this mean there is a missing entry somewhere VOC, DICT for example.

Automation Error with conditional compilation

I find strange behaviour when trying to load an Excel workbook.
I have an Excel-AddIn, written in .NET with COM Interop.
It is mainly used to create my own Ribbon-Tab, load workbooks from a menu and do some project administration.
When I try to open a workbook using two ways, I get different results:
First, when I load the Workbook (Excel 2003-Version) from within the Addin everything works fine. From the Button-Event of the ribbon, a public function openWorkbook of the Add-In is called that uses application.workbooks.open(...) to load the Excel workbook.
This way, the workbook opens without an error.
Second, when I try to call the Addin-Function from within VBA using code like:
Set addIn = Application.COMAddIns("WMExcelAddin1")
Set automationObject = addIn.Object
automationObject.openWorkbook (filename)
I get an error message:
Compile Error
Automation Error
and the IDE stops at the first occurrence of a conditional compile in one of the workbook-modules, looking like follows:
#const ebind = 0
[...]
sub proc1()
#if ebind = 1 then ' IDE Stops here
[...]
#else
[...]
#end if
end sub
I tried to use boolean datatype instead of numbers with the same effect.
I'm at my wits' end.
In Automation mode Excel does not load add-ins by default. Excel loads add-ins using the conditions add-ins were compiled with. In order for Add-In works during Automation mode, one should force Excel to load it prior to load any workbooks depending on that add-in. Below I provide the code example from my real project (with some editions) which implements this loading sequence in JScript. Comments explain steps.
function run_excel() {
dbg_log("run_excel");
g_xla_addin = null;
g_xla = null;
try {
g_add_ins = get_excel_app().AddIns;
dbg_log("finding add_in.xlam");
//Searching for the installed add-in like Application.COMAddIns("WMExcelAddin1")
g_xla_addin = find_addin(g_add_ins, "add_in.xlam");
} catch(v_err) {
throw new error(
"xla_loading"
, CR_xla_loading
, 'Unexpected error occurred while determining if add_in.xlam is installed.'
, v_err
);
}
if (g_xla_addin == null) throw new error(
"xla_loading"
, CR_xla_not_installed
, "MS Excel addin is not installed."
);
try {
dbg_log("opening add_in.xlam");
//In the example, the add-in has the name of its workbook
try { g_xla = g_excel.Workbooks(g_xla_addin.Name); } catch(e) {}
if (g_xla == null) {
g_excel.AutomationSecurity = 1; // 1 == msoAutomationSecurityLow
//Loading the add-in. The add-in also handles `OpenWorkbook` at this time.
g_xla = g_excel.Workbooks.Open(
g_xla_addin.FullName //FileName
, 2 //UpdateLinks
, true //ReadOnly
, null //Format
, null //Password
, null //WriteResPassword
, true //IgnoreReadOnlyRecommended: not display the read-only recommended message
, 2 //Origin: xlWindows
, null //Delimiter
, null //Editable
, null //Notify
, null //Converter
, false //AddToMru: don't add this workbook to the list of recently used files
, true //Local: saves files against the language of Microsoft Excel.
, 0 //CorruptLoad: xlNormalLoad
);
hide_excel(); //To speed up and not interfere with user actions
}
} catch(v_err) {
throw new error(
"xla_loading"
, CR_xla_loading
, 'Unexpected error occurred while loading add_in.xlam:\n'
, v_err
);
}
//Now the Add-In is loaded, so the VBA engine knows its API, and the workbook referencing to it are loaded fine.
try {
g_sig_cat_wbk = g_excel.Workbooks.Open(
g_sig_cat_fn //FileName
, 2 //UpdateLinks
, true //ReadOnly
, null //Format
, null //Password
, null //WriteResPassword
, true //IgnoreReadOnlyRecommended: not display the read-only recommended message
, 2 //Origin: xlWindows
, null //Delimiter
, null //Editable
, null //Notify
, null //Converter
, false //AddToMru: don't add this workbook to the list of recently used files
, false //Local: saves files against the language of Microsoft Excel.
, 0 //CorruptLoad: xlNormalLoad
);
//Calling on the loaded workbook the target macro from the loaded add_in.xlam
vba_ret(g_excel.Run(g_xla_addin.Name+"!my_addin.prepare_sig_import", g_sig_cat_wbk.Name));
} catch(v_err) {
throw new error(
"sig_cat_loading"
, CR_sig_cat_loading
, 'Error occured while loading catalog of signals:\n'
, v_err
);
}
finally {
g_sig_cat_wbk.Close(false);
g_sig_cat_wbk = null;
}
dbg_log("run_excel done");
}

NSSreamstatus if i am getting data or not

I have NSInputStream , i want to check if i am getting data from other end , i read the NSStreamStatus , i cam across that "NSStreamStatusReading" is use to check the read data .
I tried to check that status but its not working can any one tell me how to check if i am getting data or not
..
code:
if([inputStream streamStatus]==NSStreamStatusReading)
{
NSlog(#"server is sending");
}
else
{
NSlog(#"no");
}
its working when its sending but when i stop server , its not updating .

*** glibc detected *** ./test: free(): invalid pointer:

I am trying to fetch and store ID and Status from Database using statements ID = r->getInt(1) and stat = r->getString(10) where I have declared ID as int and stat as string.
Where first field is an ID containing value 1 and 10th field is status containing value 'A'.
If I try to fetch only ID, my code works fine. Else, when I try to fetch status as well, then while running the code, I am getting below mentioned error:
*** glibc detected *** ./test: free(): invalid pointer: 0x000000001c3f5a60 ***
======= Backtrace: =========
/lib64/libc.so.6[0x3d23e71684]
/lib64/libc.so.6(cfree+0x8c)[0x3d23e74ccc]
/usr/lib64/libstdc++.so.6(_ZNSsD1Ev+0x3a)[0x3d28a9dc1a]
./test[0x401837]
./test(__gxx_personality_v0+0x310)[0x401120]
/lib64/libc.so.6(__libc_start_main+0xf4)[0x3d23e1d8b4]
./test(__gxx_personality_v0+0x89)[0x400e99]
Please help.
Adding just the basics of what I am trying to achieve:
char loader_session[10];
char sql_query[500];
int ID;
string STATUS;
string CURRENT_CNT_FILE
env = Environment::createEnvironment (Environment::DEFAULT);
conn = env->createConnection( user, passwd, db);
strcpy(loader_session,"TEST");
sprintf(sql_query,"SELECT ID, SESSION_NAME, SRC_SUCCESS_PATH, SRC_CDR_PATH, LOG_FILE, CURRENT_CNT_FILE, LOG_MAX_FILE_CNT, LOG_MAX_FILE_SIZE, PROCEDURE_NAME, STATUS, ERROR_CDR_PATH, LOCK_FILE_PATH FROM TEST_DB WHERE SESSION_NAME = '%s'",loader_session);
Statement* const s = conn->createStatement(sql_query);
s->setPrefetchRowCount(10);
ResultSet* const r = s->executeQuery();
while (r->next())
{
ID = r->getInt(1);
STATUS = r->getString(10);
CURRENT_CNT_FILE = r->getString(6);
}
Ok I got a temporary solution for my question. Just by setting MALLOC_CHECK_ to 0, I am not getting the error and my code is running fine. Don't know the side effects of this, but as of now, it's working fine.

Not able to update firefox sqlite database when firefox is running-MacOS

I have the following code snippet to update firefox extension sqlite data base
NSString * profileFolderPath = [[ #"~" stringByExpandingTildeInPath] stringByAppendingPathComponent:#"/Library/Application Support/Firefox/Profiles"];
NSString *sqlitePath = [pathToProfileFolder stringByAppendingPathComponent:#"extensions.sqlite"];
int rc = sqlite3_open([sqlitePath UTF8String], &db);
if( rc )
{
NSLog(#"enable extension :%#\n",[NSString stringWithCString:sqlite3_errmsg(db)]);
sqlite3_close(db);
return NO;
}
else {
NSLog(#"opened entensions db successfully \n");
}
// check the values for active and userDisabled fields
rc = sqlite3_exec(db,"SELECT active,userDisabled FROM addon where id='myId.com'",sqliteCallback,0,&zErrMsg);
if (rc!=SQLITE_OK ) {
NSLog(#"error quering the entensions database :%#\n",[NSString stringWithCString:zErrMsg]);
if(zErrMsg)
sqlite3_free(zErrMsg);
sqlite3_close(db);
return NO;
// handle error
}
When firefox application is not in running state,I can read the values and also update the database,but when the firefox is running I am not able to read the values from the database as sqlite3_exec statement is returning the value 5 and I can see the error in console saying "error quering the extensions database :database is locked".
How can I resolve this issue.Please help.
You cannot b/c firefox keeps its own config file (and extensions db file IS a firefox own config file) open while it runs.