• No results found

make on the current record, depends on the

In document BlaisePascalMagazine 44 UK (Page 43-48)

make on the current record, depends on the

setting of

setting of

EnableVersioningEnableVersioning

 and and

VersioningMode.

VersioningMode.

 // An example on how to create a deltahandler.  // An example on how to create a deltahandler.

TM TMyDyDeleltataHaHandndleler r = = classclass((TkTkbmbmCuCuststomomDeDeltltaHaHanandldlerer))  protected   protected  ( ( :: ;;  procedure

 procedure InInsesertrtReRecocord rd varvar ReRetrtry y boboololeaeann

  v

  vaarr State TUpdateStatusState TUpdateStatus:: ));; oovveerrrriiddee;; (

( :: ;;

 procedure

 procedure DeDeleleteteReRecocord rd varvar ReRetrtry y boboololeaeann

  v

  vaarr State TUpdateStatusState TUpdateStatus:: ));; oovveerrrriiddee;; (

( :: ;;

 procedure

 procedure MoModidifyfyReRecocord rd varvar ReRetrtry y boboololeaeann

:

: ));; ;;

 var

 var State TUpdateStatusState TUpdateStatus overrideoverride

 //

 // procedure UnmodifiedRecord(var Retry:boolean;procedure UnmodifiedRecord(var Retry:boolean; var State:TUpdateStatus); override;

var State:TUpdateStatus); override;

end 

end ;;

mt

mt ..AppendRecAppendRecordord((……));;

mt StartTransaction mt StartTransaction.. ;; mt mt ..EdEdit it ……..mt mt ..PoPostst;; mt Delete mt Delete.. ;; mt Rollback mt Rollback.. ;; mt mt ..AppendRecoAppendRecordrd((……));; mt

mt ..StartTransStartTransactionaction;;  // First level of transaction // First level of transaction

mt

mt ..EdiEdit t ……..mt mt ..PosPostt;;

mt

mt ..StartTransStartTransactionaction;;  // Second level of transaction // Second level of transaction

mt Delete

mt Delete.. ;;

mt Rollback

mt Rollback.. ;;  // Back to the edited record again // Back to the edited record again

mt Rollback

mt Rollback.. ;;  // Back to the original appended record  // Back to the original appended record 

mt

mt ..AppendRecAppendRecordord((……));;

mt StartTransaction

mt StartTransaction.. ;;  // First level of transaction // First level of transaction

mt

mt ..EdEdit it ……..mt mt ..PoPostst;;

mt StartTransaction

mt StartTransaction.. ;;  // Second level of transaction // Second level of transaction

mt Delete

mt Delete.. ;;

mt Commit

mt Commit.. ;;  // We will keep the delete but not the // We will keep the delete but not the edited record.

edited record.

mt Rollback

mt Rollback.. ;;  // Ah no.. we will revert to the original // Ah no.. we will revert to the original appended record  appended record  mt mt ..CheckPoinCheckPointt;; mt Undo mt Undo. . ;;

COMPONENTS

COMPONENTS

DEVELOPERS DEVELOPERS

44

 var

 var i i ::iinntteeggeer s r s ;; ,,ssv v ::stringstring;; v v ::vvaarriiaanntt;;

 begin  begin := := ;; s s '''' : := = -- f foorr i i 00 ttoo FFiieellddCCoouunntt 11 ddoo  begin  begin   :   v v :==VaValulues es [[ii]];; ( ( (( )))) ::== i iff VVaarrIIssNNuulll l v v tthheenn ssvv '<NULL>''<NULL>' ( ( [[ ]].. )) ::== e ellssee iiff nnoott FFiieelldds s i i DDaattaaTTyyppe e iinn kkbbmmBBiinnaarryyTTyyppees s tthheenn ssv v vv else else := := ;; sv

sv '<Binary data>''<Binary data>'

  :   s s :==s s ++ssvv++' '' ';; ; ; end  end    (

  SShhoowwMMeessssaagge e (FFoorrmmaat t (('Inserted record (%s)''Inserted record (%s)',,[[ss]]))));;

end 

end ;;

 procedure

 procedure TMTMyDyDeleltataHaHandndleler r ..DeDeleleteteReRecocord rd ((varvar ReRetrtry y ::boboololeaean n ;; varvarStStatate e ::TUTUpdpdatateSeStatatutuss ));;

 var

 var i i ::iinntteeggeer s r s ;; ,,ssv v ::stringstring;; v v ::vvaarriiaanntt;;

 begin  begin := := ;; s s '''' : := = -- f foorr i i 00 ttoo FFiieellddCCoouunntt 11 ddoo  begin  begin   :   v v :==VaValulues es [[ii]];; ( ( (( )))) ::== i iff VVaarrIIssNNuulll l v v tthheenn ssvv '<NULL>''<NULL>' ( ( [[ ]].. )) ::== e ellssee iiff nnoott FFiieelldds s i i DDaattaaTTyyppe e iinn kkbbmmBBiinnaarryyTTyyppees s tthheenn ssv v vv := := ;; else

else svsv '<Binary data>''<Binary data>'

  :   s s :==s s ++ssvv++' '' ';; ; ; end  end    (

  SShhoowwMMeessssaagge e (FFoorrmmaat t (('Deleted record (%s)''Deleted record (%s)',,[[ss]]))));;

end 

end ;;

 procedure

 procedure TMTMyDyDeleltataHaHandndleler r ..MoModidifyfyReRecocord rd ((varvar ReRetrtry y ::boboololeaean n ;; varvarStStatate e ::TUTUpdpdatateSeStatatutuss ));;

 var

 var i i ::iinntteeggeer r ;; ss1 1 ,,ss2 2 ,,ssv v ::stringstring;; v v ::vvaarriiaanntt;;

 begin  begin := := ;; s1 s1 '''' := := ;; s2 s2 '''' : := = -- f foorr i i 00 ttoo FFiieellddCCoouunntt 11 ddoo  begin  begin   :   v v :==VaValulues es [[ii]];; ( ( (( )))) ::== i iff VVaarrIIssNNuulll l v v tthheenn ssvv '<NULL>''<NULL>' ( ( [[ ]].. )) ::== e ellssee iiff nnoott FFiieelldds s i i DDaattaaTTyyppe e iinn kkbbmmBBiinnaarryyTTyyppees s tthheenn ssv v vv := := ;; else

else svsv '<Binary data>''<Binary data>'

  :

  s1 s1 :==s1 s1 ++svsv++' '' ';;

  :

  v v :==OriOrigVagValuelues s [[ii]];; ( ( (( )))) ::== i iff VVaarrIIssNNuulll l v v tthheenn ssvv '<NULL>''<NULL>' ( ( [[ ]].. )) ::== e ellssee iiff nnoott FFiieelldds s i i DDaattaaTTyyppe e iinn kkbbmmBBiinnaarryyTTyyppees s tthheenn ssv v vv := := ;; else

else svsv '<Binary data>''<Binary data>'

  :   s2 s2 :==s2 s2 ++svsv++' '' ';; ; ; end  end    (

  SShhoowwMMeessssaagge e (FFoorrmmaat t (('Modified record (%s) to (%s)''Modified record (%s) to (%s)',,[[ss2 2 ,,ss11]]))));;

end 

end ;;

 //procedure TMyDeltaHandler.UnmodifiedRecord(var Retry:boolean; var St

 //procedure TMyDeltaHandler.UnmodifiedRecord(var Retry:boolean; var State:TUpdateStatus);ate:TUpdateStatus);  //begin

 //begin  //end;  //end;

 And 

 And you start the deltahandler like thisyou start the deltahandler like this::

 var  var : : ;; myDeltaHandler TMyDeltaHandler myDeltaHandler TMyDeltaHandler  begin  begin   :

  myDeltaHamyDeltaHandler ndler :==TMyDeltaHTMyDeltaHandler andler ..CreateCreate((nilnil));;

try

try

  .

  mt mt .DeltaHandlDeltaHandler er ::==myDeltaHamyDeltaHandlerndler;; . . ;; mt Resolve mt Resolve finally finally   .

  mt mt .DeltaHandlDeltaHandlerer::==nilnil;; . . ;; myDeltaHandler Free myDeltaHandler Free ; ; end  end  end  end ;; Issue

Issue Nr Nr 6 6 20152015 BLAISE PASCAL MAGAZINEBLAISE PASCAL MAGAZINE

  

COMPONENTSCOMPONENTS

DEVELOPERS DEVELOPERS

44

44

LOADING DATA

LOADING DATA

Data can be loaded into a memory table in multiple

Data can be loaded into a memory table in multiple

ways:

ways:

1.

1. InsertiInserting ng them them one one record record at at a a timetime

2.

2. Loading Loading the the data data from from another another datasetdataset

3.

3. Loading Loading the the data data from from a a filefile

As for 1, you can use the ordinary Insert/Post, or

As for 1, you can use the ordinary Insert/Post, or

AppendRecord methods.

AppendRecord methods.

As for 2, you can use:

As for 2, you can use:

 mt.LoadFro

 mt.LoadFromDataset(anmDataset(anotherdataseotherdataset,t,

[mtcpoStructure]);

[mtcpoStructure]);

This will make your memory table have the same

This will make your memory table have the same

fields as the anotherdataset (due to the

fields as the anotherdataset (due to the

mtcpoStructure option), and load a copy of all data

mtcpoStructure option), and load a copy of all data

from the dataset into the memory table.

from the dataset into the memory table.

A number of copy options exists:

A number of copy options exists:

 mt

 mtcpcpoSoStrtrucuctuturere::

Copies table structure (field definitions)

Copies table structure (field definitions) from thefrom the

source. Any field definitions you had in your local

source. Any field definitions you had in your local

memory table are removed.

memory table are removed.

 mt

 mtcpcpoOoOnlnlyAyActctiviveFeFieieldlds:s:

Only field definitions in the source that actually

Only field definitions in the source that actually

are represented as a true field, are

are represented as a true field, are copied.copied.

 mt

 mtcpcpoPoProropepertrtieies:s:

Copy over field properties like

Copy over field properties likeDisplayWidth,DisplayWidth,

DisplayLabel, Required, ReadOnly,

DisplayLabel, Required, ReadOnly,

Visible, DefaultExpression,

Visible, DefaultExpression,

Alignment, ProviderFlags, Lookup,

Alignment, ProviderFlags, Lookup,

LookupCache, LookupDataset, LookupCache, LookupDataset, LookupKeyFields, LookupResultField, LookupKeyFields, LookupResultField, KeyFields, DisplayFormat, KeyFields, DisplayFormat,

EditFormat, MaxValue, MinValue,

EditFormat, MaxValue, MinValue,

DisplayValues, TransLiterate,

DisplayValues, TransLiterate,

Precision, Currency

Precision, Currency andand BlobType. BlobType.

 mt

 mtcpcpoLoLooookukup:p:

Also copy lookup fields from the source dataset.

Also copy lookup fields from the source dataset.

 mt

 mtcpcpoCoCalalcuculalateted:d:

Also copy calculated fields from the source

Also copy calculated fields from the source

dataset.

dataset.

 mt

 mtcpcpoAoAppppenend:d:

Append records to the existing records in the

Append records to the existing records in the

memory table. This cant be used with

memory table. This cant be used with

mtcpoStructure

mtcpoStructure or ormtcpoProperties.mtcpoProperties.

 mt

 mtcpcpoFoFieieldldInIndedex:x: Copy the index position of Copy the index position of

fields to ensure field order is the same as in the

fields to ensure field order is the same as in the

original.

original.

 mt

 mtcpcpoDoDonontDtDisisabableleInIndedexexes:s:

Default a batch insertion is made, where indexes

Default a batch insertion is made, where indexes

are only updated after all records have been

are only updated after all records have been

copied over. However if you for example have an

copied over. However if you for example have an

index with unique constraint on a field, then you

index with unique constraint on a field, then you

might want to have your copy to stop early, if

might want to have your copy to stop early, if

there is a duplicate of that field value.

there is a duplicate of that field value.

That require that the indexes are updated on the

That require that the indexes are updated on the

fly for each record. Standard Edition will have a

fly for each record. Standard Edition will have a

larger performance penalty than

larger performance penalty thanProfessionalProfessional

Edition of kbmMemTabl

Edition of kbmMemTable for this situation.e for this situation.

 mt

 mtcpcpoIoIgngnororeEeErrrrorors:s:

Ignore any copy errors instead of stopping

Ignore any copy errors instead of stopping

copying.

copying.

 mt

 mtcpcpoLoLooookukupApAsDsDatata:a:

Copy over lookup fields a regular datafield, with

Copy over lookup fields a regular datafield, with

its matching data.

its matching data.

 mt

 mtcpcpoCoCalalcuculalatetedAdAsDsDatata:a:

Copy over calculated fields as a regular data field

Copy over calculated fields as a regular data field

with its calculated data.

with its calculated data.

 mt

 mtcpcpoSoStrtriningAgAsWsWidideSeStrtrining:g:

Assume that source ftString, ftFixedChar field

Assume that source ftString, ftFixedChar fieldss

should be created as ftWideString in your local

should be created as ftWideString in your local

memory table.

memory table.

 mt

 mtcpcpoWoWidideSeStrtriningUgUTFTF8:8:

If string/character/memo fields in the

If string/character/memo fields in the sourcesource

dataset do not match “wideness” of the same in

dataset do not match “wideness” of the same in

the destination dataset (

the destination dataset (your local memory tableyour local memory table),),

then automatically encode or decode to/from

then automatically encode or decode to/from

UTF8. Eg.

UTF8. Eg.

If the source dataset has field 'str1' which is a

If the source dataset has field 'str1' which is a

ftWideString

ftWideString field, while the local field, while the local

memorytable has the same field 'str1' defined as a

memorytable has the same field 'str1' defined as a

ftString

ftString field, it will UTF8 encode the data field, it will UTF8 encode the data

coming from the source field before putting it into

coming from the source field before putting it into

the destination field. Similarly if a source field is

the destination field. Similarly if a source field is

of type

of typeftString,ftString, but the destination is of type but the destination is of type

ftWideString

ftWideString then an UTF8 decoding will take then an UTF8 decoding will take

place before putting the value into the destination

place before putting the value into the destination

field. The same takes place with

field. The same takes place with

ftMemo/ftWideMemo

ftMemo/ftWideMemo and and

ftFixedChar/ftWideFixedChar

ftFixedChar/ftWideFixedChar..

If you already have an existing field structure in

If you already have an existing field structure in

your local memory table, and want to copy fields

your local memory table, and want to copy fields

from a source dataset, where the field names do

from a source dataset, where the field names do

not match, you can take advantage of field name

not match, you can take advantage of field name

mapping.

mapping.

Eg.

Eg.

This is telling kbmMemTable that the local field

This is telling kbmMemTable that the local field

named str1 is called str_1 in the source table etc.

named str1 is called str_1 in the source table etc.

As for option 3, loading from a file, you can use:

As for option 3, loading from a file, you can use:

 mt  mt.L.LoaoadFdFroromFmFilileVeViaiaFoFormrmatat(('somefilename','somefilename', someformatinstance) someformatinstance);; mt LoadFromDataset anotherdataset mt LoadFromDataset anotherdataset.. (( ,, [ []],,'str1=str_1;int2=int_2''str1=str_1;int2=int_2'));; Issue

Issue Nr Nr 6 6 20152015 BLAISE PASCAL MAGAZINEBLAISE PASCAL MAGAZINE

45

45

  

COMPONENTSCOMPONENTS

DEVELOPERS DEVELOPERS

44

Its practical if the data of field fld1 is required to

Its practical if the data of field fld1 is required to

be quickly accessible in your string list. In this

be quickly accessible in your string list. In this

example, s will only contain the value of fld2. If

example, s will only contain the value of fld2. If

you need the field value both as an object and as

you need the field value both as an object and as

part of the string, you can include it twice in your

part of the string, you can include it twice in your

field list.

field list.

Eg.

Eg. 'fld1;fld1;fld2'.'fld1;fld1;fld2'.

A different extraction method is

A different extraction method isGetRowsGetRows which which

returns requested fields as an array of an array of

returns requested fields as an array of an array of

variant.

variant.

This will return an array of variant containing an

This will return an array of variant containing an

array of variant of size 1, with the contents of the

array of variant of size 1, with the contents of the

field with

field withFieldNo=1FieldNo=1..

Eg.

Eg. v[0,0]v[0,0] is the value of the first field of the firstis the value of the first field of the first

record.

record.

Since we specified to

Since we specified to ask for kbmGetRowsRestask for kbmGetRowsRest

number of records, starting with

number of records, starting with

kbmBookMarkFirst,

kbmBookMarkFirst, then we are essentially then we are essentially

asking for all records. If we wanted to start from

asking for all records. If we wanted to start from

another place in the record set, you should

another place in the record set, you should

provide a

provide aTBookmarkTBookmark value for that place. value for that place.

That is created by navigating to the record, then

That is created by navigating to the record, then

use the Bookmark function to obtain a bookmark

use the Bookmark function to obtain a bookmark

for exactly that place in the record set.

for exactly that place in the record set.

And by providing a number instead of

And by providing a number instead of

kbmGetRowsRest,

kbmGetRowsRest, you can limit the number of you can limit the number of

records returned to that particular count.

records returned to that particular count.

The last argument of

The last argument ofGetRows,GetRows, can either be a can either be a

field number, a field name or an array of field

field number, a field name or an array of field

numbers or an array of field names.

numbers or an array of field names.

someformatinstance

someformatinstance is an instance of a stream is an instance of a stream

format component.

format component.kbmMemTablekbmMemTable comes with comes with

two,

two,TkbmMemBinaryStreamFormatTkbmMemBinaryStreamFormat and and

TkbmMemCSVStreamFormat.

TkbmMemCSVStreamFormat.

The binary stream format class stores data

The binary stream format class stores data

compactly and efficiently, and is giving the

compactly and efficiently, and is giving the

fastest performance. However the CSV stream

fastest performance. However the CSV stream

format class allows you to read in (

format class allows you to read in (and write outand write out))

comma separated formatted data, for easy

comma separated formatted data, for easy

integration with other external systems.

integration with other external systems.

kbmMW (

kbmMW (our middleware productour middleware product) comes with) comes with

additional stream formatters for XML and

additional stream formatters for XML and JSON.JSON.

Each stream format instance have a number of

Each stream format instance have a number of

flags that can be set, to tell how it's supposed to

flags that can be set, to tell how it's supposed to

handle the reading or writing of data, but that is

handle the reading or writing of data, but that is

a story for another time.

a story for another time.

sf

sf ::==TkbmMemCSTkbmMemCSVStreamForVStreamFormat mat ..CreateCreate((nilnil));;

try try   .   mmt t .LLooaaddFFrroommFFiilleeVViiaaFFoorrmmaat t (('.\mydata.csv''.\mydata.csv',,ssff)) finally finally . . ;; sf Free sf Free end  end ;; EXTRACTING DATA EXTRACTING DATA

A number of methods exist for easily extract data

A number of methods exist for easily extract data

from a memory table.

from a memory table.

 mt

 mt.E.Extxtraractct('('flfld1d1;f;fldld2'2',s,slDlDatata)a);;

This one will extract the fields fld1 and fld2 for all

This one will extract the fields fld1 and fld2 for all

records to a

records to aTStringsTStrings instance instance (TStringList(TStringList

typically)

typically) that you will have to create beforehand. that you will have to create beforehand.

If the optional

If the optionalAFormatAFormat string is given, e string is given, each lineach line

in

inTStringsTStrings will be formatted according to that will be formatted according to that

format. If none is given, then all field values for a

format. If none is given, then all field values for a

record will be separated by a space.

record will be separated by a space.

The above example will thus put a space between

The above example will thus put a space between

the value of fld1 and fld2 for each record/line.

the value of fld1 and fld2 for each record/line.

 mt.Extract(

 mt.Extract('fld1;fld2''fld1;fld2',slData,'%s,slData,'%s=%s');=%s');

This will put an equal

This will put an equal

sign between the value

sign between the value

of fld1 and fld2.

of fld1 and fld2.

It is also possible to specify that the first field (in

It is also possible to specify that the first field (in

the following case fld1) should be stored as an

the following case fld1) should be stored as an

object for the text line in the strings list.

object for the text line in the strings list.

mt.Extract('fld1;fld2',slData,'',true);

mt.Extract('fld1;fld2',slData,'',true);

Then you can access that value by:

Then you can access that value by:

 var

 var v variantv variant:: ;;

 begin

 begin

… …

  :

  v v :==TkbmVariaTkbmVariantObject ntObject ((slData slData ..Objects Objects [[ii]] ).

).ValueValue;;

  :

  s s :==slDaslData ta ..StriStrings ngs [[ii]];; …

end 

end ;;

 var

 var v variantv variant:: ;;

 begin

 begin

:

:== .. (( ,, ,, ));;

v

v mt mt GetRGetRows ows kbmGkbmGetRoetRowsRewsRest st kbmBkbmBookMookMarkFarkFirstirst 11

end 

end ;;

v

v ::==mt mt ..GetRows GetRows ((kbmGetRowkbmGetRowsRest sRest ,, kbmBookMakbmBookMarkFirst rkFirst ,,VarArrayOVarArrayOff (('f'fldld1'1',,'f'fldld2'2'))));;

Issue

Issue Nr Nr 6 6 20152015 BLAISE PASCAL MAGAZINEBLAISE PASCAL MAGAZINE

  

COMPONENTSCOMPONENTS

DEVELOPERS DEVELOPERS

44

46

STATISTICS

STATISTICS

kbmMemTable contains a number of

kbmMemTable contains a number of

functions to allow very fast grouping and

functions to allow very fast grouping and

calculation of statistical values for your

calculation of statistical values for your

data. Returning a sum of fld1 for all records

data. Returning a sum of fld1 for all records

visible in the current index.

visible in the current index.

v will contain the sum of fld1 for all records in the

v will contain the sum of fld1 for all records in the

In document BlaisePascalMagazine 44 UK (Page 43-48)

Related documents