1 {*********************************************************}
3 { Zeos Database Objects }
4 { Variables classes and interfaces }
6 { Originally written by Sergey Seroukhov }
8 {*********************************************************}
10 {@********************************************************}
11 { Copyright (c) 1999-2012 Zeos Development Group }
13 { License Agreement: }
15 { This library is distributed in the hope that it will be }
16 { useful, but WITHOUT ANY WARRANTY; without even the }
17 { implied warranty of MERCHANTABILITY or FITNESS FOR }
18 { A PARTICULAR PURPOSE. See the GNU Lesser General }
19 { Public License for more details. }
21 { The source code of the ZEOS Libraries and packages are }
22 { distributed under the Library GNU General Public }
23 { License (see the file COPYING / COPYING.ZEOS) }
24 { with the following modification: }
25 { As a special exception, the copyright holders of this }
26 { library give you permission to link this library with }
27 { independent modules to produce an executable, }
28 { regardless of the license terms of these independent }
29 { modules, and to copy and distribute the resulting }
30 { executable under terms of your choice, provided that }
31 { you also meet, for each linked independent module, }
32 { the terms and conditions of the license of that module. }
33 { An independent module is a module which is not derived }
34 { from or based on this library. If you modify this }
35 { library, you may extend this exception to your version }
36 { of the library, but you are not obligated to do so. }
37 { If you do not wish to do so, delete this exception }
38 { statement from your version. }
41 { The project web site is located on: }
42 { http://zeos.firmos.at (FORUM) }
43 { http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}
44 { svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN) }
46 { http://www.sourceforge.net/projects/zeoslib. }
49 { Zeos Development Group. }
50 {********************************************************@}
58 uses SysUtils, Classes, ZClasses, ZCollections, ZCompatibility, ZVariant,
63 {** Implements a list of functions. }
67 TZFunctionsList = class (TInterfacedObject, IZFunctionsList)
69 FFunctions: IZCollection;
71 FKeys : Array of LongInt;
73 procedure SetKeyCapacity(const NewCapacity : Integer);
74 procedure SetKey(const aKey : LongInt; const aPosition : Integer);
75 procedure RegenerateKey(const aPosition : Integer);
76 procedure RegenerateKeys;
78 property Functions: IZCollection read FFunctions write FFunctions;
79 function FindByKeyAndName(const aKey : LongInt; const aName: string): Integer;
82 destructor Destroy; override;
84 function GetCount: Integer;
85 function GetName(Index: Integer): string;
86 function GetFunction(Index: Integer): IZFunction;
88 procedure Add(Func: IZFunction);
89 procedure Remove(const Name: string);
90 function FindByName(const Name: string): Integer;
95 {** Implements an abstract function. }
97 { TZAbstractFunction }
99 TZAbstractFunction = class (TInterfacedObject, IZFunction)
103 function GetName: string;
104 function CheckParamsCount(Stack: TZExecutionStack;
105 ExpectedCount: Integer): Integer;
107 constructor Create(aName : string);
108 function Execute(Stack: TZExecutionStack;
109 VariantManager: IZVariantManager): TZVariant; virtual; abstract;
111 property Name: string read GetName;
114 {** Implements a default function list. }
115 TZDefaultFunctionsList = class (TZFunctionsList)
122 uses ZMessages, ZFunctionsMath, ZFunctionsDateTime, ZFunctionsStrings,
123 ZFunctionsConvert, ZFunctionsOther;
128 Constructs this object.
130 constructor TZFunctionsList.Create;
132 FFunctions := TZCollection.Create;
137 Destroys this object and cleanup the memory.
139 destructor TZFunctionsList.Destroy;
147 Sets the capacity of the internal Keystorage.
149 procedure TZFunctionsList.SetKeyCapacity(const NewCapacity : Integer);
151 if NewCapacity <> FCapacity then
153 SetLength(FKeys, NewCapacity);
154 FCapacity := NewCapacity;
159 Sets a key to the Keystorage
161 procedure TZFunctionsList.SetKey(const aKey : LongInt; const aPosition : Integer);
163 if aPosition >= FCapacity then
164 SetKeyCapacity(FCapacity+16);
165 FKeys[aPosition] := aKey
169 Regenerates a given key
171 procedure TZFunctionsList.RegenerateKey(const aPosition : Integer);
174 SetKey(Hash({$IFDEF UNICODE}AnsiString{$ENDIF}((FFunctions[aPosition] as IZFunction).Name)), aPosition);
180 procedure TZFunctionsList.RegenerateKeys;
187 for I := 0 to FFunctions.Count - 1 do
192 Finds a function reference by its Name and Hashkey
194 function TZFunctionsList.FindByKeyAndName(const aKey : LongInt; const aName: string): Integer;
201 for I := 0 to FFunctions.Count - 1 do
203 if aKey = FKeys[i] then
205 if aName = (FFunctions[I] as IZFunction).Name then
215 Finds a function reference
217 function TZFunctionsList.FindByName(const Name: string): Integer;
222 aName := Uppercase(Name);
223 Result := FindByKeyAndName(Hash({$IFDEF UNICODE}AnsiString{$ENDIF}(aName)), aName);
227 Adds a new function to this list.
228 @param Func a function reference.
230 procedure TZFunctionsList.Add(Func: IZFunction);
237 aName := Uppercase(Func.Name);
238 aKey := Hash({$IFDEF UNICODE}AnsiString{$ENDIF}(aName));
239 Index := FindByKeyAndName(aKey, aName);
242 FFunctions.Add(Func);
243 SetKey(aKey, FFunctions.Count-1);
246 raise TZExpressionError.Create('Function '+Func.Name+' already defined!');
250 Removes a reference to a function by it's name.
251 @param Name a name of the function to be removed.
253 procedure TZFunctionsList.Remove(const Name: string);
257 Index := FindByName(Name);
260 FFunctions.Delete(Index);
266 Cleans the list of registered functions.
268 procedure TZFunctionsList.Clear;
275 Gets a number of registered functions.
276 @returns a number of registered functions.
278 function TZFunctionsList.GetCount: Integer;
280 Result := FFunctions.Count;
284 Gets a function reference by it's index.
285 @param Index a function index.
286 @returns a function reference.
288 function TZFunctionsList.GetFunction(Index: Integer): IZFunction;
290 Result := FFunctions[Index] as IZFunction;
294 Gets a name of the functions by it's index.
295 @param Index a functon index.
296 @returns a name of the function.
298 function TZFunctionsList.GetName(Index: Integer): string;
300 Result := (FFunctions[Index] as IZFunction).Name;
303 { TZDefaultFunctionsList }
306 Constructs a default functions list and adds all available
309 constructor TZDefaultFunctionsList.Create;
312 AddMathFunctions(Self);
313 AddStringFunctions(Self);
314 AddConvertFunctions(Self);
315 AddOtherFunctions(Self);
316 AddDateTimeFunctions(Self);
319 { TZAbstractFunction }
322 Creates the function with a user defined name.
324 constructor TZAbstractFunction.Create(aName : string);
327 FName := UpperCase(aName);
331 Gets the assigned function name.
332 @returns the assigned function name.
334 function TZAbstractFunction.GetName: string;
340 Checks the function parameter count number.
341 @param Stack a stack object.
342 @param ExpectedCount a number of expected parameters.
343 @returns a real number of parameters.
345 function TZAbstractFunction.CheckParamsCount(Stack: TZExecutionStack;
346 ExpectedCount: Integer): Integer;
348 Result := DefVarManager.GetAsInteger(Stack.GetParameter(0));
349 if Result <> ExpectedCount then
351 raise TZExpressionError.Create(Format(SParametersError,
352 [ExpectedCount, Result]));