Contents
Preface
The reference blog series contains manual like reference information, and will typically not include examples or step by step instructions.
History
May 2 2020 – Original post
Dec 31 2020 – Added info about new PIVOT and SUBPIVOT sequence types.
ORM Attributes
kbmMW_Table
Used on model classes to indicate that they can be used by the ORM to interact with data in datastorages.
Usages:
[kbmMW_Table(ASettings:string)]
[kbmMW_Table(ASettings:string; const AMemberTypes:TkbmMWORMMemberTypes; const AVisibilityTypes:TkbmMWORMMemberVisibilityTypes)]
ASettings – string – Is a simplified inline YAML/JSON formatted string containing an overall description for how the model should be represented in a datastorage. The string represents an object structure of key/value property pairs, where the values can themselfs be native values (strings, integers, floats, booleans), a sub object structure, or an array of native values, sub object structures or sub arrays.
Example
[kbmMW_Table('name:person, index:{name:i1,field:name,descending:false}, index:{name:i2,unique:true,fields:[{name:name,descending:true},{name:age}]')] TPerson = class private FID:kbmMWNullable<string>; FName:kbmMWNullable<string>; FAddress:kbmMWNullable<string>; FAge:kbmMWNullable<integer>; FImage:kbmMWNullable<TMemoryStream>; procedure SetImage(AValue:kbmMWNullable<TMemoryStream>); public destructor Destroy; override; [kbmMW_Field('name:id, primary:true, generator:shortGuid',ftString,40)] property ID:kbmMWNullable<string> read FID write FID; [kbmMW_Field('name:name',ftWideString,50)] property FullName:kbmMWNullable<string> read FName write FName; [kbmMW_Field('name:address',ftWideString,50)] property Address:kbmMWNullable<string> read FAddress write FAddress; [kbmMW_Field('name:age',ftInteger)] property Age:kbmMWNullable<integer> read FAge write FAge; [kbmMW_Field('name:image',ftGraphic)] property Image:kbmMWNullable<TMemoryStream> read FImage write SetImage; end;
Properties:
- name – string – Name of the class model when represented in the data storage. In a regular SQL database this will usually be mapped to the table name. If no name is given, the name of the class will be used.
- index – sub object / array of sub objects – Describes how an index is defined. The index is usually represented in the datastorage as an optimzed way to search on specific data in the data storage version of the class model.Each sub object supports the following properties:
- name – string – Name of the index as it should be represented in the data storage.
- unique – boolean – If the index is defined as a unique index (where the combined values of the represented fields must be unique)
- One of:
- A field definition
- field – string – The class model name of the field that participate in the index.
- descending – boolean – If the index of that field should be descending. Default ascending.
- fields – array of field definitions (see above) – The class model names of the fields that participate in the index.
- A field definition
- defaultDeleteMethod – string – Specifies how the ORM should handle deletion of model data instances.
It can contain one of these string values:- default – It will simply delete the representation of the relevant model item/record from the datastorage.
- delete – Same as default.
- mark – Mark the representation of the model item/record as deleted by setting the value of a model field. Used in combination with deleteMarkProperty and deleteMarkValue.
- move – Moves the representation of the model item/record to another model class representation. Used in combination with deleteMoveToTable.
- deleteMarkProperty – string – Specifies the class model field name to be set/checked for to determined if the representation of the model item/record is considered deleted. See defaultDeleteMethod.
- deleteMarkValue – string – Specifies the value that will be stored in the class model field, when a representation of the model item/record is deleted. See defaultDeleteMethod.
- deleteMoveToTable – string – Specifies the class model name to which the class model item/record that is being deleted, should be moved to. See defaultDeleteMethod.
AMemberTypes – TkbmMWORMMemberTypes – Defines, in combination with AVisibilityTypes, which class model fields/properties that should be considered for members in the representation in the datastorage.
It can have a combination of values: (Default value [mwomtTagged])
mwomtField – Field variables in the class model are considered.
mwomtProperty – Properties in the class model are considered.
mwomtTagged – Only field variables and/or properties that have been flagged with the kbmMW_Field or kbmMW_VirtualField attribute will be considered.
AVisibilityTypes – TkbmMWORMMemberVisibilityTypes – Defines, in combination with AMemberTypes , which class model fields/properties that should be considered for members in the representation in the datastorage.
It can have a combination of values: (Default value [mwomvtTagged])
mwomvtPrivate – Field variables/properties in the private section of the class model are considered.
mwomvtProtected – Field variables/properties in the protected section of the class model are considered.
mwomvtPublic – Field variables/properties in the public section of the class model are considered.
mwomvtPublished – Field variables/properties in the published section of the class model are considered.
mwomvtTagged – Only field variables and/or properties that have been flagged with the kbmMW_Field or kbmMW_VirtualField attribute will be considered.
kbmMW_Field
Used on fields/properties in model classes to define if and how the fields/properties are to be represented in the datastorage.
Usages:
[kbmMW_Field(const ADataType:TFieldType = ftUnknown)]
[kbmMW_Field(const ADataType:TFieldType; const ASize:integer)]
[kbmMW_Field(const ADataType:TFieldType; const ASize,APrecision:integer)]
[kbmMW_Field(ASettings:string; const ADataType:TFieldType = ftUnknown)]
[kbmMW_Field(ASettings:string; const ADataType:TFieldType; const ASize:integer)]
[kbmMW_Field(ASettings:string; const ADataType:TFieldType; const ASize,APrecision:integer)]
ADataType – TFieldType – Specifies the database type that the field/property should be represented as in the datastorage. The following TFieldType’s are supported: ftFloat, ftSingle, ftBCD, ftCurrency, ftBoolean, ftBytes, ftBlob, ftGraphic, ftTypedBinary, ftDate, ftTime, ftDateTime, ftString, ftWideString, ftMemo, ftWideMemo, ftFixedChar, ftFixedWideChar, ftSmallint, ftInteger, ftWord, ftLongWord, ftShortint, ftLargeint
ASize – integer – Specifies the required character or digit width of the datatype when storage is prepared for it in the datastorage. It is primarely of interest when ADataType is ftCurrency, ftString, ftWideString, ftFixedChar, ftFixedWideChar. If ASize is not provided, it will have a default value of 255, when ADataType is ftString, ftWideString, ftFixedChar and ftFixedWideChar, 10 when ADataType is ftCurrency and 0 for other data types.
APrecision – integer – Specifies the precision in number of digits after the decimal point when storage is prepared in the datastorage. It is primarely of interest when ADataType is ftCurrency. If APrecision is not provided, it will have a default value of 4 when ADataType is ftCurrency.
ASettings – string – Is a simplified inline YAML/JSON formatted string containing a description of how the particular field/property for which the kbmMW_Field attribute is given, should be represented in a datastorage, and how various conversions and automatic data generation should operate. The string represents an object structure of key/value property pairs, where the values can themselfs be native values (strings, integers, floats, booleans), a sub object structure, or an array of native values, sub object structures or sub arrays.
if ASettings is not specified, then the field/property will be named the same in the datastorage as it is in the model class.
Properties:
- name – string – Name of the field/property in class model when it is to be represented in the data storage. In a regular SQL database this will usually be mapped to the field name. If no name is given, the name of the property/field will be used.
- primary – boolean – If true or 1, specifies that the given field/property representation in the datastorage should be considered part of a primary index. Default false.
- unique – boolean – If true or 1, specifies that the given field/property representation in the datastorage should be part of a index guaranteeing unique values in this field. Default false.
- readOnly – boolean – Currently not used! Default false.
- virtual – boolean – If true or 1, specifies that the field/property is not to be represented in a datastorage, but it can still be used for other ORM operations.
- triggerModified – boolean – If true or 1 (which is default), specifies that changes to the property/field in the model, will mark the model class instance as having been modified, and thus potential subject to persisting in the datastorage.
- default – integer/int64/string/boolean/datetime/binary – The default value for a property/field. It is of special importance when the datastorage is redefined by the ORM, as an reaction to addition of new model class fields/properties, and those fields/properties has been marked as required. Then the datastorage will automatically assign the default value for that particular new field/property representation in the datastorage for existing entries in the storage. Field/properties are considered required when they have the [kbmMW_NotNull] attribute prefixed.
- dateFormat – string – Specifies the format for a date/time field/property in the model class, when it’s value is retrieved or stored from/to the datastorage. It can have the following values:
- Unknown – No date/time format has been specified.
- Local – Handle date/time values as a Delphi local time TDateTime float value.
- UTC – Handle date/time values as a Delphi UTC TDateTime float value.
- ISO8601 – Handle date/time values as a string formatted according to the ISO8601 format. (yyyy-mm-ddThh:nn:ss.zzzTZ)
- RFC1123 – Handle date/time values as a string formatted local time according to the RFC1123 format. (dd-MMM-yyyy hh:nn:ss TZ)
- NCSA – Handle date/time values as a string formatted as a local time according to the NCSA format. (dd/MMM/yyyy:hh:nn:ss TZ)
- LocalSinceEpochMS – Handle date/time values as a local time UNIX epoch in milliseconds. (1/1000 secs since 00:00:00 Januar 1. 1970)
- UTCSinceEpochMS – Handle date/time values as an UTC time UNIX epoch in milliseconds. (1/1000 secs since 00:00:00 Januar 1. 1970)
- LocalSinceEpoch – Handle date/time values as a local time based UNIX epoch in seconds. (secs since 00:00:00 Januar 1. 1970)
- UTCSinceEpoch – Handle date/time values as an UTC based UNIX epoch in seconds. (secs since 00:00:00 Januar 1. 1970)
- LocalEpoch – Handle date/time values as a local time based epoch. See epochType.
- UTCEpoch – Handle date/time values as an UTC based epoch. See epochType.
- LocalFormat – Handle date/time values as a custom string formatted local time based value. See dateTimeFormat.
- UTCFormat – Handle date/time values as a custom string formatted UTC based value. See dateTimeFormat.
- epochType – string – Specifies the specific epoch to use when dateFormat is set to LocalEpoch or UTCEpoch. It can be one of the following values:
- Unknown – No epoch type has been specified.
- PosixS – Seconds since 1. Jan. 1970 00:00:00
- PosixMS – Milliseconds (1/1000 secs) since 1. Jan. 1970 00:00:00
- PosixUS – Microseconds (1/1000000 secs) since 1. Jan. 1970 00:00:00
- PosixNS – Nanoseconds (1/1000000000 secs) since 1. Jan. 1970 00:00:00
- NTSysTime – Milliseconds (1/1000 secs) since 1. Jan 1601 00:00:00
- NTFileTime – 100/1000000000 secs since 1. Jan 1601 00:00:00
- OS2 – 1/100 secs since 1. Jan 1980 00:00:00
- Apple – Milliseconds (1/1000 secs) since 1. Jan 2001 00:00:00
- Android – Milliseconds (1/1000 secs) since 1. Jan. 1970 00:00:00
- dateTimeFormat – string – Specifies a format string which is used when converting between strings and date/time values. It consists of a combination of special codes starting with % and optional static characters. It is used with dateFormat is set to LocalFormat or UTCFormat.Examples of format strings:%Y-%M-%D %H:%M:%S – Will produce and parse according to the format identifiers%D.%M.%Y %H:%M:%S – Will produce and parse according to the format identifiers%D.%M.%Y=(\d{2}).(\d{2}).(\d{4}) – Will produce according to the format identifiers, and parse according to the regular expression. Parses and outputs: 20.05.2018
Dato\=%D.%M.%Y=’Dato='(\d{2}).(\d{2}).(\d{4}) – Will produce according to the format identifiers, and parse according to the regular expression. Parses and outputs: Dato=20.05.2018
/Date(%E2)/=’/Date\((\d+)\)/ – Will produce according to the format identifiers, and parse according to the regular expression. Parses and outputs: /Date(1212121212)/The following special codes are supported- %Y = 4 digit year
- %Y1 = 2 digit year 19xx
- %Y2 = 2 digit year 20xx
- %Y3 = 2 digit year >=50=19xx, <50=20xx
- %M = 1 or 2 digit month
- %M1 = 3+ char US month name
- %M2 = 3+ char locale month name
- %D = 1 or 2 digit day. 2 when converting to a string
- %D1 = 1 or 2 digit day, 1 or 2 when converting to a string
- %H = 1 or 2 digit hour. 2 when converting to a string
- %H1 = 1 or 2 digit hour, 1 or 2 when converting to a string
- %N = 1 or 2 digit minute. 2 when converting to a string
- %S = 1 or 2 digit second. 2 when converting to a string
- %Z = 1,2 or 3 digit millisecond, 3 when converting to a string
- %Z1 = 1,2 or 3 digit millisecond, 1,2 or 3 when converting to a string
- %T = Timezone (+hh:mm)
- %T1 = Timezone (+hhmm)
- %P = A/P/AM/PM
- %En = UTC epoch. n defines type:
- %en = Local time epoch. n defines type:
- n=1 – Posix seconds
- n=2 – Posix milli seconds
- n=3 – Posix micro seconds
- n=4 – Posix nano seconds
- n=5 – Microsoft NT system time
- n=6 – Microsoft NT file time
- n=7 – OS/2
- n=8 – Apple (MacOS/IOS)
- n=9 – Android
- %H1 = 1 or 2 digit hour, 1 or 2 when converting to a string
- %i = Ignore one character
- %Ix = Ignore all characters until the character x
- %% = %
- generator – string – The name of a generator which will be used when populating the field with a value upon storage, typically when it do not already contain one. See generatorMode and generatorStates. The following generators are supported:
- GUID – Produce a full sized GUID. Eg. {123e4567-e89b-12d3-a456-426655440000}
- SHORTGUID – Produce a compact sized GUID. Eg. 123e4567e89b12d3a456426655440000
- SEQUENCE – Draws a new number from a generator or sequencer. See sequence and sequenceStart.
- DATETIME – Produce a time stamp.
- generatorMode – string – The situations in which the generator should generate a value. It can be one of:
- ALWAYS – The generator will always generate a new value upon storage.
- WHEN NULL – The generator will only generate a new value when the field/property is null.
- NULL – Same as WHEN NULL.
- generatorStates – array of string – Controls which storage scenarios that the generator should produce a value. It can be a combination of:
- INS – The generator will only be considered when data is to be inserted into the storage.
- UPD – The generator will only be considered when existing data is to be updated in the storage.
- MOD – Same as UPD
- DEL – The generator will only be considered when existing data is to be deleted from the storage.
- sequence – string – The name of the sequence from which unique numbers will be picked. The name must not be empty if the generator is set to generate from a sequence. The actual implementation of the sequence depends on the capabilities of the data storage, but the ORM will automatically attempt to match the best option, and can fall back to generating pivot tables.
- sequenceStart – int32 – A starting value for a sequence named by the sequence property. If not specified, the default starting point as supported by the datastorage is used. Some datastorages do not support specifying custom starting values. The starting value is only considered when the model class is being used for constructing the datastorage containers (for SQL databases… tables, fields and sequencers/generators).
- sequenceType – string – The type of sequence generator. If not specified it defaults to regular sequence (which may fall back to using a pivot table if the underlying datastorage do not support native sequences/generators). Otherwise it can have the following values:
- PIVOT – Force the sequence to be using a pivot table. The pivot tables name will, when forced default be KBMMW_COUNTER, but a different name can be given via the CounterTableName property of the metadata component.
- SUBPIVOT – Force the sequence to be using a pivot table. Counting is scoped on other fields in the record, and the generator can thus for example be used as a version counter of records holding the same other values for specific fields. E.g. If you have a the field ContractNumber (string 50), and you want to provide an additional field holding the versions of the contract, you could add another field ContractVersion where you refer to the ContractNumber as the reference of the versioning. Subpivot sequences support these additional properties:
- subPivotScope – An array of Delphi names for fields to scope the counter. In case of the above example, it would be subPivotScope: [ContractNumber]
- subPivotName – An optional name for a true database storage table that will hold the sub pivot counters for this, and potentially other, fields. It defaults to KBMMW_COUNTER or what has been setup for the CounterTableName property of the metadata component.. Example: subPivotName: ContractVersions
- display – sub object – Optional suggested display features for the field/property when data is made accessible for a TDataset. The sub object can contain:
- name – string – Caption for the field/property
- width – int32 – Width in characters for display purpose
- visible – boolean – Visibility of the field in a TDataset.
- oldNames – array of string – If this model class property/field has been renamed, provide it’s old name in this array. It will be used so the ORM can rename rather than delete and create property/field representations in the datastorage whenever possible, to retain existing data. It supports having renamed multiple times, hence the reason for an array.
- source – string – The fully qualified name of a different model class which is to be used for auto joining data to this model class. Eg. Unit1.TMyLookupTable. See value, sourceKeyFields, sourceKey, keyFields and key properties.
- sourceKey – string – The name of a single property/field in the source model class to use as the primary lookup key.
- sourceKeyFields – array of string – The names of one or more properties/field’s in the source model class to use as combined primary lookup key.
- key – string – The name of a single property/field in this model class to use as the lookup key value.
- keyFields – array of string – The names of one or more properties/field’s in the this model class to use as combined lookup key value.
- value – string – The fully qualified name of a source model class field/property to get as result of the lookup. If specified, then source, sourceKey/sourceKeyFields, key/keyFields will only be used to lookup a single native value, instead of attempting to lookup a complete linked object or list of objects. The value supports expressions, and multiple fully qualified names can be used to combine source properties/field values into one value. Eg. value:uData.TPerson.FullName or value:”uData.TPerson.FullName||\” Age:\”||uData.TPerson.Age”
kbmMW_Null
Used on fields/properties in model classes to define null value conversion.
Usages:
[kbmMW_Null]
[kbmMW_Null(ANullValue:string)]
[kbmMW_Null(ANullValue:double)]
[kbmMW_Null(ANullValue:integer)]
[kbmMW_Null(ANullValue:int64)]
[kbmMW_Null(ANullValue:boolean)]
If no arguments are given, then the default value to be used for a null value is null itself. It will often translate to zero (0) for integer values, and an empty string for string values.
Otherwise the specific value given is the value that will be considered the null value. This way it is for example possible to define that the integer value -1 should represent a null value. Within the model class field/property, the value will be seen as -1, but in the datastorage it will be understood as NULL.
kbmMW_NotNull
Indicate that the property/field must never contain the NULL value (either interpreted via the kbmMW_Null attribute or the actual value). In other words, it is, in datastorage terms, a required value.
Usages:
[kbmMW_NotNull]
kbmMW_VirtualTable
Used on model classes to indicate that they can be used by the ORM to interact with the model, but the model will never be used for updating/defining datastorages, and all properties/fields within the model class are considered virtuel fields.
Usages:
[kbmMW_VirtualTable]
[kbmMW_VirtualTable(const ABaseClass:TClass) ]
[kbmMW_VirtualTable(const AMemberTypes:TkbmMWORMMemberTypes; const AVisibilityTypes:TkbmMWORMMemberVisibilityTypes);
[kbmMW_VirtualTable(const ABaseClass:TClass; const AMemberTypes:TkbmMWORMMemberTypes; const AVisibilityTypes:TkbmMWORMMemberVisibilityTypes);
ABaseClass – TClass – Inherit this model class from a different model class, and optionally augment it with a number of additional virtual fields/properties. It is specially valuable if you have a regular model class, for which you want to pick up data from a datastorage, but in a non destructive way, where the data can’t be persisted back, or you may have added additional virtual fields for internal application purpose. The base class is used by the ORM to know which actual datastorage representation (typical table) is to be used for query access.
For example adding additional lookup information non destructively to an TAccount model class.
[kbmMW_VirtualTable(TAccount)] TAccountWithPerson = class(TAccount) private FPerson:TPerson; public destructor Destroy; override; [kbmMW_VirtualField('name:person, source:uData.TPerson, key:PID, sourceKey:ID')] property Person:TPerson read FPerson write FPerson; end;
AMemberTypes – See kbmMW_Table attribute
AVisibilityTypes – See kbmMW_Table attribute
Kim/C4D