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:

  1. GlorpDolphinPort
  2. GlorpMisc
  3. GlorpExpressions
  4. GlorpQueries
  5. GlorpExtensions
  6. GlorpDatabaseTypes
  7. GlorpDatabase
  8. GlorpUnitOfWork
  9. GlorpCore
  10. GlorpMappings

To run the tests, you'll need to load these:

  1. GlorpTestModels
  2. GlorpCollectionTypeModels
  3. GlorpDBTests
  4. GlorpTests
  5. 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.