zeoslib  UNKNOWN
 All Files
ZFunctions.pas
Go to the documentation of this file.
1 {*********************************************************}
2 { }
3 { Zeos Database Objects }
4 { Variables classes and interfaces }
5 { }
6 { Originally written by Sergey Seroukhov }
7 { }
8 {*********************************************************}
9 
10 {@********************************************************}
11 { Copyright (c) 1999-2012 Zeos Development Group }
12 { }
13 { License Agreement: }
14 { }
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. }
20 { }
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. }
39 { }
40 { }
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) }
45 { }
46 { http://www.sourceforge.net/projects/zeoslib. }
47 { }
48 { }
49 { Zeos Development Group. }
50 {********************************************************@}
51 
52 unit ZFunctions;
53 
54 interface
55 
56 {$I ZCore.inc}
57 
58 uses SysUtils, Classes, ZClasses, ZCollections, ZCompatibility, ZVariant,
59  ZExpression;
60 
61 type
62 
63  {** Implements a list of functions. }
64 
65  { TZFunctionsList }
66 
67  TZFunctionsList = class (TInterfacedObject, IZFunctionsList)
68  private
69  FFunctions: IZCollection;
70  FCapacity : Integer;
71  FKeys : Array of LongInt;
72 
73  procedure SetKeyCapacity(const NewCapacity : Integer);
74  procedure SetKey(const aKey : LongInt; const aPosition : Integer);
75  procedure RegenerateKey(const aPosition : Integer);
76  procedure RegenerateKeys;
77  protected
78  property Functions: IZCollection read FFunctions write FFunctions;
79  function FindByKeyAndName(const aKey : LongInt; const aName: string): Integer;
80  public
81  constructor Create;
82  destructor Destroy; override;
83 
84  function GetCount: Integer;
85  function GetName(Index: Integer): string;
86  function GetFunction(Index: Integer): IZFunction;
87 
88  procedure Add(Func: IZFunction);
89  procedure Remove(const Name: string);
90  function FindByName(const Name: string): Integer;
91 
92  procedure Clear;
93  end;
94 
95  {** Implements an abstract function. }
96 
97  { TZAbstractFunction }
98 
99  TZAbstractFunction = class (TInterfacedObject, IZFunction)
100  private
101  FName: string;
102  protected
103  function GetName: string;
104  function CheckParamsCount(Stack: TZExecutionStack;
105  ExpectedCount: Integer): Integer;
106  public
107  constructor Create(aName : string);
108  function Execute(Stack: TZExecutionStack;
109  VariantManager: IZVariantManager): TZVariant; virtual; abstract;
110 
111  property Name: string read GetName;
112  end;
113 
114  {** Implements a default function list. }
115  TZDefaultFunctionsList = class (TZFunctionsList)
116  public
117  constructor Create;
118  end;
119 
120 implementation
121 
122 uses ZMessages, ZFunctionsMath, ZFunctionsDateTime, ZFunctionsStrings,
123  ZFunctionsConvert, ZFunctionsOther;
124 
125 { TZFunctionsList }
126 
127 {**
128  Constructs this object.
129 }
130 constructor TZFunctionsList.Create;
131 begin
132  FFunctions := TZCollection.Create;
133  SetKeyCapacity(0);
134 end;
135 
136 {**
137  Destroys this object and cleanup the memory.
138 }
139 destructor TZFunctionsList.Destroy;
140 begin
141  SetKeyCapacity(0);
142  FFunctions := nil;
143  inherited Destroy;
144 end;
145 
146 {**
147  Sets the capacity of the internal Keystorage.
148 }
149 procedure TZFunctionsList.SetKeyCapacity(const NewCapacity : Integer);
150 begin
151  if NewCapacity <> FCapacity then
152  begin
153  SetLength(FKeys, NewCapacity);
154  FCapacity := NewCapacity;
155  end;
156 end;
157 
158 {**
159  Sets a key to the Keystorage
160 }
161 procedure TZFunctionsList.SetKey(const aKey : LongInt; const aPosition : Integer);
162 begin
163  if aPosition >= FCapacity then
164  SetKeyCapacity(FCapacity+16);
165  FKeys[aPosition] := aKey
166 end;
167 
168 {**
169  Regenerates a given key
170 }
171 procedure TZFunctionsList.RegenerateKey(const aPosition : Integer);
172 
173 begin
174  SetKey(Hash({$IFDEF UNICODE}AnsiString{$ENDIF}((FFunctions[aPosition] as IZFunction).Name)), aPosition);
175 end;
176 
177 {**
178  Regenerates all keys
179 }
180 procedure TZFunctionsList.RegenerateKeys;
181 
182 var
183  I : Integer;
184 
185 begin
186  SetKeyCapacity(0);
187  for I := 0 to FFunctions.Count - 1 do
188  RegenerateKey(i);
189 end;
190 
191 {**
192  Finds a function reference by its Name and Hashkey
193 }
194 function TZFunctionsList.FindByKeyAndName(const aKey : LongInt; const aName: string): Integer;
195 
196 var
197  I: Integer;
198 
199 begin
200  Result := -1;
201  for I := 0 to FFunctions.Count - 1 do
202  begin
203  if aKey = FKeys[i] then
204  begin
205  if aName = (FFunctions[I] as IZFunction).Name then
206  begin
207  Result := I;
208  Break;
209  end;
210  end;
211  end;
212 end;
213 
214 {**
215  Finds a function reference
216 }
217 function TZFunctionsList.FindByName(const Name: string): Integer;
218 var
219  aName: string;
220 
221 begin
222  aName := Uppercase(Name);
223  Result := FindByKeyAndName(Hash({$IFDEF UNICODE}AnsiString{$ENDIF}(aName)), aName);
224 end;
225 
226 {**
227  Adds a new function to this list.
228  @param Func a function reference.
229 }
230 procedure TZFunctionsList.Add(Func: IZFunction);
231 var
232  Index: Integer;
233  aKey : LongInt;
234  aName: string;
235 
236 begin
237  aName := Uppercase(Func.Name);
238  aKey := Hash({$IFDEF UNICODE}AnsiString{$ENDIF}(aName));
239  Index := FindByKeyAndName(aKey, aName);
240  if Index < 0 then
241  begin
242  FFunctions.Add(Func);
243  SetKey(aKey, FFunctions.Count-1);
244  end
245  else
246  raise TZExpressionError.Create('Function '+Func.Name+' already defined!');
247 end;
248 
249 {**
250  Removes a reference to a function by it's name.
251  @param Name a name of the function to be removed.
252 }
253 procedure TZFunctionsList.Remove(const Name: string);
254 var
255  Index: Integer;
256 begin
257  Index := FindByName(Name);
258  if Index >= 0 then
259  begin
260  FFunctions.Delete(Index);
261  RegenerateKeys;
262  end;
263 end;
264 
265 {**
266  Cleans the list of registered functions.
267 }
268 procedure TZFunctionsList.Clear;
269 begin
270  FFunctions.Clear;
271  SetKeyCapacity(0);
272 end;
273 
274 {**
275  Gets a number of registered functions.
276  @returns a number of registered functions.
277 }
278 function TZFunctionsList.GetCount: Integer;
279 begin
280  Result := FFunctions.Count;
281 end;
282 
283 {**
284  Gets a function reference by it's index.
285  @param Index a function index.
286  @returns a function reference.
287 }
288 function TZFunctionsList.GetFunction(Index: Integer): IZFunction;
289 begin
290  Result := FFunctions[Index] as IZFunction;
291 end;
292 
293 {**
294  Gets a name of the functions by it's index.
295  @param Index a functon index.
296  @returns a name of the function.
297 }
298 function TZFunctionsList.GetName(Index: Integer): string;
299 begin
300  Result := (FFunctions[Index] as IZFunction).Name;
301 end;
302 
303 { TZDefaultFunctionsList }
304 
305 {**
306  Constructs a default functions list and adds all available
307  standard functions.
308 }
309 constructor TZDefaultFunctionsList.Create;
310 begin
311  inherited Create;
312  AddMathFunctions(Self);
313  AddStringFunctions(Self);
314  AddConvertFunctions(Self);
315  AddOtherFunctions(Self);
316  AddDateTimeFunctions(Self);
317 end;
318 
319 { TZAbstractFunction }
320 
321 {**
322  Creates the function with a user defined name.
323 }
324 constructor TZAbstractFunction.Create(aName : string);
325 begin
326  inherited Create;
327  FName := UpperCase(aName);
328 end;
329 
330 {**
331  Gets the assigned function name.
332  @returns the assigned function name.
333 }
334 function TZAbstractFunction.GetName: string;
335 begin
336  Result := FName;
337 end;
338 
339 {**
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.
344 }
345 function TZAbstractFunction.CheckParamsCount(Stack: TZExecutionStack;
346  ExpectedCount: Integer): Integer;
347 begin
348  Result := DefVarManager.GetAsInteger(Stack.GetParameter(0));
349  if Result <> ExpectedCount then
350  begin
351  raise TZExpressionError.Create(Format(SParametersError,
352  [ExpectedCount, Result]));
353  end;
354 end;
355 
356 end.
357