From VisualWorks®, 7.5 of April 3, 2007 on April 3, 2007 at 1:22:27 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>OracleConnectionPool</name> <environment>Database</environment> <super>Core.Object</super> <private>false</private> none henvHolder herrHolder hcpoolHolder environment username password poolName poolNameLen connMin connMax connIncr connection connections <imports></imports> <category>Database-Oracle</category> <attributes> <package>OracleThapiCPEXDI</package> </attributes> </class> <comment> Database.OracleConnectionPool
OracleConnectionPool is the concrete class implementation of connection pooling using the Oracle (9 and above) OCI library. Instance Variables: connection <OracleThreadedConnection> connection is used to connect to the API in OracleThapiEXDI. connections <Set> connections is the collection of the connections using this connection pool. connIncr <SmallInteger> The next increment for connections to be opened to the database if the current number of connections are less than connMax. connMax <SmallInteger> The maximum number of connections that can be opened to the database. connMin <SmallInteger> The minimum number of connections in the connection pool. poolName <String> The name of the connection pool connected to. poolNameLen <SmallInteger> The length of the string pointed to by poolName. hcpoolHolder <ValueHolder> A private value holder which remembers the pointer for the current OCI environment handle. henvHolder <ValueHolder on: (CPointer | nil)> A private value holder which remembers the pointer for the current OCI environment handle, if any. The value holder is shared with the executor object. herrHolder <ValueHolder on: (CPointer | nil)> A private value holder which remembers the pointer for the current OCI error handle, if any. The value holder is shared with the executor object. username <String | nil> Name of current user; driver will signal if required and == nil. password <String | nil> Password of current user; driver will signal if required and == nil. environment <String | nil> Logical or physical name for environment; driver will signal if required and == nil.
</comment> <methods> Database.OracleConnectionPool <category>pool</category>
create "Acquire the external resources involved with a connection pool to the SQL-environment." | xif name pw env connClass conn | connClass := self class connectionClass. xif := connClass xif. conn := self connection. name := self username. [ name isString ] whileFalse: [ name := connClass requiredUsernameSignal raiseRequest ]. pw := self password. [ pw isString ] whileFalse: [ pw := connClass requiredPasswordSignal raiseRequest ]. (env := self environment) isNil ifTrue: [ env := connClass defaultEnvironment ]. [ env isString ] whileFalse: [ env := connClass requiredEnvironmentSignal raiseRequest ]. env := connClass mapLogical: env. [ "Begin unwind protection (1)" "Allocate necessary handles." conn unprotectedAllocHenv. conn unprotectedAllocHerr. self henv: conn henv. self herr: conn herr. ["Begin unwind protection (2)" self connectionPoolCreateExternal. ( (name size == 0) and: [ pw size == 0 ]) ifTrue: [ conn authenticationMode: xif OCI_CRED_EXT. ] ifFalse: [ conn authenticationMode: xif OCI_CRED_RDBMS. ]. "End unwind protection (2)" ] ifCurtailed: [self unprotectedFreeHcpool ]. "End unwind protection (1)" ] ifCurtailed: [ "Something went wrong so we must implicitly free any handles we've allocated." conn unprotectedFreeHerr. conn unprotectedFreeHenv. ].
destroy | conns conn | (conns := self connections) isEmpty ifFalse: [ conns do: [ :each | (each isConnected) ifTrue:[ each disconnect ]]. ]. conn := self connection. [ "Begin unwind protection (1)" self connectionPoolDestroyExternal. "End unwind protection (1)" ] ensure:[ self unprotectedFreeHcpool. conn unprotectedFreeHerr. conn unprotectedFreeHenv ].
getConnection ^self class connectionClass newForConnectionPool: self
getConnectionBusyCount "Returns the number of busy connections." ^self connection getAttribute:#OCI_ATTR_CONN_BUSY_COUNT descriptor: self hcpool type: #OCI_HTYPE_CPOOL
getConnectionOpenCount "Returns the number of open connections." ^self connection getAttribute:#OCI_ATTR_CONN_OPEN_COUNT descriptor: self hcpool type: #OCI_HTYPE_CPOOL
getConnectionTimeout "Get connections timeout value (in seconds)." ^self connection getAttribute:#OCI_ATTR_CONN_TIMEOUT descriptor: self hcpool type: #OCI_HTYPE_CPOOL
setConnectionTimeout: anInteger "Connections idle for more than this time value (in seconds) are terminated, if this attribute is not set, the connections are never timed out." self connection setAttribute: anInteger type: #OCI_ATTR_CONN_TIMEOUT descriptor: self hcpool type: #OCI_HTYPE_CPOOL
</methods> <methods> Database.OracleConnectionPool <category>accessing</category>
connections "Returns the collection of the connections in the connection pool." ^connections
connIncr "Get the next increment for connections to be opened to the database if the current number of connections are less than connMax." ^connIncr
connIncr: anInteger "Set the next increment for connections to be opened to the database if the current number of connections are less than connMax." connIncr := anInteger
connMax "Get the maximum number of connections that can be opened to the database." ^connMax
connMax: anInteger "Set the maximum number of connections that can be opened to the database." connMax := anInteger
connMin "Get the minimum number of connections in the connection pool." ^connMin
connMin: anInteger "Set the minimum number of connections in the connection pool." connMin := anInteger
environment "Answer the environment to use when connecting to the SQL-environment." ^environment
environment: aString "Set the environment to use when connecting to the SQL-environment. An empty string should be used to specify the 'default' environment. If the environment is nil, the driver will raise a proceedable exception (requiredEnvironmentSignal on a connection class) when connecting." environment := aString
password "Answer the password to use when connecting to the SQL-environment." ^password
password: aString "Set the password to use when connecting to the SQL-environment. Passwords are not required by all database systems (or on all platforms). An empty string should be used for the no-password case. If the password is nil, the driver will raise a proceedable exception (requiredPasswordSignal on a connection class) when connecting." password := aString
poolName "Returns the name of the connection pool." ^poolName
poolName: aString "Sets the name of the connection pool." poolName := aString
poolNameLen "Gets the length of the string pointed to by poolName." ^poolNameLen
poolNameLen: anInteger "Sets the length of the string pointed to by poolName." poolNameLen := anInteger
username "Answer the username to use when connecting to the SQL-environment." ^username
username: aString "Set the username to use when connecting to the SQL-environment. An empty string should be used to connect as the default user unless the driver requires something else. If the username is nil, the driver will raise a proceedable exception (requiredUsernameSignal on a connection class) when connecting." username := aString
</methods> <methods> Database.OracleConnectionPool <category>private-accessing</category>
connection ^connection
connection: aConnection connection := aConnection
hcpool ^hcpoolHolder value
hcpool: aCPointerOrNil hcpoolHolder value: aCPointerOrNil.
hcpoolHolder ^hcpoolHolder
hcpoolHolder: aValueHolder hcpoolHolder := aValueHolder
henv ^henvHolder value
henv: aCPointerOrNil henvHolder value: aCPointerOrNil.
henvHolder ^henvHolder
henvHolder: aValueHolder henvHolder := aValueHolder
herr ^herrHolder value
herr: aCPointerOrNil herrHolder value: aCPointerOrNil.
herrHolder ^herrHolder
herrHolder: aValueHolder herrHolder := aValueHolder
</methods> <methods> Database.OracleConnectionPool <category>initialize-release</category>
initialize "Establish initial value for instance variables. OracleConnectionPool initialize." henvHolder := nil asValue. herrHolder := nil asValue. hcpoolHolder := nil asValue. connMin := 1. connMax := 5. connIncr := 1. connection := self class connectionClass new. connections := Set new.
</methods> <methods> Database.OracleConnectionPool <category>private-handles</category>
unprotectedAllocHcpool | xif connClass conn hcpoolPointerPointer | connClass := self class connectionClass. xif := connClass xif. conn := self connection. ["Begin unwind protection (1)" hcpoolPointerPointer := xif OCICPool pointerType perform: xif mallocSelector with: 1. conn allocHandlePointerExternal: hcpoolPointerPointer type: #OCI_HTYPE_CPOOL. self hcpool: hcpoolPointerPointer contents. "End unwind protection (1)"] ensure: [ hcpoolPointerPointer == nil ifFalse: [ hcpoolPointerPointer freePointer ] ].
unprotectedFreeHcpool | hcpool | self connection freeHandlePointerExternal: self hcpool type: #OCI_HTYPE_CPOOL. (hcpool := self hcpool) == nil ifFalse: [ hcpool freePointer ].
</methods> <methods> Database.OracleConnectionPool <category>private-execution</category>
connectionPoolCreateExternal "Create a connection pool." | rtval xif herr hcpool henv connClass conn szPoolNamePointerPointer poolNameLenPointer poolNamePointerType poolNameLenPointerType address lenAddress | connClass := self class connectionClass. xif := connClass xif. conn := self connection. henv := self henv. herr := self herr. self unprotectedAllocHcpool. hcpool := self hcpool. [ "Begin unwind protection (1)" poolNamePointerType := xif OraText pointerType. address := poolNamePointerType primMalloc: 128 pointerKind: poolNamePointerType kind. szPoolNamePointerPointer := CPointer new newDatum: address ofType: poolNamePointerType pointerType. poolNameLenPointerType := CIntegerType short pointerType. lenAddress := poolNameLenPointerType primMalloc: 4 pointerKind: poolNameLenPointerType kind. poolNameLenPointer := CPointer new newDatum: lenAddress ofType: poolNameLenPointerType. rtval := xif OCIConnectionPoolCreate: henv with: herr with: hcpool with: szPoolNamePointerPointer with: poolNameLenPointer with: self environment with: self environment size with: self connMin with: self connMax with: self connIncr with: self username with: self username size with: self password with: self password size with: (xif OCI_DEFAULT). poolName := szPoolNamePointerPointer contents copyCStringFromHeap. poolNameLen := poolNameLenPointer contents. "End unwind protection (1)" ] ensure:[ szPoolNamePointerPointer == nil ifFalse: [ szPoolNamePointerPointer freePointer ]. poolNameLenPointer == nil ifFalse: [ poolNameLenPointer freePointer ]. ]. (rtval == xif OCI_SUCCESS) ifFalse: [ | errs | errs := conn getErrors. ^connClass unableToCreateConnectionPoolSignal raiseWith: errs errorString: errs first dbmsErrorString ].
connectionPoolDestroyExternal "Destroy the connection pool." | rtval xif herr hcpool connClass conn | connClass := self class connectionClass. conn := self connection. xif := connClass xif. herr := self herr. hcpool := self hcpool. rtval := xif OCIConnectionPoolDestroy: hcpool with: herr with: (xif OCI_DEFAULT). (rtval == xif OCI_SUCCESS) ifFalse: [ | errs | errs := conn getErrors. ^connClass unableToDestroyConnectionPoolSignal raiseWith: errs errorString: errs first dbmsErrorString ].
</methods> <methods> Database.OracleConnectionPool class <category>private-accessing</category>
connectionClass "Answer the class to use for connection objects associated with the receiver." ^OracleThreadedConnection
</methods> <methods> Database.OracleConnectionPool class <category>instance creation</category>
new ^self basicNew initialize
</methods> <methods> Database.OracleConnectionPool class <category>examples</category>
example1 " Create the connection pool, the username and password are not necessarily the same as that in each connection in the pool. " "OracleConnectionPool example1" | aBlock pool mutex isWorking answers numBusy data | pool := OracleConnectionPool new. pool username: 'scott'; password: 'tiger'; environment: 'jazzbo81.cincom.com'. pool create. Transcript show: 'New pool with timeout = ' , pool getConnectionTimeout printString; cr. answers := Dictionary new. isWorking := Semaphore new. mutex := Semaphore forMutualExclusion. aBlock := [:tableName | | conn sess ansStrm | conn := pool getConnection. conn username: 'scott'; password: 'tiger'. conn connect. sess := conn getSession. sess prepare: 'select * from ' , tableName. sess execute. ansStrm := sess answer. data := ansStrm upToEnd. sess disconnect. conn disconnect. mutex critical: [answers at: tableName put: data. "Don't signal until all three connections have been put to rest." answers size = 3 ifTrue: [isWorking signal]]]. "Start the three simultaneous connection processes." #('emp' 'bonus' 'dept') do: [:tableName | | proc | proc := aBlock newProcessWithArguments: (Array with: tableName). proc priority: 30. proc resume]. "Just to see what they're doing, print out how many connections are active." [(numBusy := pool getConnectionBusyCount) = 0] whileTrue: [(Delay forMilliseconds: 50) wait. Transcript show: 'n=' , numBusy printString; cr]. [(numBusy := pool getConnectionBusyCount) > 0] whileTrue: [(Delay forMilliseconds: 50) wait. Transcript show: 'n=' , numBusy printString; cr]. Transcript show: 'n=' , numBusy printString; cr; cr. " Wait until all of the work is done before the connection pool is destroyed." isWorking wait. " Destroy the connection pool." pool destroy. "Now print the answers collected." answers values do: [:ans | Transcript show: ans printString; cr; cr]
</methods> <methods> Database.OracleThreadedInterface <category>types</category>
OCICPool <C: typedef struct __OCICPool OCICPool>
</methods> <methods> Database.OracleThreadedInterface <category>defines</category>
OCI_ATTR_CONN_BUSY_COUNT <C: #define OCI_ATTR_CONN_BUSY_COUNT 179 >
OCI_ATTR_CONN_OPEN_COUNT <C: #define OCI_ATTR_CONN_OPEN_COUNT 180 >
OCI_ATTR_CONN_TIMEOUT <C: #define OCI_ATTR_CONN_TIMEOUT 181 >
OCI_CPOOL <C: #define OCI_CPOOL 0x0200 >
OCI_CPOOL_REINITIALIZE <C: #define OCI_CPOOL_REINITIALIZE 0x111 >
OCI_HTYPE_CPOOL <C: #define OCI_HTYPE_CPOOL 26 >
</methods> <methods> Database.OracleThreadedInterface <category>structs</category>
__OCICPool <C: struct __OCICPool>
</methods> <methods> Database.OracleNTThreadedInterface <category>types</category>
OCICPool <C: typedef struct __OCICPool OCICPool>
</methods> <methods> Database.OracleNTThreadedInterface <category>defines</category>
OCI_ATTR_CONN_BUSY_COUNT <C: #define OCI_ATTR_CONN_BUSY_COUNT 179 >
OCI_ATTR_CONN_OPEN_COUNT <C: #define OCI_ATTR_CONN_OPEN_COUNT 180 >
OCI_ATTR_CONN_TIMEOUT <C: #define OCI_ATTR_CONN_TIMEOUT 181 >
OCI_CPOOL <C: #define OCI_CPOOL 0x0200 >
OCI_CPOOL_REINITIALIZE <C: #define OCI_CPOOL_REINITIALIZE 0x111 >
OCI_HTYPE_CPOOL <C: #define OCI_HTYPE_CPOOL 26 >
</methods> <methods> Database.OracleNTThreadedInterface <category>structs</category>
__OCICPool <C: struct __OCICPool>
</methods> <methods> Database.OracleThreadedInterface <category>procedures-connection</category>
OCIConnectionPoolCreate: envhp with: errhp with: poolhp with: poolName with: poolNameLen with: dblink with: dblinkLen with: connMin with: connMax with: connIncr with: poolUsername with: poolUserLen with: poolPassword with: poolPassLen with: mode <C: sword OCIConnectionPoolCreate(OCIEnv *envhp, OCIError *errhp, OCICPool *poolhp, OraText **poolName, sb4 *poolNameLen, const OraText *dblink, sb4 dblinkLen, ub4 connMin, ub4 connMax, ub4 connIncr, const OraText *poolUsername, sb4 poolUserLen, const OraText *poolPassword, sb4 poolPassLen, ub4 mode)> ^self externalAccessFailedWith: _errorCode
OCIConnectionPoolDestroy: poolhp with: errhp with: mode <C: sword OCIConnectionPoolDestroy ( OCICPool *poolhp, OCIError *errhp, ub4 mode )> ^self externalAccessFailedWith: _errorCode
</methods> <methods> Database.OracleNTThreadedInterface <category>procedures-connection</category>
OCIConnectionPoolCreate: envhp with: errhp with: poolhp with: poolName with: poolNameLen with: dblink with: dblinkLen with: connMin with: connMax with: connIncr with: poolUsername with: poolUserLen with: poolPassword with: poolPassLen with: mode <C: sword OCIConnectionPoolCreate(OCIEnv *envhp, OCIError *errhp, OCICPool *poolhp, OraText **poolName, sb4 *poolNameLen, const OraText *dblink, sb4 dblinkLen, ub4 connMin, ub4 connMax, ub4 connIncr, const OraText *poolUsername, sb4 poolUserLen, const OraText *poolPassword, sb4 poolPassLen, ub4 mode)> ^self externalAccessFailedWith: _errorCode
OCIConnectionPoolDestroy: poolhp with: errhp with: mode <C: sword OCIConnectionPoolDestroy ( OCICPool *poolhp, OCIError *errhp, ub4 mode )> ^self externalAccessFailedWith: _errorCode
</methods> "Imported Classes:" self error: 'Attempting to file-in parcel imports. Choose terminate or close' <class> <name>Object</name> <environment>Core</environment> <super></super> <private>false</private> none <imports></imports> <category>Kernel-Objects</category> <attributes> <package>Kernel-Objects</package> </attributes> </class> <class> <name>OracleThreadedInterface</name> <environment>Database</environment> <super>Database.OracleInterface</super> <private>false</private> none <imports> Database.OracleThreadedInterfaceDictionary.* </imports> <category>Database-External-Libraries</category> <attributes> <includeFiles></includeFiles> <includeDirectories></includeDirectories> <libraryFiles></libraryFiles> <libraryDirectories></libraryDirectories> true full <package>OracleThapiEXDI</package> </attributes> </class> <class> <name>OracleNTThreadedInterface</name> <environment>Database</environment> <super>Database.OracleNTInterface</super> <private>false</private> none <imports> Database.OracleNTThreadedInterfaceDictionary.* </imports> <category>Database-External-Libraries</category> <attributes> <includeFiles></includeFiles> <includeDirectories></includeDirectories> <libraryFiles><item>oci.dll</item> <item>advapi32.dll</item></libraryFiles> <libraryDirectories></libraryDirectories> true full <package>OracleThapiEXDI</package> </attributes> </class>