On Nov 24, 2011, at 3:31 PM, Ben Coman wrote:
> I have a Microsoft Access database on Microsoft Windows that I
want to process using Pharo. ConfigurationOfODBC looked promising so
followed instructions at
http://www.pharocasts.com/2010/12/access-database-through-odbc.html,
> though using a blank MDB file rather than SQLLite, and 'TestMDB'
as the ODBC DSN, I executed...
> --8<---
> Gofer new
> squeaksource: 'ODBC';
> package: 'ConfigurationOfODBC'; load.
> (Smalltalk at: #ConfigurationOfODBC) load.
>
> connection := ODBCConnection dsn: 'TestMDB' user: '' password: ''.
> connection execute: 'CREATE TABLE user(name varchar(10), age
smallint)'.
> connection execute: 'INSERT INTO user VALUES(''Old Bob'', 100)'.
> contents := (connection query: 'select * from user;') execute: ''.
> contents asTable inspect.
> connection close.
> --8<---
> which failed on Pharo 1.3 but worked on Pharo 1.2.1. To debug
this I compared each by single stepping 1.3 & 1.2.1 side-by-side.
> I executed... connection := ODBCConnection dsn: 'TestMDB' user: ''
password: ''.
> which seemed to worked the same on both platforms up to the
inserted 'self halt' shown here...
> --8<---
> ODBCConnection>>connect
> "Connect to the database"
> self registerForFinalization.
> hEnv := self sqlAllocEnv.
> false ifTrue:
> [ self
> sqlSetEnvAttr: 200
> value: 2 "SQL_ATTR_ODBC_VERSION" ].
> self halt.
> hdbc := self sqlAllocConnect: hEnv.
> --8<---
> ODBCConnection>>sqlAllocConnect: envHandle
> | h |
> h := SQLHDBC new.
> self checkSQLReturn: (ODBCLibrary default
> sqlAllocConnectEnvironment: hEnv connection: h
> ).
> ^h
> --8<---
> ODBCLibrary(Object)>>sqlAllocConnectEnvironment:
environmentHandle connection: connectionHandle
> "SQLRETURN
> SQLAllocConnect(
> SQLHENV EnvironmentHandle,
> SQLHDBC *ConnectionHandle);"
> <cdecl: short 'SQLAllocConnect' (SQLHENV SQLHDBC*)>
> ^ self externalCallFailed
> --8<---
> ODBCConnection>>checkSQLReturn: sqlReturn
> "private - check the sqlReturn and generates an exception if
corresponds"
> self
> checkSQLReturn: sqlReturn
> environment: hEnv
> connection: hdbc
> statement: nil
> --8<---
> If you've followed the call chain down to here, then the result
is...
> In Pharo 1.2.1 (WinXP & Win7) primitive SQLAllocConnect
primitive succeeds, with sqlReturn=0
> In Pharo 1.3 (WinXP & Win7) primitive SQLAllocConnect
primitive succeeds, with sqlReturn=-2
> I cannot find what -2 may mean on any of the Microsoft ODBC API
pages, nor a few header files I checked (though I may have missed some
header file)
> =================
> To investigate further, I thought to try running the bypassed
code...
> --8<---
> ODBCConnection>>connect
> "Connect to the database"
> self registerForFinalization.
> hEnv := self sqlAllocEnv.
> self halt.
> true ifTrue:
> [ self
> sqlSetEnvAttr: 200
> value: 2 "SQL_ATTR_ODBC_VERSION" ].
> --8<---
> sqlSetEnvAttr: attr value: value
> self checkSQLReturn: (ODBCLibrary default
> sqlSetEnvAttr: hEnv attr: attr value: value length: 0
> )
> --8<---
> sqlSetEnvAttrPtr: hEnv attr: attr value: value length: length
> "SQLRETURN SQLSetEnvAttr(
> SQLHENV EnvironmentHandle,
> SQLINTEGER Attribute,
> SQLPOINTER ValuePtr,
> SQLINTEGER StringLength);"
> <cdecl: short 'SQLSetEnvAttr' (SQLHENV long void* long)>
> ^ self externalCallFailed
> --8<---
> For both 1.2.1 and 1.3 'self externalCallFailed' is executed
> for 1.2.1 errCode=12 'No module to load address from'
> for 1.3 errCode=13 'Unable to find function address'
> --8<---
> Pointers anyone?
> btw, In parallel I am also trying out DBXTalk.