2018-10-23 16:18:34 +02:00
// *************************************************************************** }
//
// Delphi MVC Framework
//
2023-01-17 08:52:26 +01:00
// Copyright (c) 2010-2023 Daniele Teti and the DMVCFramework Team
2018-10-23 16:18:34 +02:00
//
// https://github.com/danieleteti/delphimvcframework
//
// ***************************************************************************
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// ***************************************************************************
unit EntitiesU;
2020-02-03 10:51:40 +01:00
{$RTTI EXPLICIT METHODS([vcPublic, vcPublished]) FIELDS([vcPrivate, vcProtected, vcPublic, vcPublished]) PROPERTIES([vcPublic, vcPublished])}
2018-10-23 16:18:34 +02:00
interface
uses
MVCFramework. Serializer. Commons,
MVCFramework. ActiveRecord,
System. Generics. Collections,
2020-01-04 12:53:53 +01:00
System. Classes,
FireDAC. Stan. Param,
MVCFramework. Nullables;
2018-10-23 16:18:34 +02:00
type
2020-04-08 18:04:45 +02:00
TCustomEntity = class abstract( TMVCActiveRecord)
protected
procedure OnBeforeExecuteSQL( var SQL: string ) ; override ;
end ;
2018-10-23 16:18:34 +02:00
[ MVCNameCase( ncLowerCase) ]
2019-02-21 18:11:14 +01:00
[ MVCTable( 'articles' ) ]
2020-04-08 18:04:45 +02:00
TArticle = class( TCustomEntity)
2018-10-23 16:18:34 +02:00
private
2020-08-11 00:54:42 +02:00
[ MVCTableField( 'ID' , [ foPrimaryKey, foAutoGenerated] ) ]
2020-02-03 10:51:40 +01:00
fID: NullableInt32;
2020-01-04 12:53:53 +01:00
fCodice: NullableString;
2019-02-21 18:11:14 +01:00
[ MVCTableField( 'description' ) ]
2018-10-23 16:18:34 +02:00
fDescrizione: string ;
2019-02-21 18:11:14 +01:00
[ MVCTableField( 'price' ) ]
2018-10-23 16:18:34 +02:00
fPrezzo: Currency ;
public
constructor Create; override ;
destructor Destroy; override ;
2020-02-03 10:51:40 +01:00
property ID: NullableInt32 read fID write fID;
2020-01-04 12:53:53 +01:00
property Code: NullableString read fCodice write fCodice;
2019-02-21 18:11:14 +01:00
property Description: string read fDescrizione write fDescrizione;
property Price: Currency read fPrezzo write fPrezzo;
2018-10-23 16:18:34 +02:00
end ;
2020-08-11 00:54:42 +02:00
[ MVCNameCase( ncLowerCase) ]
[ MVCTable( 'articles' ) ]
TArticleWithWriteOnlyFields = class( TCustomEntity)
private
2022-01-26 23:00:32 +01:00
{$IFNDEF USE_SEQUENCES}
[ MVCTableField( 'id' , [ foPrimaryKey, foAutoGenerated, foReadOnly] ) ]
{$ELSE}
[ MVCTableField( 'id' , [ foPrimaryKey, foAutoGenerated] ,
'SEQ_ARTICLES_ID' { required for interbase } ) ]
{$ENDIF}
2020-08-11 00:54:42 +02:00
fID: NullableInt32;
[ MVCTableField( 'description' , [ foWriteOnly] ) ]
fDescrizione: string ;
[ MVCTableField( 'price' , [ foWriteOnly] ) ]
fPrice: Integer ;
public
property ID: NullableInt32 read fID write fID;
property Description: string read fDescrizione write fDescrizione;
property Price: Integer read fPrice write fPrice;
end ;
[ MVCNameCase( ncLowerCase) ]
[ MVCTable( 'articles' ) ]
TArticleWithReadOnlyFields = class( TCustomEntity)
private
[ MVCTableField( 'ID' , [ foPrimaryKey, foReadOnly] ) ]
fID: NullableInt32;
fCodice: NullableString;
[ MVCTableField( 'description' , [ foReadOnly] ) ]
fDescrizione: string ;
[ MVCTableField( 'price' , [ foReadOnly] ) ]
fPrezzo: Currency ;
public
property ID: NullableInt32 read fID write fID;
property Code: NullableString read fCodice write fCodice;
property Description: string read fDescrizione write fDescrizione;
property Price: Currency read fPrezzo write fPrezzo;
end ;
2018-10-23 16:18:34 +02:00
TOrder = class ;
[ MVCNameCase( ncLowerCase) ]
2019-02-21 18:11:14 +01:00
[ MVCTable( 'customers' ) ]
2023-10-17 18:08:30 +02:00
[ MVCNamedSQLQuery( 'BestCustomers' , 'select * from customers where rating >=4' ) ]
[ MVCNamedSQLQuery( 'WithRatingGtOrEqTo' , 'select * from customers where rating >=?' ) ]
2023-08-09 01:23:24 +02:00
[ MVCNamedSQLQuery( 'RatingLessThanPar' , 'select * from customers where rating < ? order by code, city desc' ) ]
2023-08-09 10:55:34 +02:00
[ MVCNamedSQLQuery( 'RatingEqualsToPar' , 'select /*firebird*/ * from customers where rating = ? order by code, city desc' , TMVCActiveRecordBackEnd. FirebirdSQL) ]
[ MVCNamedSQLQuery( 'RatingEqualsToPar' , 'select /*postgres*/ * from customers where rating = ? order by code, city desc' , TMVCActiveRecordBackEnd. PostgreSQL) ]
[ MVCNamedSQLQuery( 'RatingEqualsToPar' , 'select /*all*/ * from customers where rating = ? order by code, city desc' ) ]
[ MVCNamedRQLQuery( 'RatingLessThanPar' , 'lt(rating,%d);sort(+code,-city)' ) ]
[ MVCNamedRQLQuery( 'RatingEqualsToPar' , 'eq(rating,%d);sort(+code,-city)' ) ]
2023-10-17 18:08:30 +02:00
[ MVCNamedSQLQuery( 'GetAllCustomers' , 'select * from sp_get_customers()' , TMVCActiveRecordBackEnd. PostgreSQL) ]
2020-04-08 18:04:45 +02:00
TCustomer = class( TCustomEntity)
2018-10-23 16:18:34 +02:00
private
2020-01-08 15:30:10 +01:00
{$IFNDEF USE_SEQUENCES}
2019-03-05 20:55:37 +01:00
[ MVCTableField( 'id' , [ foPrimaryKey, foAutoGenerated] ) ]
2020-01-08 15:30:10 +01:00
{$ELSE}
2021-03-20 00:30:20 +01:00
[ MVCTableField( 'id' , [ foPrimaryKey, foAutoGenerated] ,
'SEQ_CUSTOMERS_ID' { required for interbase } ) ]
2020-01-08 15:30:10 +01:00
{$ENDIF}
2020-02-03 10:51:40 +01:00
fID: NullableInt64;
2019-02-21 18:11:14 +01:00
[ MVCTableField( 'code' ) ]
2020-01-04 12:53:53 +01:00
fCode: NullableString;
2019-02-21 18:11:14 +01:00
[ MVCTableField( 'description' ) ]
2020-01-04 12:53:53 +01:00
fCompanyName: NullableString;
2019-02-21 18:11:14 +01:00
[ MVCTableField( 'city' ) ]
2018-10-23 16:18:34 +02:00
fCity: string ;
2020-01-04 12:53:53 +01:00
[ MVCTableField( 'rating' ) ]
2020-02-03 10:51:40 +01:00
fRating: NullableInt32;
2019-12-23 10:35:36 +01:00
[ MVCTableField( 'note' ) ]
2020-03-27 00:37:28 +01:00
fNote: string ;
2018-10-23 16:18:34 +02:00
public
constructor Create; override ;
destructor Destroy; override ;
2021-04-25 22:40:06 +02:00
function ToString: String ; override ;
2020-02-03 10:51:40 +01:00
property ID: NullableInt64 read fID write fID;
2020-01-04 12:53:53 +01:00
property Code: NullableString read fCode write fCode;
property CompanyName: NullableString read fCompanyName write fCompanyName;
2018-10-23 16:18:34 +02:00
property City: string read fCity write fCity;
2020-02-03 10:51:40 +01:00
property Rating: NullableInt32 read fRating write fRating;
2020-03-27 00:37:28 +01:00
property Note: string read fNote write fNote;
2018-10-23 16:18:34 +02:00
end ;
2021-11-18 00:49:12 +01:00
[ MVCNameCase( ncLowerCase) ]
[ MVCTable( 'customers' ) ]
TPartitionedCustomer = class( TCustomEntity)
private
2022-01-26 23:00:32 +01:00
{$IFNDEF USE_SEQUENCES}
2021-11-18 00:49:12 +01:00
[ MVCTableField( 'id' , [ foPrimaryKey, foAutoGenerated] ) ]
2022-01-26 23:00:32 +01:00
{$ELSE}
[ MVCTableField( 'id' , [ foPrimaryKey, foAutoGenerated] ,
'SEQ_CUSTOMERS_ID' { required for interbase } ) ]
{$ENDIF}
2021-11-18 00:49:12 +01:00
fID: NullableInt64;
[ MVCTableField( 'code' ) ]
fCode: NullableString;
[ MVCTableField( 'description' ) ]
fCompanyName: NullableString;
[ MVCTableField( 'city' ) ]
fCity: string ;
[ MVCTableField( 'note' ) ]
fNote: string ;
public
function ToString: String ; override ;
property ID: NullableInt64 read fID write fID;
property Code: NullableString read fCode write fCode;
property CompanyName: NullableString read fCompanyName write fCompanyName;
property City: string read fCity write fCity;
property Note: string read fNote write fNote;
end ;
2021-11-17 15:36:20 +01:00
[ MVCNameCase( ncLowerCase) ]
[ MVCTable( 'customers' , 'ge(Rating,4)' ) ]
TGoodCustomer = class( TCustomer)
end ;
2021-11-18 00:49:12 +01:00
[ MVCTable( 'customers' ) ]
[ MVCPartition( 'rating=(integer)1' ) ]
TCustomerWithRate1 = class( TPartitionedCustomer)
end ;
[ MVCTable( 'customers' ) ]
[ MVCPartition( 'rating=(integer)2' ) ]
TCustomerWithRate2 = class( TPartitionedCustomer)
end ;
2021-11-17 15:36:20 +01:00
[ MVCNameCase( ncLowerCase) ]
[ MVCTable( 'customers' , 'le(Rating,3)' ) ]
TBadCustomer = class( TGoodCustomer)
end ;
2019-02-21 20:17:11 +01:00
[ MVCNameCase( ncLowerCase) ]
[ MVCTable( 'customers' ) ]
2022-11-15 09:27:08 +01:00
TCustomerWithReadOnlyFields = class( TCustomEntity)
2019-02-21 20:17:11 +01:00
private
2020-01-08 15:30:10 +01:00
{$IFNDEF USE_SEQUENCES}
2019-03-05 20:55:37 +01:00
[ MVCTableField( 'id' , [ foPrimaryKey, foAutoGenerated] ) ]
2020-01-08 15:30:10 +01:00
{$ELSE}
2021-03-20 00:30:20 +01:00
[ MVCTableField( 'id' , [ foPrimaryKey, foAutoGenerated] ,
'SEQ_CUSTOMERS_ID' { required for interbase } ) ]
2020-01-08 15:30:10 +01:00
{$ENDIF}
2019-02-21 20:17:11 +01:00
fID: Integer ;
2022-11-15 09:27:08 +01:00
[ MVCTableField( 'code' , [ foReadOnly] ) ]
2019-02-21 20:17:11 +01:00
fCode: string ;
2019-11-05 16:57:22 +01:00
fFormattedCode: string ;
2019-02-21 20:17:11 +01:00
[ MVCTableField( 'description' ) ]
fCompanyName: string ;
2019-11-05 16:57:22 +01:00
[ MVCTableField( 'city' ) ]
2019-02-21 20:17:11 +01:00
fCity: string ;
2020-03-27 00:37:28 +01:00
procedure SetFormattedCode( const Value: string ) ;
2019-02-21 20:17:11 +01:00
public
property ID: Integer read fID write fID;
property Code: string read fCode write fCode;
2020-03-27 00:37:28 +01:00
property FormattedCode: string read fFormattedCode write SetFormattedCode;
2019-02-21 20:17:11 +01:00
property CompanyName: string read fCompanyName write fCompanyName;
property City: string read fCity write fCity;
end ;
2018-10-23 16:18:34 +02:00
[ MVCNameCase( ncLowerCase) ]
2019-02-21 18:11:14 +01:00
[ MVCTable( 'order_details' ) ]
2020-04-08 18:04:45 +02:00
TOrderDetail = class( TCustomEntity)
2018-10-23 16:18:34 +02:00
private
2020-01-08 15:30:10 +01:00
{$IFNDEF USE_SEQUENCES}
2019-03-05 20:55:37 +01:00
[ MVCTableField( 'id' , [ foPrimaryKey, foAutoGenerated] ) ]
2020-01-08 15:30:10 +01:00
{$ELSE}
2021-03-20 00:30:20 +01:00
[ MVCTableField( 'id' , [ foPrimaryKey, foAutoGenerated] ,
'SEQ_order_details_ID' { required for interbase } ) ]
2020-01-08 15:30:10 +01:00
{$ENDIF}
2018-10-23 16:18:34 +02:00
fID: Integer ;
2019-02-21 18:11:14 +01:00
[ MVCTableField( 'id_order' ) ]
2018-10-23 16:18:34 +02:00
fOrderID: Integer ;
2019-02-21 18:11:14 +01:00
[ MVCTableField( 'id_article' ) ]
2018-10-23 16:18:34 +02:00
fArticleID: Integer ;
2019-02-21 18:11:14 +01:00
[ MVCTableField( 'unit_price' ) ]
2018-10-23 16:18:34 +02:00
fPrice: Currency ;
2019-02-21 18:11:14 +01:00
[ MVCTableField( 'discount' ) ]
2018-10-23 16:18:34 +02:00
fDiscount: Integer ;
2019-02-21 18:11:14 +01:00
[ MVCTableField( 'quantity' ) ]
2018-10-23 16:18:34 +02:00
fQuantity: Integer ;
2019-02-21 18:11:14 +01:00
[ MVCTableField( 'description' ) ]
2018-10-23 16:18:34 +02:00
fDescription: string ;
2019-02-21 18:11:14 +01:00
[ MVCTableField( 'total' ) ]
2018-10-23 16:18:34 +02:00
fTotal: Currency ;
public
constructor Create; override ;
destructor Destroy; override ;
property ID: Integer read fID write fID;
property OrderID: Integer read fOrderID write fOrderID;
property ArticleID: Integer read fArticleID write fArticleID;
property Price: Currency read fPrice write fPrice;
property Discount: Integer read fDiscount write fDiscount;
property Quantity: Integer read fQuantity write fQuantity;
property Description: string read fDescription write fDescription;
property Total: Currency read fTotal write fTotal;
end ;
2020-03-27 00:37:28 +01:00
[ MVCNameCase( ncLowerCase) ]
[ MVCTable( 'customers_plain' ) ]
2020-04-08 18:04:45 +02:00
TCustomerPlain = class( TCustomEntity)
2020-03-27 00:37:28 +01:00
private
[ MVCTableField( 'id' , [ foPrimaryKey] ) ]
fID: NullableInt64;
[ MVCTableField( 'code' ) ]
fCode: NullableString;
[ MVCTableField( 'description' ) ]
fCompanyName: NullableString;
[ MVCTableField( 'city' ) ]
fCity: string ;
[ MVCTableField( 'rating' ) ]
fRating: NullableInt32;
[ MVCTableField( 'note' ) ]
fNote: string ;
2020-06-25 22:54:57 +02:00
[ MVCTableField( 'creation_time' ) ]
FCreationTime: TTime;
[ MVCTableField( 'creation_date' ) ]
FCreationDate: TDate;
2020-03-27 00:37:28 +01:00
public
property ID: NullableInt64 read fID write fID;
property Code: NullableString read fCode write fCode;
property CompanyName: NullableString read fCompanyName write fCompanyName;
property City: string read fCity write fCity;
property Rating: NullableInt32 read fRating write fRating;
property Note: string read fNote write fNote;
2020-06-25 22:54:57 +02:00
property CreationTime: TTime read FCreationTime write FCreationTime;
property CreationDate: TDate read FCreationDate write FCreationDate;
2020-03-27 00:37:28 +01:00
end ;
2020-04-08 18:04:45 +02:00
[ MVCNameCase( ncLowerCase) ]
[ MVCTable( 'customers with spaces' ) ]
TCustomerWithSpaces = class( TCustomEntity)
private
[ MVCTableField( 'id with spaces' , [ foPrimaryKey] ) ]
fID: NullableInt64;
[ MVCTableField( 'code with spaces' ) ]
fCode: NullableString;
[ MVCTableField( 'description with spaces' ) ]
fCompanyName: NullableString;
[ MVCTableField( 'city with spaces' ) ]
fCity: string ;
[ MVCTableField( 'rating with spaces' ) ]
fRating: NullableInt32;
[ MVCTableField( 'note with spaces' ) ]
fNote: string ;
public
property ID: NullableInt64 read fID write fID;
property Code: NullableString read fCode write fCode;
property CompanyName: NullableString read fCompanyName write fCompanyName;
property City: string read fCity write fCity;
property Rating: NullableInt32 read fRating write fRating;
property Note: string read fNote write fNote;
end ;
2020-03-31 16:23:22 +02:00
[ MVCNameCase( ncLowerCase) ]
[ MVCTable( 'customers_with_code' ) ]
2020-04-08 18:04:45 +02:00
TCustomerWithCode = class( TCustomEntity)
2020-03-31 16:23:22 +02:00
private
[ MVCTableField( 'code' , [ foPrimaryKey] ) ]
fCode: NullableString;
[ MVCTableField( 'description' ) ]
fCompanyName: NullableString;
[ MVCTableField( 'city' ) ]
fCity: string ;
[ MVCTableField( 'rating' ) ]
fRating: NullableInt32;
[ MVCTableField( 'note' ) ]
fNote: string ;
public
property Code: NullableString read fCode write fCode;
property CompanyName: NullableString read fCompanyName write fCompanyName;
property City: string read fCity write fCity;
property Rating: NullableInt32 read fRating write fRating;
property Note: string read fNote write fNote;
end ;
2020-08-13 17:40:02 +02:00
[ MVCTable( 'customers_with_code' ) ]
TCustomerPlainWithClientPK = class( TCustomerWithCode)
protected
procedure OnBeforeInsert; override ;
end ;
2022-06-16 14:05:01 +02:00
[ MVCNameCase( ncLowerCase) ]
[ MVCTable( 'customers_with_guid' ) ]
TCustomerWithGUID = class( TCustomEntity)
private
2022-06-19 18:57:47 +02:00
[ MVCSerializeGuidWithoutBraces]
2022-06-16 14:05:01 +02:00
[ MVCTableField( 'idguid' , [ foPrimaryKey] ) ]
fGUID: NullableTGUID;
[ MVCTableField( 'code' ) ]
fCode: NullableString;
[ MVCTableField( 'description' ) ]
fCompanyName: NullableString;
[ MVCTableField( 'city' ) ]
fCity: string ;
[ MVCTableField( 'rating' ) ]
fRating: NullableInt32;
[ MVCTableField( 'note' ) ]
fNote: string ;
public
property GUID: NullableTGUID read fGUID write fGUID;
property Code: NullableString read fCode write fCode;
property CompanyName: NullableString read fCompanyName write fCompanyName;
property City: string read fCity write fCity;
property Rating: NullableInt32 read fRating write fRating;
property Note: string read fNote write fNote;
end ;
2018-10-23 16:18:34 +02:00
[ MVCNameCase( ncLowerCase) ]
2019-02-21 18:11:14 +01:00
[ MVCTable( 'orders' ) ]
2020-04-08 18:04:45 +02:00
TOrder = class( TCustomEntity)
2018-10-23 16:18:34 +02:00
private
2020-01-08 15:30:10 +01:00
{$IFNDEF USE_SEQUENCES}
2019-03-05 20:55:37 +01:00
[ MVCTableField( 'id' , [ foPrimaryKey, foAutoGenerated] ) ]
2020-01-08 15:30:10 +01:00
{$ELSE}
2021-03-20 00:30:20 +01:00
[ MVCTableField( 'id' , [ foPrimaryKey, foAutoGenerated] ,
'SEQ_ORDERS_ID' { required for interbase } ) ]
2020-01-08 15:30:10 +01:00
{$ENDIF}
2018-10-23 16:18:34 +02:00
fID: Integer ;
2019-02-21 18:11:14 +01:00
[ MVCTableField( 'id_customer' ) ]
2018-10-23 16:18:34 +02:00
fCustomerID: Integer ;
2019-02-21 18:11:14 +01:00
[ MVCTableField( 'order_date' ) ]
2018-10-23 16:18:34 +02:00
fOrderDate: TDate;
2019-02-21 18:11:14 +01:00
[ MVCTableField( 'total' ) ]
2018-10-23 16:18:34 +02:00
fTotal: Currency ;
public
constructor Create; override ;
destructor Destroy; override ;
property ID: Integer read fID write fID;
property CustomerID: Integer read fCustomerID write fCustomerID;
property OrderDate: TDate read fOrderDate write fOrderDate;
property Total: Currency read fTotal write fTotal;
end ;
[ MVCNameCase( ncLowerCase) ]
2019-02-21 18:11:14 +01:00
[ MVCTable( 'customers' ) ]
2018-10-23 16:18:34 +02:00
TCustomerEx = class( TCustomer)
private
fOrders: TObjectList< TOrder> ;
2020-01-08 15:30:10 +01:00
function GetOrders: TObjectList< TOrder> ;
2018-10-23 16:18:34 +02:00
protected
procedure OnAfterLoad; override ;
2020-01-08 15:30:10 +01:00
procedure OnAfterInsert; override ;
2018-10-23 16:18:34 +02:00
public
destructor Destroy; override ;
2020-01-08 15:30:10 +01:00
property Orders: TObjectList< TOrder> read GetOrders;
2018-10-23 16:18:34 +02:00
end ;
2023-08-09 10:55:34 +02:00
[ MVCNameCase( ncLowerCase) ]
[ MVCEntityActions( [ eaRetrieve] ) ]
[ MVCNamedSQLQuery( 'CustomersInTheSameCity' ,
'SELECT c.id, c.DESCRIPTION, c.city, c.code, c.rating, (SELECT count(*) - 1 FROM customers c2 WHERE c2.CITY = c.CITY) customers_in_the_same_city ' +
'FROM CUSTOMERS c WHERE city IS NOT NULL AND city <> ' '' ' ORDER BY customers_in_the_same_city' ) ]
TCustomerStats = class( TCustomEntity)
private
2023-11-01 23:13:17 +01:00
[ MVCTableField( 'id' ) ]
2023-08-09 10:55:34 +02:00
fID: NullableInt64;
[ MVCTableField( 'code' ) ]
fCode: NullableString;
[ MVCTableField( 'description' ) ]
fCompanyName: NullableString;
[ MVCTableField( 'city' ) ]
fCity: string ;
[ MVCTableField( 'rating' ) ]
fRating: NullableInt32;
[ MVCTableField( 'customers_in_the_same_city' ) ]
fCustomersInTheSameCity: Int32 ;
public
property ID: NullableInt64 read fID write fID;
property Code: NullableString read fCode write fCode;
property CompanyName: NullableString read fCompanyName write fCompanyName;
property City: string read fCity write fCity;
property Rating: NullableInt32 read fRating write fRating;
property CustomersInTheSameCity: Int32 read fCustomersInTheSameCity write fCustomersInTheSameCity;
end ;
2018-10-23 16:18:34 +02:00
[ MVCNameCase( ncLowerCase) ]
2019-02-21 18:11:14 +01:00
[ MVCTable( 'customers' ) ]
2018-10-23 16:18:34 +02:00
TCustomerWithLogic = class( TCustomer)
private
fIsLocatedInRome: Boolean ;
protected
procedure OnAfterLoad; override ;
procedure OnBeforeInsertOrUpdate; override ;
2020-03-31 16:23:22 +02:00
procedure OnValidation( const Action: TMVCEntityAction) ; override ;
2018-10-23 16:18:34 +02:00
public
property IsLocatedInRome: Boolean read fIsLocatedInRome;
end ;
2020-01-04 12:53:53 +01:00
[ MVCNameCase( ncLowerCase) ]
[ MVCTable( 'nullables_test' ) ]
2020-04-08 18:04:45 +02:00
TNullablesTest = class( TCustomEntity)
2020-01-04 12:53:53 +01:00
private
2023-01-06 15:00:54 +01:00
[ MVCTableField( 'f_int2' , [ foPrimaryKey] ) ]
2020-01-04 12:53:53 +01:00
ff_int2: NullableInt16;
[ MVCTableField( 'f_int4' ) ]
ff_int4: NullableInt32;
[ MVCTableField( 'f_int8' ) ]
ff_int8: NullableInt64;
[ MVCTableField( 'f_date' ) ]
2020-02-03 10:51:40 +01:00
ff_date: NullableTDate;
2020-01-04 12:53:53 +01:00
[ MVCTableField( 'f_time' ) ]
2020-02-03 10:51:40 +01:00
ff_time: NullableTTime;
2020-01-04 12:53:53 +01:00
[ MVCTableField( 'f_bool' ) ]
ff_bool: NullableBoolean;
[ MVCTableField( 'f_datetime' ) ]
2020-02-03 10:51:40 +01:00
ff_datetime: NullableTDateTime;
2020-01-04 12:53:53 +01:00
[ MVCTableField( 'f_float4' ) ]
ff_float4: NullableSingle;
[ MVCTableField( 'f_float8' ) ]
ff_float8: NullableDouble;
[ MVCTableField( 'f_string' ) ]
ff_string: NullableString;
[ MVCTableField( 'f_currency' ) ]
ff_currency: NullableCurrency;
2020-01-06 16:49:18 +01:00
[ MVCTableField( 'f_blob' ) ]
ff_blob: TStream;
2020-01-04 12:53:53 +01:00
public
2020-01-06 16:49:18 +01:00
constructor Create; override ;
destructor Destroy; override ;
2020-01-08 15:30:10 +01:00
// f_int2 int2 NULL,
2020-01-04 12:53:53 +01:00
property f_int2: NullableInt16 read ff_int2 write ff_int2;
2020-01-08 15:30:10 +01:00
// f_int4 int4 NULL,
2020-01-04 12:53:53 +01:00
property f_int4: NullableInt32 read ff_int4 write ff_int4;
2020-01-08 15:30:10 +01:00
// f_int8 int8 NULL,
2020-01-04 12:53:53 +01:00
property f_int8: NullableInt64 read ff_int8 write ff_int8;
2020-01-08 15:30:10 +01:00
// f_string varchar NULL,
2020-01-04 12:53:53 +01:00
property f_string: NullableString read ff_string write ff_string;
2020-01-08 15:30:10 +01:00
// f_bool bool NULL,
2020-01-04 12:53:53 +01:00
property f_bool: NullableBoolean read ff_bool write ff_bool;
2020-01-08 15:30:10 +01:00
// f_date date NULL,
2020-02-03 10:51:40 +01:00
property f_date: NullableTDate read ff_date write ff_date;
2020-01-08 15:30:10 +01:00
// f_time time NULL,
2020-02-03 10:51:40 +01:00
property f_time: NullableTTime read ff_time write ff_time;
2020-01-08 15:30:10 +01:00
// f_datetime timestamp NULL,
2020-02-03 10:51:40 +01:00
property f_datetime: NullableTDateTime read ff_datetime write ff_datetime;
2020-01-08 15:30:10 +01:00
// f_float4 float4 NULL,
2020-01-04 12:53:53 +01:00
property f_float4: NullableSingle read ff_float4 write ff_float4;
2020-01-08 15:30:10 +01:00
// f_float8 float8 NULL,
2020-01-04 12:53:53 +01:00
property f_float8: NullableDouble read ff_float8 write ff_float8;
2020-01-08 15:30:10 +01:00
// f_currency numeric(18,4) NULL
2020-01-04 12:53:53 +01:00
property f_currency: NullableCurrency read ff_currency write ff_currency;
2020-01-08 15:30:10 +01:00
// f_blob bytea NULL
2020-01-06 16:49:18 +01:00
property f_blob: TStream read ff_blob write ff_blob;
2020-01-04 12:53:53 +01:00
end ;
2023-10-03 11:11:01 +02:00
[ MVCNameCase( ncLowerCase) ]
[ MVCTable( 'default_values_test' ) ]
TDefaultValuesTest = class( TCustomEntity)
private
[ MVCTableField( 'f_int2' , [ foPrimaryKey] ) ]
ff_int2: NullableInt16;
[ MVCTableField( 'f_int4' ) ]
ff_int4: NullableInt32;
[ MVCTableField( 'f_int8' ) ]
ff_int8: NullableInt64;
[ MVCTableField( 'f_date' ) ]
ff_date: NullableTDate;
[ MVCTableField( 'f_time' ) ]
ff_time: NullableTTime;
[ MVCTableField( 'f_bool' ) ]
ff_bool: NullableBoolean;
[ MVCTableField( 'f_datetime' ) ]
ff_datetime: NullableTDateTime;
[ MVCTableField( 'f_float4' ) ]
ff_float4: NullableSingle;
[ MVCTableField( 'f_float8' ) ]
ff_float8: NullableDouble;
[ MVCTableField( 'f_string' ) ]
ff_string: NullableString;
[ MVCTableField( 'f_currency' ) ]
ff_currency: NullableCurrency;
[ MVCTableField( 'f_blob' ) ]
ff_blob: TStream;
public
constructor Create; override ;
destructor Destroy; override ;
// f_int2 int2 NULL,
property f_int2: NullableInt16 read ff_int2 write ff_int2;
// f_int4 int4 NULL,
property f_int4: NullableInt32 read ff_int4 write ff_int4;
// f_int8 int8 NULL,
property f_int8: NullableInt64 read ff_int8 write ff_int8;
// f_string varchar NULL,
property f_string: NullableString read ff_string write ff_string;
// f_bool bool NULL,
property f_bool: NullableBoolean read ff_bool write ff_bool;
// f_date date NULL,
property f_date: NullableTDate read ff_date write ff_date;
// f_time time NULL,
property f_time: NullableTTime read ff_time write ff_time;
// f_datetime timestamp NULL,
property f_datetime: NullableTDateTime read ff_datetime write ff_datetime;
// f_float4 float4 NULL,
property f_float4: NullableSingle read ff_float4 write ff_float4;
// f_float8 float8 NULL,
property f_float8: NullableDouble read ff_float8 write ff_float8;
// f_currency numeric(18,4) NULL
property f_currency: NullableCurrency read ff_currency write ff_currency;
// f_blob bytea NULL
property f_blob: TStream read ff_blob write ff_blob;
end ;
2021-03-20 00:30:20 +01:00
[ MVCNameCase( ncLowerCase) ]
[ MVCTable( 'complex_types' ) ]
TComplexTypes = class( TCustomEntity)
private
[ MVCTableField( 'id' , [ foPrimaryKey, foAutoGenerated] ) ]
fID: Int64 ;
[ MVCTableField( 'json_field' , [ ] , '' , 'json' ) ]
FJSON: String ;
[ MVCTableField( 'jsonb_field' , [ ] , '' , 'jsonb' ) ]
FJSONB: String ;
[ MVCTableField( 'xml_field' , [ ] , '' , 'xml' ) ]
fXML: String ;
public
property ID: Int64 read fID write fID;
property JSON: String read FJSON write FJSON;
property JSONB: String read FJSONB write FJSONB;
property XML: String read fXML write fXML;
end ;
2022-11-10 18:30:11 +01:00
[ MVCTable( 'customers' ) ]
[ MVCEntityActions( [ eaRetrieve] ) ] //only the "R" in CRUD
TReadOnlyCustomer = class( TCustomer)
end ;
// person, employee, manager
[ MVCTable( 'people' ) ]
[ MVCEntityActions( [ ] ) ] //no CRUD operations allowed for this entity
TAbstractPerson = class abstract( TMVCActiveRecord)
private
[ MVCTableField( 'id' , [ foPrimaryKey, foAutoGenerated] ) ]
fID: NullableInt64;
[ MVCTableField( 'last_name' ) ]
fLastName: String ;
[ MVCTableField( 'first_name' ) ]
fFirstName: String ;
[ MVCTableField( 'dob' ) ]
fDob: NullableTDate;
[ MVCTableField( 'full_name' ) ]
fFullName: NullableString;
[ MVCTableField( 'is_male' ) ]
fIsMale: NullableBoolean;
[ MVCTableField( 'note' ) ]
fNote: NullableString;
[ MVCTableField( 'photo' ) ]
fPhoto: TStream;
function GetFullName: NullableString;
protected
procedure OnBeforeInsertOrUpdate; override ;
public
constructor Create; override ;
destructor Destroy; override ;
property ID: NullableInt64 read fID write fID;
property LastName: String read fLastName write fLastName;
property FirstName: String read fFirstName write fFirstName;
property Dob: NullableTDate read fDob write fDob;
property FullName: NullableString read GetFullName;
property IsMale: NullableBoolean read fIsMale write fIsMale;
property Note: NullableString read fNote write fNote;
property Photo: TStream read fPhoto write fPhoto;
end ;
2023-07-07 20:26:49 +02:00
[ MVCTable( 'people' , 'in(person_type,["person", "employee", "manager"]))' ) ]
[ MVCPartition( 'person_type=(string)person' ) ]
TPerson = class( TAbstractPerson)
end ;
[ MVCTable( 'people' , 'in(person_type,["employee", "manager"])' ) ]
2022-11-10 18:30:11 +01:00
[ MVCPartition( 'person_type=(string)employee' ) ]
TEmployee = class( TAbstractPerson)
private
[ MVCTableField( 'salary' ) ]
fSalary: Currency ;
public
property Salary: Currency read fSalary write fSalary;
end ;
[ MVCTable( 'people' ) ]
[ MVCPartition( 'person_type=(string)manager' ) ]
TManager = class( TEmployee)
private
[ MVCTableField( 'annual_bonus' ) ]
fAnnualBonus: Currency ;
public
property AnnualBonus: Currency read fAnnualBonus write fAnnualBonus;
end ;
2023-10-01 15:22:43 +02:00
[ MVCTable( 'integers_as_booleans' ) ]
TIntegersAsBooleans = class( TMVCActiveRecord)
private
[ MVCTableField( 'id' , [ foPrimaryKey, foAutoGenerated] ) ]
FID: NullableInt64;
[ MVCTableField( 'done_int' , 'int2' ) ]
FDoneAsInteger: Integer ;
[ MVCTableField( 'done_bool' ) ]
FDoneAsBoolean: Boolean ;
procedure SetDoneAsBoolean( const Value: Boolean ) ;
procedure SetDoneAsInteger( const Value: Integer ) ;
procedure SetID( const Value: NullableInt64) ;
public
property ID: NullableInt64 read FID write SetID;
property DoneAsBoolean: Boolean read FDoneAsBoolean write SetDoneAsBoolean;
property DoneAsInteger: Integer read FDoneAsInteger write SetDoneAsInteger;
end ;
2023-11-02 17:36:19 +01:00
[ MVCNameCase( ncLowerCase) ]
[ MVCTable( 'customers_with_version' ) ]
TCustomerWithVersion = class( TCustomEntity)
private
[ MVCTableField( 'id' , [ foPrimaryKey, foAutoGenerated] ) ]
fID: NullableInt64;
[ MVCTableField( 'code' ) ]
fCode: NullableString;
[ MVCTableField( 'description' ) ]
fCompanyName: NullableString;
[ MVCTableField( 'city' ) ]
fCity: string ;
[ MVCTableField( 'rating' ) ]
fRating: NullableInt32;
[ MVCTableField( 'note' ) ]
fNote: string ;
[ MVCTableField( 'objversion' , [ foVersion] ) ]
fObjVersion: Integer ;
public
function ToString: String ; override ;
property ID: NullableInt64 read fID write fID;
property Code: NullableString read fCode write fCode;
property CompanyName: NullableString read fCompanyName write fCompanyName;
property City: string read fCity write fCity;
property Rating: NullableInt32 read fRating write fRating;
property Note: string read fNote write fNote;
end ;
2022-11-10 18:30:11 +01:00
2018-10-23 16:18:34 +02:00
implementation
uses
2020-08-13 17:40:02 +02:00
System. SysUtils, Data. DB, MVCFramework. Logger, System. Rtti;
2018-10-23 16:18:34 +02:00
constructor TArticle. Create;
begin
inherited Create;
end ;
destructor TArticle. Destroy;
begin
inherited ;
end ;
constructor TCustomer. Create;
begin
inherited Create;
end ;
destructor TCustomer. Destroy;
begin
inherited ;
end ;
2021-04-25 22:40:06 +02:00
function TCustomer. ToString: String ;
begin
Result : = '' ;
if PKIsNull then
2022-12-09 09:58:55 +01:00
Result : = '<null>'
else
Result : = fID. ValueOrDefault. ToString;
2021-04-29 22:52:28 +02:00
Result : = Format( '[ID: %6s][CODE: %6s][CompanyName: %18s][City: %16s][Rating: %3d][Note: %s]' , [
2021-04-25 22:40:06 +02:00
Result , fCode. ValueOrDefault, fCompanyName. ValueOrDefault, fCity, fRating. ValueOrDefault, fNote] ) ;
end ;
2018-10-23 16:18:34 +02:00
constructor TOrderDetail. Create;
begin
inherited Create;
end ;
destructor TOrderDetail. Destroy;
begin
inherited ;
end ;
constructor TOrder. Create;
begin
inherited Create;
end ;
destructor TOrder. Destroy;
begin
inherited ;
end ;
{ TCustomerEx }
destructor TCustomerEx. Destroy;
begin
fOrders. Free;
inherited ;
end ;
2020-01-08 15:30:10 +01:00
function TCustomerEx. GetOrders: TObjectList< TOrder> ;
begin
if not Assigned( fOrders) then
begin
fOrders : = TObjectList< TOrder> . Create( True ) ;
end ;
Result : = fOrders;
end ;
procedure TCustomerEx. OnAfterInsert;
begin
inherited ;
end ;
2018-10-23 16:18:34 +02:00
procedure TCustomerEx. OnAfterLoad;
begin
inherited ;
2020-01-08 15:30:10 +01:00
if Self. ID. HasValue then
begin
fOrders. Free;
fOrders : = TMVCActiveRecord. Where< TOrder> ( 'id_customer = ?' , [ Self. ID] ) ;
end ;
2018-10-23 16:18:34 +02:00
end ;
{ TCustomerWithLogic }
procedure TCustomerWithLogic. OnAfterLoad;
begin
inherited ;
fIsLocatedInRome : = fCity = 'ROME' ;
end ;
procedure TCustomerWithLogic. OnBeforeInsertOrUpdate;
begin
inherited ;
2020-01-04 12:53:53 +01:00
fCompanyName : = fCompanyName. ValueOrDefault. ToUpper;
2018-10-23 16:18:34 +02:00
fCity : = fCity. ToUpper;
end ;
2020-03-31 16:23:22 +02:00
procedure TCustomerWithLogic. OnValidation( const Action: TMVCEntityAction) ;
2018-10-23 16:18:34 +02:00
begin
inherited ;
2020-01-04 12:53:53 +01:00
if fCompanyName. ValueOrDefault. IsEmpty or fCity. Trim. IsEmpty or fCode. Value. Trim. IsEmpty then
2018-10-23 16:18:34 +02:00
raise Exception. Create( 'CompanyName, City and Code are required' ) ;
end ;
2022-11-15 09:27:08 +01:00
{ TCustomerWithReadOnlyFields }
2019-11-05 16:57:22 +01:00
2022-11-15 09:27:08 +01:00
procedure TCustomerWithReadOnlyFields. SetFormattedCode( const Value: string ) ;
2019-11-05 16:57:22 +01:00
begin
2020-01-08 15:30:10 +01:00
fFormattedCode : = Value;
2019-11-05 16:57:22 +01:00
end ;
2020-01-06 16:49:18 +01:00
{ TNullablesTest }
constructor TNullablesTest. Create;
begin
inherited Create;
2020-08-11 00:54:42 +02:00
ff_blob : = TMemoryStream. Create;
2020-01-06 16:49:18 +01:00
end ;
destructor TNullablesTest. Destroy;
begin
ff_blob. Free;
inherited ;
end ;
2020-04-08 18:04:45 +02:00
{ TCustomEntity }
procedure TCustomEntity. OnBeforeExecuteSQL( var SQL: string ) ;
begin
inherited ;
Log. Info( ClassName + ' | ' + SQL, 'sql_trace' ) ;
end ;
2020-08-13 17:40:02 +02:00
{ TCustomerPlainWithClientPK }
procedure TCustomerPlainWithClientPK. OnBeforeInsert;
begin
inherited ;
2021-03-20 00:30:20 +01:00
SetPK( TValue. From< NullableString> ( TGUID. NewGuid. ToString. Replace( '{' , '' ) . Replace( '-' ,
'' ) . Replace( '}' , '' ) . Substring( 0 , 2 0 ) ) ) ;
2020-08-13 17:40:02 +02:00
end ;
2021-11-18 00:49:12 +01:00
{ TPartitionedCustomer }
function TPartitionedCustomer. ToString: String ;
begin
Result : = '' ;
if PKIsNull then
Result : = '<null>' ;
Result : = Format( '[ID: %6s][CODE: %6s][CompanyName: %18s][City: %16s][Note: %s]' , [
Result , fCode. ValueOrDefault, fCompanyName. ValueOrDefault, fCity, fNote] ) ;
end ;
2022-11-10 18:30:11 +01:00
constructor TAbstractPerson. Create;
begin
inherited Create;
fPhoto : = TMemoryStream. Create;
end ;
destructor TAbstractPerson. Destroy;
begin
fPhoto. Free;
inherited ;
end ;
function TAbstractPerson. GetFullName: NullableString;
begin
Result : = fFirstName + ' ' + fLastName;
end ;
procedure TAbstractPerson. OnBeforeInsertOrUpdate;
begin
inherited ;
fFullName : = GetFullName;
end ;
2023-10-01 15:22:43 +02:00
{ TIntegersAsBooleans }
procedure TIntegersAsBooleans. SetDoneAsBoolean( const Value: Boolean ) ;
begin
FDoneAsBoolean : = Value;
end ;
procedure TIntegersAsBooleans. SetDoneAsInteger( const Value: Integer ) ;
begin
FDoneAsInteger : = Value;
end ;
procedure TIntegersAsBooleans. SetID( const Value: NullableInt64) ;
begin
FID : = Value;
end ;
2023-10-03 11:11:01 +02:00
{ TDefaultValuesTest }
constructor TDefaultValuesTest. Create;
begin
inherited Create;
ff_blob : = TMemoryStream. Create;
end ;
destructor TDefaultValuesTest. Destroy;
begin
ff_blob. Free;
inherited ;
end ;
2023-11-02 17:36:19 +01:00
{ TCustomerWithVersion }
function TCustomerWithVersion. ToString: String ;
begin
Result : = '' ;
if PKIsNull then
Result : = '<null>'
else
Result : = fID. ValueOrDefault. ToString;
Result : = Format( '[ID: %6s][CODE: %6s][CompanyName: %18s][City: %16s][Rating: %3d][Note: %s][Version: %d]' , [
Result , fCode. ValueOrDefault, fCompanyName. ValueOrDefault, fCity, fRating. ValueOrDefault, fNote, fObjVersion] ) ;
end ;
2018-10-23 16:18:34 +02:00
end .