Glorp for Dolphin
Glorp is an object-relational persistence framework for Smalltalk. This page has the packages that load under Dolphin Smalltalk 6.0.
Download
The Dolphin Glorp packages have been ported from the VisualWorks 7.8 packages. To use Glorp, you will need to load these packages:
- GlorpDolphinPort
- GlorpMisc
- GlorpExpressions
- GlorpQueries
- GlorpExtensions
- GlorpDatabaseTypes
- GlorpDatabase
- GlorpUnitOfWork
- GlorpCore
- GlorpMappings
To run the tests, you'll need to load these:
- GlorpTestModels
- GlorpCollectionTypeModels
- GlorpDBTests
- GlorpTests
- GlorpDBTypeTests
The glorp-dolphin.port file is the porting script for Dolphin Store that you can use to load the latest Glorp code from the VisualWorks public repository. It also contains the script to port the Store-Database Model package that is in Dolphin Store.
Tests
The Glorp packages have 860 tests. To run the tests, you'll need to set the GlorpDatabaseLoginResource so they know what database to use:
GlorpDatabaseLoginResource defaultLogin: ((Login new) database: PostgreSQLPlatform new; username: 'user'; password: 'pass'; connectString: 'dsn')
All of the tests except GlorpDatabasePlatformTest>>testTrimString2 should pass using the PostgreSQL ODBC driver. The GlorpDatabasePlatformTest>>testTrimString2 test fails due to the test creating a character greater than 255. Dolphin throws an error for these characters.
You will need to adjust the properties of the ODBC connection to get the tests to run. The two items that need to be changed are checking the "Unknowns as LongVarChar" and the Max LongVarChar length to be some large value (e.g., 100000).
Finally, you will need to change two Dolphin methods to allow for using large buffers. Dolphin currently cannot handle loading data larger than 64KB, these two changes allow it to load larger fields:
DBResultSet>allocBuffer: anArrayOfColNums "Private - Allocate a buffer in the receiver to hold the specified column numbers in the receiver's result set. Answer the buffer." | cols class | cols := self describeCols: anArrayOfColNums. class := (cols anySatisfy: [:each | each lengthC > ##(2 ** 16)]) ifTrue: [DBUnboundBuffer] ifFalse: [self bufferClass]. ^buffer := class new columns: cols DBField>getData: aDBStatement "Private - Retrieve the receiver's associated column data from the ODBC result set following a fetch (into the receiver's buffer)." | ret result max length size | max := ##(2 ** 16). column lengthC >= max ifTrue: [length := lengthBuf copy. result := WriteStream on: ByteArray new. [ret := ODBCLibrary default sqlGetData: aDBStatement executedHandle columnNumber: column columnNumber targetType: SQL_C_DEFAULT targetValuePtr: buffer bufferLength: max strLenOrIndPtr: length. size := max min: length value. (size > 0 and: [column type = SQL_LONGVARCHAR and: [(buffer at: size) = 0]]) ifTrue: [size := size - 1]. result next: size putAll: buffer startingAt: 1. ret = SQL_SUCCESS_WITH_INFO] whileTrue. result position > max ifTrue: [buffer := result contents. self length: buffer size] ifFalse: [self length: length value]] ifFalse: [ret := ODBCLibrary default sqlGetData: aDBStatement executedHandle columnNumber: column columnNumber targetType: SQL_C_DEFAULT targetValuePtr: buffer bufferLength: buffer size strLenOrIndPtr: lengthBuf]. aDBStatement dbCheckException: ret
There are likely better ways to fix these methods. If you know of a better way to fix these or a work around, please mail me.