ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/public/ibx/trunk/design/IBSystemTables.pas
Revision: 21
Committed: Thu Feb 26 10:33:34 2015 UTC (9 years, 2 months ago) by tony
Content type: text/x-pascal
File size: 25574 byte(s)
Log Message:
Committing updates for Release R1-2-0

File Contents

# User Rev Content
1 tony 17 (*
2     * IBX For Lazarus (Firebird Express)
3     *
4     * The contents of this file are subject to the Initial Developer's
5     * Public License Version 1.0 (the "License"); you may not use this
6     * file except in compliance with the License. You may obtain a copy
7     * of the License here:
8     *
9     * http://www.firebirdsql.org/index.php?op=doc&id=idpl
10     *
11     * Software distributed under the License is distributed on an "AS
12     * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
13     * implied. See the License for the specific language governing rights
14     * and limitations under the License.
15     *
16     * The Initial Developer of the Original Code is Tony Whyman.
17     *
18     * The Original Code is (C) 2011 Tony Whyman, MWA Software
19     * (http://www.mwasoftware.co.uk).
20     *
21     * All Rights Reserved.
22     *
23     * Contributor(s): ______________________________________.
24     *
25     *)
26    
27     unit IBSystemTables;
28    
29     {$mode objfpc}{$H+}
30    
31     interface
32    
33     uses
34     Classes, SysUtils, IBSQL, IBDatabase, StdCtrls;
35    
36     type
37    
38     { TIBSystemTables }
39    
40     TIBSystemTables = class
41     private
42     FGetTableNames: TIBSQL;
43     FGetFieldNames: TIBSQL;
44     FGetPrimaryKeys: TIBSQL;
45     FTestSQL: TIBSQL;
46     FTableAndColumnSQL: TIBSQL;
47     FGetGeneratorsSQL: TIBSQL;
48     FGetProcedures: TIBSQL;
49     FGetProcedureParams: TIBSQL;
50     FGetProcedureInfo: TIBSQL;
51     function GetSQLType(SQLType: TIBSQLTypes): string;
52     procedure AddWhereClause(TableName: string; QuotedStrings: boolean; SQL: TStrings;
53     UseOldValues: boolean = false);
54     procedure GetProcParams(ProcName: string; ParamList: TStrings; InputParams: boolean); overload;
55     function GetWord(S: string; WordNo: integer): string;
56 tony 21 function RemoveSQLText(aMessage: string): string;
57 tony 17 public
58     constructor Create;
59     destructor Destroy; override;
60     procedure SelectDatabase(Database: TIBDatabase; Transaction: TIBTransaction);
61     procedure GetTableNames(TableNames: TStrings);
62     procedure GetFieldNames(TableName: string; FieldNames: TStrings;
63     IncludePrimaryKeys:boolean=true; IncludeReadOnlyFields: boolean = true);
64     procedure GetPrimaryKeys(TableName: string; PrimaryKeys: TStrings);
65     procedure GetTableAndColumns(SelectSQL: string; var FirstTableName: string;
66     Columns: TStrings);
67     procedure GetProcedureNames(ProcNames: TStrings; WithOutputParams: boolean=false);
68     procedure GetProcParams(ProcName: string; var ExecuteOnly: boolean;
69     InputParams, OutputParams: TStrings); overload;
70     procedure GetGenerators(GeneratorNames: TStrings);
71     procedure GenerateSelectSQL(TableName: string; QuotedStrings: boolean; FieldNames,SQL: TStrings);
72     procedure GenerateRefreshSQL(TableName: string; QuotedStrings: boolean; FieldNames,SQL: TStrings);
73     procedure GenerateInsertSQL(TableName: string; QuotedStrings: boolean; FieldNames, SQL: TStrings);
74     procedure GenerateModifySQL(TableName: string; QuotedStrings: boolean; FieldNames,SQL: TStrings);
75     procedure GenerateDeleteSQL(TableName: string; QuotedStrings: boolean; SQL: TStrings);
76     procedure GenerateExecuteSQL(ProcName: string; QuotedStrings: boolean; ExecuteOnly: boolean;
77     InputParams, OutputParams, ExecuteSQL: TStrings);
78     function GetStatementType(SQL: string; var IsStoredProcedure: boolean): TIBSQLTypes;
79     function GetFieldNames(FieldList: TListBox): TStrings;
80 tony 19 procedure TestSQL(SQL: string; GenerateParamNames: boolean = false);
81 tony 17 end;
82    
83     implementation
84    
85 tony 19 uses IB, Dialogs, IBUtils;
86 tony 17
87     { TIBSystemTables }
88    
89     const
90     sqlGETTABLES = 'Select Trim(RDB$RELATION_NAME) as TableName From RDB$RELATIONS ' +
91     'Where RDB$SYSTEM_FLAG = 0 ' +
92     'Order by 1';
93    
94     sqlGETALLFIELDS = 'Select Trim(RDB$FIELD_NAME) as ColumnName FROM RDB$RELATION_FIELDS ' +
95     'Where RDB$RELATION_NAME = :TableName ' +
96     'order by RDB$FIELD_POSITION asc ';
97    
98     sqlGETFIELDS = 'Select Trim(RF.RDB$FIELD_NAME) as ColumnName FROM RDB$RELATION_FIELDS RF ' +
99     'JOIN RDB$FIELDS B On B.RDB$FIELD_NAME = RF.RDB$FIELD_SOURCE '+
100     'Where RF.RDB$RELATION_NAME = :TableName and B.RDB$COMPUTED_SOURCE is NULL ' +
101     'order by RF.RDB$FIELD_POSITION asc ';
102    
103     sqlGETPRIMARYKEYS = 'Select Trim(S.RDB$FIELD_NAME) as ColumnName From '+
104     '(Select RDB$INDEX_NAME,RDB$FIELD_NAME FROM RDB$INDEX_SEGMENTS Order by RDB$FIELD_POSITION ASC) S ' +
105     'JOIN RDB$RELATION_CONSTRAINTS C On C.RDB$INDEX_NAME = S.RDB$INDEX_NAME ' +
106     'Where C.RDB$CONSTRAINT_TYPE = ''PRIMARY KEY'' and RDB$RELATION_NAME = :TableName';
107    
108     sqlUPDATEFIELDS = 'Select Trim(RF.RDB$FIELD_NAME) as ColumnName FROM RDB$RELATION_FIELDS RF ' +
109     'JOIN RDB$FIELDS B On B.RDB$FIELD_NAME = RF.RDB$FIELD_SOURCE '+
110     'Where RF.RDB$RELATION_NAME = :TableName and RF.RDB$FIELD_NAME not in ' +
111     '(Select RDB$FIELD_NAME FROM RDB$INDEX_SEGMENTS S JOIN RDB$RELATION_CONSTRAINTS C On C.RDB$INDEX_NAME = S.RDB$INDEX_NAME '+
112     'Where C.RDB$CONSTRAINT_TYPE = ''PRIMARY KEY'' and C.RDB$RELATION_NAME = RF.RDB$RELATION_NAME) and B.RDB$COMPUTED_SOURCE is NULL ' +
113     'order by 1 asc ';
114    
115     sqlALLUPDATEFIELDS = 'Select Trim(RDB$FIELD_NAME) as ColumnName FROM RDB$RELATION_FIELDS RF ' +
116     'Where RF.RDB$RELATION_NAME = :TableName and RDB$FIELD_NAME not in ' +
117     '(Select RDB$FIELD_NAME FROM RDB$INDEX_SEGMENTS S JOIN RDB$RELATION_CONSTRAINTS C On C.RDB$INDEX_NAME = S.RDB$INDEX_NAME '+
118     'Where C.RDB$CONSTRAINT_TYPE = ''PRIMARY KEY'' and C.RDB$RELATION_NAME = RF.RDB$RELATION_NAME)' +
119     'order by 1 asc ';
120    
121     sqlGETGENERATORNAMES = 'Select RDB$GENERATOR_NAME FROM RDB$GENERATORS '+
122     'Where RDB$SYSTEM_FLAG = 0 '+
123     'Order by 1 asc';
124    
125     sqlGETPROCEDURES = 'Select Trim(RDB$PROCEDURE_NAME) as ProcName, RDB$PROCEDURE_INPUTS, '+
126     'RDB$PROCEDURE_OUTPUTS From RDB$PROCEDURES '+
127     'Where RDB$SYSTEM_FLAG = 0 and RDB$PROCEDURE_TYPE <= :ProcType Order by 1 asc';
128    
129     sqlGETPROCPARAM = 'Select Trim(P.RDB$PARAMETER_NAME) as ParamName '+
130     'From RDB$PROCEDURE_PARAMETERS P '+
131     'JOIN RDB$FIELDS F On F.RDB$FIELD_NAME = P.RDB$FIELD_SOURCE '+
132     'Where P.RDB$SYSTEM_FLAG = 0 and P.RDB$PROCEDURE_NAME = :ProcName and P.RDB$PARAMETER_TYPE = :type '+
133     'Order by P.RDB$PARAMETER_NUMBER asc';
134    
135     sqlCheckProcedureNames = 'Select * From RDB$PROCEDURES Where Upper(Trim(RDB$PROCEDURE_NAME)) = Upper(:ProcName)';
136    
137     sqlGETPROCEDUREINFO = 'Select RDB$PROCEDURE_TYPE From RDB$PROCEDURES Where Upper(Trim(RDB$PROCEDURE_NAME)) = Upper(:ProcName)';
138    
139     function TIBSystemTables.GetSQLType(SQLType: TIBSQLTypes): string;
140     begin
141     case SQLType of
142     SQLUnknown: Result := 'Unknown';
143     SQLSelect: Result := 'Select';
144     SQLInsert: Result := 'Insert';
145     SQLUpdate: Result := 'Update';
146     SQLDelete: Result := 'Delete';
147     SQLDDL: Result := 'DDL';
148     SQLGetSegment: Result := 'GetSegment';
149     SQLPutSegment: Result := 'PutSegment';
150     SQLExecProcedure: Result := 'Execute Procedure';
151     SQLStartTransaction: Result := 'StartTransaction';
152     SQLCommit: Result := 'Commit';
153     SQLRollback: Result := 'Rollback';
154     SQLSelectForUpdate: Result := 'Select for Update';
155     SQLSetGenerator: Result := 'Set Generator';
156     end;
157     end;
158    
159     procedure TIBSystemTables.AddWhereClause(TableName: string;
160     QuotedStrings: boolean; SQL: TStrings; UseOldValues: boolean);
161     var WhereClause: string;
162     Separator: string;
163     Count: integer;
164     Prefix: string;
165     begin
166     if not assigned(FGetPrimaryKeys.Database) or not FGetPrimaryKeys.Database.Connected or
167     not assigned(FGetPrimaryKeys.Transaction) then
168     Exit;
169     Count := 0;
170     WhereClause := 'Where';
171     Separator := ' A.';
172     if UseOldValues then
173     Prefix := ':OLD_'
174     else
175     Prefix := ':';
176     FGetPrimaryKeys.Prepare;
177     FGetPrimaryKeys.ParamByName('TableName').AsString := TableName;
178     FGetPrimaryKeys.ExecQuery;
179     try
180     while not FGetPrimaryKeys.EOF do
181     begin
182     Inc(Count);
183     if QuotedStrings then
184     WhereClause := WhereClause + Separator + '"' + FGetPrimaryKeys.FieldByName('ColumnName').AsString +
185 tony 19 '" = ' + Prefix+ AnsiUpperCase(FGetPrimaryKeys.FieldByName('ColumnName').AsString)
186 tony 17 else
187 tony 19 WhereClause := WhereClause + Separator + QuoteIdentifierIfNeeded(FGetFieldNames.Database.SQLDialect,FGetPrimaryKeys.FieldByName('ColumnName').AsString) +
188     ' = ' + Prefix + AnsiUpperCase(FGetPrimaryKeys.FieldByName('ColumnName').AsString);
189 tony 17 Separator := ' AND A.';
190     FGetPrimaryKeys.Next
191     end;
192     finally
193     FGetPrimaryKeys.Close
194     end;
195     if Count > 0 then
196     SQL.Add(WhereClause)
197     end;
198    
199     procedure TIBSystemTables.GetProcParams(ProcName: string; ParamList: TStrings;
200     InputParams: boolean);
201     begin
202     if not assigned(FGetProcedureParams.Database) or not FGetProcedureParams.Database.Connected or
203     not assigned(FGetProcedureParams.Transaction) then
204     Exit;
205     ParamList.Clear;
206     with FGetProcedureParams do
207     begin
208     with Transaction do
209     if not InTransaction then StartTransaction;
210     Prepare;
211     ParamByName('ProcName').AsString := ProcName;
212     if InputParams then
213     ParamByName('type').AsInteger := 0
214     else
215     ParamByName('type').AsInteger := 1;
216     ExecQuery;
217     try
218     while not EOF do
219     begin
220     ParamList.Add(FieldByName('ParamName').AsString);
221     Next;
222     end;
223     finally
224     Close
225     end;
226     end;
227     end;
228    
229     function TIBSystemTables.GetWord(S: string; WordNo: integer): string;
230     const
231     SpaceChars = [' ',#$0a,#$0d,#$09,'('];
232     var I: integer;
233     StartIdx: integer;
234     InWhiteSpace: boolean;
235     begin
236     Result := '';
237     StartIdx := 1;
238     InWhiteSpace := true;
239     for I := 1 to Length(S) do
240     begin
241     if InWhiteSpace then
242     begin
243     if not (S[I] in SpaceChars) then
244     begin
245     StartIdx := I;
246     InWhiteSpace := false
247     end
248     end
249     else
250     begin
251     if S[I] in SpaceChars then
252     begin
253     Dec(WordNo);
254     if WordNo = 0 then
255     begin
256     Result := System.copy(S,StartIdx,I - StartIdx);
257     Exit
258     end;
259     InWhiteSpace := true
260     end
261     end
262     end;
263     end;
264    
265 tony 21 function TIBSystemTables.RemoveSQLText(aMessage: string): string;
266     var idx: integer;
267     begin
268     idx := Pos(sSQLErrorSeparator,aMessage);
269     if idx > 0 then
270     Result := system.copy(aMessage,1,idx)
271     else
272     Result := aMessage;
273     end;
274    
275 tony 17 constructor TIBSystemTables.Create;
276     begin
277     FGetTableNames := TIBSQL.Create(nil);
278     FGetFieldNames := TIBSQL.Create(nil);
279     FGetPrimaryKeys := TIBSQL.Create(nil);
280     FGetProcedures := TIBSQL.Create(nil);
281     FTestSQL := TIBSQL.Create(nil);
282     FTableAndColumnSQL := TIBSQL.Create(nil);
283 tony 19 FTableAndColumnSQL.GenerateParamNames := true; {Permissive}
284 tony 17 FGetGeneratorsSQL := TIBSQL.Create(nil);
285     FGetProcedureParams := TIBSQL.Create(nil);
286     FGetProcedureInfo := TIBSQL.Create(nil);
287     end;
288    
289     destructor TIBSystemTables.Destroy;
290     begin
291     if assigned(FGetFieldNames) then FGetFieldNames.Free;
292     if assigned(FGetTableNames) then FGetTableNames.Free;
293     if assigned(FTestSQL) then FTestSQL.Free;
294     if assigned(FGetPrimaryKeys) then FGetPrimaryKeys.Free;
295     if assigned(FTableAndColumnSQL) then FTableAndColumnSQL.Free;
296     if assigned(FGetGeneratorsSQL) then FGetGeneratorsSQL.Free;
297     if assigned(FGetProcedures) then FGetProcedures.Free;
298     if assigned(FGetProcedureParams) then FGetProcedureParams.Free;
299     if assigned(FGetProcedureInfo) then FGetProcedureInfo.Free;
300     inherited Destroy;
301     end;
302    
303     procedure TIBSystemTables.SelectDatabase(Database: TIBDatabase;
304     Transaction: TIBTransaction);
305     begin
306     FGetTableNames.Database := Database;
307     FGetTableNames.Transaction := Transaction;
308     FGetTableNames.SQL.Text := sqlGETTABLES;
309     FGetFieldNames.Database := Database;
310     FGetFieldNames.Transaction := Transaction;
311     FGetFieldNames.SQL.Text := sqlGETFIELDS;
312     FTestSQL.Database := Database;
313     FTestSQL.Transaction := Transaction;
314     FGetPrimaryKeys.Database := Database;
315     FGetPrimaryKeys.Transaction := Transaction;
316     FGetPrimaryKeys.SQL.Text := sqlGETPRIMARYKEYS;
317     FTableAndColumnSQL.Database := Database;
318     FTableAndColumnSQL.Transaction := Transaction;
319     FGetGeneratorsSQL.Database := Database;
320     FGetGeneratorsSQL.Transaction := Transaction;
321     FGetGeneratorsSQL.SQL.Text := sqlGETGENERATORNAMES;
322     FGetProcedureParams.Database := Database;
323     FGetProcedureParams.Transaction := Transaction;
324     FGetProcedureParams.SQL.Text := sqlGETPROCPARAM;
325     FGetProcedureInfo.Database := Database;
326     FGetProcedureInfo.Transaction := Transaction;
327     FGetProcedureInfo.SQL.Text := sqlGETPROCEDUREINFO;
328     FGetProcedures.Database := Database;
329     FGetProcedures.Transaction := Transaction;
330     FGetProcedures.SQL.Text := sqlGETPROCEDURES;
331     end;
332    
333     procedure TIBSystemTables.GetTableNames(TableNames: TStrings);
334     begin
335     if not assigned(FGetTableNames.Database) or not FGetTableNames.Database.Connected or
336     not assigned(FGetTableNames.Transaction) then
337     Exit;
338     with FGetTableNames.Transaction do
339     if not InTransaction then StartTransaction;
340     TableNames.Clear;
341     FGetTableNames.ExecQuery;
342     try
343     while not FGetTableNames.EOF do
344     begin
345     TableNames.Add(FGetTableNames.FieldByName('TableName').AsString);
346     FGetTableNames.Next
347     end;
348     finally
349     FGetTableNames.Close
350     end;
351     end;
352    
353     procedure TIBSystemTables.GetFieldNames(TableName: string;
354     FieldNames: TStrings; IncludePrimaryKeys: boolean;
355     IncludeReadOnlyFields: boolean);
356     begin
357     if not assigned(FGetFieldNames.Database) or not FGetFieldNames.Database.Connected or
358     not assigned(FGetFieldNames.Transaction) then
359     Exit;
360     with FGetFieldNames.Transaction do
361     if not InTransaction then StartTransaction;
362     FieldNames.Clear;
363     if IncludePrimaryKeys then
364     begin
365     if IncludeReadOnlyFields then
366     FGetFieldNames.SQL.Text := sqlGETALLFIELDS
367     else
368     FGetFieldNames.SQL.Text := sqlGETFIELDS
369     end
370     else
371     if IncludeReadOnlyFields then
372     FGetFieldNames.SQL.Text := sqlALLUPDATEFIELDS
373     else
374     FGetFieldNames.SQL.Text := sqlUPDATEFIELDS;
375     FGetFieldNames.Prepare;
376     FGetFieldNames.ParamByName('TableName').AsString := TableName;
377     FGetFieldNames.ExecQuery;
378     try
379     while not FGetFieldNames.EOF do
380     begin
381     FieldNames.Add(FGetFieldNames.FieldByName('ColumnName').AsString);
382     FGetFieldNames.Next
383     end;
384     finally
385     FGetFieldNames.Close
386     end;
387     end;
388    
389     procedure TIBSystemTables.GetPrimaryKeys(TableName: string; PrimaryKeys: TStrings);
390     begin
391     if not assigned(FGetPrimaryKeys.Database) or not FGetPrimaryKeys.Database.Connected or
392     not assigned(FGetPrimaryKeys.Transaction) then
393     Exit;
394     with FGetPrimaryKeys.Transaction do
395     if not InTransaction then StartTransaction;
396     PrimaryKeys.Clear;
397     FGetPrimaryKeys.Prepare;
398     FGetPrimaryKeys.ParamByName('TableName').AsString := TableName;
399     FGetPrimaryKeys.ExecQuery;
400     try
401     while not FGetPrimaryKeys.EOF do
402     begin
403     PrimaryKeys.Add(FGetPrimaryKeys.FieldByName('ColumnName').AsString);
404     FGetPrimaryKeys.Next
405     end;
406     finally
407     FGetPrimaryKeys.Close
408     end;
409     end;
410    
411     procedure TIBSystemTables.GetTableAndColumns(SelectSQL: string;
412     var FirstTableName: string; Columns: TStrings);
413     var I: integer;
414     begin
415     FirstTableName := '';
416     if not assigned(FTableAndColumnSQL.Database) or not FTableAndColumnSQL.Database.Connected or
417     not assigned(FTableAndColumnSQL.Transaction) or (Trim(SelectSQL) = '') then
418     Exit;
419     with FTableAndColumnSQL.Transaction do
420     if not InTransaction then StartTransaction;
421     FTableAndColumnSQL.SQL.Text := SelectSQL;
422     try
423     FTableAndColumnSQL.Prepare;
424     case FTableAndColumnSQL.SQLType of
425     SQLSelect:
426     begin
427     if FTableAndColumnSQL.Current.Count > 0 then
428     FirstTableName := strpas(FTableAndColumnSQL.Current.Vars[0].Data^.relname)
429     else
430     FirstTableName := '';
431     if assigned(Columns) then
432     begin
433     Columns.Clear;
434     for I := 0 to FTableAndColumnSQL.Current.Count - 1 do
435     Columns.Add(FTableAndColumnSQL.Current.Vars[I].Name)
436     end;
437     end;
438     { If not a select statement then return table or procedure name
439     as First Table Name }
440     SQLUpdate:
441     FirstTableName := GetWord(SelectSQL,2);
442    
443     else
444     FirstTableName := GetWord(SelectSQL,3);
445     end
446     except on E:EIBError do
447     // ShowMessage(E.Message);
448     end;
449     end;
450    
451     procedure TIBSystemTables.GetProcedureNames(ProcNames: TStrings; WithOutputParams: boolean);
452     begin
453     if not assigned(FGetProcedures.Database) or not FGetProcedures.Database.Connected or
454     not assigned(FGetProcedures.Transaction) then
455     Exit;
456     ProcNames.Clear;
457     with FGetProcedures do
458     begin
459     with Transaction do
460     if not InTransaction then StartTransaction;
461     Prepare;
462     if WithOutputParams then
463     ParamByName('ProcType').AsInteger := 1
464     else
465     ParamByName('ProcType').AsInteger := 2;
466     ExecQuery;
467     try
468     while not EOF do
469     begin
470     ProcNames.Add(FieldByName('ProcName').AsString);
471     Next;
472     end;
473     finally
474     Close
475     end;
476     end;
477     end;
478    
479     procedure TIBSystemTables.GetProcParams(ProcName: string;
480     var ExecuteOnly: boolean; InputParams, OutputParams: TStrings);
481     begin
482     GetProcParams(ProcName,InputParams,true);
483     GetProcParams(ProcName,OutputParams,false);
484     ExecuteOnly := OutputParams.Count = 0;
485     if not ExecuteOnly then
486     with FGetProcedureInfo do
487     begin
488     with Transaction do
489     if not InTransaction then StartTransaction;
490     Prepare;
491     ParamByName('ProcName').AsString := ProcName;
492     ExecQuery;
493     try
494     if not EOF then
495     ExecuteOnly := FieldByName('RDB$PROCEDURE_TYPE').AsInteger = 2
496     finally
497     Close
498     end;
499     end;
500     end;
501    
502     procedure TIBSystemTables.GetGenerators(GeneratorNames: TStrings);
503     begin
504     if not assigned(FGetGeneratorsSQL.Database) or not FGetGeneratorsSQL.Database.Connected or
505     not assigned(FGetGeneratorsSQL.Transaction) then
506     Exit;
507     GeneratorNames.Clear;
508     with FGetGeneratorsSQL do
509     begin
510     with Transaction do
511     if not InTransaction then StartTransaction;
512     ExecQuery;
513     try
514     while not EOF do
515     begin
516     GeneratorNames.Add(FieldByName('RDB$GENERATOR_NAME').AsString);
517     Next;
518     end;
519     finally
520     Close
521     end;
522     end;
523    
524     end;
525    
526     procedure TIBSystemTables.GenerateSelectSQL(TableName: string; QuotedStrings: boolean; FieldNames,SQL: TStrings);
527     var SelectSQL: string;
528     Separator : string;
529     I: integer;
530     begin
531     SQL.Clear;
532     if not assigned(FGetFieldNames.Database) or not FGetFieldNames.Database.Connected or
533     not assigned(FGetFieldNames.Transaction) then
534     begin
535     Messagedlg('No Database Connected',mtError,[mbOK],0);
536     Exit;
537     end;
538     SelectSQL := 'Select';
539     Separator := ' A.';
540     for I := 0 to FieldNames.Count - 1 do
541     begin
542     if QuotedStrings then
543     SelectSQL := SelectSQL + Separator + '"' + FieldNames[I] + '"'
544     else
545 tony 19 SelectSQL := SelectSQL + Separator + QuoteIdentifierIfNeeded(FGetFieldNames.Database.SQLDialect,FieldNames[I]);
546 tony 17 Separator := ', A.';
547     end;
548     SelectSQL := SelectSQL + ' From ' + TableName + ' A';
549     SQL.Add(SelectSQL);
550     end;
551    
552     procedure TIBSystemTables.GenerateRefreshSQL(TableName: string; QuotedStrings: boolean; FieldNames,SQL: TStrings);
553     begin
554     GenerateSelectSQL(TableName,QuotedStrings,FieldNames,SQL);
555     AddWhereClause(TableName,QuotedStrings,SQL)
556     end;
557    
558     procedure TIBSystemTables.GenerateInsertSQL(TableName: string;
559     QuotedStrings: boolean; FieldNames,SQL: TStrings);
560     var InsertSQL: string;
561     Separator: string;
562     I: integer;
563     begin
564     SQL.Clear;
565     InsertSQL := 'Insert Into ' + TableName + '(';
566     Separator := '';
567     for I := 0 to FieldNames.Count - 1 do
568     begin
569     if QuotedStrings then
570     InsertSQL := InsertSQL + Separator + '"' + FieldNames[I] + '"'
571     else
572 tony 19 InsertSQL := InsertSQL + Separator + QuoteIdentifierIfNeeded(FGetFieldNames.Database.SQLDialect,FieldNames[I]) ;
573 tony 17 Separator := ', ';
574     end;
575     InsertSQL := InsertSQL + ')';
576     SQL.Add(InsertSQL);
577     InsertSQL := 'Values(';
578     Separator := ':';
579     for I := 0 to FieldNames.Count - 1 do
580     begin
581 tony 19 InsertSQL := InsertSQL + Separator + AnsiUpperCase(FieldNames[I]) ;
582 tony 17 Separator := ', :';
583     end;
584     InsertSQL := InsertSQL + ')';
585     SQL.Add(InsertSQL);
586     end;
587    
588     procedure TIBSystemTables.GenerateModifySQL(TableName: string; QuotedStrings: boolean;
589     FieldNames,SQL: TStrings);
590     var UpdateSQL: string;
591     Separator: string;
592     I: integer;
593     begin
594     SQL.Clear;
595     Separator := #$0d#$0a' A.';
596     UpdateSQL := 'Update ' + TableName + ' A Set ';
597     for I := 0 to FieldNames.Count - 1 do
598     begin
599     if QuotedStrings then
600 tony 19 UpdateSQL := UpdateSQL + Separator + '"' + FieldNames[I] + '" = :' + AnsiUpperCase(FieldNames[I])
601 tony 17 else
602 tony 19 UpdateSQL := UpdateSQL + Separator + QuoteIdentifierIfNeeded(FGetFieldNames.Database.SQLDialect,FieldNames[I]) + ' = :' + AnsiUpperCase(FieldNames[I]);
603 tony 17 Separator := ','#$0d#$0a' A.';
604     end;
605     SQL.Add(UpdateSQL);
606     AddWhereClause(TableName,QuotedStrings,SQL,true)
607     end;
608    
609     procedure TIBSystemTables.GenerateDeleteSQL(TableName: string; QuotedStrings: boolean; SQL: TStrings);
610     begin
611     SQL.Clear;
612     SQL.Add('Delete From ' + TableName + ' A');
613     AddWhereClause(TableName,QuotedStrings,SQL)
614     end;
615    
616     procedure TIBSystemTables.GenerateExecuteSQL(ProcName: string;
617     QuotedStrings: boolean; ExecuteOnly: boolean; InputParams, OutputParams,
618     ExecuteSQL: TStrings);
619     var SQL: string;
620     I: integer;
621     Separator: string;
622     begin
623     Separator := '';
624     if not ExecuteOnly and (OutputParams.Count > 0) then //Select Query
625     begin
626     SQL := 'Select ';
627     for I := 0 to OutputParams.Count - 1 do
628     begin
629     if QuotedStrings then
630     SQL := SQL + Separator + '"' + OutputParams[I] + '"'
631     else
632 tony 19 SQL := SQL + Separator + QuoteIdentifierIfNeeded(FGetFieldNames.Database.SQLDialect,OutputParams[I]);
633 tony 17 Separator := ', ';
634     end;
635     SQL := SQL + ' From ' + ProcName;
636     if InputParams.Count > 0 then
637     begin
638     Separator := '(:';
639     for I := 0 to InputParams.Count - 1 do
640     begin
641 tony 19 SQL := SQL + Separator + AnsiUpperCase(InputParams[I]);
642 tony 17 Separator := ', :';
643     end;
644     SQL := SQL + ')'
645     end
646     end
647     else // Execute Procedure
648     begin
649     if QuotedStrings then
650     SQL := 'Execute Procedure "' + ProcName + '"'
651     else
652 tony 19 SQL := 'Execute Procedure ' + QuoteIdentifierIfNeeded(FGetFieldNames.Database.SQLDialect,ProcName);
653 tony 17 if InputParams.Count > 0 then
654     begin
655     Separator := ' :';
656     for I := 0 to InputParams.Count - 1 do
657     begin
658     if QuotedStrings then
659     SQL := SQL + Separator + '"' + InputParams[I] + '"'
660     else
661 tony 19 SQL := SQL + Separator + AnsiUpperCase(InputParams[I]);
662 tony 17 Separator := ', :';
663     end;
664     end
665     end;
666     ExecuteSQL.Text := SQL
667     end;
668    
669     function TIBSystemTables.GetStatementType(SQL: string; var IsStoredProcedure: boolean): TIBSQLTypes;
670     var TableName: string;
671     begin
672     Result := sqlUnknown;
673     if not assigned(FTestSQL.Database) or not FTestSQL.Database.Connected or
674     not assigned(FTestSQL.Transaction) or (Trim(SQL) = '') then
675     Exit;
676     IsStoredProcedure := false;
677     FTestSQL.SQL.Text := SQL;
678 tony 19 FTestSQL.GenerateParamNames := true; {permissive}
679 tony 17 try
680     FTestSQL.Prepare;
681     Result := FTestSQL.SQLType
682     except on E:EIBError do
683     // ShowMessage(E.Message);
684     end;
685     if (Result = SQLSelect) and (FTestSQL.Current.Count > 0) then
686     begin
687     TableName := strpas(FTestSQL.Current.Vars[0].Data^.relname);
688     FTestSQL.SQL.Text := sqlCheckProcedureNames;
689     FTestSQL.Prepare;
690     FTestSQL.ParamByName('ProcName').AsString := TableName;
691     FTestSQL.ExecQuery;
692     try
693     IsStoredProcedure := not FTestSQL.EOF;
694     finally
695     FTestSQL.Close
696     end;
697     end;
698     end;
699    
700     function TIBSystemTables.GetFieldNames(FieldList: TListBox): TStrings;
701     var I: integer;
702     begin
703     Result := TStringList.Create;
704     try
705     if FieldList.SelCount = 0 then
706     Result.Assign(FieldList.Items)
707     else
708     for I := 0 to FieldList.Items.Count - 1 do
709     if FieldList.Selected[I] then
710     Result.Add(FieldList.Items[I]);
711     except
712     Result.Free;
713     raise
714     end;
715     end;
716    
717 tony 19 procedure TIBSystemTables.TestSQL(SQL: string;
718     GenerateParamNames: boolean);
719 tony 17 begin
720     if not assigned(FTestSQL.Database) or not FTestSQL.Database.Connected or
721     not assigned(FTestSQL.Transaction) then
722     begin
723     Messagedlg('No Database Connected',mtError,[mbOK],0);
724     Exit;
725     end;
726 tony 19 FTestSQL.GenerateParamNames := GenerateParamNames;
727 tony 17 FTestSQL.SQL.Text := SQL;
728     try
729     FTestSQL.Prepare;
730     ShowMessage('SQL '+ GetSQLType(FTestSQL.SQLType) + ' Statement Looks OK');
731     except on E:EIBError do
732 tony 21 ShowMessage(RemoveSQLText(E.Message));
733 tony 17 end;
734     end;
735    
736     end.
737 tony 19