forked from Sovos-Compliance/convey-public-libs
-
Notifications
You must be signed in to change notification settings - Fork 1
/
KBMMEMTABLE.PAS
12969 lines (11606 loc) · 409 KB
/
KBMMEMTABLE.PAS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
unit kbmMemTable;
interface
{$INCLUDE kbmMemTable.inc}
uses
SysUtils,
Classes,
DB,
DBCommon
{$IFDEF LINUX}
, Types
, Libc
{$ELSE}
, Windows
{$ENDIF}
{$IFDEF LEVEL5}
, syncobjs
, Masks
{$ENDIF}
{$IFDEF LEVEL6}
, variants
, fmtbcd
, SqlTimSt
{$ENDIF};
{$B-} // Enable short circuit evaluation.
// kbmMemTable v. 3.01
const
COMPONENT_VERSION = '3.01';
// =========================================================================
// An inmemory temporary table.
// Can be used as a demonstration of how to create descendents of TDataSet,
// or as in my case, to allow a program to generate temporary data that can
// be used directly by all data aware controls.
//
// Copyright 1999,2000,2001 Kim Bo Madsen/Components4Developers DK
// All rights reserved.
//
// LICENSE AGREEMENT
// PLEASE NOTE THAT THE LICENSE AGREEMENT HAS CHANGED!!! 16. Feb. 2000
//
// You are allowed to use this component in any project for free.
// You are NOT allowed to claim that you have created this component or to
// copy its code into your own component and claim that it was your idea.
//
// -----------------------------------------------------------------------------------
// IM OFFERING THIS FOR FREE FOR YOUR CONVINIENCE, BUT
// YOU ARE REQUIRED TO SEND AN E-MAIL ABOUT WHAT PROJECT THIS COMPONENT (OR DERIVED VERSIONS)
// IS USED FOR !
// -----------------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------------
// PLEASE NOTE THE FOLLOWING ADDITION TO THE LICENSE AGREEMENT:
// If you choose to use this component for generating middleware libraries (with similar
// functionality as dbOvernet, Midas, Asta etc.), those libraries MUST be released as
// Open Source and Freeware!
// -----------------------------------------------------------------------------------
//
// You dont need to state my name in your software, although it would be
// appreciated if you do.
//
// If you find bugs or alter the component (f.ex. see suggested enhancements
// further down), please DONT just send the corrected/new code out on the internet,
// but instead send it to me, so I can put it into the official version. You will
// be acredited if you do so.
//
//
// DISCLAIMER
// By using this component or parts theirof you are accepting the full
// responsibility of the use. You are understanding that the author cant be
// made responsible in any way for any problems occuring using this component.
// You also recognize the author as the creator of this component and agrees
// not to claim otherwize!
//
// Please forward corrected versions (source code ONLY!), comments,
// and emails saying you are using it for this or that project to:
// kbm@components4developers.com
//
// Latest version can be found at:
// http://www.components4developers.com
//
// Suggestions for future enhancements:
//
// - IDE designer for adding static data to the memtable.
// - Optimized sorting. Combosort, many way mergesort or the like for large datasets.
// - Swap functionality for storing parts of an active table on disk for
// preserving memory.
//
// History:
//
//1.00: The first release. Was created due to a need for a component like this.
// (15. Jan. 99)
//1.01: The first update. Release 1.00 contained some bugs related to the ordering
// of records inserted and to bookmarks. Problems fixed. (21. Jan. 99)
//1.02: Fixed handling of NULL values. Added SaveToStream, SaveToFile,
// LoadFromStream and LoadFromFile. SaveToStream and SaveToFile is controlled
// by a flag telling if to save data, contents of calculated fields,
// contents of lookupfields and contents of non visible fields.
// Added an example application with Delphi 3 source code. (26. Jan. 99)
//
//1.03: Claude Rieth from Computer Team sarl (clrieth@team.lu) came up with an
// implementation of CommaText and made a validation check in _InternalInsert.
// Because I allready have implemented the saveto.... functions, I decided
// to implement Claude's idea using my own saveto.... functions. (27. Jan. 99)
// I have decided to rename the component, because Claude let me know that
// the RX library have a component with the same name as this.
// Thus in the future the component will be named TkbmMemTable.
// SaveToStream and LoadFromStream now set up date and decimal separator
// temporary to make sure that the data saved can be loaded on another
// installation with different date and decimal separator setups.
// Added EmptyTable method to clear the contents of the memory table.
//
//1.04: Wagner ADP (wagner@cads-informatica.com.br) found a bug in the _internalinsert
// procedure which he came up with a fix for. (4. Feb. 99)
// Added support for the TDataset protected function findrecord.
// Added support for CreateTable, DeleteTable.
//
//1.05: Charlie McKeegan from Task Software Limited (charlie@task.co.uk) found
// a minor bug (and came up with a fix) in SetRecNo which mostly is
// noticeable in a grid where the grid wont refresh when the record slider
// is moved to the end of the recordset. (5. Feb. 99)
// Changed SaveToStream to use the displayname of the field as the header
// instead of the fieldname.
//
//1.06: Introduced a persistence switch and a reference to a file. If the
// persistence switch is set, the file will be read aut. on table open,
// and the contents of the table will be saved in the table on table close.
//
//1.07: Changed calculation of fieldofsets in InternalOpen to follow the fielddefs
// instead of fields. It has importance when rearranging fields.
// Because of this change the calculation of fieldoffsets into the buffer
// has been changed too. These corrections was found to be needed to
// support the new components tkbmPooledQuery and tkbmPooledStoredProc
// (found in the package tkbmPooledConn)
// which in turn handles pooled connections to a database. Very usefull
// in f.ex a WWW application as they also makes the BDE function threadsafe,
// and limits the concurrent connections to a database.
//
//1.08: Changed buffer algorithm in GetLine since the old one was faulty.
// Problem was pointed out by: Markus Roessler@gmx.de
//
//1.09: Added LoadFromDataset, SaveToDataset, CreateTableAs,
// BCD and BLOB support by me.
// James Baile (James@orchiddata.demon.co.uk) pointed out a bug in GetRecNo
// which could lead to an endless loop in cases with filtering. He also
// provided code for sorting, which I have been rearranging a bit and
// implemented.
// Travis Diamond (tdiamond@airmail.net) pointed out a bug in GetWord where
// null fields would be skipped.
// Claudio Driussi (c.driussi@popmail.iol.it) send me version including
// a sort routine, and Ive used some of he's ideas to implement a sorting
// mechanism. Further he's code contained MoveRecords and MoveCurRec which
// I decided to include in a modified form for Drag and Drop record
// rearrangements.
//
//1.10: Support for Locate. (17. May. 99)
// Claudio Driussi (c.driussi@popmail.iol.it) came up with a fix for
// GetRecNo. MoveRecord is now public.
// Andrius Adamonis (andrius@prototechnika.lt) came up with fix for
// call to validation routines in SetFieldData and support for
// OldValue and NewValue in GetActiveRecordBuffer.
//
//1.11: Pascalis Bochoridis from SATO S.A Greece (pbohor@sato.gr)
// Corrected bookmark behavior (substituted RecordNo from TRecInfo with unused Bookmark)
// Corrected GetRecNo & SetRecNo (Scrollbars now work ok at First and Last record)
// Added LocateRecord, Locate, Lookup (I decided to use his Locate instead of my own).
//
//1.12: Added CloseBlob. Corrected destructor. (26. May. 99)
// Corrected GetFieldData and SetFieldData. Could result in overwritten
// memory elsewhere because of use of DataSize instead of Size.
// Pascalis Bochoridis from SATO S.A Greece (phohor@sato.gr) send me a corrected
// LocateRecord which solves problems regarding multiple keyfields.
// Thomas Bogenrieder (tbogenrieder@wuerzburg.netsurf.de) have suggested a faster
// LoadFromStream version which is much faster, but loads the full stream contents into
// memory before processing. I fixed a few bugs in it, rearranged it and decided
// to leave it up to you what you want to use.
// I suggest that if you need speed for smaller streams, use his method, else use mine.
// You c an activate his method by uncommenting the define statement FAST_LOADFROMSTREAM
// a few lines down.
//
//1.13 Corrected SetRecNo and MoveRecord. (31. May. 99)
// By Pascalis Bochoridis from SATO S.A Greece (phohor@sato.gr)
//
//1.14 Respecting DefaultFields differently. (3. Jun. 99)
// LoadFromDataset now includes a CopyStructure flag.
// Supporting Master/Detail relations.
// Now the Sort uses a new property for determining the fields to sort on,
// which means its possible to sort on other fields than is used for
// master/detail. Added SortOn(FieldNames:string) which is used for quick
// addhoc sorting by just supplying the fieldnames as parameters to the
// SortOn command.
// Fixed memory leak in LoadFromDataset (forgot to free bookmark).
// Added CopyFieldProperties parameter to LoadFromDataset and CreateTableAs which
// if set to TRUE will copy f.ex. DisplayName, DisplayFormat, EditMask etc. from
// the source.
// Corrected OnValidate in SetFieldData. Was placed to late to have any impact.
// Now checking for read only fields in SetFieldData.
//
//1.15 Totally rearranged LocateRecord to handle binary search when (23. Jun. 99)
// the data searched is sorted.
// I was inspired by Paulo Conzon (paolo.conzon@smc.it) who send me a version with the Locate method
// hacked for binary search. New methods PopulateRecord and PopulateField is used to create
// a key record to search for.
// Changed Sort and SortOn to accept sortoptions by a parameter instead of having a property.
// The following sort options exists: mtsoCaseInsensitive and mtsoDescending.
// mtsoPartialKey is used internally from LocateRecord where the TLocateOptions are remapped to
// TkbmMemTableCompareOptions.
//
//1.16 Bug fixed in SaveToDataset. Close called where it shouldnt. (19. Jul. 99)
// Bug reported by Reinhard Kalinke (R_Kalinke@compuserve.com)
// Fixed a few bugs + introduced Blob saving/loading in LoadFromStream/SaveToStream and thus
// also LoadFromFile/SaveToFile. To save blob fields specify mtfSaveBlobs in save flags.
// Full AutoInc implementation (max. 1 autoinc field/table).
// These fixes and enhancements was contributed by Arséne von Wys (arsene@vonwyss.ch)
// SetFieldData triggered the OnChange event to often. This is now fixed. Bug discovered by
// Andrius Adamonis (andrius@prototechnika.lt).
// Added mtfSkipRest save flag which if set will ONLY write out the fields specified by the rest of
// the flags, while default operation is to put a marker to indicate a field skipped.
// Usually mtfSkipRest shouldnt be specified if the stream should be reloaded by LoadFromStream later on.
// But for generating Excel CSV files or other stuff which doesnt need to be reloaded,
// mtfSkipRest can be valuable.
// Greatly speeded up LoadFromStream (GetLine and GetWord).
//
//1.17 Supporting fieldtypes ftFixedChar,ftWideString.
// Added runtime fieldtype checking for catching unsupported fields.
// Raymond J. Schappe (rschappe@isthmus-ts.com) found a bug in CompareFields which he send a fix for.
// Added a read only Version property.
// The faster LoadFromStream added in 1.12 has now been removed due to the optimization of
// the original LoadFromStream in 1.16. Tests shows no noticably performance difference anymore.
// Inspired by Bruno Depero (bdepero@usa.net) which send me some methods for saving and
// loading table definitions, I added mtfSaveDef to TkbmMemTableSaveFlag. If used the table
// definition will be saved in a file. To copy another datasets definition, first do a CreateTableAs,
// then SaveToFile/SaveToStream with mtfSaveDef.
// Renamed TkbmSupportedFieldTypes to kbmSupportedFieldTypes and TkbmBlobTypes to kbmBlobTypes.
// Generalized Delphi/BCB definitions.
// Denis Tsyplakov (den@vrn.sterling.ru) suggested two new events: OnLoadField and OnLoadRecord
// which have been implemented.
// Added OnCompressSave and OnDecompressLoad for user defined (de)compression of SaveToStream,
// LoadFromStream, SaveToFile and LoadFromFile.
// Bruno Depero (bdepero@usa.net) inspired me to do this, since he send me a version including
// Zip compression. But I like to generalize things and not to depend on any other specific
// 3. part library. Now its up to you which compression to use.
// Added OnCompressBlobStream and OnDecompressBlobStream for (de)compression of inmemory blobs.
// Added LZH compression to the Demo project by Bruno Depero (bdepero@usa.net).
//
//1.18 Changed SaveToStream and LoadFromStream to code special characters in string fields
// (ftString,ftWideString,ftFixedChar,ftMemo,ftFmtMemo).
// You may change this behaviour to the old way by setting kbmStringTypes to an empty set.
// Fixed severe blob null bug. Blobs fields was sometimes reported IsNull=true even if
// they had data in them.
// Fixed a few minor bugs.
//
//1.19 Fixed a bug in CodedStringToString where SetLength was to long. (10. Aug. 1999)
// Bug reported by Del Piero (tomli@mail.tycoon.com.tw).
// Fixed bug in LoadFromStream where DuringTableDef was wrongly initialized
// to true. Should be false. Showed when a CSV file without definition was loaded.
// Bug reported by Mr. Schmidt (ISAT.Schmidt@t-online.de)
//
//1.20 Marcelo Roberto Jimenez (mroberto@jaca.cetuc.puc-rio.br) reported a few bugs(23. Aug. 1999)
// to do with empty dataset, which he also corrected (GetRecNo, FilterMasterDetail).
// Furthermore he suggested and provided code for a Capacity property, which
// can be used to preallocate room in the internal recordlist for a specific
// minimum number of records.
// Explicitly typecasted @ to PChar in several places to avoid problem about
// people checking 'Typed @' in compile options.
//
//1.21 Corrected Locate on filtered recordssets. (24. Aug. 1999)
// Problem observed by Keith Blows (keithblo@woollyware.com)
//
//1.22 Corrected GetActiveRecord and added overridden SetBlockReadSize to be (30. Aug. 1999)
// compatible with D4/BCB4's TProvider functionality. The information and
// code has been generously supplied by Jason Wharton (jwharton@ibobjects.com).
// Paul Moorcroft (pmoor@netspace.net.au) added SaveToBinaryFile, LoadFromBinaryFile,
// SaveToBinaryStream and LoadFromBinaryStream. They save/load the contents incl.
// structure to/from the stream/file in a binary form which saves space and is
// faster.
// Added support for ftLargeInt (D4/D5/BCB4).
//
//1.23 Forgot to add defines regarding Delphi 5. I havnt got D5 yet, and thus (12. Sep. 1999)
// not tested this myself, but have relied on another person telling me that it
// do work in D5. Let me know if it doesnt.
// Added save flag mtfSaveFiltered to allow saving all records regardless if they are
// filtered or not. Suggestion posed by Jose Mauro Teixeira Marinho (marinho@aquarius.ime.eb.br)
// Added automatic resort when records are inserted/edited into a sorted table by
// Jirí Hostinský (tes@pce.cz). The autosort is controlled by AutoSort flag which is
// disabled by default. Furthermore at least one SortField must be defined for the auto
// sort to be active.
//
//1.24 The D5 story is continuing. Removed the override keyword on BCDToCurr (7. Oct. 1999)
// and CurrToBCD for D5 only. Changed type of PersistentFile from String to TFileName.
// Support for SetKey, GotoKey, FindKey inspired by sourcecode from Azuer (blue@nexmil.net) for
// TkbmMemTable v. 1.09, but now utilizing the new internal search features.
// Fixed bug with master/detail introduced in 1.21 or so.
// Fixed old bug in GetRecNo which didnt know how to end a count on a filtered recordset.
// Support for SetRange, SetRangeStart, SetRangeEnd, ApplyRange, CancelRange,
// EditRangeStart, EditRangeEnd, FindNearest, EditKey.
// Fixed several bugs to do with date, time and datetime fields. Now the internal
// storage format is a TDateTimeRec.
// Fixed problems when saving a CSV file on one machine and loading it on another
// with different national setup. Now the following layout is allways used on
// save and load (unless the flag mtfSaveInLocalFormat is specified on the SaveToStream/SaveToFile method,
// in which case the local national setup is used for save. Beware that the fileformat will not be
// portable between machines, but can be used for simply creating a Comma separated report for other
// use): DateSeparator:='/' TimeSeparator:=':' ThousandSeparator:=',' DecimalSeparator:='.'
// ShortDateFormat:='dd/mm/yyyy' CurrencyString:='' CurrencyFormat:=0 NegCurrFormat:=1
// Date problems reported by Craig Murphy (craig@isleofjura.demon.co.uk).
// We are getting close to have a very complete component now !!!
//
//1.25 Added CompareBookmarks, BookmarkValid, InternalBookmarkValid by (11. Oct. 1999)
// Lars Søndergaard (ls@lunatronic.dk)
//
//1.26 In 1.24 I introduced a new keybuffer principle for performance and easyness.(14. Oct. 1999)
// Unfortunately I forgot a few things to do with Master/Detail. They have now
// been fixed. Problem reported by Dirk Carstensen (D.Carstensen@FH-Wolfenbuettel.DE)
// He also translated all string ressources to German.
// Simply define the localization type wanted further down and recompile TkbmMemTable.
// Fixed AutoSort problem when AutoSort=true on first record insert.
// Further more setting AutoSort=true on a nonsorted dataset will result in an
// automatic full sort on table open.
// Problem reported by Carl (petrolia@inforamp.net)
// Added events OnSave and OnLoad which are called by SaveToDataSet,
// SaveToStream, SaveToBinaryStream, SaveToFile, SaveToBinaryFile,
// LoadFromDataSet, LoadFromStream, LoadFromBinaryStream,
// LoadFromFile, LoadFromBinaryFile. StorageType defines what type of save/load
// is going on: mtstDataSet, mtstStream, mtstBinaryStream, mtstFile and mtstBinaryFile.
// Stream specifies the stream used to save/load. Will be nil if StorageType is mtstDataSet.
//
//1.27 In 1.26 I unfortunately made 2 errors... Forgot to rename the german ressource file's (19. Oct. 1999)
// unitname and made another autosort problem. Things are going a bit fast at the moment,
// thus it is up to you all to test my changes :)
// Well..well... the german ressourcefile's unitname is now correct.
// AutoSort is now working as it should. Been checking it :)
// And its pretty fast too. Tried with 100.000 records, almost immediately
// on a PII 500Mhz.
// Added autosort facilities to the demo project and posibility to change
// number of records in sample data. Tried with 1 million records... and it works :)
// although quicksort is not the optimal algorithm to use on a very unbalanced
// large recordset. It seems to be fast enough for around 10.000 records.
// (almost immediately on a PII 500Mhz.)
// Published SortOptions, and added SortDefault to do a sort using the published
// sortfields and options. Mind you that Sort(...) sets up new sortoptions.
//
//1.28 Added PersistentSaveOptions. (21. Oct. 1999)
// Added PersistentSaveFormat either mtsfBinary or mtsfCSV.
// Fixed some flaws regarding persistense in designmode which could lead to loss of
// data in the persistent file and loss of field definitions.
//
//1.29 I. M. M. VATOPEDIOU (monh@vatopedi.thessal.singular.gr) found a bug in GetRecNo (22. Oct. 1999)
// which he send a fix for.
//
//1.30 Fernando (tolentino@atalaia.com.br) send OldValue enhancements and thus introduced
// InternalInsert, InternalEdit, InternalCancel procedures.
// Furthermore he suggested to rename TkbmMemTable to TkbmCustomMemTable and descend TkbmMemTable from it.
// I decided to follow his suggestion as to make it easier to design own memory table children.
// Kanca (kanca@ibm.net) send me example on runtime creation of TkbmMemTable. The example
// has been put in the demo project as a comment.
// Holger Dors (dors@kittelberger.de) suggested a version of CompareBookmarks which guarantiees
// values -1, 0 or 1 as result. This has now been implemented.
// Furthermore he retranslated an incorrect German translation for FindNearest.
//
//1.31 SetRecNo and GetRecNo has been analyzed carefully and rewritten to (26. Oct. 1999)
// reflect normal behaviour. Locate was broken in 1.29 because of the prev.
// GetRecNo fix. Reported by Carl (petrolia@inforamp.net).
// There have been significant speedups in insert record and delete record.
// Now TkbmMemTable contains a componenteditor for D5. Source has been donated by
// Albert Research (albertrs@redestb.es) and partly changed by me.
// Ressourcestrings has been translated to French by John Knipper (knipjo@altavista.net)
// Removed InternalInsert for D3. Problem reported by John Knipper.
//
//1.32 Fernando (tolentino@atalaia.com.br) sent Portuguese/Brasillian translation. (5. Nov. 1999)
// Vasil (vasils@ru.ru) sent Russian translation.
// Javier Tari Agullo (jtari@cyber.es) sent Spanish translation.
// Tero Tilus (terotil@cc.jyu.fi) suggested to save the visibility flag of a field too
// along with all the other fielddefinitions in the SaveToStream/LoadFromStream etc. methods.
// I changed CreateTableAs format to:
// procedure CreateTableAs(Source:TDataSet; CopyOptions:TkbmMemTableCopyTableOptions);
// where copyoptions can be:
// mtcpoStructure - Copy structure from the source datasource.
// mtcpoOnlyActiveFields - Only copy structure of active fields in the source datasource.
// mtcpoProperties - Also copy field info like DisplayName etc. from the source datasource.
// mtcpoLookup - Also copy lookup definitions from the source datasource.
// mtcpoCalculated - Also copy calculated fielddefinitions from the source datasource.
// or a combination of those values in square brackets [...].
// Further LoadFromDataSet is now following the same syntax.
// A new method CreateFieldAs has been appended used by CreateTableAs.
// Lookup fields defined in the memorytable now works as expected.
// Now the designer will show all types of database tables, not only STANDARD.
// Changed CopyRecords to allow copying of calculated data, and not clearing out
// lookup fields on destination.
// Fixed autosort error reported by Walter Yu (walteryu@21cn.com).
//
//1.33 Fixed error in CopyRecords which would lead to wrongly clearing calculated fields (23. Nov. 1999)
// after they have correcly been set.
// Fixed problem with autosort when inserting record before first.
// Fixed exception problem with masterfields property during load. Problem
// reported by Jose Luis Tirado (jltirado@jazzfree.com).
// Fixed a few errors in the demo application.
// Added Italian translation by Bruno Depero (bdepero@usa.net).
//
//1.34 Fixed Resort problem not setting FSorted=true. Problem reported by (3. Dec. 1999)
// Tim_Daborn@Compuserve.com.
// Added Slovakian translation by Roman Olexa (systech@ba.telecom.sk)
// Added Romanian translation by Sorin Pohontu (spohontu@assist.cccis.ro)
// Fixed problem about FSortFieldList not being updated when new sortfields are defined.
// The fix solves the AutoSort problem reported by Sorin Pohontu (spohontu@assist.cccis.ro)
// Javier Tari Agullo (jtari@cyber.es) send a fix for Spanish translation.
// Added threaded dataset controller (TkbmThreadDataSet).
// Put it on a form, link the dataset property to a dataset.
// When you need to use a dataset, do:
//
// ds:=ThreadDataset.Lock;
// try
// ...
// finally
// ThreadDataset.Unlock;
// end;
//
//1.35 LargeInt type handling changed. Now it will be read and saved 21. Dec. 1999
// as a float, not as an integer. General fixes to do with LargeInt field
// types. Bug reported by Fernando P. Nájera Cano (j.najera@cgac.es).
// Fixed bug reported by Urs Wagner (Urs_Wagner%NEUE_BANKENSOFTWARE_AG@raiffeisen.ch)
// where a field could be edited even if no Edit or Insert statement has been issued.
// Jozef Bielik (jozef@gates96.com) suggested to reset FRecNo and FSorted when
// last record is deleted in _InternalDelete. This has been implemented.
//
//1.36 Edison Mera Menéndez (edmera@yahoo.com) send fix for bug in autoupdate. 23. Dec. 1999
// Further he send code for a faster resort based on binary search for
// insertionpoint instead of the rather sequential one in the previous version.
// In case of problems, the old code can be activated by defining ORIGINAL_RESORT
// He also suggested and send code for an unified _InternalSearch which does the
// job of selecting either sequential or binary search.
// Brad - RightClick (brade@rightclick.com.au) suggested that autosort should be
// disengaged during load operations. I agree and thus have implemented it.
// Implemented that EmptyTable implecitely does a cancel in case the table
// was in Edit mode. Suggested by Albert Research (albertrs@redestb.es).
//
//1.37 Claude Rieth from Computer Team sarl (clrieth@team.lu) suggested to be able to 3. Jan. 2000
// specify save options for CommaText. Thus CommaTextOptions has been added.
// Several people have been having trouble installing in BCB4. The reason is
// that some unused 3.rd party libraries sneeked into the TkbmMemTable
// BCB4 project file. It has been fixed.
// Bookmark handling has been corrected. Problem reported by Dick Boogaers (d.boogaers@css.nl).
// InternalLoadFromBinaryStream has been fixed with regards to loading a NULL date.
// A date is considered NULL when the value of the date is 0.0 (1/1/1899).
// Problem reported by Paul Moorcroft (pmoor@netspace.net.au)
// Ohh.. and HAPPY NEWYEAR everybody! The world didnt vanish because of 2 digits.
// Isnt that NICE !! :)
//
//2.00a BETA First beta release.
// CompareBookmark corrected to handle nil bookmark pointers by 5. Jan. 2000
// jozef bielik (jozef@gates96.com)
// Indexes introduced. AddIndex,DeleteIndex,IndexDefs supported.
// AutoSort removed, Resort removed, Sort and SortOn now emulated via an internal index
// named __MT__DEFSORT__.
// Indexes introduced as a way into the internal indexes. Not really needed by most.
// EnableIndexes can be set to false to avoid updating the indexes during a heavy load
// operation f.ex. The indexes will be invalid until next UpdateIndexes is issued.
// mtfSaveIndexDef added to possible save flags.
// Save formats changed for both CSV files and binary files. For reading v.1.xx
// files, either use CSV format or for binary files, set the compatibility
// definition further down. V. 1.xx will NOT be compatible with files written
// in v.2.xx format unless no table definitions are written.
// _InternalSearch, _InternalBinarySearch and _InternalSequentialSearch removed.
// ftBytes fieldtype corrected. Usage is shown in the demo project.
//
//2.00b BETA Fixed D4 installation problem reported by Edison Mera Menéndez (edmera@yahoo.com).
// Published IndexDefs.
// Added support for ixUnique.
// Thomas Everth (everth@wave.co.nz) fixed two minor issues in LoadFromDataSet and
// SaveToDataSet. Further he provided the protected method UpdateRecords, and the
// public method UpdateToDataset which can be used to sync. another dataset with
// the contents of the memorytable.
// Fixed lookup to correcly handle null or empty keyvalues.
//
//2.00c BETA Renamed IndexFields to IndexFieldNames. Supporting IndexName.
// Fixed designtime indexdefinitions wouldnt be activated at runtime.
// Fixed Sort/SortOn would generate exception. Fixed Sort/SortOn on blob
// would generate exception.
//
//2.00d BETA Fixed Master/Detail.
// Changed the internal FRecords TList to a double linked list to make
// deletes alot easier from the list. FRecords have been superseeded by
// FFirstRecord and FFLastRecord. Changed the recordstructure. Introduced
// TkbmRecord and PkbmRecord which is the definition of a record item.
// Fixed SwitchToIndex to maintain current record the same after a switch.
// Added notification handling to reflect removal of other components.
// Added support for borrowing structures from another TDataset in the
// table designer.
//
//2.00e BETA Changed bookmark functionality.
// Fixed D4 installation.
// Fixed index updating.
// Optimized indexing and bookmark performance.
// Added record validity check.
// Still some bookmark problems.
//
//2.00f BETA Removed the double linked list idea from 2.00d. Back to a TList.
// Reason is the bookmark handling is not easy to get to work with pointers,
// plus its needed to be able to delete a record without actually removing
// it from the 'physical' database. Thus PackTable has been introduced.
// Deleting a record actually frees the recordcontents, but the spot in
// the TList will not be deleted, just marked as deleted (nil). PackTable removes
// all those empty spots, but at the same time invalidates bookmarks.
// EmptyTable does what the name says, empty it including empty spots and
// records as allways. Result should be that bookmarks are working as they
// should, and GotoBookmark is very fast now.
// Empty spots will automatically be reused when inserting new records
// by the use of a list of deleted recordID's, FDeletedRecords.
// Protected function LocateRecord changed.
// Locate changed, Lookup behaviour improved.
// CancelRange behaviour improved.
//
//2.00g BETA Fixed edit error when only 1 record was left and indexes defined.
// Problem reported by Dick Boogaers (d.boogaers@css.nl).
// Fixed error occuring when inserting records in an empty memtable with
// a unique index defined.
// Fixed error when altering a field which is indexed to a value bigger than
// biggest value for that field in the table.
//
//2.00h BETA Added IndexFields property as suggested by Dick Boogaers (d.boogaers@css.nl).
//
//2.00i BETA Added AttachedTo property for having two or more views on the
// physical same data. Updating one table will show immediately in the others.
// Fielddefinitions will be inherited from the primary table holding the data.
// There can only be one level of attachments. Eg. t2 can be attached to t1,
// but then t3 can't be attached at t2, but must be directly attached to t1.
// Its possible to have different indexes on the tables sharing same data.
// Fixed SearchRecordID problem which sometimes didnt find the record even
// if it definitely existed. The reason and solution is explained in the
// SearchRecordID method.
// Made TkbmCustomMemTable threadsafe.
// ftArray and ftADT support added by Stas Antonov (hcat@hypersoft.ru).
//
//2.00j BETA Changed to not check for disabled controls on DisableControls/EnableControls
// pairs. Fixed wrong call to _InternalEmpty in InternalClose when an attached
// table close. Thread locking changed and fixed.
// New property AttachedAutoRefresh. Set to false to disallow the cascading refreshes
// on dataaware controls connected to all the attached memorytables.
//
//2.00k BETA Made public properties on TkbmIndex:
// IsOrdered:boolead It can be used to determine if the index is up to date.
// Or it can be set to true to force that the index must be percieved as up to date,
// even if it hasnt been fully resorted since creation. Usefull f.ex. when loading
// data from a presorted file. Eg.:
// mt.EnableIndexes:=false;
// mt.LoadFromFile(...);
// mt.EnableIndexes:=true;
//
// // Since the data was saved using the index named 'iSomeIndex' and thus loaded
// // in the right sortorder, dont reupdate the iSomeIndex index.
// mt.Indexes.Get('iSomeIndex').IsOrdered:=true;
//
// // At some point, update all nonordered indexes.
// mt.UpdateIndexes;
//
// IndexType:TkbmIndexType Should only be used to determine the indextype. Dont set.
// CompareOptions:TkbmMemTableCompareOptions Should only be used to determine the compare options.
// Dont set.
// IndexOptions:TIndexOptions Should only be used to determine the indexoptions. Dont set.
// IndexFields:string Should only be used to determine the fields in the index. Dont set.
// IndexFieldList:TList Should only be used to gain access to a list of TField objects
// of fields participating in the index. Dont alter or set.
// Dataset:TkbmCustomMemTable Should only be used to determine the dataset on which the
// index is created. Dont set.
// Name:string Should only be used to determine the name used during creation of the index.
// Dont set.
// References:TList References to the records. The references are sorted in the way the index defines.
// IsRowOrder:boolean Used to determine if this index is a row order index. (the order the records
// are inserted).
// IsInternal:boolean Used to determine if this index is an internal index (used by SortOn f.ex.)
// IndexOfs:integer Used to determine what position this index have in the TkbmIndexes list.
// Fixed ftBytes bug reported by Gianluca Bonfatti (gbonfatti@libero.it).
//
//2.01 FINAL Cosmin (monh@vatopedi.thessal.singular.gr) reported some problems
// and came up with some fixes. I have loosely followed them to solve the problems.
// a) Fixed loading data into readonly fields using LoadFrom...
// Developers can use new 'IgnoreReadOnly' public property if they want to
// update fields which are actually defined as readonly. Remember to
// set it to false again to avoid users updating readonly fields.
// b) Fixed readonly on table level.
// c) New read only property: RangeActive:boolean. True if a range is set.
// d) Fixed autoinc. fields.
// Fixed bogus warning about undefined return from SearchRecordID.
//
//2.01a Fixed wrong use of FBufferSize in PrepareKeyRecord. Should be FRecordSize;
//
//2.10 Now complete support for Filter property!
//
//2.11 The filter property is only supported for D5. IFDEF's inserted to maintain
// backwards compatibility.
// Support for a UniqueRecordID which allways will increase on each insert
// in contrast to RecordID which is not unique through the lifetime of
// a memorytable (eg. reusing deleted record spots).
// Support for RecordTag (longint) which can be used by any application to fill
// extra info into the record for own use without having to create a real
// field for that information. Remember that the application is responsible
// for freeing memory pointed to by this tag (if thats the way its used).
// Added mtfSaveIgnoreRange and mtfSaveIgnoreMasterDetail to solve problem reported
// by monh@vatopedi.thessal.singular.gr that saving data during master/detail
// or ranges will only save 'visible' records.
//
//2.20 NOTE!!!!! !!!! !!!!! NEW LICENSE AGREEMENT !!!! PLEASE READ !!!!!
// Fixed quite serious bug in PrepareKeyRecord which would overwrite 16. Feb. 2000
// memory. Problem occured after using one of the SetKey, EditKey, FindKey,
// GotoKey, FindNearest methods.
// Enhanced record validation scheme. Can now check for memory overruns.
// Changed the inner workings of FindKey and FindNearest a little bit.
// Fixed that if an IndexDef was specified without any fields, an exception will
// be raised.
// Added CopyBlob boolean flag to _InternalCopyRecord which if set, also
// duplicates all blobs in the copy. Remember to _InternalFreeRecord with
// the FreeBlob boolean flag set for these copies.
// Added journaling functionality through the new properties
// Journal:TkbmJournal, EnableJournal:boolean, IsJournaling:boolean and
// IsJournalAvailable:boolean. The journaling features are inspired by
// CARIOTOGLOU MIKE (Mike@singular.gr).
//
//2.21 Fixed backward compatibility with Delphi 3.
//
//2.22 Fixed Sort and SortOn problem with CancelRange.
// Fixed compile problem when defining BINARY_FILE_1_COMPATIBILITY.
//
//2.23 Fixed several bugs in TkbmCustomMemTable.UpdateIndexes which would
// lead to duplicate indexdefinitions on every update, which again would
// lead to the infamous idelete<0 bug.
// Inserted several checks for table being active in situations where
// indexes are modified.
//
//2.24 Fixed bug reported by Jean-Pierre LIENARD (jplienard@compuserve.com)
// where Sort/SortOn called 2 times around a close/open pair would lead
// to AV. InternalClose now deletes a sortindex if one where created.
// Thus Sort/SortOn are only temporary (as they were supposed to be in
// the first place anyway :)
// Fixed small filtering bug.
//
//2.30a ALPHA Fixed bug in BinarySearch. Before it correctly found a matching record
// but it was not guranteed the first available record matching. Now it
// backtracks to make sure its the first one in the sortorder which matchs.
// Fixed old problem when persistent tables are not written on destruction
// of the component.
// Fixed GetByFieldNames (use to find an index based on fieldnames) to be
// case insensitive.
// Journal is now freed on close of table, not destruction.
// Fixed bug in _InternalCompareRecords which would compare with one field
// to little if maxfields were specified (noticed in some cases in M/D
// setups).
// Changed internals of _InternalSaveToStream and _InternalSaveToBinaryStream.
// Support for versioning implemented. Support for saving deltas using
// SaveToBinary... supported using flag mtfSaveDeltas.
// Resolver class (TkbmCustomDeltaHandler) for descending from to
// make delta resolvers.
// Added StartTransaction, Commit, Rollback as virtual methods for local
// transaction handling. Override these to handle middleware transactions.
// Added readonly TransactionLevel which shows the level of the current
// transaction.
// CARIOTOGLOU MIKE (Mike@singular.gr) came up with a big part of the versioning code
// and had several suggestions to how to handle deltas and versioning.
//
//2.30b BETA Added checking for empty record in list of records in several places (lst.items[n]=nil)
// Added new save flag mtfSaveDontFilterDeltas which if not specified, filters out
// all records which has been inserted and then deleted again within the same session.
// (A session understood like from load of records to save of them).
// Added new property AllData which can be read to get a variant containing all data
// and be set from a variant to load all data from.
// Added new property AllDataOptions which defines which data will be saved using the
// AllData property. Suggested by CARIOTOGLOU MIKE (Mike@singular.gr).
// Added designtime persistense of data on form by the new property StoreDataOnForm.
// If a designtime memtable contains data and thus is active, setting StoreDataOnForm:=true
// and saving the form will save the data on the form. Thus the data will be available
// when the form is loaded next time aslong the memtable is active (opened).
// Added Czech translation by Roman Krejci (info@rksolution.cz)
// Added property IsFieldModified(i:integer):boolean for checking if a field has been modified.
// The status is only available until Cancel or Post. Suggested by Alexandre DANVY (alex-dan@ebp.fr)
// Tabledesigner layout fixed.
//
//2.30c BETA Added two generaly available procedures: 3. Mar. 2000
// StreamToVariant and VariantToStream which handles putting a stream into
// a variant and extracting it again. Means its possible to store f.ex a complete
// file in a variant by opening the file with a TFileStream and pass the stream
// through StreamToVariant.
// Added example of transactioning to the demo project.
// Added support for TField.DefaultExpression (default value for each field).
// Define DO_CHECKRECORD to call _InternalCheckRecord. Was default before.
// Normally only to be used in debug situations.
// Applied some performance optimizations.
//
//2.30 FINAL Fixed before close bug which would clear a persistent file
// if the programmer called close before destroy. Problem reported by
// Frans Bouwmans (fbouwmans@spiditel.nl)
// Fixed clear index bug not resetting FSortIndex. Problem reported by
// Ronald Eckersberger (TeamDM) (ron@input.at)
// Published AutoCalcFields.
// Added property: RecalcOnFetch (default true) which regulates if
// calculated fields should be recalced on each fetch of a record or not.
// Fixed resetting AttachedTo when parent table is destroyed.
//
//2.31 Fixed D3 compatibility.
// Fixed Resolver. OrigValues as record at checkpoint, Values as
// record in current version.
// Fixed missing resync in FindNearest reported by
// Alexander V. Miloserdov (tatco@cherkiz.spb.su).
//
//2.32 Fixed TkbmCustomMemTable.DeleteIndex A/V bug in D4. Problem reported
// by Alexander V. Miloserdov (tatco@cherkiz.spb.su).
//
//2.33 Refixed again FindNearest. This time it works ;)
//
//2.34 Fixed missing filter in SaveTo.... Problem reported by Alexei Smirnov (alexeisu@kupol.ru)
// Fixed missing use of binary search. Problem reported by Tim Daborn (Tim_Daborn@Compuserve.com)
// Data persistency on destruction of component fixed. Fix by Cosmin (monh@vatopedi.thessal.singular.gr)
// UpdateRecord fixed with regards to only one key field specified.
// Fix by Marcello Tavares (TAVARES@emicol.com.br)
// Brazilian ressource file changed by Marcello Tavares (TAVARES@emicol.com.br).
// Added KBM_MAX_FIELDS which can be changed to set max. number of fields
// to handle in a table. Default 256.
// Fixed bug in error message when unsupported field added to fielddef.
// Problem reported by Alexandre Danvy (alex-dan@ebp.fr)
// Fixed some bugs regarding SetRangeStart/End EditRangeStart/End and ApplyRange.
// Remember to set IndexFieldNames to an index to use including the fields used for the range.
// Better is to use a filter or similar.
//
//2.35 Fixed bug not clearing out indexes on table close.
//
//2.36 Fixed bug in DeleteIndex which would not reset FCurIndex correctly. 30. mar. 2000
// Problem seen when SortOn or Sort would be called many times.
// Problem reported by Michail Haralampos (Space Systems) (spacesys@otenet.gr)
// Changed CreateTableAs to not to update fielddefs while source table is allready
// active for compatibility with a bug in Direct Oracle Access. Problem
// reported by Holger Dors (dors@kittelberger.de)
// Changed handling of oldrecord and current record during an edit of a record to
// correctly cancel changes to a blob. Problem reported by Ludek Horcicka (ludek.horcicka@bcbrno.cz)
//
//2.37 Fixed A/V bug versioning blobfields. Problem reported by Jerzy Labocha (jurekl@geocities.com).
// Optimized indexing when record edited which does not affect index.
// Suggested by Lou Fernandez (lfernandez@horizongt.com).
// Fixed bug in InternalLoadFromBinary where check for ixNonMaintained was in wrong order
// compared to savetobinary.
// Fixed bug in InternalLoadFromBinary where indexes was created and marked
// as updated prematurely. Problem reported by Jerzy Labocha (jurekl@geocities.com).
// Changed LoadFromDataSet to allow copy of properties from default fields.
// Problem reported by Tim Evans (time@cix.compulink.co.uk).
//
//2.38 Fixed bug not correctly determining autoinc value on loading binary file.
// Problem and fix reported by Jerzy Labocha (jurekl@geocities.com).
// Fixed small bug in SaveToStream where nil records would risc being saved.
// Fixed bug in SetRecNo reported by Mike Cariotoglou (Mike@singular.gr).
// Added RespectFilter on TkbmIndex.Search and TkbmIndexes.Search for Locate etc. to
// respect filters set. Problem reported by Andrew Leiper (Andy@ietgroup.com).
// Added to index search routines to make them threadsafe.
// Fixed bug updating indexes of attached tables on edit of master table.
// Problem reported by Lou Fernandez (lfernandez@horizongt.com).
// Added CSV delimiter properties: CSVQuote, CSVFieldDelimiter, CSVRecordDelimiter
// which are all char to define how CSV output or input should be handled.
// CSVRecordDelimiter can be #0 to not insert a recorddelimiter. Note that
// #13+#10 will be inserted at all times anyway to seperate records.
// Fixed bug in _InternalClearRecord and added new protected method
// UnmodifiedRecord in TkbmCustomDeltaHandler.
// Changed algorithm of dsOldRecord to return first version of record.
// Added 3 new public medium level functions:
// function GetVersionFieldData(Field:TField; Version:integer):variant;
// function GetVersionStatus(Version:integer):TUpdateStatus;
// function GetVersionCount:integer;
// which can be used to obtain info about previous versions of current record.
// GetVersionCount get number of versions of current record. Min 1.
// GetVersionFieldData gets a variant of data of a specific version. Current
// record version (newest) is 0.
// GetVersionStatus returns the TUpdateStatus info of a specific version. Current
// record version (newest) is 0.
// Inspiration and fixes by Mike Cariotoglou (Mike@singular.gr).
//
//2.39 Fixed bug setting Filtered while Filter is empty.
// Fixed autoinc bug on attached tables reported by Jerzy Labocha (jurekl@geocities.com).
// Added GetRows function for getting a specified number of rows at a starting point
// and return them as a variant. Code contributed by Reinhard Kalinke (R_Kalinke@compuserve.com)
// Added integer property LoadLimit which will limit the number of records loaded using LoadFrom....
// methods. Suggested by Roman Olexa (systech@ba.telecom.sk). if LoadLimit<=0 then
// no limit is imposed.
// Added read only integer property LoadCount which specifies how many records
// was affected in last load operation.
// Added read only boolean property LoadedCompletely which is true if all data was loaded,
// false if the load was interrupted because of LoadLimit.
// Fixed LoadFrom.... to not load into non data fields. Fix by cosmin@lycosmail.com.
// Fixed persistency on destruction of component.
// Added partial Dutch ressourcefile by M.H. Avegaart (avegaart@mccomm.nl).
// Added method Reset to clear out data, fields, indexes and more by kanca@ibm.net.
// LoadFromBinaryStream/File now tries to guess approx. how many records will be loaded
// and thus adjust capacity accordingly.
// Improved persistent save to not delete original file before finished writing new.
// Suggested by Paul Bailey (paul@cirrlus.co.za).
// Fixed minor bug in GetRecordCount when table not active by Csehi Andras (acsehi@qsoft.hu)
//
//2.40 Fixed problem with SetRange specifying fewer fields than number of index fields, giving 12. May. 2000
// wrong number of resulting records. Problem reported by Jay Herrmann (Jayh@adamsbusinessforms.com)
// Added new AddIndex2 method to TkbmCustomMemTable which allows to define some additional indexsetups:
// mtcoIgnoreLocale which use standard CompareStr instead of AnsiCompareStr.
// mtcoIgnoreNullKey which specifies that a null key field value will be ignored in record comparison.
// Except for the ExtraOptions parameter its equal in functionality to AddIndex.
// Added new property: OnCompareFields which can be used to handle specialized sortings and searches.
// Made the following functions publicly available:
// function CompareFields(KeyField,AField:pointer; FieldType: TFieldType; Partial, CaseInsensitive,IgnoreLocale:boolean):Integer;
// function StringToCodedString(const Source:string):string;
// function CodedStringToString(const Source:string):string;
// function StringToBase64(const Source:string):string;
// function Base64ToString(const Source:string):string;
// Added new property: AutoIncMinValue which can be used to set startvalue for autoinc. field.
// Added new property: AutoIncValue which can be used to obtain current next value for an autoinc field.
//
//2.41 Fixed problem regarding calculated fields on attached table not updating. Problem
// reported by aZaZel (azazel@planningsrl.it).
//
//2.42 Added PersistentBackup:boolean and PersistentBackupExt:string which controls if to make 25. May. 2000
// a backup of the previous persistent file and which extension the file should have.
// Code provided by cosmin@lycosmail.com.
// Made ResetAutoInc public. Suggested by cosmin@lycosmail.com.
// Fixed missing copy of RecordTag in InternalCopyR*. Reported by Alexey Trizno (xpg@mail.spbnit.ru).
// Added property groups by Chris G. Royle (cgr@dialabed.co.za).
// Fixed missing reset of UpdateStatus in _InternalClearRecord. Reported by CARIOTOGLOU MIKE (Mike@singular.gr)
// Fixed Search bug on empty table. Problem seen inserting into empty table with ixunique index defined.
// Problem reported by George Tasker (gtasker@informedsources.com.au)
// Published BeforeRefresh and AfterRefresh.
// Fixed deactivation of designed active table during runtime. Reason was missing inherited
// in Loaded method. Problem reported by John McLaine (johnmclaine@hotmail.com)
//
//2.43 Added OnProgress event which will fire on long operations notifying how
// many percent has been accomplished. The operation performed can be
// found in the Code parameter.
// Added new FastQuickSort procedure to TkbmIndex. Enhances searchspeed by
// somewhere around 50-75%. Sorting 100.000 records on a field on a PII 450Mhz
// now takes approx 5 secs. FastQuickSort (combination of a modified Quicksort and
// Insertion sort) is now the default sorting mechanism.
// To reenable the previous standard Quicksort mechanism, put a comment on the
// USE_FASTQUICKSORT definition further down.
// Danish translation of ressource strings added.
// Added public low level function GetDeletedRecordsCount:integer.
// Changed master/detail behaviour to allow more indexfields than masterfields.
// Change proposed seperately by Thomas Everth (everth@wave.co.nz) and
// IMB Tameio (vatt@internet.gr)
// Updated Brasilian translation by Eduardo Costa e Silva (SoftAplic) (eduardo@softaplic.com.br)
// Added protected procedure PopulateBlob by Fernando (tolentino@atalaia.com.br)
// Fixed issues compiling in D3 and BCB4.
// Commented out not copying nondatafields in LoadFromDataset as implemented in v.2.39
// Problem reported by Roman Olexa (systech@ba.telecom.sk).
//
//2.44 Removed stupid bug I implemented in 2.43. Forgot to remove some code.
// Fixed the demo project handling range. The demo of the SetRange function
// forgot that no index named 'Period' was defined, thus the range was set
// on the currently active index instead.
// Added support for using SortOn('',....) for selecting the roworder index.
// Defined some consts for internal indexnames and internal journal field names.
// kbmRowOrderIndex = '__MT__ROWORDER'
// kbmDefSortIndex = '__MT__DEFSORT'
// kbmJournalOperationField = '__MT__Journal_Operation'
// kbmJournalRecordTypeField = '__MT__Journal_RecordType'
//
//2.45 Fixed Master/detail problem setting masterfields while table not active.
// Problem reported by CARIOTOGLOU MIKE (Mike@singular.gr).
// Fixed Filter expression problem when reordering fields in runtime.
// Problem reported by houyuguo@21cn.com.
// Added several more progress functions.
// Added TableState which can be polled to decide whats going on in the table at
// the moment.
// Added AutoReposition property (default false) which determines if automatically
// to reposition to new place for record on record post, or to stay at current pos.
// Fixed dupplicate fieldname problem with attached tables as reported by
// Roman Olexa (systech@ba.telecom.sk). If fieldnames conflict between the
// current table and the table attached to, the original current table field
// is removed from the table, and the attached to table field used instead.
//
//2.45b Fixed missing FOrdered:=true on FastQuicksort. Problem reported
// by Tim Daborn (Tim_Daborn@Compuserve.com)
//
//2.46 Fixed SetFilterText bug. Problem reported by Anders Thomsen (thomsenjunk@hotmail.com)
// Added BCB 5 support by Lester Caine (lester@lsces.globalnet.co.uk)
//
//2.47 Added copy flag mtcpoAppend for appending data using LoadFromDataset.
// Added Master/Detail designer. Corrected master/detail functionality.
// Added Hungarian translation by Csehi Andras (acsehi@qsoft.hu)
//
//2.48 Fixed InternalSaveToStream to save in current indexorder. Problem reported
// by Cosmin (vatt@internet.gr) and Christoph Ansermot (info@illuminati.ch)
// Fixed InternalAddRecord to respect the Append flag. Problem reported by
// Milleder Markus (QI/LSR-Wi) (Markus.Milleder@tenovis.com)
// Fixed filter bug < which was considered the same as <=. Bug reported by
// Milleder Markus (QI/LSR-Wi) (Markus.Milleder@tenovis.com)
//
//2.49 Fixed TkbmIndexes.Clear leaving an invalid FSortIndex. 16. July 2000
// Problem fixed by Jason Mills (jmills@sync-link.com).
// Fixed D3 bugs which wouldnt allow to compile. Problem fixed by
// Speets, RCJ (ramon.speets@corusgroup.com)
// Changed ftVarBytes to work similar to ftBytes. Problem reported by
// mike cariotoglou (Mike@singular.gr)
// Fixed filtering of strings through the Filter property. Problem reported
// by several.
// Modified demoproject with FindKey functionality and string field.
// For the time being, removed support for the WideString fieldtype.
// Changed SaveToBinaryxxxxx to save in the order of the current index.
// Beware that if the current index is not up to date, it could mean
// saving less records than there actually is in the table.
// Changed binary file format to include null value info. LoadFromBinaryxxx
// is backwards compatible, but files saved with SaveToBinaryxxxx can only
// be read by software incoorporating TkbmMemTable v. 2.49 or newer.
// If needed, one of the BINARY_FILE_XXX_COMPATIBILITY defines can be
// specified for saving in a format compatible with older versions of
// TkbmMemTable.
//
//2.50 Fixed bug on SortOn after UpdateIndexes. Problem reported by Gate (x_gate@hotmail.com)
// a-d Added IndexByName(IndexName:string) property to obtain a TkbmIndex object for
// Beta the specified indexname.
// Added Enabled property to TkbmIndex which can be set to false to disable
// updating that index or true to allow updating again. An automatic rebuild
// is issued if needed.
// Fixed incorrect definition of properties EnableVersioning and VersioningMode
// in TkbmMemTable. Problem reported by U. Classen (uc@dsa-ac.de)
// Made CopyRecords public and changed it to copy from current pos in source.
// Fixed counter bug in CopyRecords which would copy one record more than limit.
// Fix suggested by Wilfried Mestdagh (wilfried_sonal@compuserve.com).
// Added saveflag mtfSaveAppend which will append the current dataset to
// the data previously saved in the file or stream. Suggested
// by Denis Tsyplakov (den@icsv.ru)
// Fixed AutoInc problem using InsertRecord/AppendRecord as reported by
// Jerzy Labocha (jurekl@ramzes.szczecin.pl)
// Fixed D3 inst. by replacing TField.FullName for TField.FieldName for
// level 3 installations only. Problem reported by Marcel Langr (mlangr@ivar.cz)
// Fixed cancel/Blob bug. Pretty tuff to fix. Several routines heavily
// rewritten to solve problem. Those changes also allows for better strings
// optimization.
// Fixed bug reported by jacky@acroprise.com.tw in SwitchToIndex on empty table.
// Fixed autoreposition bug by CARIOTOGLOU MIKE (Mike@singular.gr).
// Fixed attachedto bug during destroy by Vladimir Piven (grumbler@ekonomik.com.ua).
// Optimized per record memory usage by compiling out the debug values startident and endident
// + made record allocation one call to getmem instead of two. Suggested by
// Lluís Ollé (mailto:llob@menta.net)
// Added Performance property which can hold mtpfFast, mtpfBalanced or mtpfSmall.
// Meaning:
// mtpfFast=One GetMem/Rec. No recordcompression.
// mtpfBalanced=One or more GetMem/Rec. Null varlength fields are compressed.
// mtpfSmall=Like mtpfBalanced except varlength field level compression is made.
// Use mtpfFast if all string values will have a value which are close to the
// max size of the string fields or raw speed is important.
// Use mtpfBalanced if most string fields will be null.
// Use mtpfSmall in other cases.
// Added OnCompressField and OnDecompressField which can be used to
// create ones own field level compression and decompression for all nonblob
// varlength fields. For blobfields checkout OnCompressBlob and OnDecompressBlob.
// Added OnSetupField which can be used to overwrite indirection of
// specific fields when Performance is mtpfBalanced or mtpfSmall.
// Fixed locate on date or time fields giving variant conversion error.
// Problem reported by Tim Daborn (Tim_Daborn@Compuserve.com).
// Updated Russian ressources and added Ukrainian ressources by
// Vladimir (grumbler@ekonomik.com.ua)
//
//2.50e Fixed delete on master when attached to it.
// Beta Fixed delete on client table without versioning enabled
// attached to a master with versioning enabled.
// The bug fix makes sure the client is using same versioning
// method as the master table.
// Bugs reported by Davy Anest (davy-ane@ebp.fr)
// Vladimir (grumbler@ekonomik.com.ua) suggested a bit different way of
// copying field properties from during attaching to a master table.
// Since I cannot completely grasp the implications of the changed scheme,
// I have included it to leave it up to you to test it. The old scheme
// is commented out in SetAttachedTo.
// Alex Wijoyo (alex_wijoyo@telkom.net) suggested changing CreateTableAs.
// Instead of using FieldDefs.Assign.... then a routine of our own is used.
// This to avoid complications he had using TkbmMemTable in a DLL.
// ProviderFlags are now copied in CopyFieldProperties. Bug reported by
// Csehi Andras (acsehi@qsoft.hu).
// Hungarian ressource file updated by Csehi Andras (acsehi@qsoft.hu).
// InternalSave.... fixed when not specifying mtfSaveBlobs.
// Fixed InternalLoadFrom..... A/V when stream size = 0.
// Bugs reported by Arsène von Wyss (arsene@vonwyss.ch).
// Changed InternalLoadFromStream to not call progress on each line,
// but rather on each 100 lines.
// Added MarkAllDirty in TkbmIndexes to make sure UpdateIndexes will
// make a full update of all indexes regardless of previous state.
// Solves bug when sequence Open table, Close table, LoadFrom.... didnt
// update indexes correctly.
// Added properties CSVTrueString and CSVFalseString for setting
// stringrepresentation of true and false. Default value 'True' and 'False'.
// Notice they are caxe sensitive.
// Updated demo project to show OnProgress event.
// Added new class TkbmSharedData for datasharing between memtables.
// Modifed TkbmCustomMemtable to use this new class.
// Added Standalone property which can be set to true for true standalone
// memorytables that is tables that are not attaching to other table and other
// tables dont attach to. The table is not threadsafe if Standalone=true.
// It can gain a few percentage of speed.
// Reintroduced Capacity property for prespecifying expected number of records.
// Today i've tested inserting 1 million records of 1 string field with field
// length 10 chars. Its able to insert 100.000 recs/sec.
// Method used:
// kbmMemTable1.Open;
// kbmMemTable1.DisableControls;
// kbmMemTable1.EnableIndexes:=false;
// kbmMemTable1.Performance:=mtpfFast;
// kbmMemTable1.Standalone:=true;