kbmMemTable v. 7.77.50 Standard and Professional Edition released

This is a minor release, required for kbmMW v. 5.04.30:

  • Added support for DEFAULT column value in SQL CREATE and ALTER TABLE.

kbmMemTable is the premier high performance, high functionality in
memory dataset for Delphi and C++Builder with kbmMemTable Professional
topping the scales as being the worlds fastest!

If you have an up to date Service and Update (SAU) subscription, then
you can immediately visit https://portal.components4developers.com to
download the latest kbmMemTable release.

If not, please visit our shop at http://www.components4developers.com
and extend your SAU with another 12 months.

ANN: kbmMW Professional and Enterprise Edition v. 5.04.10 released!

We are happy to announce v5.04.10 of our popular middleware for Delphi and C++Builder.

If you like kbmMW, please let others know! Share the word!

We strive hard to ensure kbmMW continues to set the bar for what an n-tier product must be capable of in the real world!

This release is primarily bugfix release, but does also contain a number of new features:

  • Local and remote checksum support for file service and client
  • Scheduler improvements with support for run of a batch of multiple parallel child jobs
  • AMQP improvements

Please look in the end of this post for a detailed change list.

Professional and Enterprise Edition is available for all with a current active SAU. If your SAU has run out, please visit our shop to extend it with another 12 months.

CodeGear Edition is available for free, but only supports a specific Delphi/Win32 SKU, contains a limited feature set and do not include source.

Please visit https://portal.components4developers.com to download.

—-

kbmMW is the premiere n-tier product for Delphi, C++Builder and FPC on .Net, Win32, Win64, Linux, Java, PHP, Android, IOS, embedded devices, websites, mainframes and more.

Please visit http://www.components4developers.com for more information about kbmMW.

—-

Components4Developers is a company established in 1999 with the purpose of providing high quality development tools for developers and enterprises. The primary focus is on SOA, EAI and systems integration via our flagship product kbmMW.

kbmMW is a portable, highly scalable, high end application server and enterprise architecture integration (EAI) development framework for Win32, ..Net and Linux with clients residing on Win32, .Net, Linux, Unix, Mainframes, Minis, Embedded and many other places. It is currently used as the backbone in hundreds of central systems, in
hospitals, courts, private, industries, offshore industry, finance, telecom, governements, schools, laboratories, rentals, culture institutions, FDA approved medical devices, military and more.


5.04.10 Nov 3 2017

Fixes
=====
– Fixed bugs and improved XML<>ON conversion.
– Fixed bugs in TkbmMWConfiguration.

Changes/minor additions
=======================
– Added KeepAliveTimeout and KeepAliveInterval to Indy TCP server transports

5.04.00 Nov 2 2017

New stuff
=========
– Added OnAccessException event to TkbmMWCustomFileClient.
– Added Checksum, ChecksumEx, SameFile, SameFileEx, LocalChecksum to TkbmMWCustomFileClient
Checksum(Ex) and LocalChecksum use SHA256 to calculate checksum.
SameFile(Ex) calculates checksum on both local and remote file and compares those.
On platforms supporting TkbmMWScheduler, the calculations are run in parallel.
– Added WithObject and WithInterface to TkbmMWScheduledEvent to allow
piggybacking additional data to events.
– Added additional overloaded SynchronizedAfterRun and AfterRun for anonymous
procedures to TkbmMWScheduledEvent.
– Added WhenException methods to TkbmMWScheduledEvent to allow handling exceptions.
– Added WaitRun(s) to TkbmMWScheduledEvent to allow pausing a thread until an
event has finished running.
– Added additional Run/RunNow methods to TkbmMWScheduler to allow for scheduling
multiple parallel jobs that will be run under control of one scheduled event.
Only when all jobs has run, the scheduled event is considered to have run.
– Added mwxonoPreferAttributes and mwxonoAutoIdentifyArrayElement to
TkbmMWXMLObjectNotationOption.
mwxonoPreferAttributes controls if conversion from object notation
should prefer defining XML node values as attributes or as elements.
mwxonoAutoIdentifyArrayElement controls if conversion from object notation
should include index (i) attribute to precisely identify a row in an array.
– Updated many database adapters to prevent certain leaks on exceptions.
– Added MaxFileSize to TkbmMWFileServiceDefinition to define maximum size of file
that is allowed to be received by the server. Default no limit.
– Added TkbmMWVirtualConfigurationStorage to kbmMWConfiguration unit.
It allows for getting and storing configuration from any type of medias.
– Added TkbmMWMarshal.Bytes2Memory function in kbmMWGlobal.
– Added ToString to IkbmMWAutoValue.
– Added kbmMWExplode function to kbmMWGlobal. It allows for exploding
strings with start and end tags as delimiters.
– Added PrettyChar2String function to IkbmMWLogFormatter.
– Made Char2PrettyChar function in IkbmMWLogFormatter implementers public.
– Added support for detecting version of databases for some databases in
TkbmMWCustomConnectionPool.
– Added TkbmMWThreadONObject and TkbmMWThreadONArray to kbmMWObjectNotation.
They allows for multithreaded access to the same base object notation object or array.
– Added additional support for CoInitialize and CoUnInitialize for UNIDac adapter.
– Added BasicProperties property to IkbmMWAMQPChannel.
– Updated database adapter wizard to generate up to date code.
– Improved stability of TkbmMWFileService, TkbmMWFileClient and TkbmMWFilePool.
– Improved error handling in kbmMWORM.

Fixes
=====
– Fixed bugs in TkbmMWScheduler.
– Fixed compilation errors in AMQP on some IDE SKU versions.
– Fixed header properties not available under some circumstances in AMQP.
– Fixed bugs in TkbmMWAuthorizationManager.
– Fixed bugs in kbmMWConfiguration.
– Fixed bugs in kbmMWHTTPUtils resulting in stack overflow.
– Fixed some null handling issues in TkbmMWObjectNotation.
– Removed leftover debug code from TkbmMWBPStringMaskPart.
– Fixed bugs in TkbmMWAMQPChannel.
– Fixed NULL marshalling issue in TkbmMWONNullableMarshal.
– Fixed kbmMWServer not instantiating minimum number of services at startup.
– Fixed IDE Debug visualizers.

Changes/minor additions
=======================
– Improved GetStreamEx and PutStreamEx to allow for retry on failure in TkbmMWCustomFileClient.
– Generally improved exception and error handling in TkbmMWCustomFileClient.
– Improved PutStreamEx to include offset and total file size in server call.
– Improved TkbmMWSQLiteMetaData to support obtaining version meta data and index info
from older SQLite versions (pre 3.8.3)

ANN: kbmMW Professional and Enterprise Edition v. 5.03.00 released!

We are happy to announce v5.03 of our popular middleware for Delphi and C++Builder.

If you like kbmMW, please let others know! Share the word!

We strive hard to ensure kbmMW continues to set the bar for what an n-tier product must be capable of in the real world!

This release is fairly large and brings several new features:

  • Automatic database upgrade to match your ORM classes (please test carefully before deploying to production environments containing existing data!)
  • New! Template based binary parser for advanced bit fiddling
  • New! Detailed metadata extraction and creation on many supported databases, including SQLite, MSSQL, Oracle, PostgreSQL, MySQL, Interbase, Firebird
  • New! Virtual fields and tables in ORM
  • New! Thread safe configuration system for easy one style read/write access to configuration files and registry.
  • New! Debug visualizers for kbmMWNullable and kbmMWDateTime values.
  • New! CHM help files with 24800+ topics.
  • + Many many more additions and improvements and bugfixes for reported bugs

Please look in the end of this post for a detailed change list.

Professional and Enterprise Edition is available for all with a current active SAU. If your SAU has run out, please visit our shop to extend it with another 12 months.

CodeGear Edition is available for free, but only supports a specific Delphi/Win32 SKU, contains a limited feature set and do not include source.

Please visit https://portal.components4developers.com to download.

—-

kbmMW is the premiere n-tier product for Delphi, C++Builder and FPC on .Net, Win32, Win64, Linux, Java, PHP, Android, IOS, embedded devices, websites, mainframes and more.

Please visit http://www.components4developers.com for more information about kbmMW.

—-

Components4Developers is a company established in 1999 with the purpose of providing high quality development tools for developers and enterprises. The primary focus is on SOA, EAI and systems integration via our flagship product kbmMW.

kbmMW is a portable, highly scalable, high end application server and enterprise architecture integration (EAI) development framework for Win32, ..Net and Linux with clients residing on Win32, .Net, Linux, Unix, Mainframes, Minis, Embedded and many other places. It is currently used as the backbone in hundreds of central systems, in
hospitals, courts, private, industries, offshore industry, finance, telecom, governements, schools, laboratories, rentals, culture institutions, FDA approved medical devices, military and more.


 

5.03.00 Sep 16 2017

Important notes (changes that may break existing code)
======================================================
* Fixed Delphi C++ HPP generator errors related to kbmMWNullable.pas and kbmMWDateTime.pas
The changes needed to fix it for kbmMWNullable.pas unfortunately require
us to default unsupporting assigning of a variant directly to a kbmMWNullable.
However if you are using Delphi ONLY and will never use the C++Builder header files
you can add {$DEFINE KBMMW_DELPHI_ONLY} in kbmMWConfig.inc.
Then you can still assign a variant directly to a kbmMWNullable in Delphi.
The changes in kbmMWDateTime is using overloaded versions of methods
instead of using default value Math.NaN which is translated incorrectly
by the HPP emitter.
* Removed PrependTableName from all metadata classes and thus it may
error with missing property on opening forms/datamodules containing
metadata components. Ignore that specific property missing error and save.

New stuff
=========
– Added support for defining root type for marshalled objects. Array or Object.
– Added support for using nth next best marshalling type if primary is not registered in known types.
– Added log to AutoRegisterServices in kbmMWServer.pas
– Added support for bit values in YAML. A bit value starts with b or B and contains only 0 or 1’s
– Added support for default metadata class for database adapters. It will be used when
no explicit metadata component has been linked to the connection pool.
– Added OnLoginSuccess and OnLoginFail events to TkbmMWAuthorizationManager.
– Added support for understanding bit values in TkbmMWObjectNotation.
– Added Path method to TkbmMWONCustomObject which will take a delimited path and
traverse the tree optionally adding needed objects on the way.
– Added support for custom properties and basic properties in AMQP.
– Added support for Default date/time in TkbmMWDateTime.
– Added Reset method to TkbmMWDateTime, completely clearing its value.
– Added additional constructors to TkbmMWDateTime allowing direct timezone information.
– Added Memory2Binary and a number of BitCount methods to TkbmMWPlatformMarshal.
– Added support for reference counted data in TkbmMWAutoValue.
– Added kbmMWGetApplicationVersionInfoAsString and kbmMWBackupFile global methods to kbmMWGlobal.pas.
– Added support for specifying quote in kbmMWQuoteString and kbmMWUnquoteString.
– Added support for different start and endquote in kbmMWImplode.
– Added kbmMWDigitCount2Multiplier, kbmMWUnsignedDigitCount, kbmMWSignedDigitCount and
kbmMWExplodeFloat to kbmMWGlobal.pas, which determines metadata of a float value.
– Added kbmMWBitStringToInteger and kbmMWIntegerToBitString to kbmMWGlobal.pas
– Added overloaded Get method to TkbmMWSmartClientORM requesting dataset from server,
returned as an object/list, and providing custom arguments.
– Added overloaded RunSQL methods to TkbmMWMemSQL allowing executing SQL directly on
one or more provided TDataset sources.
– Added support for multistatement execution in TkbmMWMemSQL. Statements are separated by semicolon.
– Added support for salting initial string or byte keys in kbmMWCipherHash.pas.
– Added Clone method to TkbmMWCustomDef in kbmMWConnectionPool.pas
– Added support for detecting deleted fields in TkbmMWFieldDefs.
– Added MetaGetDef and MetaRename functions to TkbmMWCustomMetaData.
– Added significant changes to TkbmMWCustomSQLRewriter, including datatype mapping
and rewriting of numerous statement types.
– Added DefaultMetaData and CurrentMetaData properties to TkbmMWCustomConnectionPool to
allow for using kbmMW specified default metadata, alternative specific assigned on.
– Added support for piping outcome of query thru internal SQL statement as postprocessing
in TkbmMWCustomPooledDataset. Syntax: somequery <!PIPE!> somepipestatement
somequery is the query sent to the backend database. The resultset from that
is the piped thri the kbmMW SQL type somepipestatement.
Use constant KBMMW_QUERYPIPE to add pipe statement.
– Added support for mwfdctStrictPrecision and mwfdctStrictSize in TkbmMWFieldDefs.ChangedFields.
Strict indicates values must match exactly.
– Added DeletedFields, DeleteByFieldName and GetByFieldName to TkbmMWFieldDefs.
– Added additional overloaded Rewrite methods to TkbmMWCustomSQLRewriter.
– Added Terminate to TkbmMWScheduledEvent to prematurely terminate ongoing execution.
– Added Delay method to IkbmMWScheduledEvent which can be called at any time
including during execution of the said event to add additional delay to the
coming run’s of the event.
– Added support for multistatements in kbmMWSQLite.pas
– Vastly expanded TkbmMWCustomSQLMetaData.
– Added support for readonly and virtual field attribute in TkbmMW_FieldAttribute (kbmMW_Field)
– Added new TkbmMW_VirtualFieldAttribute (kbmMW_VirtualField) to indicate field
which will show up in resultset but do not exist in datastore.
– Added CreateDBDataset to TkbmMWORM which will generate a TDataset
matching the referenced TkbmMWORMTable.
– Added CompatibleTable, GetUpgradeTableStatements, UpgradeTable to TkbmMWORM which
are used for checking if a class is compatible with the underlying datastore,
and which can either directly upgrade the underlying datastore or suggest
statements to make the upgrade happen. Use with caution on production systems!
– Vastly expanded kbmSQLRewriter.pas to support metadata, indexes, new statements etc.
– Added Reset method to kbmMWNullable to reset its contents.
– Added PrettyChar to TkbmMWCustomLogFormatter to be able to selectively
choose what each byte value should display in the log.
– Added additional Warning, Error and Fatal overloaded methods to TkbmMWLog.
– Added support for property AutoSplitLines in TkbmMWStringsLogManager.
– Added support for providing HTTP related values (mwatURL, mwatHost, mwatUserAgent,
mwatHeader (named item), mwatCookie (named item) as argument in smart services.
– Added support for new kbmMWConfiguration unit which provides access to automatically
load and optionally save configurations to various storages.
Either use Config.As…. methods directly, or specify attribute
[kbmMW_Config(‘path:a.b.c.value, direction:rw’)] on any
property or field in a class.
If the class descends from TkbmMWConfigurableObject, the field/property
will automatically receive the value as defined in the Config object,
when the class is instantiated, and similarly store the value back
to the Config object when the class instance is destroyed.
Classes not descending from TkbmMWConfigurableObject can also
take advantage of the attribute. Just make sure to
call Config.ReadConfig(TValue.From(self)); or Config.WriteConfig(TValue.From(self));
for example in AfterContruction and BeforeDestruction methods of your class.
Also register your class as a kbmMW known class.
– Added support for using kbmMW_Config attribute for arguments in smart services.
– Added new unit kbmMWBinaryParser which can be used for parsing binary data
according to a custom template. Check the blogs on http://www.components4developers.com
for info.
– Added new debug visualizers for kbmMWDateTime, kbmMWNullable,
kbmMWDuration and TkbmMWAutoValue values during debug.
– Added Object Notation based stats (kbmMWONStats) unit for
registering statistics in object notation format, which
hence can be saved and loaded as any of the object notation
streaming formats.

Fixes
=====
– Fixed scheduler so exceptions will not stop execution threads.
– Fixed incorrect Args[0] in REST transport stream. Now correctly contains called URL.
– Fixed detection of added and changed fields in TkbmMWFieldsList, and added detailed info about differences.
– Fixed XML namespace crash issue.
– Fixed REST streamformat incorrectly double translating UTF8
– Fixed deletemessage and rejectmessage when provinding a message already tentatively
popped resulted in message not being deleted/rejected, but instead leaked.
– Fixed TkbmMWDynamicLockFreeHashArray and siblings related to deadlock (due to using
locking without escalation support for performance reasons) and due to incorrect
management of capacity of GC generations.
– Fixed potential leaks happening on exceptions in certain places in kbmMWORM.
– Fixed occational A/V due to reporting triggering memory logging.
– Fixed REST handling of returned objects (bug introduced in 5.0.2)
– Fixed DOA adapter related to LOB
– Fixed TkbmMWStringBuilder.GetLastChar which amongst others affected YAML parsing.
– Fixed scheduler clean shutdown of defined events when removing them.
– Fixed initialdelay not respected in Scheduler.
– Fixed destruction shutdown bugs in Scheduler.
– Fixed YAML null parsing bug (hazeltine).
– Fixed various parsing bugs in YAML.
– Fixed time to execute calculation in kbmMWScheduler.pas.
– Fixed string offset issues for Linux.
– Fixed IOS TkbmMWTiming timebase issues.
– Fixed A/V bug in TkbmMWDOMXMLNameSpaceList during destruction, due to
non owned namespaces.
– Fixed IBO adapter compile errors.
– Fixed Delphi C++ HPP generator errors related to kbmMWNullable.pas and kbmMWDateTime.pas
The changes needed to fix it for kbmMWNullable.pas unfortunately require
us to default unsupporting assigning of a variant directly to a kbmMWNullable.
However if you are using Delphi ONLY and will never use the C++Builder header files
you can add {$DEFINE KBMMW_DELPHI_ONLY} in kbmMWConfig.inc.
Then you can still assign a variant directly to a kbmMWNullable in Delphi.
The changes in kbmMWDateTime is using overloaded versions of methods
instead of using default value Math.NaN which is translated incorrectly
by the HPP emitter.
– Removed PrependTableName from all metadata classes and thus it may
error with missing property on opening forms/datamodules containing
metadata components. Ignore that specific property missing error and save.
– Fixed some TkbmMWORM.ExistsTable overloads incorrectly calling CreateTable.
– Fixed TkbmMWORM.ListFromDataset returning undefined value upon error.
– Added UTCAsVariant, LocalAsVariant, LocalDateAsVariant and LocalTimeAsVariant
properties to TkbmMWDateTime.
– Fixed warning at installation of designtime package related to smart service setup.

Changes/minor additions
=======================
– Improved shutdown of transport, and scheduled events.
– Checked encryption and updated SQLite Server/Client demoes to support compression.
– Updated AMQPClient demo with sending with properties sample.
– Set AnonymousResult to default true for REST attributes.
– Improved kbmMWGetFileVersionInfoAsString to also support Android.
– Improved server side ForwardMessage, ForwardRequest, ForwardResponse when original message comes from client messaging transport.
– Improved client transport disconnect.
– Updated Metaxxxx methods on database adapters to take AOwner argument.
Typically it will be empty, but with index relations, it will hold table name.
– Improved support for providing NodeID in server side messaging transport, even
though contents is encrypted.
– Cleaned up kbmMWGlobal.pas by grouping all kbmMWTextxxxx methods as class methods in TkbmMWTextPChar,
and added similar set handling bytes as class methods in TkbmMWTextPByte.
– Improved kbmMWGetComputerName and kbmMWGetComputerModel to support additional platforms.
– Changed Save and Load methods of TkbmMWCustomStat to not take any field names.
Specialized versions of TkbmMWCustomStat will handle that.
– Improved REST streamformat marshalling.
– Improved TkbmMWClientTransactionResolver.
– Renamed TkbmMWCustomRewriter to TkbmMWCustomSQLRewriter.
– Improved stability of event execution in kbmMWScheduler.pas during exceptions.
– Optimized TkbmMWLockFreeHashArray to use generational garbage collection for
higher performance and concurrency.
– Starting to converting some utility threads (garbage collection and such) to
use be kbmMWScheduledEvent instead.
– Improved object marshalling.
– Changed default log level filter in TkbmMWCustomLogManager to [mwllBasic,mwllNormal].
– Changed default flush value in TkbmMWStreamLogManager to 0 (force each write to disk)
– Improvements added to kbmMWRTTI.pas
– Improved kbmMWDebugMemory.pas to detect when reporting is happening to avoid deadlocks.
– Enhanced TkbmMW_ArgAttribute (kbmMW_Arg) to allow for referencing specific argument index alternatively specific named argument.

REST easy with kbmMW #6 – Database 2

Now our fine REST server has been running for some time, and we start to understand we need to expand it with some more data.

Adding an additional table for new info is easy, as its done the same way as shown in REST easy with kbmMW #2 – Database

However what if we need to add additional fields to the TContact class? What do we do with the data storage?

Until upcoming release of kbmMW, we would have had to make our own table update mechanism, which often is easy to do, as long as you add new fields, and those fields should not be part of primary keys and such.

But from next release of kbmMW, we also release a new beta feature in the kbmMW ORM. The ability to determine if the data storage is compatible with the class, and the ability to automatically update the data storage to match the new look of the class.

It sounds so deceptively simple to do so, but when we also want it to work across different databases, handling indexes and more, it suddenly starts to require quite detailed understanding of databases and their metadata.

So as a spin off of this new feature, kbmMW also comes with vastly improved database metadata handling, even better understanding of SQL query variants, more features in our in house SQL parser and much more.

Ok.. enough of the sales talk…. How do you do it then?

The original TContact class was defined like this:

unit Unit9;

interface

uses
 DB,
 System.Generics.Collections,
 kbmMWRTTI,
 kbmMWORM,
 kbmMWNullable;

type

[kbmMW_Table('name:contact')]
TContact = class
private
 FID:kbmMWNullable;
 FName:kbmMWNullable;
 FAddress:kbmMWNullable;
 FZipCode:kbmMWNullable;
 FCity:kbmMWNullable;
 FComments:kbmMWNullable;
public
 [kbmMW_Field('primary:true, generator:shortGuid',ftString,40)]
 property ID:kbmMWNullable read FID write FID;

 [kbmMW_Field('name:name',ftString,50)] 
 property Name:kbmMWNullable read FName write FName;

 [kbmMW_Field('name:address',ftString,80)]
 property Address:kbmMWNullable read FAddress write FAddress;

 [kbmMW_Field('name:zipCode',ftInteger)]
 property ZipCode:kbmMWNullable read FZipCode write FZipCode;

 [kbmMW_Field('name:city',ftString,50)]
 property City:kbmMWNullable read FCity write FCity;

 [kbmMW_Field('name:comments',ftMemo)]
 property Comments:kbmMWNullable read FComments write FComments;
end;

implementation

initialization
 kbmMWRegisterKnownClasses([TContact,TObjectList]);
end.

Lets add a Gender field, change the Name field to be unique (just for fun), and change the zip code field to be a string type matching the property type (previously we, perhaps incorrectly, defined it as an integer data storage field, where storing it as a string might have been better).

unit Unit9;

interface

uses
 DB,
 System.Generics.Collections,
 kbmMWRTTI,
 kbmMWORM,
 kbmMWNullable;

type

[kbmMW_Table('name:contact')]
TContact = class
private
 FID:kbmMWNullable;
 FName:kbmMWNullable;
 FAddress:kbmMWNullable;
 FZipCode:kbmMWNullable;
 FCity:kbmMWNullable;
 FGender:kbmMWNullable;
 FComments:kbmMWNullable;
public
 [kbmMW_Field('primary:true, generator:shortGuid',ftString,40)]
 property ID:kbmMWNullable read FID write FID;

 [kbmMW_Field('name:name, unique:true',ftString,50)] 
 property Name:kbmMWNullable read FName write FName;

 [kbmMW_Field('name:address',ftString,80)]
 property Address:kbmMWNullable read FAddress write FAddress;

 [kbmMW_Field('name:zipCode',ftString,20)]
 property ZipCode:kbmMWNullable read FZipCode write FZipCode;

 [kbmMW_Field('name:city',ftString,50)]
 property City:kbmMWNullable read FCity write FCity;

 [kbmMW_Field('name:gender',ftString,1)]
 property Gender:kbmMWNullable read FGender write FGender;

 [kbmMW_Field('name:comments',ftMemo)]
 property Comments:kbmMWNullable read FComments write FComments;
end;

implementation

initialization
 kbmMWRegisterKnownClasses([TContact,TObjectList]);
end.

Usually these changes in the class would render that class incompatible with the data storage. In fact we can now ask the ORM if the data storage is compatible with the class we have.

if not FORM.CompatibleTable(TContact) then
  raise Exception.Create('TContact is not compatible with the datastore');

When we call CompatibleTable this way, it compares using the strictest comparison method, which means that storage fields and index definitions must be not only compatible, but identical.

By adding an TkbmMWONObject instance to the call, we can be told what problems there are:

var
  issues:TkbmMWONObject;
begin
 issues:=TkbmMWONObject.Create;
 try
  if not FORM.CompatibleTable(TContact,issues) then
  begin
   // Decipher issues object.
   // There may be 3 properties in the object, named add, modify, delete
   // and each of those will be an array of objects with properties for name, unique, primary, required, size, precision and dataType.
  end;
 finally
   issues.Free;
 end;
end;

This way you get detailed information about the changes needed to make the data storage compatible with your class.

It is possible to tune exactly what to compare and how, and thus limit the strictness of the comparison mechanism. This is done by adding one additional argument to CompatibleTable, namely the ACompatibleFlags:TkbmMWORMCompatibleTableFlags.

TkbmMWORMCompatibleTableFlags is a set of flags including:

  • mwoctfBasic – Basic strictness. Translates to mwfdctDataType, mwfdctPrecision, mwfdctSize
  • mwoctfStrict – Strongest strictness. Translates to mwfdctPrimary, mwfdctUnique, mwfdctRequired, mwfdctDataType, mwfdctStrictPrecision, mwfdctStrictSize
  • mwoctfConstraints – Include constaints validation. Translates to mwfdctPrimary, mwfdctUnique, mwfdctRequired
  • mwoctfType – Include generic data type validation. Translates to mwfdctSize, mwfdctPrecision, mwfdctDataType.

The translated comparing flags cant be provided directly, but is used internally, and only shown for completeness.

  • mwfdctPrimary – Primary key definition must match.
  • mwfdctUnique – Unique field constraint must match.
  • mwfdctRequired – Required field constraint (not null) must match.
  • mwfdctDataType – Exact data type must match.
  • mwfdctStrictPrecision – Field precision must match exactly. If not specified the data storage may have a larger field precision than required.
  • mwfdctStrictSize – Field size must match exactly. If not specified the data storage may have a larger field size than required.

Walking thru the issues table can be fun, but even more fun would be not to have to do so.

var
  sl:TStringList;
begin
 sl:=FORM.GetUpgradeTableStatements(TTable2);
 try
  // It will make a strict comparison (arguments can be added to choose non strict comparison),
  // and generate a list of statements in generic kbmMemTable SQL format
  // that can be used to transform the data storage to be compatible with
  // the class.
  // It could be ALTER TABLE xxx DROP COLUMN yyy
 finally
  sl.Free;
 end;

Now the observant reader may say: “Thats all fine, but I for a fact know that SQLite do not support ALTER TABLE DROP COLUMN statements! So it wont work!”

You are right…. about the SQLite limitation. However remember that kbmMW will translate the statements into something acceptable by the target database type, so SQLite will in fact suddenly be able to have a column dropped from a table containing data. kbmMW will do its best to make it happen.

If you would like to see the rewritten SQL. In other words generic kbmMemTable SQL converted to specific target database syntax, then do like this:

var
 sl:TStringList;
begin
 sl:=FORM.GetUpgradeTableStatements(TTable2,false);
 try
  // Now the list of statements will have been converted to 
  // the specific target database.
 finally
 sl.Free;
 end;

And after all this gibberish then how to make the data store compatible with the new class?

FORM.UpgradeTable(TTable2);

After running this, the table “contact” in the database will have been made compatible with the class, with all remaining data retained.

If you have huge tables with billions of rows, then it might be better to get inspiration from the output from GetUpgradeTableStatements, and apply the changes under human supervision.

Although kbmMW attempts to do things in a safe way, I also recommends backing up the data storage before attempting an automatic upgrade.

Currently kbmMW contains SQL rewriters that targets  SQLite, MySQL/MariaDB, PostgreSQL, MSSQL 2008/2012+, Oracle 9+,  Interbase/Firebird and generic SQL92 and SQL2003 compatible databases.

When the beta of this upgrade mechanism is released we urge people to test it upgrading capabilities carefully before deploying to production.

best regards

Kim/C4D