Author: Vladimir Orlenko
Writing n-tier Application for accessing client's app to DataBase without
installing Client of Database via 3th server using Indy
Answer:
This is simple sample how organize work client's app with DataBase without
installing Database client or organize remote access to database.
1 unit Unit1;
2
3 interface
4
5 uses
6 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
7 Dialogs, StdCtrls, IdTCPServer, IdBaseComponent, IdComponent,
8 IdTCPConnection, IdTCPClient, DBClient, Provider, Grids, DBGrids, DB,
9 OracleData, Oracle, IdAntiFreezeBase, IdAntiFreeze;
10
11 type
12 TForm1 = class(TForm)
13 OracleSession1: TOracleSession;
14 OracleDataSet1: TOracleDataSet;
15 DataSource1: TDataSource;
16 DBGrid1: TDBGrid;
17 DataSetProvider1: TDataSetProvider;
18 ClientDataSet1: TClientDataSet;
19 IdTCPClient1: TIdTCPClient;
20 IdTCPServer1: TIdTCPServer;
21 Button1: TButton;
22 Memo1: TMemo;
23 IdAntiFreeze1: TIdAntiFreeze;
24 procedure Button1Click(Sender: TObject);
25 procedure IdTCPServer1Connect(AThread: TIdPeerThread);
26 procedure IdTCPServer1Execute(AThread: TIdPeerThread);
27 private
28 { Private declarations }
29 public
30 { Public declarations }
31 end;
32
33 var
34 Form1: TForm1;
35
36 implementation
37
38 {$R *.dfm}
39
40 procedure variantToStream(const v: oleVariant; stream: TStream);
41 var
42 p: pointer;
43 begin
44 stream.position := 0;
45 stream.size := varArrayHighBound(v, 1) - varArrayLowBound(v, 1) + 1;
46 p := varARrayLock(v);
47 stream.write(p^, stream.size);
48 varARrayUnlock(v);
49 stream.position := 0;
50 end;
51
52 procedure VarArrayToStream(const Data: OleVariant; Stream: TStream);
53 var
54 p: Pointer;
55 begin
56 p := VarArrayLock(Data);
57 try
58 Stream.write(p^, VarArrayHighBound(Data, 1) + 1); //assuming low bound = 0
59 finally
60 VarArrayUnlock(Data);
61 end;
62 end;
63
64 function StreamToVarArray(Stream: TStream): OleVariant;
65 var
66 p: Pointer;
67 begin
68 Result := VarArrayCreate([0, Stream.Size - 1], varByte);
69 p := VarArrayLock(Result);
70 try
71 Stream.Position := 0; //start from beginning of stream
72 Stream.read(p^, Stream.Size);
73 finally
74 VarArrayUnlock(Result);
75 end;
76 end;
77
78 procedure TForm1.Button1Click(Sender: TObject);
79 var
80 ms: TMemoryStream;
81 begin
82 ms := TMemoryStream.Create;
83 if not IdTCPClient1.Connected then
84 IdTCPClient1.Connect;
85 if IdTCPClient1.Connected then
86 Memo1.Lines.Add('connected')
87 else
88 Memo1.Lines.Add('Not Connected');
89
90 IdTCPClient1.write('open');
91 IdTCPClient1.ReadStream(ms, STrToINt(IdTCPClient1.ReadString(10)));
92 ClientDataSet1.Data := StreamToVarArray(ms);
93 // ClientDataSet1.LoadFromStream(ms);
94 ClientDataSet1.Active := True;
95 end;
96
97 procedure TForm1.IdTCPServer1Connect(AThread: TIdPeerThread);
98 begin
99 //
100 end;
101
102 procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
103 var
104 s: string;
105 ms: TMemoryStream;
106 begin
107 with AThread.Connection do
108 begin
109 s := ReadString(4);
110 if s = 'open' then
111 begin
112 ms := TMemoryStream.Create;
113 VarArrayToStream(DataSetProvider1.Data, ms);
114 s := IntToSTr(ms.Size);
115 while length(s) < 10 do
116 begin
117 s := '0' + s;
118 end;
119 write(s);
120 ms.Seek(0, soFromBeginning);
121
122 WriteStream(ms);
123 end;
124 end;
125 end;
126
127 end.
|