Repository URL to install this package:
|
Version:
3.2.0 ▾
|
{
This file is part of the Free Pascal run time library.
Copyright (c) 2007 by Michael Van Canneyt, member of the
Free Pascal development team
Data Dictionary Code Generator Implementation.
See the file COPYING.FPC, included in this distribution,
for details about the copyright.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
**********************************************************************}
unit fpcgtiopf;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, db, fpddcodegen;
TYpe
TClassOption = (caCreateClass,caConstructor,caDestructor,caCreateList,
caListAddMethod,caListItemsProperty,caOverrideRead,
caOverrideReadThis,caOverrideSave);
TClassOptions = Set of TClassOption;
TVisitorOption = (voRead,voReadList,voCreate,voDelete,voUpdate,
voCommonSetupParams,voSingleSaveVisitor,voRegisterVisitors);
TVisitorOptions = set of TVisitorOption;
{ TTiOPFFieldPropDef }
TTiOPFFieldPropDef = Class(TFieldPropDef)
Public
Constructor Create(ACollection : TCollection); override;
end;
{ TTiOPFCodeOptions }
TTiOPFCodeOptions = Class (TClassCodeGeneratorOptions)
Private
FClassOptions: TClassOptions;
FFinalVisitors: TVisitorOptions;
FListAncestorName: String;
FListClassName : String;
FVisitorOptions: TVisitorOptions;
FTableName : String;
function GetListClassName: String;
procedure SetClassOptions(const AValue: TClassOptions);
procedure SetListAncestorName(const AValue: String);
procedure SetListClassName(const AValue: String);
procedure SetVisitorOptions(const AValue: TVisitorOptions);
Public
Constructor Create; override;
Procedure Assign(ASource : TPersistent); override;
Published
Property ClassOptions : TClassOptions Read FClassOptions Write SetClassOptions;
Property VisitorOptions : TVisitorOptions Read FVisitorOptions Write SetVisitorOptions;
Property FinalVisitors : TVisitorOptions Read FFinalVisitors Write FFinalVisitors;
Property ListAncestorName : String Read FListAncestorName Write SetListAncestorName;
Property ListClassName : String Read GetListClassName Write SetListClassName;
Property AncestorClass;
Property TableName : String Read FTableName Write FTableName;
end;
{ TTiOPFCodeGenerator }
TTiOPFCodeGenerator = Class(TDDClassCodeGenerator)
procedure CreateListImplementation(Strings: TStrings; const ObjectClassName, ListClassName: String);
function BeginInit(Strings: TStrings; const AClass: String): String;
function BeginAcceptVisitor(Strings: TStrings; const AClass, ObjectClassName: String): String;
function BeginSetupParams(Strings: TStrings; const AClass,ObjectClassName: String; DeclareObject : Boolean): String;
function BeginMapRowToObject(Strings: TStrings; const AClass, ObjectClassName : String): String;
procedure DeclareObjectvariable(Strings: TStrings;
const ObjectClassName: String);
private
Function CreateSQLStatement(V: TVisitorOption) : String;
function GetOpt: TTiOPFCodeOptions;
Function UseCommonSetupParams : Boolean;
Function SingleSaveVisitor : Boolean;
Function VisitorClassName(V : TVisitorOption; Const ObjectClassName : String) : String;
// Auxiliary routines
procedure WriteFieldAssign(Strings: TStrings; F: TFieldPropDef);
procedure WriteAssignToParam(Strings: TStrings; F: TFieldPropDef);
procedure WriteReadWriteOverride(Strings: TStrings; const AAMethod, AVisitorGroup: String);
procedure WriteRegisterVisitorLine(Strings: TStrings;
const V: TVisitorOption; const ObjectClassName: String);
procedure WriteSetSQL(Strings: TStrings; const ASQL: String);
procedure WriteSQLConstants(Strings: TStrings);
Procedure WriteTerminateVisitor(Strings : TStrings; V : TVisitorOption; const ObjectClassName: String);
procedure WriteSetupParams(Strings: TStrings; const AClassName, ObjectClassName: String);
// Visitors
procedure WriteCommonSetupVisitor(Strings: TStrings; const ObjectClassName: String);
procedure WriteSaveVisitor(Strings: TStrings; const ObjectClassName: String);
procedure WriteCreateVisitor(Strings: TStrings; const ObjectClassName: String);
procedure WriteDeleteVisitor(Strings: TStrings; const ObjectClassName: String);
procedure WriteUpdateVisitor(Strings: TStrings; const ObjectClassName: String);
procedure WriteReadListVisitor(Strings: TStrings; const ObjectClassName: String);
procedure WriteReadVisitor(Strings: TStrings; const ObjectClassName: String );
procedure WriteVisitorDeclaration(Strings: TStrings; V: TVisitorOption; const ObjectClassName: String);
procedure WriteVisitorImplementation(Strings: TStrings; V: TVisitorOption; const ObjectClassName: String);
procedure WriteVisitorRegistration(Strings: TStrings; const ObjectClassName: String);
Protected
// Not to be overridden.
procedure WriteListAddObject(Strings: TStrings; const ListClassName, ObjectClassName: String);
// Overrides of parent objects
Function CreateFieldPropDefs : TFieldPropDefs; override;
function AllowPropertyDeclaration(F: TFieldPropDef; AVisibility: TVisibilities): Boolean; override;
Function GetInterfaceUsesClause : string; override;
procedure WriteVisibilityStart(V: TVisibility; Strings: TStrings); override;
Procedure DoGenerateInterface(Strings: TStrings); override;
Procedure DoGenerateImplementation(Strings: TStrings); override;
procedure CreateImplementation(Strings: TStrings); override;
Function NeedsConstructor : Boolean; override;
Function NeedsDestructor : Boolean; override;
Class Function NeedsFieldDefs : Boolean; override;
Function CreateOptions : TCodeGeneratorOptions; override;
//
// New methods
//
// Override to add declarations to list declaration
procedure DoCreateListDeclaration(Strings: TStrings; const ObjectClassName, ListClassName, ListAncestorName: String); virtual;
Public
procedure CreateListDeclaration(Strings: TStrings; const ObjectClassName, ListClassName, ListAncestorName: String);
Property TiOPFOptions : TTiOPFCodeOptions Read GetOpt;
end;
Const
SOID = 'OID'; // OID property.
SDefTableName = 'MYTABLE'; // Default table name.
implementation
Function StripType(S : String) : string;
begin
Result:=S;
If (Result<>'') and (Result[1]='T') then
Delete(Result,1,1);
end;
{ TTiOPFFieldPropDef }
constructor TTiOPFFieldPropDef.Create(ACollection: TCollection);
begin
inherited Create(ACollection);
PropSetters:=[psWrite];
end;
{ TTiOPFCodeOptions }
function TTiOPFCodeOptions.GetListClassName: String;
begin
Result:=FListClassName;
If (Result='') then
Result:=ObjectClassName+'List';
end;
procedure TTiOPFCodeOptions.SetClassOptions(const AValue: TClassOptions);
Var
B : Boolean;
begin
If AValue=FClassOptions then
Exit;
B:=Not(caCreateList in FClassOptions) and (caCreateList in AValue);
FClassOptions:=AValue;
If B then
Include(FVisitorOptions,voReadList);
end;
procedure TTiOPFCodeOptions.SetListAncestorName(const AValue: String);
begin
CheckIdentifier(AValue,False);
FListAncestorName:=AValue;
end;
procedure TTiOPFCodeOptions.SetListClassName(const AValue: String);
begin
CheckIdentifier(AValue,True);
FListClassName:=AValue;
end;
procedure TTiOPFCodeOptions.SetVisitorOptions(const AValue: TVisitorOptions);
Var
V : TVisitorOption;
begin
FVisitorOptions:=AValue;
// Consistency check
If voSingleSaveVisitor in FVisitorOptions then
begin
Exclude(FVisitorOptions,voCommonSetupParams);
Exclude(FVisitorOptions,voCreate);
Exclude(FVisitorOptions,voUpdate);
Exclude(FVisitorOptions,voDelete);
end
else If voCommonSetupParams in FVisitorOptions then
begin
Include(FVisitorOptions,voCreate);
Include(FVisitorOptions,voUpdate);
end;
For V:=Low(TVisitorOption) to High(TVisitorOption) do
If Not (V in FVisitorOptions) then
Exclude(FFinalVisitors,V);
end;
constructor TTiOPFCodeOptions.Create;
begin
inherited Create;
FListAncestorName:='TtiObjectList';
AncestorClass:='TtiObject';
ObjectClassName:='MyObject';
TableName:=SDefTableName;
FVisitorOptions:=[voRead,voCreate,voDelete,voUpdate];
FClassOptions:=[caCreateClass,caCreateList,caListAddMethod,caListItemsProperty];
end;
procedure TTiOPFCodeOptions.Assign(ASource: TPersistent);
Var
OC : TTiOPFCodeOptions;
begin
If ASource is TTiOPFCodeOptions then
begin
OC:=ASource as TTiOPFCodeOptions;
FListAncestorName:=OC.FListAncestorName;
AncestorClass:=OC.AncestorClass;
FVisitorOptions:=OC.FVisitorOptions;
FClassOptions:=OC.FClassOptions;
FTableName:=OC.TableName;
FFinalVisitors:=OC.FinalVisitors;
end;
inherited Assign(ASource);
end;
{ TTiOPFCodeGenerator }
{ ---------------------------------------------------------------------
General overrides
---------------------------------------------------------------------}
function TTiOPFCodeGenerator.NeedsConstructor: Boolean;
begin
Result:=inherited NeedsConstructor;
Result:=Result or (caConstructor in TiOPFOptions.ClassOptions);
end;
function TTiOPFCodeGenerator.NeedsDestructor: Boolean;
begin
Result:=inherited NeedsDestructor;
Result:=Result or (caDestructor in TiOPFOptions.ClassOptions);
end;
class function TTiOPFCodeGenerator.NeedsFieldDefs: Boolean;
begin
Result:=True;
end;
function TTiOPFCodeGenerator.CreateOptions: TCodeGeneratorOptions;
begin
Result:=TTiOPFCodeOptions.Create;
end;
function TTiOPFCodeGenerator.GetOpt: TTiOPFCodeOptions;
begin
Result:=CodeOptions as TTiOPFCodeOptions;
end;
function TTiOPFCodeGenerator.UseCommonSetupParams: Boolean;
begin
Result:=VoCommonSetupParams in tiOPFOptions.VisitorOptions;
end;
function TTiOPFCodeGenerator.SingleSaveVisitor: Boolean;
begin
Result:=voSingleSaveVisitor in tiOPFOptions.VisitorOptions;
end;
function TTiOPFCodeGenerator.VisitorClassName(V: TVisitorOption;
const ObjectClassName: String): String;
Var
S : String;
begin
Case V of
voRead : S:='Read';
voReadList : S:='ReadList';
voCreate : S:='Create';
voDelete : S:='Delete';
voUpdate : S:='Update';
voCommonSetupParams : S:='UpdateCreate';
voSingleSaveVisitor : S:='Save';
else
Result:='Unknown';
end;
// Real class name
Result:=Format('T%s%sVisitor',[S,StripType(ObjectClassName)]);
end;
procedure TTiOPFCodeGenerator.WriteCommonSetupVisitor(Strings: TStrings;
const ObjectClassName: String);
Var
CS,C,S : String;
I : Integer;
begin
C:=VisitorClassName(voCommonSetupParams,ObjectClassName);
Addln(Strings,'{ %s }',[C]);
Addln(Strings);
WriteSetupParams(Strings,C,ObjectClassName);
end;
procedure TTiOPFCodeGenerator.WriteSaveVisitor(Strings: TStrings; const ObjectClassName: String);
Procedure WriteSQLCase(Const ACaselabel,ASQL : String);
begin
addln(Strings,ACaseLabel+':');
incIndent;
WriteSetSQL(Strings,ASQL);
DecIndent;
end;
Var
OCN,CS,C,S : String;
I : Integer;
F : TFieldPropDef;
begin
OCN:=StripType(ObjectClassName);
C:=VisitorClassName(voSingleSaveVisitor,OCN);
Addln(Strings,'{ %s }',[C]);
Addln(Strings);
// Init
S:=BeginInit(Strings,C);
AddLn(Strings,'Case Visited.ObjectState of');
IncIndent;
try
WriteSQLCase('posCreate',Format('SQLCreate%s',[OCN]));
WriteSQLCase('posUpdate',Format('SQLUpdate%s',[OCN]));
WriteSQLCase('posDelete',Format('SQLDelete%s',[OCN]));
finally
DecIndent;
end;
Addln(Strings,'end;');
DecIndent;
EndMethod(Strings,S);
// AcceptVisitor
S:=BeginAcceptVisitor(Strings,C,ObjectClassName);
AddLn(Strings,'Result:=Result and (Visited.ObjectState in [posCreate,posDelete,posUpdate]);');
DecIndent;
EndMethod(Strings,S);
S:=BeginSetupParams(Strings,C,ObjectClassName,True);
Addln(Strings,'With Query do',[ObjectClassName]);
IncINdent;
try
Addln(Strings,'begin');
F:=Fields.FindPropName('OID');
If (F<>Nil) then
WriteAssignToParam(Strings,F)
else
AddLn(Strings,'// No OID property found. Add delete key parameter setup code here.');
AddLn(Strings,'If (Visited.ObjectState<>posDelete) then');
IncIndent;
try
AddLn(Strings,'begin');
For I:=0 to Fields.Count-1 do
If Fields[i].Enabled and (CompareText(Fields[i].PropertyName,'OID')<>0) then
WriteAssignToParam(Strings,Fields[i]);
AddLn(Strings,'end;');
Finally
DecIndent;
end;
Addln(Strings,'end;');
finally
DecIndent;
end;
DecIndent;
EndMethod(Strings,S);
end;
function TTiOPFCodeGenerator.GetInterfaceUsesClause: string;
begin
Result:=inherited GetInterfaceUsesClause;
If (Result<>'') then
Result:=Result+', ';
Result:=Result+'tiVisitor, tiVisitorDB, tiObject';
If (voRegisterVisitors in tiOPFoptions.VisitorOptions)
or ([caOverrideRead,caOverrideReadThis,caOverrideSave]*tiOPFOptions.ClassOptions<>[]) then
Result:=Result+', tiOPFManager';
end;
procedure TTiOPFCodeGenerator.DoGenerateInterface(Strings: TStrings);
Var
V : TVisitorOption;
begin
If (caCreateClass in TiOPFOptions.ClassOptions) then
inherited DoGenerateInterface(Strings)
else
begin
Addln(Strings,'Type');
Addln(Strings);
end;
With TiOPFOptions do
begin
IncIndent;
try
If caCreateList in ClassOptions then
CreateListDeclaration(Strings,ObjectClassName,ListClassName,ListAncestorName);
If voCommonSetupParams in VisitorOptions then
WriteVisitorDeclaration(Strings,voCommonSetupParams,ObjectClassName);
For V:=Low(TVisitorOption) to High(TVisitorOption) do
If (V in VisitorOptions) and (V<>voCommonSetupParams) then
WriteVisitorDeclaration(Strings,V,ObjectClassName);
Finally
DecIndent;
end;
end;
If voRegisterVisitors in tiOPFoptions.VisitorOptions then
begin
AddLn(Strings);
AddLn(Strings,'Procedure Register'+tiOPFoptions.ObjectClassName+'Visitors;');
AddLn(Strings);
end;
end;
procedure TTiOPFCodeGenerator.WriteVisitorDeclaration(Strings : TStrings; V : TVisitorOption; Const ObjectClassName : String);
Var
S,T,A : string;
begin
// Ancestor name
// Common setup case
If (V in [voCreate,voUpdate]) and (UseCommonSetupParams) then
A:=Format('TUpdateCreate%sVisitor',[StripType(ObjectClassName)])
else If (V in [voCreate,voDelete,voUpdate,voCommonSetupParams,voSingleSaveVisitor]) then
A:='TtiVisitorUpdate'
else
A:='TtiVisitorSelect';
// Real class
S:=VisitorClassName(V,ObjectClassName);
AddLn(Strings,'{ %s }',[S]);
AddlN(Strings,'%s = Class(%s)',[S,A]);
AddlN(Strings,'Protected');
IncIndent;
Try
If (V<>VoCommonSetupParams) then
begin
AddLn(Strings,'Procedure Init; override;');
AddLn(Strings,'Function AcceptVisitor : Boolean; override;');
If Not ((V in [voCreate,voUpdate]) and UseCommonSetupParams) then
AddLn(Strings,'Procedure SetupParams; override;');
end
else
AddLn(Strings,'Procedure SetupParams; override;');
If (V in [voRead,voReadList]) then
AddLn(Strings,'Procedure MapRowToObject; override;');
if (V in TiOPFOptions.FinalVisitors) then
Addln(Strings,'Procedure Execute(Const AData : TtiVisited); override;');
Finally
DecIndent;
end;
AddlN(Strings,'end;');
AddlN(Strings);
end;
Function TTiOPFCodeGenerator.CreateSQLStatement(V : TVisitorOption) : String;
Function AddToS(Const S,Add : String) : string;
begin
Result:=S;
If (Result<>'') then
Result:=Result+', ';
Result:=Result+Add;
end;
Var
I : integer;
W,S,VS,TN : String;
F : TFieldPropDef;
begin
TN:=TiOPFOptions.TableName;
If (TN='') then
TN:=SDefTableName;
S:='';
VS:='';
W:='Your condition here';
Result:='';
Case V of
voRead,
voReadList : begin
Result:='SELECT ';
For I:=0 to Fields.Count-1 do
begin
F:=Fields[i];
If F.Enabled then
begin
S:=AddToS(S,F.FieldName);
If (V=voRead) and (F.PropertyName=SOID) then
W:=Format('%s = :%s',[F.FieldName,F.FieldName]);
end;
end;
Result:=Result+S+Format(' FROM %s WHERE (%s);',[TN,W]);
end;
voCreate : begin
Result:=Format('INSERT INTO %s (',[TN]);
For I:=0 to Fields.Count-1 do
begin
F:=Fields[i];
If F.Enabled then
begin
S:=AddToS(S,F.FieldName);
VS:=AddToS(VS,':'+F.FieldName);
end;
end;
Result:=Result+S+') VALUES ('+VS+');';
end;
voDelete : begin
For I:=0 to Fields.Count-1 do
begin
F:=Fields[i];
If (F.PropertyName=SOID) then
W:=Format('%s = :%s',[F.FieldName,F.FieldName]);
end;
Result:=Format('DELETE FROM %s WHERE (%s);',[TN,W]);
end;
voUpdate : begin
Result:=Format('UPDATE %s SET ',[TN]);
For I:=0 to Fields.Count-1 do
begin
F:=Fields[i];
If F.Enabled then
If (F.PropertyName=SOID) then
W:=Format('%s = :%s',[F.FieldName,F.FieldName])
else
S:=AddToS(S,F.FieldName+' = :'+F.FieldName);
end;
Result:=Result+S+Format(' WHERE (%s);',[W]);
end;
end;
end;
procedure TTiOPFCodeGenerator.WriteSQLConstants(Strings : TStrings);
Const
VisSQL : Array [TVisitorOption] of string
= ('Read','ReadList','Create','Delete','Update','','','');
Var
OCN,S : String;
V : TVisitorOption;
begin
AddLn(Strings,'Const');
IncIndent;
try
OCN:=StripType(TiOPFOptions.ObjectClassName);
For V:=Low(TVisitorOption) to High(TVisitorOption) do
If ((V in TiOPFOptions.VisitorOptions) or
(SingleSaveVisitor and (V in [voCreate,voUpdate,voDelete]))) and (VisSQL[V]<>'') then
begin
S:=CreateSQLStatement(V);
S:=Format('SQL%s%s = ''%s'';',[VisSQL[V],OCN,S]);
AddLn(Strings,S);
end;
finally
DecIndent;
end;
AddLn(Strings,'');
end;
procedure TTiOPFCodeGenerator.WriteTerminateVisitor(Strings : TStrings;V : TVisitorOption;
const ObjectClassName: String);
Var
S : String;
begin
S:=VisitorclassName(V,ObjectClassName);
S:=Format('Procedure %s.Execute(Const AData : TtiVisited);',[S]);
BeginMethod(Strings,S);
AddLn(Strings,'begin');
IncIndent;
try
AddLn(Strings,'Inherited Execute(AData);');
Addln(Strings,'If not AcceptVisitor then');
IncIndent;
Try
Addln(Strings,'Exit; // ==>');
Finally
DecIndent;
end;
AddLn(Strings,'ContinueVisiting:=False;');
Finally
DecIndent;
end;
EndMethod(Strings,S);
end;
procedure TTiOPFCodeGenerator.DoGenerateImplementation(Strings: TStrings);
Var
V : TVisitorOption;
begin
If (caCreateClass in TiOPFOptions.ClassOptions) then
inherited DoGenerateImplementation(Strings);
With TiOPFOptions do
begin
If (VisitorOptions<>[]) then
WriteSQLConstants(Strings);
If caCreateList in ClassOptions then
CreateListImplementation(Strings,ObjectClassName,ListClassName);
For V:=Low(TVisitorOption) to High(TVisitorOption) do
If V in VisitorOptions then
WriteVisitorImplementation(Strings,V,ObjectClassName);
If (voRegisterVisitors in TiOPFOptions.VisitorOptions) then
WriteVisitorRegistration(Strings,ObjectClassName);
end;
end;
{ ---------------------------------------------------------------------
Override read/write/readthis
---------------------------------------------------------------------}
procedure TTiOPFCodeGenerator.WriteVisibilityStart(V: TVisibility;
Strings: TStrings);
begin
Inherited;
If (V=vPublic) then
begin
if (caOverrideSave in TiOPFOptions.ClassOptions) then
AddLn(Strings,'Procedure Save; override;');
If (caOverrideRead in TiOPFOptions.ClassOptions) then
AddLn(Strings,'Procedure Read; override;');
If (caOverrideReadThis in TiOPFOptions.ClassOptions) then
AddLn(Strings,'Procedure ReadThis; override;');
end;
end;
procedure TTiOPFCodeGenerator.CreateImplementation(Strings: TStrings);
begin
inherited CreateImplementation(Strings);
if (caOverrideSave in TiOPFOptions.ClassOptions) then
WriteReadWriteOverride(Strings,'Save','Save');
If (caOverrideRead in TiOPFOptions.ClassOptions) then
WriteReadWriteOverride(Strings,'Read','Read');
If (caOverrideReadThis in TiOPFOptions.ClassOptions) then
WriteReadWriteOverride(Strings,'ReadThis','Read');
end;
procedure TTiOPFCodeGenerator.WriteReadWriteOverride(Strings : TStrings; Const AAMethod,AVisitorGroup : String);
Const
SExecVisitor = 'GTIOPFManager.VisitorManager.Execute(''%s_%s'',Self);';
Var
OCN,S: String;
begin
OCN:=TiOPFOptions.ObjectClassName;
S:=Format('Procedure %s.%s;',[OCN,AAMethod]);
BeginMethod(Strings,S);
AddLn(Strings,'begin');
IncIndent;
S:=Format(SExecVisitor,[OCN,AVisitorGroup]);
AddLn(Strings,S);
DecIndent;
EndMethod(Strings,S);
end;
{ ---------------------------------------------------------------------
Visitor helper routines
---------------------------------------------------------------------}
procedure TTiOPFCodeGenerator.WriteVisitorImplementation(Strings : TStrings; V : TVisitorOption; Const ObjectClassName : String);
begin
Case V of
voRead : WriteReadVisitor(Strings,ObjectClassName);
voReadList : WriteReadListVisitor(Strings,ObjectClassName);
voCreate : WriteCreateVisitor(Strings,ObjectClassName);
voDelete : WriteDeleteVisitor(Strings,ObjectClassName);
voUpdate : WriteUpdateVisitor(Strings,ObjectClassName);
voCommonSetupParams : WriteCommonSetupVisitor(Strings,ObjectClassName);
voSingleSaveVisitor : WriteSaveVisitor(Strings,ObjectClassName);
end;
If v in TiOPFOptions.FinalVisitors then
WriteTerminateVisitor(Strings,V,ObjectClassName);
end;
Function TTiOPFCodeGenerator.BeginInit(Strings : TStrings; const AClass : String) : String;
begin
Result:=Format('Procedure %s.Init;',[AClass]);
BeginMethod(Strings,Result);
AddLn(Strings,'begin');
IncIndent;
end;
Function TTiOPFCodeGenerator.BeginAcceptVisitor(Strings : TStrings; Const AClass, ObjectClassName: String) : String;
begin
Result:=Format('Function %s.AcceptVisitor : Boolean;',[AClass]);
BeginMethod(Strings,Result);
AddLn(Strings,'begin');
IncIndent;
AddLn(Strings,'Result:=Visited is %s;',[ObjectClassName]);
end;
Function TTiOPFCodeGenerator.BeginSetupParams(Strings : TStrings; const AClass,ObjectClassName : String; DeclareObject : Boolean) : String;
begin
Result:=Format('Procedure %s.SetupParams;',[AClass]);
BeginMethod(Strings,Result);
If DeclareObject Then
DeclareObjectVariable(Strings,ObjectClassName);
AddLn(Strings,'begin');
IncIndent;
If DeclareObject Then
Addln(Strings,'O:=%s(Visited);',[ObjectClassName]);
end;
Procedure TTiOPFCodeGenerator.DeclareObjectvariable(Strings : TStrings; Const ObjectClassName : String);
begin
AddLn(Strings,'var');
IncIndent;
try
AddLn(Strings,'O : %s;',[ObjectClassName]);
AddLn(Strings);
finally
DecIndent;
end;
end;
Function TTiOPFCodeGenerator.BeginMapRowToObject(Strings : TStrings; Const AClass,ObjectClassName : String) : String;
begin
Result:=Format('Procedure %s.MapRowToObject;',[AClass]);
BeginMethod(Strings,Result);
DeclareObjectVariable(Strings,ObjectClassName);
AddLn(Strings,'begin');
IncIndent;
end;
{ ---------------------------------------------------------------------
Visitor registration
---------------------------------------------------------------------}
procedure TTiOPFCodeGenerator.WriteRegisterVisitorLine(Strings : TStrings; Const V: TVisitorOption; Const ObjectClassName : String);
Var
C : String;
S : String;
begin
C:=VisitorClassName(v,ObjectClassName);
Case V of
voRead : S:='Read';
voReadList : S:='ReadList';
voCreate : S:='Save';
voDelete : S:='Save';
voUpdate : S:='Save';
end;
S:=ObjectClassName+'_'+S;
S:=Format('GTIOPFManager.RegisterVisitor(''%s'',%s);',[S,C]);
AddLn(Strings,S);
end;
procedure TTiOPFCodeGenerator.WriteVisitorRegistration(Strings : TStrings; Const ObjectClassName : String);
Const
RealVis = [voRead,voReadList,voCreate,voDelete,voUpdate];
Var
v : TVisitorOption;
S : String;
begin
Addln(Strings);
S:='Procedure Register'+ObjectClassName+'Visitors;';
BeginMethod(Strings,S);
AddLn(Strings,'begin');
IncIndent;
For v:=Low(TVisitorOption) to High(TVisitorOption) do
begin
If (V in RealVis) and (V in TiOPFOptions.VisitorOptions) then
WriteRegisterVisitorLine(Strings,V,ObjectClassName);
end;
DecIndent;
EndMethod(Strings,S);
end;
{ ---------------------------------------------------------------------
Read Visitor
---------------------------------------------------------------------}
procedure TTiOPFCodeGenerator.WriteReadVisitor(Strings : TStrings; Const ObjectClassName : String);
Var
OCN,CS,C,S : String;
I : Integer;
F : TFieldPropDef;
begin
OCN:=StripType(ObjectClassName);
CS:=Format('SQLRead%s',[OCN]);
C:=VisitorClassName(voRead,OCN);
Addln(Strings,'{ %s }',[C]);
Addln(Strings);
// Init
S:=BeginInit(Strings,C);
WriteSetSQL(Strings,CS);
DecIndent;
EndMethod(Strings,S);
// AcceptVisitor
S:=BeginAcceptVisitor(Strings,C,ObjectClassName);
DecIndent;
EndMethod(Strings,S);
// AcceptSetupParams
F:=Fields.FindPropName('OID');
S:=BeginSetupParams(Strings,C,ObjectClassName,F<>Nil);
If (F<>Nil) then
WriteAssignToParam(Strings,F)
else
AddLn(Strings,'// Set up as needed');
DecIndent;
EndMethod(Strings,S);
// MapRowToObject
S:=BeginMapRowToObject(Strings,C,ObjectClassName);
Addln(Strings,'O:=%s(Visited);',[ObjectClassName]);
Addln(Strings,'With Query do',[ObjectClassName]);
IncINdent;
try
Addln(Strings,'begin');
For I:=0 to Fields.Count-1 do
If Fields[i].Enabled then
WriteFieldAssign(Strings,Fields[i]);
Addln(Strings,'end;');
finally
DecIndent;
end;
DecIndent;
EndMethod(Strings,S);
end;
procedure TTiOPFCodeGenerator.WriteFieldAssign(Strings : TStrings; F : TFieldPropDef);
Var
PN,FN,SFN,R,S : String;
begin
PN:=F.PropertyName;
FN:=F.FieldName;
SFN:=CreateString(FN);
If (PN=SOID) then
R:=Format('O.OID.AssignFromTIQuery(''%s'',Query);',[FN])
else
Case F.PropertyType of
ptBoolean :
S:='AsBoolean';
ptShortint, ptByte,
ptSmallInt, ptWord,
ptLongint, ptCardinal,
ptInt64:
S:='AsInteger';
ptShortString, ptAnsiString, ptWideString :
S:='AsString';
ptSingle, ptDouble, ptExtended, ptComp :
S:='AsFloat';
ptCurrency :
S:='AsFloat';
ptDateTime :
S:='AsDateTime';
ptEnumerated :
R:=Format('Integer(O.%s):=FieldAsInteger[%s];',[PN,SFN]);
ptSet :
S:=Format('// Add custom set loading code here for %s from %s',[PN,FN]);
ptStream :
R:=Format('AssignFieldAsStream(%s,O.%s);',[SFN,PN]);
ptTStrings :
R:=Format('O.%s.Text:=FieldAsString[%s];',[PN,SFN]);
ptCustom :
R:=Format('// Add custom loading code here for %s from %s',[PN,FN]);
end;
If (S<>'') then
R:=Format('O.%s:=Field%s[%s];',[PN,S,SFN]);
AddLn(Strings,R);
end;
procedure TTiOPFCodeGenerator.WriteAssignToParam(Strings : TStrings; F : TFieldPropDef);
Var
PN,FN,SFN,R,S : String;
begin
PN:=F.PropertyName;
FN:=F.FieldName;
SFN:=CreateString(FN);
If (PN=SOID) then
R:=Format('O.OID.AssignToTIQuery(''%s'',Query);',[FN])
else
Case F.PropertyType of
ptBoolean :
S:='AsBoolean';
ptShortint, ptByte,
ptSmallInt, ptWord,
ptLongint, ptCardinal,
ptInt64, ptQWord :
S:='AsInteger';
ptShortString, ptAnsiString, ptWideString :
S:='AsString';
ptSingle, ptDouble, ptExtended, ptComp :
S:='AsFloat';
ptCurrency :
S:='AsCurrency';
ptDateTime :
S:='AsDateTime';
ptEnumerated :
R:=Format('ParamAsInteger[%s]:=Integer(O.%s);',[SFN,PN]);
ptSet :
S:=Format('// Add custom set loading code here for %s from %s',[PN,FN]);
ptStream :
R:=Format('AssignParamFromStream(%s,O.%s);',[SFN,PN]);
ptTStrings :
R:=Format('ParamAsString[%s]:=O.%s.Text;',[SFN,PN]);
ptCustom :
R:=Format('// Add custom loading code here for %s from %s',[PN,FN]);
end;
If (S<>'') then
R:=Format('Param%s[%s]:=O.%s;',[S,SFN,PN]);
AddLn(Strings,R);
end;
{ ---------------------------------------------------------------------
List Read Visitor
---------------------------------------------------------------------}
procedure TTiOPFCodeGenerator.WriteReadListVisitor(Strings : TStrings; Const ObjectClassName : String);
Var
OCN,CS,C,S,LN : String;
I : Integer;
begin
LN:=tiOPFOptions.ListClassName;
OCN:=StripType(ObjectClassName);
CS:=Format('SQLReadList%s',[OCN]);
C:=VisitorClassName(voReadList,OCN);
Addln(Strings,'{ %s }',[C]);
Addln(Strings);
// Init
S:=BeginInit(Strings,C);
WriteSetSQL(Strings,CS);
DecIndent;
EndMethod(Strings,C);
// AcceptVisitor
S:=BeginAcceptVisitor(Strings,C,LN);
DecIndent;
EndMethod(Strings,S);
// AcceptSetupParams
S:=BeginSetupParams(Strings,C,'',False);
DecIndent;
EndMethod(Strings,S);
// MapRowToObject
S:=BeginMapRowToObject(Strings,C,ObjectClassName);
Addln(Strings,'O:=%s.Create;',[ObjectClassName]);
Addln(Strings,'With Query do',[ObjectClassName]);
IncINdent;
try
Addln(Strings,'begin');
For I:=0 to Fields.Count-1 do
If Fields[i].Enabled then
WriteFieldAssign(Strings,Fields[i]);
Addln(Strings,'end;');
finally
DecIndent;
end;
Addln(Strings,'O.ObjectState:=posClean;');
Addln(Strings,'%s(Visited).Add(O);',[LN]);
DecIndent;
EndMethod(Strings,S);
end;
{ ---------------------------------------------------------------------
Create Visitor
---------------------------------------------------------------------}
procedure TTiOPFCodeGenerator.WriteCreateVisitor(Strings : TStrings; Const ObjectClassName : String);
Var
OCN,CS,C,S : String;
I : Integer;
begin
OCN:=StripType(ObjectClassName);
CS:=Format('SQLCreate%s',[OCN]);
C:=VisitorClassName(voCreate,OCN);
Addln(Strings,'{ %s }',[C]);
Addln(Strings);
// Init
S:=BeginInit(Strings,C);
WriteSetSQL(Strings,CS);
DecIndent;
EndMethod(Strings,S);
// AcceptVisitor
S:=BeginAcceptVisitor(Strings,C,ObjectClassName);
AddLn(Strings,'Result:=Result and (Visited.ObjectState=posCreate);');
DecIndent;
EndMethod(Strings,S);
If Not (UseCommonSetupParams) then
WriteSetupParams(Strings,C,ObjectClassName);
end;
procedure TTiOPFCodeGenerator.WriteSetupParams(Strings : TStrings; Const AClassName,ObjectClassName : String);
Var
S : String;
I : Integer;
begin
// SetupParams
S:=BeginSetupParams(Strings,AClassName,ObjectClassName,True);
Addln(Strings,'With Query do',[ObjectClassName]);
IncINdent;
try
Addln(Strings,'begin');
For I:=0 to Fields.Count-1 do
If Fields[i].Enabled then
WriteAssignToParam(Strings,Fields[i]);
Addln(Strings,'end;');
finally
DecIndent;
end;
DecIndent;
EndMethod(Strings,S);
end;
procedure TTiOPFCodeGenerator.WriteSetSQL(Strings : TStrings; Const ASQL : String);
begin
Addln(Strings,Format('Query.SQLText:=%s;',[ASQL]));
end;
procedure TTiOPFCodeGenerator.WriteDeleteVisitor(Strings : TStrings; Const ObjectClassName : String);
Var
OCN,CS, C,S : String;
F : TFieldPropDef;
begin
OCN:=StripType(ObjectClassName);
CS:=Format('SQLDelete%s',[OCN]);
C:=VisitorClassName(voDelete,OCN);
Addln(Strings,'{ %s }',[C]);
// Init
S:=BeginInit(Strings,C);
WriteSetSQL(Strings,CS);
DecIndent;
EndMethod(Strings,S);
// AcceptVisitor
S:=BeginAcceptVisitor(Strings,C,ObjectClassName);
AddLn(Strings,'Result:=Result and (Visited.ObjectState=posDelete);');
DecIndent;
EndMethod(Strings,S);
// SetupParams
S:=BeginSetupParams(Strings,C,ObjectClassName,True);
F:=Fields.FindPropName('OID');
If (F<>Nil) then
WriteAssignToParam(Strings,F)
else
AddLn(Strings,'// Add parameter setup code here ');
DecIndent;
EndMethod(Strings,S);
end;
procedure TTiOPFCodeGenerator.WriteUpdateVisitor(Strings : TStrings; Const ObjectClassName : String);
Var
OCN,CS,C,S : String;
I : Integer;
begin
OCN:=StripType(ObjectClassName);
CS:=Format('SQLUpdate%s',[OCN]);
C:=VisitorClassName(voUpdate,OCN);
Addln(Strings,'{ %s }',[C]);
Addln(Strings);
// Init
S:=BeginInit(Strings,C);
WriteSetSQl(Strings,CS);
DecIndent;
EndMethod(Strings,S);
// AcceptVisitor
S:=BeginAcceptVisitor(Strings,C,ObjectClassName);
AddLn(Strings,'Result:=Result and (Visited.ObjectState=posUpdate);');
DecIndent;
EndMethod(Strings,S);
If Not (UseCommonSetupParams) then
WriteSetupParams(Strings,C,ObjectClassName);
end;
{ ---------------------------------------------------------------------
List object commands
---------------------------------------------------------------------}
procedure TTiOPFCodeGenerator.DoCreateListDeclaration(Strings: TStrings;
const ObjectClassName, ListClassName, ListAncestorName: String);
begin
If caListItemsProperty in tiOPFOptions.ClassOptions then
begin
AddLn(Strings,'Private');
IncIndent;
Try
AddLn(Strings,'Function GetObj(AIndex : Integer) : %s;',[ObjectClassname]);
AddLn(Strings,'Procedure SetObj(AIndex : Integer; AValue : %s);',[ObjectClassname]);
Finally
DecIndent;
end;
end;
If (caListAddMethod in tiOPFOptions.ClassOptions) then
begin
AddLn(Strings,'Public');
IncIndent;
Try
Addln(Strings,'Function Add(AnItem : %s) : Integer; reintroduce;',[ObjectClassName]);
Finally
DecIndent;
end;
end;
If (caListItemsProperty in tiOPFOptions.ClassOptions) then
begin
If Not (caListAddMethod in tiOPFOptions.ClassOptions) then
AddLn(Strings,'Public');
IncIndent;
Try
AddLn(Strings,'Property Items[AIndex : Integer] : %s Read GetObj Write SetObj; Default;',[ObjectClassname]);
Finally
DecIndent;
end;
end;
end;
procedure TTiOPFCodeGenerator.CreateListDeclaration(Strings: TStrings;
const ObjectClassName, ListClassName, ListAncestorName: String);
begin
Addln(Strings);
Addln(Strings,'{ %s }',[ListClassName]);
Addln(Strings);
Addln(Strings,'%s = Class(%s)',[ListClassName,ListAncestorName]);
DoCreateListDeclaration(Strings,ObjectClassName,ListClassName,ListAncestorName);
AddLn(Strings,'end;');
Addln(Strings);
end;
procedure TTiOPFCodeGenerator.WriteListAddObject(Strings: TStrings;
const ListClassName, ObjectClassName: String);
Var
S : String;
begin
S:=Format('Function %s.Add(AnItem : %s) : Integer;',[ListClassName,ObjectClassName]);
BeginMethod(Strings,S);
Addln(Strings,'begin');
IncIndent;
try
Addln(Strings,'Result:=inherited Add(AnItem);');
finally
DecIndent;
end;
EndMethod(Strings,S);
Addln(Strings);
end;
function TTiOPFCodeGenerator.CreateFieldPropDefs: TFieldPropDefs;
begin
Result:=TFieldPropDefs.Create(TTiOPFFieldPropDef);
end;
function TTiOPFCodeGenerator.AllowPropertyDeclaration(F: TFieldPropDef;
AVisibility: TVisibilities): Boolean;
begin
If F.PropertyName=SOID then
Result:=False
else
Result:=inherited AllowPropertyDeclaration(F, AVisibility);
end;
procedure TTiOPFCodeGenerator.CreateListImplementation(Strings: TStrings; const ObjectClassName, ListClassName: String);
Var
S : String;
begin
If caListItemsProperty in tiOPFOptions.ClassOptions then
begin
AddLn(Strings,'{ %s }',[ListClassName]);
AddLn(Strings);
S:=Format('Function %s.GetObj(AIndex : Integer) : %s;',[ListClassName,ObjectClassname]);
BeginMethod(Strings,S);
AddLn(Strings,'begin');
IncIndent;
try
AddLn(Strings,'Result:=%s(Inherited Items[AIndex]);',[ObjectClassname]);
finally
DecIndent;
end;
EndMethod(Strings,S);
Addln(Strings);
S:=Format('Procedure %s.SetObj(AIndex : Integer; AValue : %s);',[ListClassName,ObjectClassname]);
BeginMethod(Strings,S);
AddLn(Strings,'begin');
IncIndent;
try
AddLn(Strings,'Inherited Items[AIndex]:=AValue;');
finally
DecIndent;
end;
EndMethod(Strings,S);
Addln(Strings);
end;
If (caListAddMethod in tiOPFOptions.ClassOptions) then
WriteListAddObject(Strings,ListClassName,ObjectClassName);
end;
Initialization
RegisterCodeGenerator('tiOPF','tiOPF classes and hard-coded visitors for the data',TTiOPFCodeGenerator);
Finalization
UnRegisterCodeGenerator(TTiOPFCodeGenerator);
end.