Componentes.Terceros.RemObj.../official/5.0.23.613/Data Abstract for Delphi/Source/IDE/uDASchemaUnitsGenerator.pas

857 lines
40 KiB
ObjectPascal

unit uDASchemaUnitsGenerator;
interface
uses
Classes, uDAInterfaces, uDAClasses;
type
{ TDASchemaCodeGenerator }
TDASchemaCodeGenerator = class(TStringList)
private
fSchema : TDASchema;
fFileName : string;
protected
procedure DoWriteCode; virtual; abstract;
property FileName : string read fFileName;
property Schema : TDASchema read fSchema;
public
constructor Create(aSchema : TDASchema);
procedure Write(const someText: string; Indentation: integer = 0); overload;
procedure WriteLines(const someText: string);
procedure WriteEmptyLine;
procedure WriteCode(const aFileName : string);
end;
{ TClientUnitSchemaGenerator }
TClientUnitSchemaGenerator = class(TDASchemaCodeGenerator)
protected
procedure DoWriteCode; override;
end;
{ TServerUnitSchemaGenerator }
TServerUnitSchemaGenerator = class(TDASchemaCodeGenerator)
private
fClientUnitName: string;
protected
procedure DoWriteCode; override;
public
property ClientUnitName : string read fClientUnitName write fClientUnitName;
end;
procedure GenerateSchemaUnits(aSchema : TDASchema);
function GetDAType(ad: TDADataType): string;
implementation
uses
uROIDETools, uRODLToPascal, SysUtils, Dialogs, uROTypes, uROClasses;
function GetDATypeMethod(ad: TDADataType): string;
begin
case ad of
datAutoInc: Result := 'Integer';
datLargeAutoInc: Result := 'LargeInt';
datWideMemo: Result := 'WideString';
datSingleFloat: Result := 'Single';
else
Result := DADataTypeNames[ad];
end;
end;
{ TDASchemaCodeGenerator }
procedure TDASchemaCodeGenerator.Write(const someText: string; Indentation: integer = 0);
var
i: integer;
s: string;
begin
s := '';
for i := 1 to Indentation do s := s + ' ';
s := s + someText;
Add(s)
end;
procedure TDASchemaCodeGenerator.WriteLines(const someText: string);
begin
Text := Text+someText;
end;
procedure TDASchemaCodeGenerator.WriteEmptyLine;
begin
Add('');
end;
constructor TDASchemaCodeGenerator.Create(aSchema: TDASchema);
begin
inherited Create;
fSchema := aSchema;
end;
procedure TDASchemaCodeGenerator.WriteCode(const aFileName: string);
begin
fFileName := aFileName;
Clear;
DoWriteCode;
SaveToFile(aFileName);
end;
{ Misc }
procedure GenerateSchemaUnits(aSchema : TDASchema);
var clienttargetfilename,
servertargetfilename : string;
begin
clienttargetfilename := IncludeTrailingPathDelimiter(ModuleDir(CurrentProject))+aSchema.Name+'Client_Intf.pas';
if PromptForFileName(clienttargetfilename, 'Delphi unit (*.pas)|*.pas', '*.pas', 'Save '+aSchema.Name+' client access unit', '', TRUE) then begin
with TClientUnitSchemaGenerator.Create(aSchema) do try
WriteCode(clienttargetfilename);
CurrentProject.AddFile(clienttargetfilename, TRUE);
finally
Free;
end;
end;
servertargetfilename := IncludeTrailingPathDelimiter(ModuleDir(CurrentProject))+aSchema.Name+'Server_Intf.pas';
if PromptForFileName(servertargetfilename, 'Delphi unit (*.pas)|*.pas', '*.pas', 'Save '+aSchema.Name+' server access unit', '', TRUE) then begin
with TServerUnitSchemaGenerator.Create(aSchema) do try
ClientUnitName := ChangeFileExt(ExtractFileName(clienttargetfilename), '');
WriteCode(servertargetfilename);
CurrentProject.AddFile(servertargetfilename, TRUE);
finally
Free;
end;
end;
end;
function GenFindParams(aDataset : TDADataset; AddType, UsePrefix, UseComma : boolean) : string;
var x : integer;
begin
result := '';
with aDataset do begin
for x := 0 to (Fields.Count-1) do
if Fields[x].InPrimaryKey then begin
if UsePrefix then result := result+'a'+Fields[x].Name
else result := result+Fields[x].Name;
if AddType
then result := result+': '+GetDAType(Fields[x].DataType);
if UseComma
then result := result+','
else result := result+'; ';
end;
if UseComma
then result := Copy(result, 1, Length(result)-1)
else result := Copy(result, 1, Length(result)-2);
end;
end;
function GetDAType(ad: TDADataType): string;
begin
case ad of
datMemo: Result := 'IROStrings';
datBlob: Result := 'IROStream';
datAutoInc: Result := 'Integer';
datWideMemo: Result := 'WideString';
datLargeAutoInc: Result := 'Int64';
datGuid: result := 'TGuid';
datXml: result := 'IXmlNode';
datLargeUint,
datLargeInt: Result := 'Int64';
datDecimal: Result := 'TBcd';
datSingleFloat: Result := 'Single';
else
Result := DADataTypeNames[ad];
end;
end;
{ TClientUnitSchemaGenerator }
procedure TClientUnitSchemaGenerator.DoWriteCode;
var i, x : integer;
guid : TGUID;
guids : TStringList;
//s, s2 : string;
bVar: boolean;
begin
guids := TStringList.Create;
with Schema do try
for i := 0 to (Datasets.Count-1) do begin
CreateGUID(guid);
guids.Add(GUIDToString(guid));
end;
Write(Format('unit %s;', [ChangeFileExt(ExtractFileName(FileName), '')]));
WriteEmptyLine;
Write('interface');
WriteEmptyLine;
Write('uses');
Write(' Classes, DB, SysUtils, uROClasses, uDADataTable, FmtBCD, uROXMLIntf;');
// Data table GUIDs
WriteEmptyLine;
Write('const');
Write('{ Data table rules ids', PASCAL_INDENTATION_LEVEL_1);
Write(' Feel free to change them to something more human readable', PASCAL_INDENTATION_LEVEL_1);
Write(' but make sure they are unique in the context of your application }', PASCAL_INDENTATION_LEVEL_1);
for i := 0 to (Datasets.Count-1) do begin
Write(Format('RID_%s = ''%s'';', [MakeValidIdentifier(Datasets[i].Name), guids[i]]), PASCAL_INDENTATION_LEVEL_1);
end;
// Data table names
WriteEmptyLine;
Write('{ Data table names }', PASCAL_INDENTATION_LEVEL_1);
for i := 0 to (Datasets.Count-1) do begin
Write(Format('nme_%s = ''%s'';', [MakeValidIdentifier(Datasets[i].Name), Datasets[i].Name]), PASCAL_INDENTATION_LEVEL_1);
end;
WriteEmptyLine;
// Data table fields
for i := 0 to (Datasets.Count-1) do begin
Write(Format('{ %s fields }', [Datasets[i].Name]), PASCAL_INDENTATION_LEVEL_1);
for x := 0 to (Datasets[i].Fields.Count-1) do
Write(Format('fld_%s%s = ''%s'';', [MakeValidIdentifier(Datasets[i].Name), Datasets[i].Fields[x].Name, Datasets[i].Fields[x].Name]), PASCAL_INDENTATION_LEVEL_1);
WriteEmptyLine;
Write(Format('{ %s field indexes }', [Datasets[i].Name]), PASCAL_INDENTATION_LEVEL_1);
for x := 0 to (Datasets[i].Fields.Count-1) do
Write(Format('idx_%s%s = %d;', [MakeValidIdentifier(Datasets[i].Name), MakeValidIdentifier(Datasets[i].Fields[x].Name), x]), PASCAL_INDENTATION_LEVEL_1);
WriteEmptyLine;
end;
Write('type');
for i := 0 to (Datasets.Count-1) do begin
if (Trim(Datasets[i].Description)<>'') then begin
Write('{', PASCAL_INDENTATION_LEVEL_1);
Write(Datasets[i].Description, PASCAL_INDENTATION_LEVEL_1);
Write('}', PASCAL_INDENTATION_LEVEL_1);
end;
// Base interface
CreateGUID(guid); // This interface is just for reference. People will use the others
Write(Format('{ I%s }', [MakeValidIdentifier(Datasets[i].Name)]), PASCAL_INDENTATION_LEVEL_1);
Write(Format('I%s = interface(IDAStronglyTypedDataTable)', [MakeValidIdentifier(Datasets[i].Name)]), PASCAL_INDENTATION_LEVEL_1);
Write(Format('[''%s'']', [GuidToString(guid)]), PASCAL_INDENTATION_LEVEL_1);
with Datasets[i] do begin
Write('{ Property getters and setters }', PASCAL_INDENTATION_LEVEL_2);
for x := 0 to (Fields.Count-1) do begin
Write(Format('function Get%sValue: %s;', [MakeValidIdentifier(Fields[x].Name), GetDAType(Fields[x].DataType)]), PASCAL_INDENTATION_LEVEL_2);
if not (Fields[x].DataType in [datMemo, datblob]) then
Write(Format('procedure Set%sValue(const aValue: %s);', [MakeValidIdentifier(Fields[x].Name), GetDAType(Fields[x].DataType)]), PASCAL_INDENTATION_LEVEL_2);
Write(Format('function Get%sIsNull: Boolean;', [MakeValidIdentifier(Fields[x].Name)]), PASCAL_INDENTATION_LEVEL_2);
Write(Format('procedure Set%sIsNull(const aValue: Boolean);', [MakeValidIdentifier(Fields[x].Name)]), PASCAL_INDENTATION_LEVEL_2);
end;
WriteEmptyLine;
{Write('// Methods', PASCAL_INDENTATION_LEVEL_2);
// Generates the Find method
s := GenFindParams(Datasets[i], TRUE, TRUE, FALSE);
if (s<>'') then Write(Format('function Find(%s; LocateOptions : TLocateOptions) : boolean;', [s]), PASCAL_INDENTATION_LEVEL_2);}
// Properties
WriteEmptyLine;
Write('{ Properties }', PASCAL_INDENTATION_LEVEL_2);
for x := 0 to (Fields.Count-1) do
begin
if Fields[x].DataType in [datMemo, datBlob] then
Write(Format('property %s: %s read Get%sValue;',
[MakeValidIdentifier(Fields[x].Name), GetDAType(Fields[x].DataType),
MakeValidIdentifier(Fields[x].Name)]), PASCAL_INDENTATION_LEVEL_2)
else
Write(Format('property %s: %s read Get%sValue write Set%sValue;',
[MakeValidIdentifier(Fields[x].Name), GetDAType(Fields[x].DataType),
MakeValidIdentifier(Fields[x].Name),
MakeValidIdentifier(Fields[x].Name)]), PASCAL_INDENTATION_LEVEL_2);
Write(Format('property %sIsNull: Boolean read Get%sIsNull write Set%sIsNull;',
[MakeValidIdentifier(Fields[x].Name),
MakeValidIdentifier(Fields[x].Name),
MakeValidIdentifier(Fields[x].Name)]), PASCAL_INDENTATION_LEVEL_2);
end;
end;
Write(Format('end;', []), PASCAL_INDENTATION_LEVEL_1);
WriteEmptyLine;
// Implementor class
Write(Format('{ T%sDataTableRules }', [MakeValidIdentifier(Datasets[i].Name)]), PASCAL_INDENTATION_LEVEL_1);
Write(Format('T%sDataTableRules = class(TDADataTableRules, I%s)', [MakeValidIdentifier(Datasets[i].Name),
MakeValidIdentifier(Datasets[i].Name)]), PASCAL_INDENTATION_LEVEL_1);
with Datasets[i] do begin
Write('private', PASCAL_INDENTATION_LEVEL_1);
for x := 0 to (Fields.Count-1) do begin
if Fields[x].DataType in [datMemo, datBlob] then
Write(Format('f_%s: %s;',[MakeValidIdentifier(Fields[x].Name), GetDAType(Fields[x].DataType)]),PASCAL_INDENTATION_LEVEL_2);
end;
for x := 0 to (Fields.Count-1) do begin
if Fields[x].DataType = datMemo then
Write(Format('procedure %s_OnChange(Sender: TObject);',[MakeValidIdentifier(Fields[x].Name)]),PASCAL_INDENTATION_LEVEL_2)
else
if Fields[x].DataType = datBlob then
Write(Format('procedure %s_OnChange(Sender: TObject);',[MakeValidIdentifier(Fields[x].Name)]),PASCAL_INDENTATION_LEVEL_2);
end;
Write('protected', PASCAL_INDENTATION_LEVEL_1);
Write('{ Property getters and setters }', PASCAL_INDENTATION_LEVEL_2);
for x := 0 to (Fields.Count-1) do begin
Write(Format('function Get%sValue: %s; virtual;', [MakeValidIdentifier(Fields[x].Name), GetDAType(Fields[x].DataType)]), PASCAL_INDENTATION_LEVEL_2);
if not (Fields[x].DataType in [datMemo, datBlob]) then
Write(Format('procedure Set%sValue(const aValue: %s); virtual;', [MakeValidIdentifier(Fields[x].Name), GetDAType(Fields[x].DataType)]), PASCAL_INDENTATION_LEVEL_2);
Write(Format('function Get%sIsNull: Boolean; virtual;', [MakeValidIdentifier(Fields[x].Name)]), PASCAL_INDENTATION_LEVEL_2);
Write(Format('procedure Set%sIsNull(const aValue: Boolean); virtual;', [MakeValidIdentifier(Fields[x].Name)]), PASCAL_INDENTATION_LEVEL_2);
end;
WriteEmptyLine;
Write('{ Properties }', PASCAL_INDENTATION_LEVEL_2);
for x := 0 to (Fields.Count-1) do
begin
if Fields[x].DataType in [datMemo, datBlob] then
Write(Format('property %s: %s read Get%sValue;',
[MakeValidIdentifier(Fields[x].Name),
GetDAType(Fields[x].DataType),
MakeValidIdentifier(Fields[x].Name)]), PASCAL_INDENTATION_LEVEL_2)
else
Write(Format('property %s: %s read Get%sValue write Set%sValue;',
[MakeValidIdentifier(Fields[x].Name),
GetDAType(Fields[x].DataType),
MakeValidIdentifier(Fields[x].Name),
MakeValidIdentifier(Fields[x].Name)]), PASCAL_INDENTATION_LEVEL_2);
Write(Format('property %sIsNull: Boolean read Get%sIsNull write Set%sIsNull;',
[MakeValidIdentifier(Fields[x].Name),
MakeValidIdentifier(Fields[x].Name),
MakeValidIdentifier(Fields[x].Name)]), PASCAL_INDENTATION_LEVEL_2);
end;
WriteEmptyLine;
{Write('procedure Validate; override;', PASCAL_INDENTATION_LEVEL_3);
WriteEmptyLine;}
Write('public', PASCAL_INDENTATION_LEVEL_1);
Write('constructor Create(aDataTable: TDADataTable); override;', PASCAL_INDENTATION_LEVEL_2);
Write('destructor Destroy; override;', PASCAL_INDENTATION_LEVEL_2);
WriteEmptyLine;
// Generates the Find method
{s := GenFindParams(Datasets[i], TRUE, TRUE, FALSE);
if (s<>'') then Write(Format('function Find(%s; LocateOptions : TLocateOptions) : boolean;', [s]), PASCAL_INDENTATION_LEVEL_2);}
end;
Write(Format('end;', []), PASCAL_INDENTATION_LEVEL_1);
WriteEmptyLine;
end;
Write('implementation');
WriteEmptyLine;
Write('uses Variants, uROBinaryHelpers;');
WriteEmptyLine;
for i := 0 to (Datasets.Count-1) do begin
// Implementor class
Write(Format('{ T%sDataTableRules }', [MakeValidIdentifier(Datasets[i].Name)]));
with Datasets[i] do begin
Write(Format('constructor T%sDataTableRules.Create(aDataTable: TDADataTable);', [MakeValidIdentifier(Name)]));
bVar:=False;
// create StrList
for x := 0 to (Fields.Count-1) do begin
if Fields[x].DataType = datMemo then begin
if not bVar then begin
Write('var');
bVar:=True;
end;
Write(' StrList: TStringList;');
Break;
end;
end;
// create ROStream
for x := 0 to (Fields.Count-1) do begin
if Fields[x].DataType = datBlob then begin
if not bVar then begin
Write('var');
end;
Write(' ROStream: TROStream;');
Break;
end;
end;
Write('begin');
Write(' inherited;');
for x := 0 to (Fields.Count-1) do begin
if Fields[x].DataType = datMemo then begin
WriteEmptyLine;
Write(' StrList := TStringList.Create;');
Write(Format(' StrList.OnChange := %s_OnChange;', [MakeValidIdentifier(Fields[x].Name)]));
Write(Format(' f_%s := NewROStrings(StrList,True);', [MakeValidIdentifier(Fields[x].Name)]));
end else
if Fields[x].DataType = datBlob then begin
WriteEmptyLine;
Write(' ROStream := TROStream.Create;');
Write(Format(' ROStream.OnChange := %s_OnChange;', [MakeValidIdentifier(Fields[x].Name)]));
Write(Format(' f_%s := ROStream;', [MakeValidIdentifier(Fields[x].Name)]));
end;
end;
Write('end;');
WriteEmptyLine;
Write(Format('destructor T%sDataTableRules.Destroy;', [MakeValidIdentifier(Name)]));
Write('begin');
Write(' inherited;');
Write('end;');
WriteEmptyLine;
// Generates the Find method body
{s := GenFindParams(Datasets[i], TRUE, TRUE, FALSE);
if (s<>'') then begin
Write(Format('function T%s.Find(%s; LocateOptions : TLocateOptions) : boolean;', [Name, s]));
Write('begin');
s := GenFindParams(Datasets[i], FALSE, FALSE, TRUE);
s2 := GenFindParams(Datasets[i], FALSE, TRUE, TRUE);
if (Pos(',', s2)=0)
then Write(Format('result := DataTable.Locate(''%s'', %s, LocateOptions);', [s, s2]), PASCAL_INDENTATION_LEVEL_1)
else Write(Format('result := DataTable.Locate(''%s'', VarArrayOf([%s]), LocateOptions);', [s, s2]), PASCAL_INDENTATION_LEVEL_1);
Write('end;');
WriteEmptyLine;
end;}
{Write(Format('procedure T%s.Validate;', [Name]));
Write('begin');
Write('end;');
WriteEmptyLine;}
{ToDo: -cDA3 improve handling of Memos (and possibly Blobs, too), so that assignments to the returned
IROStream (ie MyField.Text := 'Hello') get carried back to the field data properly.
currently, the onmly way to chage the field is to actually assign a new IROStream to
the property via "MyField := ...", which is NOT GOOD.}
for x := 0 to (Fields.Count-1) do begin
if Fields[x].DataType = datMemo then begin
Write(Format('procedure T%sDataTableRules.%s_OnChange(Sender: TObject);', [MakeValidIdentifier(Name), MakeValidIdentifier(Fields[x].Name)]));
Write('begin');
Write(Format(' if DataTable.Editing then DataTable.Fields[idx_%s%s].AsVariant := TStringList(Sender).Text;', [MakeValidIdentifier(Datasets[i].Name), MakeValidIdentifier(Datasets[i].Fields[x].Name), GetDAType(Fields[x].DataType)]));
Write('end;');
WriteEmptyLine;
end else
if Fields[x].DataType = datBlob then begin
Write(Format('procedure T%sDataTableRules.%s_OnChange(Sender: TObject);', [MakeValidIdentifier(Name), MakeValidIdentifier(Fields[x].Name)]));
Write('begin');
Write(Format(' if DataTable.Editing then DataTable.Fields[idx_%s%s].LoadFromStream(TROStream(Sender));', [MakeValidIdentifier(Datasets[i].Name), MakeValidIdentifier(Datasets[i].Fields[x].Name), GetDAType(Fields[x].DataType)]));
Write('end;');
WriteEmptyLine;
end;
end;
for x := 0 to (Fields.Count-1) do begin
Write(Format('function T%sDataTableRules.Get%sValue: %s;', [MakeValidIdentifier(Name), MakeValidIdentifier(Fields[x].Name), GetDAType(Fields[x].DataType)]));
Write('begin');
case Fields[x].DataType of { }
datMemo:begin
Write(Format(' result := f_%s;',[MakeValidIdentifier(Fields[x].Name)]));
Write(Format(' result.Text := DataTable.Fields[idx_%s%s].AsString;', [MakeValidIdentifier(Datasets[i].Name), MakeValidIdentifier(Datasets[i].Fields[x].Name)]));
end;
datBlob:begin
Write(Format(' result := f_%s;',[MakeValidIdentifier(Fields[x].Name)]));
Write(' result.Position := 0;');
Write(' if not Result.InUpdateMode then begin');
Write(Format(' DataTable.Fields[idx_%s%s].SaveToStream(result);', [MakeValidIdentifier(Datasets[i].Name), MakeValidIdentifier(Datasets[i].Fields[x].Name)]));
Write(' result.Position := 0;');
Write(' end;');
end;
else
Write(Format(' result := DataTable.Fields[idx_%s%s].As%s;', [MakeValidIdentifier(Datasets[i].Name), MakeValidIdentifier(Datasets[i].Fields[x].Name), GetDATypeMethod(Fields[x].DataType)]));
end; { case }
Write('end;');
WriteEmptyLine;
if not (Fields[x].DataType in [datMemo, datBlob]) then begin
Write(Format('procedure T%sDataTableRules.Set%sValue(const aValue: %s);', [MakeValidIdentifier(Name), MakeValidIdentifier(Fields[x].Name), GetDAType(Fields[x].DataType)]));
Write('begin');
Write(Format(' DataTable.Fields[idx_%s%s].As%s := aValue;', [MakeValidIdentifier(Datasets[i].Name), MakeValidIdentifier(Datasets[i].Fields[x].Name), GetDATypeMethod(Fields[x].DataType)]));
Write('end;');
WriteEmptyLine;
end;
Write(Format('function T%sDataTableRules.Get%sIsNull: boolean;', [MakeValidIdentifier(Name), MakeValidIdentifier(Fields[x].Name)]));
Write('begin');
Write(Format(' result := DataTable.Fields[idx_%s%s].IsNull;', [MakeValidIdentifier(Datasets[i].Name), MakeValidIdentifier(Datasets[i].Fields[x].Name)]));
Write('end;');
WriteEmptyLine;
Write(Format('procedure T%sDataTableRules.Set%sIsNull(const aValue: Boolean);', [MakeValidIdentifier(Name), MakeValidIdentifier(Fields[x].Name)]));
Write('begin');
Write(' if aValue then');
Write(Format(' DataTable.Fields[idx_%s%s].AsVariant := Null;', [MakeValidIdentifier(Datasets[i].Name), MakeValidIdentifier(Datasets[i].Fields[x].Name)]));
Write('end;');
WriteEmptyLine;
end;
end;
WriteEmptyLine;
end;
Write('initialization');
for i := 0 to (Datasets.Count-1) do
Write(Format('RegisterDataTableRules(RID_%s, T%sDataTableRules);', [MakeValidIdentifier(Datasets[i].Name), MakeValidIdentifier(Datasets[i].Name)]), PASCAL_INDENTATION_LEVEL_1);
WriteEmptyLine;
Write('end.');
finally
guids.Free;
end;
end;
{ TServerUnitSchemaGenerator }
procedure TServerUnitSchemaGenerator.DoWriteCode;
var i, x : integer;
guid : TGUID;
guids : TStringList;
//s, s2 : string;
bVar: Boolean;
begin
guids := TStringList.Create;
with Schema do try
for i := 0 to (Datasets.Count-1) do begin
CreateGUID(guid);
guids.Add(GUIDToString(guid));
end;
Write(Format('unit %s;', [ChangeFileExt(ExtractFileName(FileName), '')]));
WriteEmptyLine;
Write('interface');
WriteEmptyLine;
Write('uses');
Write(Format(' Classes, DB, SysUtils, uROClasses, uDADataTable, uDABusinessProcessor, FmtBCD, uROXMLIntf, %s;', [ClientUnitName]));
// Data table GUIDs
WriteEmptyLine;
Write('const');
Write('{ Delta rules ids ', PASCAL_INDENTATION_LEVEL_1);
Write(' Feel free to change them to something more human readable', PASCAL_INDENTATION_LEVEL_1);
Write(' but make sure they are unique in the context of your application }', PASCAL_INDENTATION_LEVEL_1);
for i := 0 to (Datasets.Count-1) do begin
Write(Format('RID_%sDelta = ''%s'';', [MakeValidIdentifier(Datasets[i].Name), guids[i]]), PASCAL_INDENTATION_LEVEL_1);
end;
WriteEmptyLine;
Write('type');
for i := 0 to (Datasets.Count-1) do begin
// Business delta change
Write(Format('{ I%sDelta }', [MakeValidIdentifier(Datasets[i].Name)]), PASCAL_INDENTATION_LEVEL_1);
Write(Format('I%sDelta = interface(I%s)', [MakeValidIdentifier(Datasets[i].Name), MakeValidIdentifier(Datasets[i].Name)]), PASCAL_INDENTATION_LEVEL_1);
Write(Format('[''%s'']', [guids[i]]), PASCAL_INDENTATION_LEVEL_1);
with Datasets[i] do begin
Write('{ Property getters and setters }', PASCAL_INDENTATION_LEVEL_2);
for x := 0 to (Fields.Count-1) do begin
Write(Format('function GetOld%sValue : %s;', [MakeValidIdentifier(Fields[x].Name), GetDAType(Fields[x].DataType)]), PASCAL_INDENTATION_LEVEL_2);
end;
WriteEmptyLine;
// Properties
Write('{ Properties }', PASCAL_INDENTATION_LEVEL_2);
for x := 0 to (Fields.Count-1) do
Write(Format('property Old%s : %s read GetOld%sValue;',
[MakeValidIdentifier(Fields[x].Name),
GetDAType(Fields[x].DataType),
MakeValidIdentifier(Fields[x].Name),
MakeValidIdentifier(Fields[x].Name)]), PASCAL_INDENTATION_LEVEL_2);
Write(Format('end;', []), PASCAL_INDENTATION_LEVEL_1);
end;
WriteEmptyLine;
// Implementor class
Write(Format('{ T%sBusinessProcessorRules }', [MakeValidIdentifier(Datasets[i].Name)]), PASCAL_INDENTATION_LEVEL_1);
Write(Format('T%sBusinessProcessorRules = class(TDABusinessProcessorRules, I%s, I%sDelta)', [MakeValidIdentifier(Datasets[i].Name), MakeValidIdentifier(Datasets[i].Name), MakeValidIdentifier(Datasets[i].Name)]), PASCAL_INDENTATION_LEVEL_1);
with Datasets[i] do begin
Write('private', PASCAL_INDENTATION_LEVEL_1);
for x := 0 to (Fields.Count-1) do begin
if Fields[x].DataType in [datMemo, datBlob] then
Write(Format('f_%s: %s;',[MakeValidIdentifier(Fields[x].Name), GetDAType(Fields[x].DataType)]),PASCAL_INDENTATION_LEVEL_2);
end;
for x := 0 to (Fields.Count-1) do begin
if Fields[x].DataType = datMemo then
Write(Format('procedure %s_OnChange(Sender: TObject);',[MakeValidIdentifier(Fields[x].Name)]),PASCAL_INDENTATION_LEVEL_2)
else
if Fields[x].DataType = datBlob then
Write(Format('procedure %s_OnChange(Sender: Tobject);',[MakeValidIdentifier(Fields[x].Name)]),PASCAL_INDENTATION_LEVEL_2);
end;
Write('protected', PASCAL_INDENTATION_LEVEL_1);
Write('{ Property getters and setters }', PASCAL_INDENTATION_LEVEL_2);
for x := 0 to (Fields.Count-1) do begin
Write(Format('function Get%sValue: %s; virtual;', [MakeValidIdentifier(Fields[x].Name), GetDAType(Fields[x].DataType)]), PASCAL_INDENTATION_LEVEL_2);
Write(Format('function Get%sIsNull: Boolean; virtual;', [MakeValidIdentifier(Fields[x].Name)]), PASCAL_INDENTATION_LEVEL_2);
Write(Format('function GetOld%sValue: %s; virtual;', [MakeValidIdentifier(Fields[x].Name), GetDAType(Fields[x].DataType)]), PASCAL_INDENTATION_LEVEL_2);
Write(Format('function GetOld%sIsNull: Boolean; virtual;', [MakeValidIdentifier(Fields[x].Name)]), PASCAL_INDENTATION_LEVEL_2);
if not(Fields[x].DataType in [datMemo, datBlob]) then
Write(Format('procedure Set%sValue(const aValue: %s); virtual;', [MakeValidIdentifier(Fields[x].Name), GetDAType(Fields[x].DataType)]), PASCAL_INDENTATION_LEVEL_2);
Write(Format('procedure Set%sIsNull(const aValue: Boolean); virtual;', [MakeValidIdentifier(Fields[x].Name)]), PASCAL_INDENTATION_LEVEL_2);
end;
WriteEmptyLine;
Write('{ Properties }', PASCAL_INDENTATION_LEVEL_2);
for x := 0 to (Fields.Count-1) do begin
if (Fields[x].DataType in [datMemo, datBlob]) then
Write(Format('property %s : %s read Get%sValue;',
[MakeValidIdentifier(Fields[x].Name),
GetDAType(Fields[x].DataType),
MakeValidIdentifier(Fields[x].Name)]), PASCAL_INDENTATION_LEVEL_2)
else
Write(Format('property %s : %s read Get%sValue write Set%sValue;',
[MakeValidIdentifier(Fields[x].Name),
GetDAType(Fields[x].DataType),
MakeValidIdentifier(Fields[x].Name),
MakeValidIdentifier(Fields[x].Name)]), PASCAL_INDENTATION_LEVEL_2);
Write(Format('property %sIsNull : Boolean read Get%sIsNull write Set%sIsNull;',
[MakeValidIdentifier(Fields[x].Name),
MakeValidIdentifier(Fields[x].Name),
MakeValidIdentifier(Fields[x].Name)]), PASCAL_INDENTATION_LEVEL_2);
Write(Format('property Old%s : %s read GetOld%sValue;',
[MakeValidIdentifier(Fields[x].Name),
GetDAType(Fields[x].DataType),
MakeValidIdentifier(Fields[x].Name),
MakeValidIdentifier(Fields[x].Name)]), PASCAL_INDENTATION_LEVEL_2);
Write(Format('property Old%sIsNull : Boolean read GetOld%sIsNull;',
[MakeValidIdentifier(Fields[x].Name),
MakeValidIdentifier(Fields[x].Name),
MakeValidIdentifier(Fields[x].Name)]), PASCAL_INDENTATION_LEVEL_2);
end;
WriteEmptyLine;
Write('public', PASCAL_INDENTATION_LEVEL_1);
Write('constructor Create(aBusinessProcessor: TDABusinessProcessor); override;', PASCAL_INDENTATION_LEVEL_2);
Write('destructor Destroy; override;', PASCAL_INDENTATION_LEVEL_2);
WriteEmptyLine;
// Generates the Find method
{s := GenFindParams(Datasets[i], TRUE, TRUE, FALSE);
if (s<>'') then Write(Format('function Find(%s; LocateOptions : TLocateOptions) : boolean;', [s]), PASCAL_INDENTATION_LEVEL_2);}
end;
Write(Format('end;', []), PASCAL_INDENTATION_LEVEL_1);
WriteEmptyLine;
end;
Write('implementation');
WriteEmptyLine;
Write('uses');
Write(' Variants, uROBinaryHelpers, uDAInterfaces;');
WriteEmptyLine;
for i := 0 to (Datasets.Count-1) do begin
// Implementor class
Write(Format('{ T%sBusinessProcessorRules }', [MakeValidIdentifier(Datasets[i].Name)]));
with Datasets[i] do begin
Write(Format('constructor T%sBusinessProcessorRules.Create(aBusinessProcessor: TDABusinessProcessor);', [MakeValidIdentifier(Name)]));
bVar:=False;
// create StrList
for x := 0 to (Fields.Count-1) do begin
if Fields[x].DataType = datMemo then begin
if not bVar then begin
Write('var');
bVar:=True;
end;
Write(' StrList: TStringList;');
Break;
end;
end;
// create ROStream
for x := 0 to (Fields.Count-1) do begin
if Fields[x].DataType = datBlob then begin
if not bVar then begin
Write('var');
end;
Write(' ROStream: TROStream;');
Break;
end;
end;
Write('begin');
Write(' inherited;');
for x := 0 to (Fields.Count-1) do begin
if Fields[x].DataType = datMemo then begin
WriteEmptyLine;
Write(' StrList := TStringList.Create;');
Write(Format(' StrList.OnChange := %s_OnChange;', [MakeValidIdentifier(Fields[x].Name)]));
Write(Format(' f_%s := NewROStrings(StrList,True);', [MakeValidIdentifier(Fields[x].Name)]));
end else
if Fields[x].DataType = datBlob then begin
WriteEmptyLine;
Write(' ROStream := TROStream.Create;');
Write(Format(' ROStream.OnChange := %s_OnChange;', [MakeValidIdentifier(Fields[x].Name)]));
Write(Format(' f_%s := ROStream;', [MakeValidIdentifier(Fields[x].Name)]));
end;
end;
Write('end;');
WriteEmptyLine;
Write(Format('destructor T%sBusinessProcessorRules.Destroy;', [MakeValidIdentifier(Name)]));
Write('begin');
Write(' inherited;');
Write('end;');
WriteEmptyLine;
for x := 0 to (Fields.Count-1) do begin
if Fields[x].DataType = datMemo then begin
Write(Format('procedure T%sBusinessProcessorRules.%s_OnChange(Sender: TObject);', [MakeValidIdentifier(Name), MakeValidIdentifier(Fields[x].Name)]));
Write('begin');
Write(Format(' BusinessProcessor.CurrentChange.NewValueByName[fld_%s%s] := TStringList(Sender).Text;', [MakeValidIdentifier(Datasets[i].Name), MakeValidIdentifier(Datasets[i].Fields[x].Name)]));
Write('end;');
WriteEmptyLine;
end else
if Fields[x].DataType = datBlob then begin
Write(Format('procedure T%sBusinessProcessorRules.%s_OnChange(Sender: TObject);', [MakeValidIdentifier(Name), MakeValidIdentifier(Fields[x].Name)]));
Write('begin');
Write(Format(' BusinessProcessor.CurrentChange.NewValueByName[fld_%s%s] := VariantBinaryFromBinary((TROStream(Sender) as IROStream).Stream);', [MakeValidIdentifier(Datasets[i].Name), MakeValidIdentifier(Datasets[i].Fields[x].Name)]));
Write('end;');
WriteEmptyLine;
end;
end;
for x := 0 to (Fields.Count-1) do begin
Write(Format('function T%sBusinessProcessorRules.Get%sValue: %s;', [MakeValidIdentifier(Name), MakeValidIdentifier(Fields[x].Name), GetDAType(Fields[x].DataType)]));
Write('begin');
case Fields[x].DataType of
datMemo:begin
Write(Format(' result := f_%s;',[MakeValidIdentifier(Fields[x].Name)]));
Write(Format(' result.Text := BusinessProcessor.CurrentChange.NewValueByName[fld_%s%s];', [MakeValidIdentifier(Datasets[i].Name), MakeValidIdentifier(Datasets[i].Fields[x].Name)]));
end;
datBlob:begin
Write(Format(' result := f_%s;',[MakeValidIdentifier(Fields[x].Name)]));
Write(' result.Position := 0;');
Write(' if not Result.InUpdateMode then begin');
Write(Format(' WriteVariantBinaryToBinary(BusinessProcessor.CurrentChange.NewValueByName[fld_%s%s], result.Stream);', [MakeValidIdentifier(Datasets[i].Name), MakeValidIdentifier(Datasets[i].Fields[x].Name)]));
Write(' result.Position := 0;');
Write(' end;');
end;
datDecimal: begin
Write(Format(' result := GetVarDecimal(BusinessProcessor.CurrentChange.NewValueByName[fld_%s%s]);', [MakeValidIdentifier(Datasets[i].Name), MakeValidIdentifier(Datasets[i].Fields[x].Name), GetDAType(Fields[x].DataType)]));
end;
datXml: begin
Write(Format(' result := GetVarXml(BusinessProcessor.CurrentChange.NewValueByName[fld_%s%s]);', [MakeValidIdentifier(Datasets[i].Name), MakeValidIdentifier(Datasets[i].Fields[x].Name), GetDAType(Fields[x].DataType)]));
end;
datGuid: begin
Write(Format(' result := GetVarGuid(BusinessProcessor.CurrentChange.NewValueByName[fld_%s%s]);', [MakeValidIdentifier(Datasets[i].Name), MakeValidIdentifier(Datasets[i].Fields[x].Name), GetDAType(Fields[x].DataType)]));
end;
else begin
Write(Format(' result := BusinessProcessor.CurrentChange.NewValueByName[fld_%s%s];', [MakeValidIdentifier(Datasets[i].Name), MakeValidIdentifier(Datasets[i].Fields[x].Name), GetDAType(Fields[x].DataType)]));
end;
end;
Write('end;');
WriteEmptyLine;
Write(Format('function T%sBusinessProcessorRules.Get%sIsNull: Boolean;', [MakeValidIdentifier(Name), MakeValidIdentifier(Fields[x].Name)]));
Write('begin');
Write(Format(' result := VarIsNull(BusinessProcessor.CurrentChange.NewValueByName[fld_%s%s]);', [MakeValidIdentifier(Datasets[i].Name), MakeValidIdentifier(Datasets[i].Fields[x].Name)]));
Write('end;');
WriteEmptyLine;
Write(Format('function T%sBusinessProcessorRules.GetOld%sValue: %s;', [MakeValidIdentifier(Name), MakeValidIdentifier(Fields[x].Name), GetDAType(Fields[x].DataType)]));
Write('begin');
case Fields[x].DataType of
datMemo:begin
Write(' result := NewROStrings();');
Write(Format(' result.Text := BusinessProcessor.CurrentChange.OldValueByName[fld_%s%s];', [MakeValidIdentifier(Datasets[i].Name), MakeValidIdentifier(Datasets[i].Fields[x].Name)]));
end;
datBlob:begin
Write(' result := NewROStream();');
Write(Format(' WriteVariantBinaryToBinary(BusinessProcessor.CurrentChange.OldValueByName[fld_%s%s], result.Stream);', [MakeValidIdentifier(Datasets[i].Name), MakeValidIdentifier(Datasets[i].Fields[x].Name)]));
end;
datDecimal: begin
Write(Format(' result := GetVarDecimal(BusinessProcessor.CurrentChange.OldValueByName[fld_%s%s]);', [MakeValidIdentifier(Datasets[i].Name), MakeValidIdentifier(Datasets[i].Fields[x].Name), GetDAType(Fields[x].DataType)]));
end;
datXml: begin
Write(Format(' result := GetVarXml(BusinessProcessor.CurrentChange.OldValueByName[fld_%s%s]);', [MakeValidIdentifier(Datasets[i].Name), MakeValidIdentifier(Datasets[i].Fields[x].Name), GetDAType(Fields[x].DataType)]));
end;
datGuid: begin
Write(Format(' result := GetVarGuid(BusinessProcessor.CurrentChange.OldValueByName[fld_%s%s]);', [MakeValidIdentifier(Datasets[i].Name), MakeValidIdentifier(Datasets[i].Fields[x].Name), GetDAType(Fields[x].DataType)]));
end;
else begin
Write(Format(' result := BusinessProcessor.CurrentChange.OldValueByName[fld_%s%s];', [MakeValidIdentifier(Datasets[i].Name), MakeValidIdentifier(Datasets[i].Fields[x].Name), GetDAType(Fields[x].DataType)]));
end;
end;
Write('end;');
WriteEmptyLine;
Write(Format('function T%sBusinessProcessorRules.GetOld%sIsNull: Boolean;', [MakeValidIdentifier(Name), MakeValidIdentifier(Fields[x].Name)]));
Write('begin');
Write(Format(' result := VarIsNull(BusinessProcessor.CurrentChange.OldValueByName[fld_%s%s]);', [MakeValidIdentifier(Datasets[i].Name), MakeValidIdentifier(Datasets[i].Fields[x].Name)]));
Write('end;');
WriteEmptyLine;
if not(Fields[x].DataType in [datMemo, datBlob]) then begin
Write(Format('procedure T%sBusinessProcessorRules.Set%sValue(const aValue: %s);', [MakeValidIdentifier(Name), MakeValidIdentifier(Fields[x].Name), GetDAType(Fields[x].DataType)]));
Write('begin');
case Fields[x].DataType of
datDecimal: begin
Write(Format(' BusinessProcessor.CurrentChange.NewValueByName[fld_%s%s] := BCDToVariant(aValue);', [MakeValidIdentifier(Datasets[i].Name), MakeValidIdentifier(Datasets[i].Fields[x].Name), GetDAType(Fields[x].DataType)]));
end;
datXml: begin
Write( ' if aValue = nil then');
Write(Format(' BusinessProcessor.CurrentChange.NewValueByName[fld_%s%s] := ''''', [MakeValidIdentifier(Datasets[i].Name), MakeValidIdentifier(Datasets[i].Fields[x].Name), GetDAType(Fields[x].DataType)]));
Write( ' else');
Write(Format(' BusinessProcessor.CurrentChange.NewValueByName[fld_%s%s] := aValue.XML;', [MakeValidIdentifier(Datasets[i].Name), MakeValidIdentifier(Datasets[i].Fields[x].Name), GetDAType(Fields[x].DataType)]));
end;
datGuid: begin
Write(Format(' BusinessProcessor.CurrentChange.NewValueByName[fld_%s%s] := GUIDToString(aValue);', [MakeValidIdentifier(Datasets[i].Name), MakeValidIdentifier(Datasets[i].Fields[x].Name), GetDAType(Fields[x].DataType)]));
end;
else
Write(Format(' BusinessProcessor.CurrentChange.NewValueByName[fld_%s%s] := aValue;', [MakeValidIdentifier(Datasets[i].Name), MakeValidIdentifier(Datasets[i].Fields[x].Name), GetDAType(Fields[x].DataType)]));
end;
Write('end;');
WriteEmptyLine;
end;
Write(Format('procedure T%sBusinessProcessorRules.Set%sIsNull(const aValue: Boolean);', [MakeValidIdentifier(Name), MakeValidIdentifier(Fields[x].Name)]));
Write('begin');
write(' if aValue then');
Write(Format(' BusinessProcessor.CurrentChange.NewValueByName[fld_%s%s] := Null;', [MakeValidIdentifier(Datasets[i].Name), MakeValidIdentifier(Datasets[i].Fields[x].Name)]));
Write('end;');
WriteEmptyLine;
end;
end;
WriteEmptyLine;
end;
Write('initialization');
for i := 0 to (Datasets.Count-1) do
Write(Format('RegisterBusinessProcessorRules(RID_%sDelta, T%sBusinessProcessorRules);', [MakeValidIdentifier(Datasets[i].Name), MakeValidIdentifier(Datasets[i].Name)]), PASCAL_INDENTATION_LEVEL_1);
WriteEmptyLine;
Write('end.');
finally
guids.Free;
end;
end;
end.