1 {*********************************************************}
3 { Zeos Database Objects }
4 { Test Case for TZURL Class }
6 {*********************************************************}
8 {@********************************************************}
9 { Copyright (c) 1999-2012 Zeos Development Group }
11 { License Agreement: }
13 { This library is distributed in the hope that it will be }
14 { useful, but WITHOUT ANY WARRANTY; without even the }
15 { implied warranty of MERCHANTABILITY or FITNESS FOR }
16 { A PARTICULAR PURPOSE. See the GNU Lesser General }
17 { Public License for more details. }
19 { The source code of the ZEOS Libraries and packages are }
20 { distributed under the Library GNU General Public }
21 { License (see the file COPYING / COPYING.ZEOS) }
22 { with the following modification: }
23 { As a special exception, the copyright holders of this }
24 { library give you permission to link this library with }
25 { independent modules to produce an executable, }
26 { regardless of the license terms of these independent }
27 { modules, and to copy and distribute the resulting }
28 { executable under terms of your choice, provided that }
29 { you also meet, for each linked independent module, }
30 { the terms and conditions of the license of that module. }
31 { An independent module is a module which is not derived }
32 { from or based on this library. If you modify this }
33 { library, you may extend this exception to your version }
34 { of the library, but you are not obligated to do so. }
35 { If you do not wish to do so, delete this exception }
36 { statement from your version. }
39 { The project web site is located on: }
40 { http://zeos.firmos.at (FORUM) }
41 { http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}
42 { svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN) }
44 { http://www.sourceforge.net/projects/zeoslib. }
47 { Zeos Development Group. }
48 {********************************************************@}
55 Classes, {$IFDEF MSEgui}mclasses,{$ENDIF}
59 TZURLStringList = Class(TStringList)
61 function GetTextStr: string; override;
62 procedure SetTextStr(const Value: string); override;
63 function GetURLText: String;
65 property URLText: String read GetURLText;
78 FProperties: TZURLStringList;
79 FOnPropertiesChange: TNotifyEvent;
80 procedure SetPrefix(const Value: string);
81 procedure SetProtocol(const Value: string);
82 procedure SetHostName(const Value: string);
83 procedure SetConnPort(const Value: Integer);
84 function GetDatabase: string;
85 procedure SetDatabase(const Value: string);
86 function GetUserName: string;
87 procedure SetUserName(const Value: string);
88 function GetPassword: string;
89 procedure SetPassword(const Value: string);
90 function GetLibLocation: String;
91 procedure SetLibLocation(const Value: String);
92 function GetURL: string;
93 procedure SetURL(const Value: string);
94 procedure DoOnPropertiesChange(Sender: TObject);
95 function GetParamAndValue(AString: String; Var Param, Value: String): Boolean;
96 procedure AddValues(Values: TStrings);
98 constructor Create; overload;
99 constructor Create(const AURL: String); overload;
100 constructor Create(const AURL: String; Info: TStrings); overload;
101 constructor Create(const AURL: TZURL); overload;
102 constructor Create(Const AURL, AHostName: string; const APort: Integer;
103 const ADatabase, AUser, APassword: string; Info: TStrings); overload;
105 destructor Destroy; override;
106 property Prefix: string read FPrefix write SetPrefix;
107 property Protocol: string read FProtocol write SetProtocol;
108 property HostName: string read FHostName write SetHostName;
109 property Port: Integer read FPort write SetConnPort;
110 property Database: string read GetDatabase write SetDatabase;
111 property UserName: string read GetUserName write SetUserName;
112 property Password: string read GetPassword write SetPassword;
113 property LibLocation: string read GetLibLocation write SetLibLocation;
114 property Properties: TZURLStringList read FProperties;
115 property URL: string read GetURL write SetURL;
117 property OnPropertiesChange: TNotifyEvent read FOnPropertiesChange write FOnPropertiesChange;
122 uses ZCompatibility, StrUtils;
125 function TZURLStringList.GetTextStr: string;
127 Result := inherited GetTextStr;
128 Result := StringReplace(Result, #9, ';', [rfReplaceAll]); //unescape the #9 char to ';'
131 procedure TZURLStringList.SetTextStr(const Value: string);
133 inherited SetTextStr(StringReplace(Value, ';', #9, [rfReplaceAll])); //escape the ';' char to #9
136 function TZURLStringList.GetURLText: String;
138 Result := StringReplace(GetTextStr, ';', #9, [rfReplaceAll]); //keep all ';' escaped
139 Result := StringReplace(Result, LineEnding, ';', [rfReplaceAll]); //return a URL-usable string
140 if Result[Length(Result)] = ';' then
141 Result := Copy(Result, 1, Length(Result)-1);
146 constructor TZURL.Create;
151 FProperties := TZURLStringList.Create;
152 FProperties.CaseSensitive := False;
153 FProperties.NameValueSeparator := '=';
154 FProperties.OnChange := DoOnPropertiesChange;
157 constructor TZURL.Create(const AURL: String);
163 constructor TZURL.Create(const AURL: String; Info: TStrings);
166 if Assigned(Info) then
170 constructor TZURL.Create(const AURL: TZURL);
175 constructor TZURL.Create(Const AURL, AHostName: string; const APort: Integer;
176 const ADatabase, AUser, APassword: string; Info: TStrings);
179 Self.HostName := AHostName;
181 Self.Database := ADataBase;
182 Self.UserName := AUser;
183 Self.Password := APassword;
184 if Assigned(Info) then
188 destructor TZURL.Destroy;
195 procedure TZURL.SetPrefix(const Value: string);
200 procedure TZURL.SetProtocol(const Value: string);
205 procedure TZURL.SetHostName(const Value: string);
207 FHostName := StringReplace(Value, ';', #9, [rfReplaceAll]); //escape the ';' char to #9
210 procedure TZURL.SetConnPort(const Value: Integer);
215 function TZURL.GetDatabase: string;
217 Result := StringReplace(FDatabase, #9, ';', [rfReplaceAll]); //unescape the #9 char to ';'
220 procedure TZURL.SetDatabase(const Value: string);
222 FDatabase := StringReplace(Value, ';', #9, [rfReplaceAll]); //escape the ';' char to #9
225 function TZURL.GetUserName: string;
227 Result := StringReplace(FUserName, #9, ';', [rfReplaceAll]); //unescape the #9 char to ';'
230 procedure TZURL.SetUserName(const Value: string);
232 FUserName := StringReplace(Value, ';', #9, [rfReplaceAll]); //escape the ';' char to #9
235 function TZURL.GetPassword: string;
237 Result := StringReplace(FPassword, #9, ';', [rfReplaceAll]); //unescape the #9 char to ';'
240 procedure TZURL.SetPassword(const Value: string);
242 FPassword := StringReplace(Value, ';', #9, [rfReplaceAll]); //escape the ';' char to #9
245 function TZURL.GetLibLocation: String;
247 Result := StringReplace(FLibLocation, #9, ';', [rfReplaceAll]); //unescape the #9 char to ';'
250 procedure TZURL.SetLibLocation(const Value: String);
252 FLibLocation := StringReplace(Value, ';', #9, [rfReplaceAll]); //escape the ';' char to #9
255 function TZURL.GetURL: string;
257 hasParamPart : boolean;
258 procedure AddParamPart(const ParamPart: String);
261 Result := Result + ';'
263 Result := Result + '?';
264 Result := Result + ParamPart;
265 hasParamPart := True;
270 hasParamPart := false;
273 Result := Result + Prefix + ':';
276 Result := Result + Protocol + ':';
278 Result := Result + '//'; //Allways set the doubleslash to avoid unix '/' path issues if host is empty
281 if HostName <> '' then
283 Result := Result + HostName;
285 Result := Result + ':' + IntToStr(Port);
289 if Database <> '' then
290 Result := Result + '/' + FDatabase;
293 if FUserName <> '' then
294 AddParamPart('username=' + FUserName);
297 if FPassword <> '' then
298 AddParamPart('password=' + FPassword);
301 if Properties.Count > 0 then
302 AddParamPart(Properties.GetURLText); //Adds the escaped string
305 if FLibLocation <> '' then
306 AddParamPart('LibLocation='+ FLibLocation);
309 procedure TZURL.SetURL(const Value: string);
318 AProperties: TStrings;
329 AProperties := TStringList.Create;
335 I := Pos(':', AValue);
337 raise Exception.Create('TZURL.SetURL - The prefix is missing');
338 APrefix := Copy(AValue, 1, I - 1);
339 Delete(AValue, 1, I);
342 I := Pos(':', AValue);
344 raise Exception.Create('TZURL.SetURL - The protocol is missing');
345 AProtocol := Copy(AValue, 1, I - 1);
346 Delete(AValue, 1, I);
349 if Pos('//', AValue) = 1 then
351 Delete(AValue, 1, 2);
352 if (Pos(':', AValue) > 0) and ((Pos(':', AValue) < Pos('/', AValue)) or (Pos('/', AValue)=0)) then
353 AHostName := Copy(AValue, 1, Pos(':', AValue) - 1)
354 else if Pos('/', AValue) > 0 then
355 AHostName := Copy(AValue, 1, Pos('/', AValue) - 1)
356 else if Pos('?', AValue) > 0 then
357 AHostName := Copy(AValue, 1, Pos('?', AValue) - 1)
361 Delete(AValue, 1, Length(AHostName));
364 if Pos(':', AValue) = 1 then
366 Delete(AValue, 1, 1);
367 if Pos('/', AValue) > 0 then
368 APort := Copy(AValue, 1, Pos('/', AValue) - 1)
369 else if Pos('?', AValue) > 0 then
370 APort := Copy(AValue, 1, Pos('?', AValue) - 1)
374 Delete(AValue, 1, Length(APort));
378 if Pos('/', AValue) = 1 then
379 Delete(AValue, 1, 1);
382 I := Pos('?', AValue);
385 ADatabase := Copy(AValue, 1, I - 1);
386 Delete(AValue, 1, I);
387 AProperties.Text := StringReplace(AValue, ';', LineEnding, [rfReplaceAll]);
393 FProtocol := AProtocol;
394 FHostName := AHostName;
395 FPort := StrToIntDef(APort, 0);
396 FDatabase := ADatabase;
397 FUserName := AUserName;
398 FPassword := APassword;
399 FProperties.Text := AProperties.Text;
405 procedure TZURL.DoOnPropertiesChange(Sender: TObject);
407 FProperties.OnChange := nil;
409 if FProperties.Values['UID'] <> '' then
411 UserName := FProperties.Values['UID'];
412 FProperties.Delete(FProperties.IndexOfName('UID'));
415 if FProperties.Values['PWD'] <> '' then
417 Password := FProperties.Values['PWD'];
418 FProperties.Delete(FProperties.IndexOfName('PWD'));
421 if FProperties.Values['username'] <> '' then
423 UserName := FProperties.Values['username'];
424 FProperties.Delete(FProperties.IndexOfName('username'));
427 if FProperties.Values['password'] <> '' then
429 Password := FProperties.Values['password'];
430 FProperties.Delete(FProperties.IndexOfName('password'));
433 if FProperties.Values['LibLocation'] <> '' then
435 LibLocation := FProperties.Values['LibLocation'];
436 FProperties.Delete(FProperties.IndexOfName('LibLocation'));
440 FProperties.OnChange := DoOnPropertiesChange;
443 if Assigned(FOnPropertiesChange) then
444 FOnPropertiesChange(Sender);
447 function TZURL.GetParamAndValue(AString: String; Var Param, Value: String): Boolean;
451 DelimPos := PosEx('=', AString);
452 Result := DelimPos <> 0;
455 if DelimPos <> 0 then
457 Param := Copy(AString, 1, DelimPos -1);
458 Value := Copy(AString, DelimPos+1, Length(AString)-DelimPos);
459 Result := Value <> ''; //avoid loosing empty but added Params. e.g TestIdentifierQuotes
463 procedure TZURL.AddValues(Values: TStrings);
466 Param, Value: String;
468 for i := 0 to Values.Count -1 do
469 if GetParamAndValue(Values[i], Param, Value) then
470 FProperties.Values[Param] := Value
472 if FProperties.IndexOf(Values[i]) = -1 then //add unique params only!
473 FProperties.Add(Values[i]);