From VisualWorks®, 7.6 of February 1, 2008 on February 1, 2008 at 12:45:09 pm (Dialog confirm: 'You are filing-in a Parcel source file!\\While this is possible it will not have\the same effect as loading the parcel.\None of the Parcel''s prerequisites will\be loaded and none of its load actions\will be performed.\\Are you sure you want to file-in?' withCRs) ifFalse: [self error: 'Parcel file-in abandoned. Choose terminate or close.'] <class> <name>CTLibThreadedInterface</name> <environment>Database</environment> <super>Database.CTLibInterface</super> <private>false</private> none <imports> Database.CTLibThreadedInterfaceDictionary.* </imports> <category>Database-External-Libraries</category> <attributes> <includeFiles></includeFiles> <includeDirectories></includeDirectories> <libraryFiles></libraryFiles> <libraryDirectories></libraryDirectories> true full <package>CTLibThapiEXDI</package> </attributes> </class> <comment> Database.CTLibThreadedInterface
This class defines multi-threaded calling conventions for the Sybase Client library.
</comment> <class> <name>CTLibLinuxThreadedInterface</name> <environment>Database</environment> <super>Database.CTLibThreadedInterface</super> <private>false</private> none <imports> Database.CTLibLinuxThreadedInterfaceDictionary.* </imports> <category>Database-External-Libraries</category> <attributes> <includeFiles></includeFiles> <includeDirectories></includeDirectories> <libraryFiles><item>libsybase.so</item></libraryFiles> <libraryDirectories><item>$(SYBASE)/lib</item></libraryDirectories> false full <package>CTLibThapiEXDI</package> </attributes> </class> <comment> Database.CTLibLinuxThreadedInterface
CTLibLinuxThreadedInterface defines multi-threaded calling conventions for the Linux (Intel) Open Client CT-Library version 10.0.x and later.
</comment> <class> <name>CTLibThreadedSession</name> <environment>Database</environment> <super>Database.CTLibSession</super> <private>false</private> none accessProtect <imports></imports> <category>Database-CTLib THAPI</category> <attributes> <package>CTLibThapiEXDI</package> </attributes> </class> <comment> Database.CTLibThreadedSession
CTLibThreadedSession is the concrete implementation of multi-threaded session services using the Sybase library. Instance variables: accessProtect <Semaphore | nil> The Semaphore is used to serialize the access of Sybase thread-unsafe routines.
</comment> <class> <name>CTLibNTThreadedInterface</name> <environment>Database</environment> <super>Database.CTLibThreadedInterface</super> <private>false</private> none <imports> Database.CTLibNTThreadedInterfaceDictionary.* </imports> <category>Database-External-Libraries</category> <attributes> <includeFiles></includeFiles> <includeDirectories></includeDirectories> <libraryFiles><item>libcs.dll</item> <item>libct.dll</item> <item>libsybcs.dll</item> <item>libsybct.dll</item></libraryFiles> <libraryDirectories></libraryDirectories> false full <package>CTLibThapiEXDI</package> </attributes> </class> <comment> Database.CTLibNTThreadedInterface
CTLibNTThreadedInterface defines multi-threaded calling conventions for the Windows NT (Intel) Open Client CT-Library version 10.0.x and later.
</comment> <class> <name>CTLibHPUXThreadedInterface</name> <environment>Database</environment> <super>Database.CTLibThreadedInterface</super> <private>false</private> none <imports> Database.CTLibHPUXThreadedInterfaceDictionary.* </imports> <category>Database-External-Libraries</category> <attributes> <includeFiles></includeFiles> <includeDirectories></includeDirectories> <libraryFiles><item>libcomn.sl</item> <item>libinsck.sl</item> <item>libintl.sl</item> <item>libtcl.sl</item> <item>libct.sl</item> <item>libcs.sl</item> <item>libsybcomn.sl</item> <item>libsybinsck.sl</item> <item>libsybintl.sl</item> <item>libsybtcl.sl</item> <item>libsybct.sl</item> <item>libsybcs.sl</item></libraryFiles> <libraryDirectories></libraryDirectories> false full <package>CTLibThapiEXDI</package> </attributes> </class> <comment> Database.CTLibHPUXThreadedInterface
CTLibHPUXThreadedInterface defines multi-threaded calling conventions for the HPUX Open Client CT-Library version 10.0.x and later.
</comment> <class> <name>CTLibAOSFThreadedInterface</name> <environment>Database</environment> <super>Database.CTLibThreadedInterface</super> <private>false</private> none <imports> Database.CTLibAOSFThreadedInterfaceDictionary.* </imports> <category>Database-External-Libraries</category> <attributes> <includeFiles></includeFiles> <includeDirectories></includeDirectories> <libraryFiles><item>libcomn.so</item> <item>libintl.so</item> <item>libtcl.so</item> <item>libct.so</item> <item>libcs.so</item> <item>libsybcomn.so</item> <item>libsybintl.so</item> <item>libsybtcl.so</item> <item>libsybct.so</item> <item>libsybcs.so</item></libraryFiles> <libraryDirectories><item>$(SYBASE)/lib</item></libraryDirectories> true full <package>CTLibThapiEXDI</package> </attributes> </class> <comment> Database.CTLibAOSFThreadedInterface
CTLibAOSTThreadedInterface defines multi-threaded calling conventions for the AOSF Open Client CT-Library version 10.0.x and later.
</comment> <class> <name>CTLibAixThreadedInterface</name> <environment>Database</environment> <super>Database.CTLibThreadedInterface</super> <private>false</private> none <imports> Database.CTLibAixThreadedInterfaceDictionary.* </imports> <category>Database-External-Libraries</category> <attributes> <includeFiles></includeFiles> <includeDirectories></includeDirectories> <libraryFiles><item>libcomn.so.a</item> <item>libintl.so.a</item> <item>libtcl.so.a</item> <item>libct.so.a</item> <item>libcs.so.a</item> <item>libsybcomn.so.a</item> <item>libsybintl.so.a</item> <item>libsybtcl.so.a</item> <item>libsybct.so.a</item> <item>libsybcs.so.a</item></libraryFiles> <libraryDirectories><item>$(SYBASE)/lib</item></libraryDirectories> false full <package>CTLibThapiEXDI</package> </attributes> </class> <comment> Database.CTLibAixThreadedInterface
CTLibAixThreadedInterface defines multi-threaded calling conventions for the AIX Open Client CT-Library version 10.0.x and later.
</comment> <class> <name>CTLibThreadedConnection</name> <environment>Database</environment> <super>Database.CTLibConnection</super> <private>false</private> none accessProtect <imports></imports> <category>Database-CTLib THAPI</category> <attributes> <package>CTLibThapiEXDI</package> </attributes> </class> <comment> Database.CTLibThreadedConnection
CTLibThreadedConnection is the concrete class implementation of multi-threaded connection services using the Sybase library. Instance variables: accessProtect <Semaphore | nil> The Semaphore is used to serialize the access of Sybase thread-unsafe routines.
</comment> <class> <name>CTLibPowerMacThreadedInterface</name> <environment>Database</environment> <super>Database.CTLibThreadedInterface</super> <private>false</private> none <imports> Database.CTLibPowerMacThreadedInterfaceDictionary.* </imports> <category>Database-External-Libraries</category> <attributes> <includeFiles></includeFiles> <includeDirectories></includeDirectories> <libraryFiles><item>libcs</item> <item>libct</item> <item>libsybcs</item> <item>libsybct</item></libraryFiles> <libraryDirectories></libraryDirectories> false full <package>CTLibThapiEXDI</package> </attributes> </class> <comment> Database.CTLibPowerMacThreadedInterface
CTLibPowerMacThreadedInterface defines multi-threaded calling conventions for the PowerMac Open Client CT-Library version 10.0.x and later.
</comment> <class> <name>CTLibSolarisThreadedInterface</name> <environment>Database</environment> <super>Database.CTLibThreadedInterface</super> <private>false</private> none <imports> Database.CTLibSolarisThreadedInterfaceDictionary.* </imports> <category>Database-External-Libraries</category> <attributes> <includeFiles></includeFiles> <includeDirectories></includeDirectories> <libraryFiles><item>libcomn.so</item> <item>libintl.so</item> <item>libtcl.so</item> <item>libct.so</item> <item>libcs.so</item> <item>libsybcomn.so</item> <item>libsybintl.so</item> <item>libsybtcl.so</item> <item>libsybct.so</item> <item>libsybcs.so</item></libraryFiles> <libraryDirectories></libraryDirectories> false full <package>CTLibThapiEXDI</package> </attributes> </class> <comment> Database.CTLibSolarisThreadedInterface
CTLibSolarisThreadedInterface defines multi-threaded calling conventions for the Open Client CT-Library version 10.0.x and later on the Solaris platform.
</comment> <class> <name>CTLibWin16ThreadedInterface</name> <environment>Database</environment> <super>Database.CTLibThreadedInterface</super> <private>false</private> none <imports> Database.CTLibWin16ThreadedInterfaceDictionary.* </imports> <category>Database-External-Libraries</category> <attributes> <includeFiles></includeFiles> <includeDirectories></includeDirectories> <libraryFiles><item>wcslib.dll</item> <item>wctlib.dll</item> <item>wcssyblib.dll</item> <item>wctsyblib.dll</item></libraryFiles> <libraryDirectories></libraryDirectories> false full <package>CTLibThapiEXDI</package> </attributes> </class> <comment> Database.CTLibWin16ThreadedInterface
CTLibWin16ThreadedInterface defines multi-threaded calling conventions for the Windows 3.1 platform Open Client CT-Library version 10.0.x and later.
</comment> <name>RegisteredCTLibThreadedConnections</name> <environment>Database.CTLibThreadedConnection</environment> <private>false</private> <constant>false</constant> <category>private-registry</category> <initializer>Array new: 5</initializer> <attributes> <package>CTLibThapiEXDI</package> </attributes> <methods> Database.CTLibThreadedInterface <category>accessing</category>
csVersion ^self CS_VERSION_125
</methods> <methods> Database.CTLibThreadedInterface class <category>private</category>
platformSymbol "this must contain the platform symbol that will match that returned by determinePlatformType." "platform symbols known today include: #nt Windows/NT #win95 Windows95 #hp_unix HP/UX #sun5_unix Solaris #aix_unix AIX #alpha_unix DEC/Unix #os2 OS/2 #powermac Power Mac #mac Mac 68K #linux_i386_unix Linux" ^#unknown
</methods> <methods> Database.CTLibThreadedInterface class <category>parcel load/unload/save</category>
postLoadFrom: aParcel super postLoadFrom: aParcel
</methods> <methods> Database.CTLibLinuxThreadedInterface class <category>private</category>
platformSymbol "this must contain the platform symbol that will match that returned by determinePlatformType." ^#linux_i386_unix
</methods> <methods> Database.CTLibThreadedSession <category>private-execution</category>
acquireExternal "Acquire external resources." | xif pCmd rc errs | xif := self class xif. [ "Begin unwind protection" pCmd := xif PTR perform: xif mallocSelector with: 1. pCmd contents: nil. accessProtect critical: [rc := xif ct_cmd_alloc: self conn with: pCmd ]. ( traceLevel >= 2 ) ifTrue: [ (self traceStream) print: rc; nextPutAll: ' = ct_cmd_alloc( conn = '; nextPutAll: (self conn referentAddress printStringRadix: 16); nextPutAll: ', pCmd = '; nextPutAll: (pCmd referentAddress printStringRadix: 16); nextPutAll: ' )'; crtab; nextPutAll: 'cmd='; nextPutAll: (pCmd contents referentAddress printStringRadix: 16). self class trace: self emitTrace ]. self cmd: pCmd contents. textLimit isNil ifTrue: [ textLimit := 32768 "default" ]. "End unwind protection" ] ensure: [ pCmd notNil ifTrue: [ pCmd freePointer ]. ( rc isNil or: [ rc == xif CS_FAIL ] ) ifTrue: [ self cmd: nil. errs := self class connectionClass errorsOnQueue: self conn referentAddress. self class connectionClass externalDatabaseErrorSignal raiseWith: errs errorString: errs first dbmsErrorString ] ]
dismissExternal "Release the external resources." | xif rc | pRowsFetched == nil ifFalse: [ pRowsFetched freePointer. pRowsFetched := nil ]. self cmd isNil ifTrue: [ ^self ]. self cancelExternal. xif := self class xif. rc := xif ct_cmd_drop: self cmd. ( traceLevel >= 2 ) ifTrue: [ (self traceStream) print: rc; nextPutAll: '= ct_cmd_drop( cmd='; nextPutAll: (self cmd referentAddress printStringRadix: 16); nextPutAll: ' )'. self class trace: self emitTrace ]. self cmd: nil. rc == xif CS_SUCCEED ifFalse: [ self class connectionClass errorsOnQueue: self conn referentAddress]
executeExternal "Execute the prepared SQL text." "Since the Sybase CT-Library does not support the notion of preparing SQL, the actual prepare is done here together with the execute." | rc err xif | xif := self class xif. "Send the assembled query batch to the server and start it executing." accessProtect critical: [ rc := xif ct_send: self cmd ]. ( traceLevel >= 1 ) ifTrue: [ (self traceStream) print: rc; nextPutAll: ' = ct_send( cmd='; nextPutAll: (self cmd referentAddress printStringRadix: 16); nextPutAll: ' )'. self class trace: self emitTrace ]. (rc == xif CS_FAIL) ifTrue: [ err := self class connectionClass errorsOnQueue: self conn referentAddress. self class connectionClass unableToExecuteSQLSignal raiseWith: err errorString: err first dbmsErrorString ]
getResultsExternal "Get next set of results for an SQL statement and raise exceptions for any errors." | xif rc errs pRes signal | self aboutToAnswer. xif := self class xif. [ "Begin unwind protection." pRes := xif CS_INT perform: xif mallocSelector with: 1. accessProtect critical: [rc := xif ct_results: self cmd with: pRes ]. ( traceLevel >= 2 ) ifTrue: [ (self traceStream) print: rc; nextPutAll: ' = ct_results( cmd='; nextPutAll: (self cmd referentAddress printStringRadix: 16); nextPutAll: ', pRes='; nextPutAll: (pRes referentAddress printStringRadix: 16); nextPutAll: ' )'; crtab; nextPutAll: 'pRes contents= '; print: (pRes contents). self class trace: self emitTrace ]. (rc == xif CS_SUCCEED) ifTrue: [ res_type := pRes contents ] ifFalse: [ res_type := 0 ]. "End unwind protection." ] ensure: [ pRes == nil ifFalse: [ pRes freePointer ] ]. (rc == xif CS_CANCELED) ifTrue: [ self releaseBuffersAndAdaptors ]. "results have been cancelled" ( rc == xif CS_FAIL or: [ rc == xif CS_SUCCEED and: [res_type == xif CS_CMD_FAIL] ] ) ifFalse: [ ^rc ]. "Report the error detected." errs := self class connectionClass errorsOnQueue: self conn referentAddress. ( errs isNil or: [ errs isEmpty ] ) ifTrue: [ signal := connection class unableToExecuteSQLSignal ] ifFalse: [ | error connClass | error := errs first. signal := (connClass := connection class) perform: (connClass signalMap at: error dbmsErrorCode ifAbsent: [ #unableToExecuteSQLSignal ]). ]. signal raiseWith: errs errorString: errs first dbmsErrorString. ^rc
getResultsInfoExternal: infoType "get information about the results, typically get number of columns or a number of affected rows" | xif rc pResInfo resInfo errs | xif := self class xif. [ "Begin unwind protection." pResInfo := xif CS_INT perform: xif mallocSelector with: 1. accessProtect critical: [rc := xif ct_res_info: self cmd with: infoType with: pResInfo with: xif CS_UNUSED with: nil ]. resInfo := pResInfo contents. ( traceLevel >= 3 ) ifTrue: [ (self traceStream) print: rc; nextPutAll: ' = ct_res_info( cmd = '; nextPutAll: (self cmd referentAddress printStringRadix: 16); nextPutAll: ', infoType='; print: infoType; nextPutAll: ', pResInfo='; nextPutAll: (pResInfo referentAddress printStringRadix: 16); nextPutAll: ', buflen=CS_UNUSED, outlen=NULL'; nextPutAll: ' )'; crtab; nextPutAll: 'result= '; print: resInfo. self class trace: self emitTrace ]. "End unwind protection." ] ensure: [ pResInfo == nil ifFalse: [ pResInfo freePointer ] ]. (rc == xif CS_SUCCEED) ifFalse: [ "Report the error detected." errs := self class connectionClass errorsOnQueue: self conn referentAddress. ^self class connectionClass externalDatabaseErrorSignal raiseWith: errs errorString: errs first dbmsErrorString. ]. ^resInfo
</methods> <methods> Database.CTLibThreadedSession <category>private-answer set</category>
getBlockOfRowsExternal "Fetch the next block of rows into the memory allocated for this purpose." | xif rc err | xif := self class xif. ( pRowsFetched isNil ) ifTrue: [ pRowsFetched := xif CS_INT perform: xif mallocSelector with: 1 ]. pRowsFetched contents: 0. accessProtect critical: [ rc := xif ct_fetch: self cmd with: xif CS_UNUSED with: xif CS_UNUSED with: xif CS_UNUSED with: pRowsFetched ]. ( traceLevel >= 3 ) ifTrue: [ (self traceStream) print: rc; nextPutAll: ' = ct_fetch( cmd = '; nextPutAll: (self cmd referentAddress printStringRadix: 16); nextPutAll: ', type=CS_UNUSED, offset=CS_UNUSED, option=CS_UNUSED, ptr_rows_read='; nextPutAll: (pRowsFetched referentAddress printStringRadix: 16); nextPutAll: ' )'; crtab; nextPutAll: 'rows_read='; print: pRowsFetched contents. self class trace: self emitTrace ]. rowsInBlock := pRowsFetched contents. ( (rc == xif CS_ROW_FAIL) or: [rc == xif CS_FAIL] ) ifTrue: [ err := self class connectionClass errorsOnQueue: self conn referentAddress. self class connectionClass unableToFetchDataSignal raiseWith: err errorString: err first dbmsErrorString. ^self ]. totalRows := totalRows + rowsInBlock
</methods> <methods> Database.CTLibThreadedSession <category>initialize-release</category>
initialize super initialize. accessProtect := Semaphore forMutualExclusion.
</methods> <methods> Database.CTLibThreadedSession <category>private-cursor</category>
closeCursorExternal "Sybase doesn't really have a prepare concept, so the query assembled here isn't sent to the server until we actually execute." | xif rc err | xif := self class xif. "Give the expanded query text to the CT-Library." accessProtect critical: [ rc := xif ct_cursor: self cmd with: xif CS_CURSOR_CLOSE with: nil with: xif CS_UNUSED with: nil with: xif CS_UNUSED with: xif CS_DEALLOC ]. ( traceLevel >= 1 ) ifTrue: [ (self traceStream) print: rc; nextPutAll: ' = ct_cursor( cmd='; nextPutAll: (self cmd referentAddress printStringRadix: 16); nextPutAll: ', type=CS_CURSOR_CLOSE)'; nextPutAll: ', name=NULL'; nextPutAll: ', namelen=CS_UNUSED'; nextPutAll: ', query=NULL'; nextPutAll: ', buflen=CS_UNUSED'; nextPutAll: ', option=CS_DEALLOC)'. self class trace: self emitTrace ]. (rc == xif CS_SUCCEED) ifFalse: [ err := self class connectionClass errorsOnQueue: self conn referentAddress. self class connectionClass unableToExecuteSQLSignal raiseWith: err errorString: err first dbmsErrorString ]. self executeExternal. self resultsExternal
createCursorExternal "Sybase doesn't really have a prepare concept, so the query assembled here isn't sent to the server until we actually execute." | xif expandedQuery expandedQuery1 pExpandedQuery rc err curName cursorType | xif := self class xif. "Remove any prior return information." self returnStatus: nil. "Rebuild a query from the query fragments, expanding bind parameters in-line." queryFragments size == 1 ifTrue: [ expandedQuery := queryFragments at: 1 ] ifFalse: [ | queryStream | queryStream := WriteStream on: (String new: query size). queryStream nextPutAll: (queryFragments at: 1). 2 to: queryFragments size by: 2 do: [ :index | | bindOp value | bindOp := queryFragments at: index. (value := self inBindInputAt: bindOp) isNil ifTrue: [ queryStream nextPutAll: 'NULL' ] ifFalse: [ value printOnForCTLib: queryStream ]. queryStream nextPutAll: (queryFragments at: index + 1) ]. expandedQuery := queryStream contents ]. self scrollable ifTrue: [ cursorType := xif CS_SCROLL_CURSOR ] ifFalse: [ cursorType := xif CS_FOR_UPDATE ]. (curName := self cursorName) isNil ifTrue: [ curName := 'Cursor', (self cmd referentAddress printStringRadix: 16). self cursorName: curName. ]. "Give the expanded query text to the CT-Library." [ "Begin unwind protection" expandedQuery1 := expandedQuery asByteArrayEncoding: xif encoding. pExpandedQuery := expandedQuery1 perform: xif copyToHeapSelector. accessProtect critical: [ rc := xif ct_cursor: self cmd with: xif CS_CURSOR_DECLARE with: curName with: curName size with: pExpandedQuery with: expandedQuery1 size with: cursorType ]. ( traceLevel >= 1 ) ifTrue: [ (self traceStream) print: rc; nextPutAll: ' = ct_cursor( cmd='; nextPutAll: (self cmd referentAddress printStringRadix: 16); nextPutAll: ', type=CS_CURSOR_DECLARE)'; nextPutAll: ', name='; nextPutAll: cursorName; nextPutAll: ', namelen='; print: cursorName size; nextPutAll: ', query='; nextPutAll: expandedQuery; nextPutAll: ', buflen='; print: expandedQuery1 size; nextPutAll: ', option=)'; print: cursorType; nextPutAll: ' )'; cr. self class trace: self emitTrace ]. (rc == xif CS_SUCCEED) ifFalse: [ err := self class connectionClass errorsOnQueue: self conn referentAddress. self class connectionClass unableToExecuteSQLSignal raiseWith: err errorString: err first dbmsErrorString ]. accessProtect critical: [ rc := xif ct_cursor: self cmd with: xif CS_CURSOR_ROWS with: nil with: xif CS_UNUSED with: nil with: xif CS_UNUSED with: self blockFactor ]. ( traceLevel >= 1 ) ifTrue: [ (self traceStream) print: rc; nextPutAll: ' = ct_cursor( cmd='; nextPutAll: (self cmd referentAddress printStringRadix: 16); nextPutAll: ', type=CS_CURSOR_ROWS)'; nextPutAll: ', name=NULL'; nextPutAll: ', namelen=CS_UNUSED'; nextPutAll: ', query=NULL'; nextPutAll: ', buflen=CS_UNUSED'; nextPutAll: ', option=)'; print: self blockFactor; nextPutAll: ' )'; cr. self class trace: self emitTrace ]. (rc == xif CS_SUCCEED) ifFalse: [ err := self class connectionClass errorsOnQueue: self conn referentAddress. self class connectionClass unableToExecuteSQLSignal raiseWith: err errorString: err first dbmsErrorString ]. accessProtect critical: [ rc := xif ct_cursor: self cmd with: xif CS_CURSOR_OPEN with: nil with: xif CS_UNUSED with: nil with: xif CS_UNUSED with: xif CS_UNUSED ]. ( traceLevel >= 1 ) ifTrue: [ (self traceStream) print: rc; nextPutAll: ' = ct_cursor( cmd='; nextPutAll: (self cmd referentAddress printStringRadix: 16); nextPutAll: ', type=CS_CURSOR_OPEN)'; nextPutAll: ', name=NULL'; nextPutAll: ', namelen=CS_UNUSED'; nextPutAll: ', query=NULL'; nextPutAll: ', buflen=CS_UNUSED'; nextPutAll: ', option=CS_UNUSED)'. self class trace: self emitTrace ]. (rc == xif CS_SUCCEED) ifFalse: [ err := self class connectionClass errorsOnQueue: self conn referentAddress. self class connectionClass unableToExecuteSQLSignal raiseWith: err errorString: err first dbmsErrorString ]. "End unwind protection" ] ensure: [ pExpandedQuery notNil ifTrue: [ pExpandedQuery freePointer ] ].
</methods> <methods> Database.CTLibThreadedSession <category>private-binding</category>
bindExternal "Sybase doesn't really have a prepare concept, so the query assembled here isn't sent to the server until we actually execute." | xif expandedQuery expandedQuery1 pExpandedQuery rc err | self useCursor ifTrue: [ ^self createCursorExternal ]. xif := self class xif. "Remove any prior return information." self returnStatus: nil. "Rebuild a query from the query fragments, expanding bind parameters in-line." queryFragments size == 1 ifTrue: [ expandedQuery := queryFragments at: 1 ] ifFalse: [ | queryStream | queryStream := WriteStream on: (String new: query size). queryStream nextPutAll: (queryFragments at: 1). 2 to: queryFragments size by: 2 do: [ :index | | bindOp value | bindOp := queryFragments at: index. (value := self inBindInputAt: bindOp) isNil ifTrue: [ queryStream nextPutAll: 'NULL' ] ifFalse: [ value printOnForCTLib: queryStream ]. queryStream nextPutAll: (queryFragments at: index + 1) ]. expandedQuery := queryStream contents ]. "Give the expanded query text to the CT-Library." [ "Begin unwind protection" expandedQuery1 := expandedQuery asByteArrayEncoding: xif encoding. pExpandedQuery := expandedQuery1 perform: xif copyToHeapSelector. accessProtect critical: [ rc := xif ct_command: self cmd with: xif CS_LANG_CMD with: pExpandedQuery with: expandedQuery1 size with: xif CS_UNUSED ]. ( traceLevel >= 1 ) ifTrue: [ (self traceStream) print: rc; nextPutAll: ' = ct_command( cmd='; nextPutAll: (self cmd referentAddress printStringRadix: 16); nextPutAll: ', query='; nextPutAll: expandedQuery; nextPutAll: ', buflen='; print: expandedQuery1 size; nextPutAll: ', option=CS_UNUSED)'. self class trace: self emitTrace ]. "End unwind protection" ] ensure: [ pExpandedQuery notNil ifTrue: [ pExpandedQuery freePointer ] ]. (rc == xif CS_SUCCEED) ifFalse: [ err := self class connectionClass errorsOnQueue: self conn referentAddress. self class connectionClass unableToExecuteSQLSignal raiseWith: err errorString: err first dbmsErrorString ]
</methods> <methods> Database.CTLibThreadedSession class <category>accessing</category>
connectionClass "Answer the class to use for connection objects associated with receiver." ^CTLibThreadedConnection
</methods> <methods> Database.CTLibNTThreadedInterface class <category>private</category>
platformSymbol "this must contain the platform symbol that will match that returned by determinePlatformType." ^#nt
</methods> <methods> Database.CTLibHPUXThreadedInterface class <category>private</category>
platformSymbol "this must contain the platform symbol that will match that returned by determinePlatformType." ^#hp_unix
</methods> <methods> Database.CTLibAOSFThreadedInterface class <category>private</category>
platformSymbol "this must contain the platform symbol that will match that returned by determinePlatformType." ^#alpha_unix
</methods> <methods> Database.CTLibAixThreadedInterface class <category>private</category>
platformSymbol "this must contain the platform symbol that will match that returned by determinePlatformType." ^#aix_unix
</methods> <methods> Database.CTLibThreadedConnection <category>private-library calls</category>
acquireExternal: aPassword "Acquire the external resources involved with a connection" | uid pwd env env1 errs rc xif pEnv | self initializeExternal. self setInterfaceFileExternal. self setLoginTimeoutExternal. uid := self username. [ uid isString ] whileFalse: [ uid := self class requiredUsernameSignal raiseRequest ]. pwd := aPassword. [ pwd isString ] whileFalse: [ pwd := self class requiredPasswordSignal raiseRequest ]. (env := self environment) isNil ifTrue: [ env := self class defaultEnvironment ]. [ env isString ] whileFalse: [ env := self class requiredEnvironmentSignal raiseRequest ]. env := self class mapLogical: env. xif := self class xif. "set properties for connecting" self setPropsExternal: xif CS_USERNAME string: uid. self setPropsExternal: xif CS_PASSWORD string: pwd. self setPropsExternal: xif CS_HOSTNAME string: hostName. self setPropsExternal: xif CS_APPNAME string: appName. [ "Begin unwind protection (level 1)" [ "Begin unwind protection (level 2)" env1 := env asByteArrayEncoding: xif encoding. pEnv := env1 perform: xif copyToHeapSelector. accessProtect critical: [ rc := xif ct_connect: self conn with: pEnv with: env1 size ]. ( traceLevel >= 2 ) ifTrue: [ (self traceStream) print: rc; nextPutAll: ' = ct_connect( conn='; nextPutAll: (self conn referentAddress printStringRadix: 16); nextPutAll: ', srv_name=', env; nextPutAll: ', snamelen='; print: env1 size; nextPutAll: ' )'. self class trace: self emitTrace ] "End unwind protection (level 1)" ] ensure: [ pEnv notNil ifTrue: [ pEnv freePointer ]. ( rc isNil or: [ rc == xif CS_SUCCEED ] ) ifFalse: [ errs := self class errorsOnQueue: self conn referentAddress. self class unableToConnectToSQLserverSignal raiseWith: errs errorString: errs first dbmsErrorString] ] "End unwind protection (level 2)" ] ifCurtailed: [ self dismissExternal ]
initializeExternal "Allocate/initialize CTLib context, set callbacks, allocate CTLib connection." "Note: performance can be slightly improved by moving context and callbacks initialization to the class initialization. Doesn't look like a big gain." | rc xif pPointer | xif := self class xif. xif loadLibraries. self contextHolder: nil asValue. self connHolder: nil asValue. [ "Begin unwind protection" pPointer := xif PTR perform: xif mallocSelector with: 1. pPointer contents: nil. "allocate and initialize CTLib context" accessProtect critical: [ rc := xif cs_ctx_alloc: self csVersion with: pPointer ]. ( traceLevel >= 1 ) ifTrue: [ (self traceStream) print: rc; nextPutAll: ' = ct_ctx_alloc( csVersion='; print: xif csVersion; nextPutAll: ', pPointer='; nextPutAll: (pPointer referentAddress printStringRadix: 16); nextPutAll: ' )'; crtab; nextPutAll: 'context='; nextPutAll: (pPointer contents referentAddress printStringRadix: 16). self class trace: self emitTrace ]. self context: pPointer contents. accessProtect critical: [ rc := xif ct_init: self context with: self csVersion ]. ( traceLevel >= 1 ) ifTrue: [ (self traceStream) print: rc; nextPutAll: ' = ct_init( context='; nextPutAll: (self context referentAddress printStringRadix: 16); nextPutAll: ', version='; print: xif csVersion; nextPutAll: ')'. self class trace: self emitTrace ]. "set callbacks for error processing" self setClientMsgHandlerCB. self setServerMsgHandlerCB. "allocate CTLib connection" pPointer contents: nil. rc := xif ct_con_alloc: self context with: pPointer. ( traceLevel >= 1 ) ifTrue: [ (self traceStream) print: rc; nextPutAll: ' = ct_con_alloc( context='; nextPutAll: (self context referentAddress printStringRadix: 16); nextPutAll: ', pPointer='; nextPutAll: (pPointer referentAddress printStringRadix: 16); nextPutAll: ' )'; crtab; nextPutAll: 'conn='; nextPutAll: (pPointer contents referentAddress printStringRadix: 16). self class trace: self emitTrace ]. self conn: pPointer contents. self class acquireQueue: self conn referentAddress. "End unwind protection." ] ensure: [ pPointer notNil ifTrue: [ pPointer freePointer ]. ( rc isNil or: [ rc ~= xif CS_SUCCEED ] ) ifTrue: [ self dismissExternal. "Usually this error occurs when either the Object Engine has not been linked with the CT-Library libraries (Unix), or the DLLs for those libraries cannot be found in the search path (Windows, OS/2, et al)." self class externalDatabaseLibraryInaccessibleSignal raise ] ]
setClientMsgHandlerCB "define and set a callback for messages coming from the client" | rc xif | xif := self class xif. "define the callback" clientMsgHandlerCB := CCallback do: [ :context :conn :msg | "ignore warnings" (msg memberAt: #msgnumber) > 0 ifTrue: [ self class queue: conn newError: ( CTLibError new severity: (msg memberAt: #severity); dbmsErrorCode: (msg memberAt: #msgnumber); dbmsErrorString: ((msg memberAt: #msgstring) copyCStringFromHeap: xif encoding); osErrorCode: (msg memberAt: #osnumber); osErrorString: ((msg memberAt: #osstring) copyCStringFromHeap: xif encoding)) ]. xif CS_SUCCEED "return CS_SUCCEED" ] ofType: xif clientMsgHandlerType. "set the callback" accessProtect critical: [ rc := xif ct_callback: self context with: nil with: xif CS_SET with: xif CS_CLIENTMSG_CB with: clientMsgHandlerCB ]. ( traceLevel >= 2 ) ifTrue: [ (self traceStream) print: rc; nextPutAll: ' = ct_callback( context='; nextPutAll: (self context referentAddress printStringRadix: 16); nextPutAll: ', NULL, CS_SET, CS_CLIENTMSG_CB, ..)'. self class trace: self emitTrace ]
setInterfaceFileExternal "Specify the path of the interfaces file that will be searched during subsequent calls to ct_connect()." | rc xif errs fileName pFileName | interfaceFileName isNil ifTrue: [ ^self ]. xif := self class xif. fileName := interfaceFileName asByteArrayEncoding: xif encoding. [ "Begin unwind protection (level 1)" [ "Begin unwind protection (level 2)" pFileName := fileName perform: xif copyToHeapSelector. accessProtect critical: [ rc := xif ct_config: self context with: xif CS_SET with: xif CS_IFILE with: pFileName with: fileName size with: nil ]. ( traceLevel >= 2 ) ifTrue: [ (self traceStream) print: rc; nextPutAll: ' = ct_config( context='; nextPutAll: (self context referentAddress printStringRadix: 16); nextPutAll: ', action=CS_SET, property=CS_IFILE, fileName='; nextPutAll: interfaceFileName; nextPutAll: ', buflen='; print: fileName size; nextPutAll: ', outlen=NULL'. self class trace: self emitTrace ]. "End unwind protection (level 1)" ] ensure: [ pFileName notNil ifTrue: [ pFileName freePointer ]. ( rc isNil or: [ rc == xif CS_SUCCEED ] ) ifFalse: [ errs := self class errorsOnQueue: self conn referentAddress. self class externalDatabaseErrorSignal raiseWith: errs errorString: errs first dbmsErrorString ] ] "End unwind protection (level 2)" ] ifCurtailed: [ self dismissExternal ]
setLoginTimeoutExternal "Set the length of time in seconds that CT-Library will wait for a login response after calling ct_connect()." | rc errs xif pSeconds | loginTimeoutSeconds isNil ifTrue: [ ^self ]. xif := self class xif. [ "Begin unwind protection (level 1)" [ "Begin unwind protection (level 2)" pSeconds := xif CS_INT perform: xif mallocSelector with: 1. pSeconds contents: loginTimeoutSeconds. accessProtect critical: [ rc := xif ct_config: self context with: xif CS_SET with: xif CS_LOGIN_TIMEOUT with: pSeconds with: xif CS_UNUSED with: nil ]. ( traceLevel >= 2 ) ifTrue: [ (self traceStream) print: rc; nextPutAll: ' = ct_config( context='; nextPutAll: (self context referentAddress printStringRadix: 16); nextPutAll: ', action=CS_SET, property=CS_LOGIN_TIMEOUT, seconds='; print: loginTimeoutSeconds; nextPutAll: ', buflen=CS_UNUSED, outlen=NULL'. self class trace: self emitTrace ]. "End unwind protection (level 1)" ] ensure: [ pSeconds notNil ifTrue: [ pSeconds freePointer ]. ( rc isNil or: [ rc == xif CS_SUCCEED ] ) ifFalse: [ errs := self class errorsOnQueue: self conn referentAddress. self class externalDatabaseErrorSignal raiseWith: errs errorString: errs first dbmsErrorString ] ] "End unwind protection (level 2)" ] ifCurtailed: [ self dismissExternal ]
setPropsExternal: property string: value "set a specified property for the connection structure" | rc xif value1 pValue errs | value isNil ifTrue: [ ^self ]. xif := self class xif. value1 := value asByteArrayEncoding: xif encoding. [ "Begin unwind protection (level 1)" [ "Begin unwind protection (level 2)" pValue := value1 perform: xif copyToHeapSelector. accessProtect critical: [ rc := xif ct_con_props: self conn with: xif CS_SET with: property with: pValue with: value1 size with: nil ]. ( traceLevel >= 2 ) ifTrue: [ (self traceStream) print: rc; nextPutAll: ' = ct_con_props( conn='; nextPutAll: (self conn referentAddress printStringRadix: 16); nextPutAll: ', action=CS_SET, property='; print: property; nextPutAll: ', value='; nextPutAll: value; nextPutAll: ', length='; print: value1 size; nextPutAll: ', outlen=NULL)'. self class trace: self emitTrace ]. "End unwind protection (level 1)" ] ensure: [ pValue notNil ifTrue: [ pValue freePointer ]. ( rc isNil or: [ rc == xif CS_SUCCEED ] ) ifFalse: [ errs := self class errorsOnQueue: self conn referentAddress. self class externalDatabaseErrorSignal raiseWith: errs errorString: errs first dbmsErrorString ] ] "End unwind protection (level 2)" ] ifCurtailed: [ self dismissExternal ]
setServerMsgHandlerCB "define and set a callback for messages coming from the server" | rc xif | xif := self class xif. "define the callback" serverMsgHandlerCB := CCallback do: [ :context :conn :msg | "ignore warnings" (msg memberAt: #severity) > 10 ifTrue: [ self class queue: conn newError: ( CTLibError new dbmsErrorCode: (msg memberAt: #msgnumber); msgstate: (msg memberAt: #state); severity: (msg memberAt: #severity); dbmsErrorString: ((msg memberAt: #text) copyCStringFromHeap: xif encoding); srvname: ((msg memberAt: #svrname) copyCStringFromHeap: xif encoding); procname: ((msg memberAt: #proc) copyCStringFromHeap: xif encoding); line: (msg memberAt: #line) ) ]. xif CS_SUCCEED "return CS_SUCCEED" ] ofType: xif serverMsgHandlerType. "set the callback" accessProtect critical: [ rc := xif ct_callback: self context with: nil with: xif CS_SET with: xif CS_SERVERMSG_CB with: serverMsgHandlerCB ]. ( traceLevel >= 2 ) ifTrue: [ (self traceStream) print: rc; nextPutAll: ' = ct_callback( context='; nextPutAll: (self context referentAddress printStringRadix: 16); nextPutAll: ', NULL, CS_SET, CS_SERVERMSG_CB, ..)'. self class trace: self emitTrace ]
</methods> <methods> Database.CTLibThreadedConnection <category>connections</category>
getSession "Answer an instance of the driver's subclass of ExternalDatabaseSession." "this needs access protection when multiple processes contain sessions which were obtained from a common connection" accessProtect critical: [^super getSession].
</methods> <methods> Database.CTLibThreadedConnection <category>initialize-release</category>
initialize super initialize. accessProtect := Semaphore forMutualExclusion.
</methods> <methods> Database.CTLibThreadedConnection class <category>class initialization</category>
initialize "CTLibThreadedConnection initialize" super initialize. PlatformType := self platformType. self initializeExternalInterfaceMap.
initializeExternalInterfaceMap "self initializeExternalInterfaceMap" xifMap := IdentityDictionary new. self privateThreadedInterfaces do: [:each | xifMap at: (each platformSymbol) put: each name]
privateThreadedInterfaces "Return collection of loaded threaded interfaces note - this method depends on the naming convention that threaded interfaces have the word Threaded in them, and non-threaded do not -- e.g. CTLibThreadedNTInterface" ^CTLibThreadedInterface withAllSubclasses
</methods> <methods> Database.CTLibThreadedConnection class <category>private-accessing</category>
interfaceClass "Answer the class to use as the CTLibInterface for the current platform." | interfaceClassName | interfaceClassName := xifMap at: self platformType ifAbsent: [nil]. ^self environment at: interfaceClassName ifAbsent: [nil].
sessionClass "Answer the class to use for session objects associated with receiver." ^CTLibThreadedSession
</methods> <methods> Database.CTLibThreadedConnection class <category>threading</category>
isThreaded ^true
</methods> <methods> Database.CTLibThreadedConnection class <category>accessing</category>
kind "Answer a symbol representing the type of DMBS the receiver provides services for." ^#'SYBASE-CTLib Threaded'
</methods> <methods> Database.CTLibThreadedConnection class <category>private-registry</category>
registry ^RegisteredCTLibThreadedConnections
registry: aCollection RegisteredCTLibThreadedConnections := aCollection
</methods> <methods> Database.CTLibPowerMacThreadedInterface class <category>private</category>
platformSymbol ^#Power_MacOSX
</methods> <methods> Database.CTLibSolarisThreadedInterface class <category>private</category>
platformSymbol ^#sun5_unix
</methods> <methods> Database.CTLibWin16ThreadedInterface class <category>private</category>
platformSymbol ^#win32s
</methods> <methods> Database.CTLibThreadedInterface <category>procedures</category>
cs_ctx_alloc: version with: outptr <C: CS_RETCODE _threaded cs_ctx_alloc(CS_INT version, CS_CONTEXT * * outptr)> ^self externalAccessFailed
cs_ctx_drop: context <C: CS_RETCODE _threaded cs_ctx_drop(CS_CONTEXT * context)> ^self externalAccessFailed
ct_bind: cmd with: item with: datafmt with: buf with: outputlen with: indicator <C: CS_RETCODE _threaded ct_bind(CS_COMMAND * cmd, CS_INT item, CS_DATAFMT * datafmt, CS_VOID * buf, CS_INT * outputlen, CS_SMALLINT * indicator)> ^self externalAccessFailed
ct_callback: context with: connection with: action with: type with: func <C: CS_RETCODE _threaded ct_callback(CS_CONTEXT * context, CS_CONNECTION * connection, CS_INT action, CS_INT type, CS_VOID * func)> ^self externalAccessFailed
ct_cancel: connection with: cmd with: type <C: CS_RETCODE _threaded ct_cancel(CS_CONNECTION * connection, CS_COMMAND * cmd, CS_INT type)> ^self externalAccessFailed
ct_close: connection with: option <C: CS_RETCODE _threaded ct_close(CS_CONNECTION * connection, CS_INT option)> ^self externalAccessFailed
ct_cmd_alloc: connection with: cmdptr <C: CS_RETCODE _threaded ct_cmd_alloc(CS_CONNECTION * connection, CS_COMMAND * * cmdptr)> ^self externalAccessFailed
ct_cmd_drop: cmd <C: CS_RETCODE _threaded ct_cmd_drop(CS_COMMAND * cmd)> ^self externalAccessFailed
ct_command: cmd with: type with: buf with: buflen with: option <C: CS_RETCODE _threaded ct_command(CS_COMMAND * cmd, CS_INT type, CS_CHAR * buf, CS_INT buflen, CS_INT option)> ^self externalAccessFailed
ct_config: context with: action with: property with: buf with: buflen with: outlen <C: CS_RETCODE _threaded ct_config(CS_CONTEXT * context, CS_INT action, CS_INT property, CS_VOID * buf, CS_INT buflen, CS_INT * outlen)> ^self externalAccessFailed
ct_connect: connection with: server_name with: snamelen <C: CS_RETCODE _threaded ct_connect(CS_CONNECTION * connection, CS_CHAR * server_name, CS_INT snamelen)> ^self externalAccessFailed
ct_con_alloc: context with: connection <C: CS_RETCODE _threaded ct_con_alloc(CS_CONTEXT * context, CS_CONNECTION * * connection)> ^self externalAccessFailed
ct_con_drop: connection <C: CS_RETCODE _threaded ct_con_drop(CS_CONNECTION * connection)> ^self externalAccessFailed
ct_con_props: connection with: action with: property with: buf with: buflen with: outlen <C: CS_RETCODE _threaded ct_con_props(CS_CONNECTION * connection, CS_INT action, CS_INT property, CS_VOID * buf, CS_INT buflen, CS_INT * outlen)> ^self externalAccessFailed
ct_describe: cmd with: item with: datafmt <C: CS_RETCODE _threaded ct_describe(CS_COMMAND * cmd, CS_INT item, CS_DATAFMT * datafmt)> ^self externalAccessFailed
ct_exit: context with: option <C: CS_RETCODE _threaded ct_exit(CS_CONTEXT * context, CS_INT option)> ^self externalAccessFailed
ct_fetch: cmd with: type with: offset with: option with: count <C: CS_RETCODE _threaded ct_fetch(CS_COMMAND * cmd, CS_INT type, CS_INT offset, CS_INT option, CS_INT * count)> ^self externalAccessFailed
ct_init: context with: version <C: CS_RETCODE _threaded ct_init(CS_CONTEXT * context, CS_INT version)> ^self externalAccessFailed
ct_options: connection with: action with: option with: param with: paramlen with: outlen <C: CS_RETCODE _threaded ct_options(CS_CONNECTION * connection, CS_INT action, CS_INT option, CS_VOID * param, CS_INT paramlen, CS_INT * outlen)> ^self externalAccessFailed
ct_results: cmd with: result_type <C: CS_RETCODE _threaded ct_results(CS_COMMAND * cmd, CS_INT * result_type)> ^self externalAccessFailed
ct_res_info: cmd with: operation with: buf with: buflen with: outlen <C: CS_RETCODE _threaded ct_res_info(CS_COMMAND * cmd, CS_INT operation, CS_VOID * buf, CS_INT buflen, CS_INT * outlen)> ^self externalAccessFailed
ct_send: cmd <C: CS_RETCODE _threaded ct_send(CS_COMMAND * cmd)> ^self externalAccessFailed
</methods> <initialize> Database.CTLibThreadedConnection </initialize> "Imported Classes:" self error: 'Attempting to file-in parcel imports. Choose terminate or close' <class> <name>CTLibInterface</name> <environment>Database</environment> <super>External.ExternalInterface</super> <private>false</private> none encoding getSelectorMap fSqlTypeToConversionMap fetchBufferSize putSelectorMap fSqlTypeFromConversionMap libraryLoaded fSqlTypeToServerTypeConversionMap <imports> Database.CTLibInterfaceDictionary.* </imports> <category>Database-External-Libraries</category> <attributes> <includeFiles></includeFiles> <includeDirectories></includeDirectories> <libraryFiles></libraryFiles> <libraryDirectories></libraryDirectories> true full <package>CTLibEXDI</package> </attributes> </class> <class> <name>CTLibConnection</name> <environment>Database</environment> <super>Database.ExternalDatabaseConnection</super> <private>false</private> none contextHolder connHolder appName hostName interfaceFileName loginTimeoutSeconds clientMsgHandlerCB serverMsgHandlerCB csVersion signalMap <imports></imports> <category>Database-CTLib</category> <attributes> <package>CTLibEXDI</package> </attributes> </class> <class> <name>CTLibSession</name> <environment>Database</environment> <super>Database.ExternalDatabaseSession</super> <private>false</private> none cmdHolder returnStatus textLimit reasonPointer currentRowIndex totalRows rowsInBlock pRowsFetched res_type rowCount useCursor cursorName <imports></imports> <category>Database-CTLib</category> <attributes> <package>CTLibEXDI</package> </attributes> </class>