📄 tiofp documentation - a worked example of using the tiopf.htm
字号:
ContactMgr_TestData.sql. Enter the SQL as shown below, then run the script, or
run each statement one at the time by selecting it and pressing F8.</P><PRE>/*****************************************************************
Create the contact manager test data
*/
insert into Person values
( 1, 'Peter', 'Hinrichsen', 'Mr.', 'P.W.', 'The founder of the tiOPF project' ) ;
insert into adrs values
( 2, 1, 'Street', '23 Victoria Pde.', 'Collingwood', 'VIC', '3066', 'Australia' ) ;
insert into adrs values
( 3, 1, 'Postal', 'PO Box 429', 'Abbotsford', 'VIC', '3067', 'Australia' ) ;
insert into EAdrs values
( 4, 1, 'EMail', 'peter_hinrichsen@techinsite.com.au' ) ;
insert into EAdrs values
( 5, 1, 'Mobile', '0418 108 353' ) ;
insert into EAdrs values
( 6, 1, 'Fax', '+61 3 9419 1682' ) ;
commit ;</PRE>
<P>Test that the data has been correctly inserted by running the following
queries in the tiSQLEditor:</P><PRE>select * from person ;
select * from adrs ;
select * from eadrs ;</PRE>
<P>The results of the third select statement are shown below:</P>
<P><IMG height=173
src="tiOFP Documentation - A worked example of using the tiOPF_files/6_AWorkedExampleOfUsingTheTIOPF_clip_image001_0008.gif"
width=410></P>
<P>Now that we have created a database, and inserted some test data we can look
at the various strategies available for mapping the database into the business
objects we created.</P>
<H2>Alternative BOM – database mapping strategies</H2>
<P>There are three strategies available for mapping objects to a relational
database:</P>
<OL>
<LI>Hard code the SQL into the application, and use the Visitor framework to
map the SQL to the objects. This is implemented by linking in the unit
Adrs_SrvHardCodeSQL.pas
<LI>Use the tiSQLManager application to maintain the SQL outside the
application. This has the advantage of decoupling the SQL from the
application, but the disadvantage of forcing you to add the tiSQLManager
tables to the database. (This will be corrected when we have an XML
persistence layer available)
<LI>Set up mappings between the objects and tables, properties and columns and
let the persistence framework generate the SQL for you. This can be
implemented by linking in Adrs_SrvAutoGenSQL.pas (This strategy is under
construction, and this example will work in most classes. There are some
problems with BLOBS, and the way the mappings are defined is a little messy)
</LI></OL>
<P>In summary, you must link in one and only one of the three unit files. The
best way of achieving this is to create a dependencies unit that will provide a
central point for determining the strategy to be used. Create a new unit called
ContactMgr_Dependencies, which looks like this:</P><PRE>Unit ContactMgr_Dependencies;
Interface
Uses
ContactMgr_BOM,
//ContactMgr_SvrHardCode
//ContactMgr_SvrSQLMgr
ContactMgr_SvrAutoMap
;
Implementation
End.</PRE>
<P>As you can see, the above example is using the auto-map option, but switching
options is as simple as un-commenting the relevant unit (assuming you have
created these units in the first place!). You now need to add this to the
project source. Select Project...View Source and modify the source so it looks
like the listing below:</P><PRE>Program ContactMgr;
Uses
tiLog,
tiPersist,
Forms,
FMain In 'FMain.pas' {frmMain},
ContactMgr_BOM In 'ContactMgr_BOM.pas',
ContactMgr_Cli In 'ContactMgr_Cli.pas',
ContactMgr_Tst In 'ContactMgr_Tst.pas',
FContactMgr_Person In ' FContactMgr_Person.pas' {TFormContactMgr_Person},
ContactMgr_Dependencies In 'ContactMgr_Dependencies.pas';
{$R *.RES}
Begin
SetupLogForClient;
Application.Initialize;
gTIPerMgr.LoadPersistenceFramework;
Application.CreateForm(TfrmMain, frmMain);
Application.Run;
gTIPerMgr.UnLoadPersistenceFramework;
End.</PRE>
<H2>Hard code the SQL</H2>
<P>Create a new unit called ContactMgr_SvrHardCode.pas</P>
<P>Add tiPtnVisSQL to the visitor and type the interface as shown below:</P>
<P>Hit Ctrl+Shift+C to fill in the implementation</P>
<P>Add ContactMgr_BOM, tiPersist and tiPtnVisPerObj to the implementation uses
clause.</P><PRE>unit ContactMgr_SvrHardCode;
interface
uses
tiPtnVisSQL
;
type
TVisPeopleReadHardCode = class( TVisOwnedQrySelect )
protected
function AcceptVisitor : boolean ; override ;
procedure Init ; override ;
procedure SetupParams ; override ;
procedure MapRowToObject ; override ;
end ;
implementation
uses
ContactMgr_BOM
,tiPersist
,tiPtnVisPerObj
;</PRE>
<P>In the implementation of AcceptVisitor, type result := Visited is TPerson</P><PRE>{ TVisPeopleReadHardCode }
function TVisPeopleReadHardCode.AcceptVisitor: boolean;
begin
result := ( Visited is TPeople ) ;
end;</PRE>
<P>In the implementation of Init, enter the SQL to select all the people. This
can be simplified by entering SELECT * FROM PEOPLE in the tiSQLEditor and
executing the query. There is then an option to copy the SQL to the clipboard
with the delimeters and line breaks added. The result is shown below:</P><PRE>procedure TVisPeopleReadHardCode.Init;
begin
Query.SQL.Text :=
'select ' +
' OID ' +
' ,FIRST_NAME ' +
' ,LAST_NAME ' +
' ,TITLE ' +
' ,INITIALS ' +
' ,NOTES ' +
'from ' +
' person ' ;
end;</PRE>
<P>Enter the MapRowToObject implementation as shown below. This is made easier
by executing the SELECT SQL, then using the SQL | MapRowToObject to copy the
necessary code to the clipboard and pasting it into Delphi. The code looks like
this as it is copied to the clipboard.</P><PRE>procedure TVisEAdrsReadHardCode.MapRowToObject;
var
lData : T<Class type> ;
begin
lData := T<Class type>.Create ;
lData.Oid.AssignFromTiQuery(Query);
lData.FirstName := Query.FieldAsString[ 'FIRST_NAME' ] ;
lData.LastName := Query.FieldAsString[ 'LAST_NAME' ] ;
lData.Title := Query.FieldAsString[ 'TITLE' ] ;
lData.Initials := Query.FieldAsString[ 'INITIALS' ] ;
lData.Notes := Query.FieldAsString[ 'NOTES' ] ;
lData.ObjectState := posClean ;
TPerVisList( Visited ).Add( lData ) ;
end;</PRE>
<P>All you have to do is replace the T<Class type> place holders with
TPerson and the result looks like this:</P><PRE>procedure TVisPeopleReadHardCode.MapRowToObject;
var
lData : TPerson ;
begin
lData := TPerson.Create ;
lData.Oid.AssignFromTiQuery(Query);
lData.FirstName := Query.FieldAsString[ 'FIRST_NAME' ] ;
lData.LastName := Query.FieldAsString[ 'LAST_NAME' ] ;
lData.Title := Query.FieldAsString[ 'TITLE' ] ;
lData.Initials := Query.FieldAsString[ 'INITIALS' ] ;
lData.Notes := Query.FieldAsString[ 'NOTES' ] ;
lData.ObjectState := posClean ;
TPerVisList( Visited ).Add( lData ) ;
end;</PRE>
<P>SetupParams has no code in the implementation:</P><PRE>procedure TVisPeopleReadHardCode.SetupParams;
begin
// Do nothing
end;</PRE>
<P>Register the visitor with the persistence framework like this:</P><PRE>initialization
gTIPerMgr.RegReadVisitor( TVisPeopleReadHardCode ) ;
end.</PRE>
<P>The 12 Visitors that comprise the full implementation of the Contact Manager
persistence visitors, implemented by hard coding SQL can be found in
ContactMgr_SrvHardCode.pas.</P>
<P>Use the tiSQLManager</P>
<P>Create the tiSQLManager tables</P><PRE>create domain domain_oid as integer not null ;
create table Next_OID ( oid domain_oid ) ;
insert into next_oid ( oid ) values ( 100000 ) ;
create domain domain_sql as blob sub_type 1 ;
create domain domain_str20 as varchar( 20 ) not null ;
create domain domain_str50 as varchar( 50 ) not null ;
create domain domain_str100 as varchar( 100 ) ;
create domain domain_integer as integer default 0 not null ;
create domain domain_boolean as char( 1 ) default 'F' check ( value in ( 'T', 'F' )) ;
/* SQLMan_Group table */
create table sqlman_group
( oid domain_oid,
group_name domain_str50,
disp_order domain_integer,
primary key ( oid )) ;
/* SQLMan_SQL table */
create table sqlman_sql
( oid domain_oid,
group_oid domain_oid,
disp_order domain_integer,
query_version domain_integer,
query_name domain_str50,
query_description domain_sql,
query_locked domain_boolean,
test_include domain_boolean,
sql domain_sql,
primary key ( oid )) ;
/* SQLMan_Param Table */
create table sqlman_param
( oid domain_oid,
sql_oid domain_oid,
disp_order domain_integer,
param_name domain_str20,
param_type domain_str20,
param_value domain_str50,
param_isnull domain_boolean,
primary key ( oid )) ;
/* SQLMan_Interface Table */
create table sqlman_interface
( oid domain_oid,
sql_oid domain_oid,
disp_order domain_integer,
field_name domain_str20,
field_type domain_str20,
primary key ( oid )) ;
/* Add ref integ */
alter table SQLMan_SQL
add foreign key ( Group_OID ) references SQLMan_Group ( OID ) ;
alter table SQLMan_Param
add foreign key ( SQL_OID ) references SQLMan_SQL ( OID ) ;
alter table SQLMan_Interface
add foreign key ( SQL_OID ) references SQLMan_SQL ( OID ) ;
/* Add unique constraint */
create unique index I_SQLMan_Group
on SQLMan_Group
( Group_Name ) ;
create unique index I_SQLMan_SQL
on SQLMan_SQL
( Query_Name ) ;
create unique index I_SQLMan_Param
on SQLMan_Param
( SQL_OID, Param_Name ) ;
create unique index I_SQLMan_Interface
on SQLMan_Interface
( SQL_OID, Field_Name ) ;
insert into sqlman_group
( oid, group_name, disp_order ) values
( 1, 'System', 0 ) ;
insert into sqlman_group values ( 2, 'Queries', 0 ) ;
commit ;</PRE>
<P>Write the tiSQLManager Visitors</P><PRE>Unit ContactMgr_SvrSQLMgr;
interface
uses
tiPtnVisSQL
;
type
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// *
// * Read visitors
// *
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
TVisPeopleReadSQLMgr = class( TVisQrySelect )
protected
function AcceptVisitor : boolean ; override ;
procedure Init ; override ;
procedure SetupParams ; override ;
procedure MapRowToObject ; override ;
end ;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// *
// * Delete visitors
// *
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
TVisPeopleDeleteSQLMgr = class( TVisQryUpdate )
protected
function AcceptVisitor : boolean ; override ;
procedure Init ; override ;
procedure SetupParams ; override ;
end ;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// *
// * Update visitors
// *
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
TVisPeopleUpdateSQLMgr = class( TVisQryUpdate )
protected
function AcceptVisitor : boolean ; override ;
procedure Init ; override ;
procedure SetupParams ; override ;
end ;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// *
// * Create visitors
// *
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
TVisPeopleCreateSQLMgr = class( TVisQryUpdate )
protected
function AcceptVisitor : boolean ; override ;
procedure Init ; override ;
procedure SetupParams ; override ;
end ;
implemen
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -