Table of a VFeld from a VCursor
Ruslan Zasukhin
sunshine at public.kherson.ua
Tue Nov 22 23:36:30 CST 2005
On 11/22/05 12:21 AM, "Ed Kleban" <Ed at Kleban.com> wrote:
> // When you define your VTable subclasses you define the FieldCursors
> // you want to be able to use in addition to table fields:
>
> Sub CTblForms(db as CRbProjectDB, tableName as String)
> // Initialize the receiver and its fields.
>
> self.name = tableName
>
> // Define the Table Fields
> fFrmFlags = new VByte( "FFrmFlags" )
> fFrmLabel = new VVarChar( "FFrmLabel", 504 )
> fFrmTagTyp = new VVarChar( "FFrmTagTyp", 504)
> fFrmXmlTag = new VVarChar( "FFrmXmlTag", 504)
>
> // Define the FieldCursors
> cursorOnFFrmXmlTag = new CFCVarChar( fFrmXmlTag )
> cursorOnFFrmFlags = new CFCByte( fFrmFlags )
> End Sub
>
>
> // Subsequently, in your code you can use the FieldCursors
> // to randomly access a single field of a given record without
> // reading in every single table field when all you need is
> // a single field's value:
>
> flagByteFromRecord32 = MyTblForms.cursorOnFFrmFlags.integerValue( 32 )
> MyTblForms.cursorOnFFrmFlags.integerValue( 21 ) = kFlagValForRec21
Okay, I see idea of hacking :-)
Only problem you can meet is record locks.
May be you will prefer use kNoLocks.
> // To make this possible...
>
> // You need to define a subclass of CFCField for each different
> // kind of Vfield subclass that you want to be able create a
> // FieldCursor for. This gets done once and reused in all the
> // applications where you want to use FieldCursors. It is essentially
> // the common FieldCursor add-in code. Here are some example guts
> // out of CFCByte:
>
> Function integerValue(recId as Integer, doUpdateCheck = true) As Integer
> // Return an Integer with the value of the reciever's fcCursorField at
> // recId from the updated fcCursor on fcTable in fcDatabase.
> // If doUpdateCheck is false then assume that no rows have been
> // added to fcTable and that the fcCursor is valid.
>
> if doUpdateCheck and updateFieldCursor then // fcCursorChanged
> fcFCByte = fcCursor.ByteField( 1 )
> end
>
> fcCursor.position = recId
> return fcFCByte.Value
> End Function
>
>
> Function integerValue(recId as Integer, newIntVal as Integer, _
> doUpdateCheck = true, assigns newValStr as string) As String
>
> // Change the value of the reciever's fcCursorField at recId
> // from the updated fcCursor on fcTable in fcDatabase to newIntVal.
> // If doUpdateCheck is false then assume that no rows have been
> // added to fcTable and that the fcCursor is valid.
>
> if doUpdateCheck and updateFieldCursor then // fcCursorChanged
> fcFCByte = fcCursor.ByteField( 1 )
> end
>
> fcCursor.position = recId
> fcFCByte.Value = newIntVal
> fcCursor.UpdateRecord
> End Function
>
>
> // The central magic that makes all this work transparently so you
> // don't have worry about the state of the FieldCursor is the
> // updateFieldCursor method, and the common code called from the
> // constructors for all CFCField subclasses:
>
> Protected Function updateFieldCursor() As Boolean
> // Update the receiver's cursor from it's field if necessary.
> // Return true if the Cursor was updated or false if the
> // former fcCursor is fine to use.
>
> const here = "updateFieldCursor"
>
> if fcCursor is nil or fcCursor.RecordCount <> fcTable.RecordCount then
> fcCursor = fcDatabase.SqlSelect( _
> fcSqlString, EVCursorLocation.kClientSide, _
> EVLockType.kNoLocks, EVCursorDirection.kRandom )
KClientSide -- give you READ ONLY cursor. Better use ServerSide
> #if DebugBuild then
> if fcCursor.RecordCount <> fcTable.RecordCount then
> fail( here, "Update error" )
> end if
> #endif
>
> return true // Cursor was modified
> else
> return false // Cursor is fine as-is.
> end
> End Function
>
>
> Sub CFCField(aVField as VField)
> // Initialize the receiver to be a cursor on aVField
>
> const here = "CFCField"
>
> #if DebugBuild then
> if aVField is nil or aVField.Table is nil _
> or aVField.Table.Database is nil then
> fail( here, "Implementation Error" )
> end
> #endif
>
> if not self.checkFieldType( aVField ) then
> fail( here, "Invalid VField subclass" )
> end
>
> // Cache useful values in properties
> fcTable = aVField.Table
> fcSqlString = glue( "Select ", aVField.Name, " from ", fcTable.Name )
> fcDatabase = aVField.Table.Database
> // There is no need or reason to cache the argument aVField.
> End Sub
--
Best regards,
Ruslan Zasukhin
VP Engineering and New Technology
Paradigma Software, Inc
Valentina - Joining Worlds of Information
http://www.paradigmasoft.com
[I feel the need: the need for speed]
More information about the Valentina
mailing list