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