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