ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/public/ibx/trunk/runtime/IB.pas
Revision: 39
Committed: Tue May 17 08:14:52 2016 UTC (8 years, 6 months ago) by tony
Content type: text/x-pascal
File size: 19447 byte(s)
Log Message:
Committing updates for Release R1-4-1

File Contents

# User Rev Content
1 tony 33 {************************************************************************}
2     { }
3     { Borland Delphi Visual Component Library }
4     { InterBase Express core components }
5     { }
6     { Copyright (c) 1998-2000 Inprise Corporation }
7     { }
8     { InterBase Express is based in part on the product }
9     { Free IB Components, written by Gregory H. Deatz for }
10     { Hoagland, Longo, Moran, Dunst & Doukas Company. }
11     { Free IB Components is used under license. }
12     { }
13     { The contents of this file are subject to the InterBase }
14     { Public License Version 1.0 (the "License"); you may not }
15     { use this file except in compliance with the License. You }
16     { may obtain a copy of the License at http://www.Inprise.com/IPL.html }
17     { Software distributed under the License is distributed on }
18     { an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either }
19     { express or implied. See the License for the specific language }
20     { governing rights and limitations under the License. }
21     { The Original Code was created by InterBase Software Corporation }
22     { and its successors. }
23     { Portions created by Inprise Corporation are Copyright (C) Inprise }
24     { Corporation. All Rights Reserved. }
25     { Contributor(s): Jeff Overcash }
26     { }
27     { IBX For Lazarus (Firebird Express) }
28     { Contributor: Tony Whyman, MWA Software http://www.mwasoftware.co.uk }
29     { Portions created by MWA Software are copyright McCallum Whyman }
30     { Associates Ltd 2011 }
31     { }
32     {************************************************************************}
33    
34     unit IB;
35    
36     {$Mode Delphi}
37    
38     interface
39    
40     uses
41     {$IFDEF WINDOWS }
42     Windows,
43     {$ELSE}
44     unix,
45     {$ENDIF}
46     SysUtils, Classes, IBExternals, IBUtils, DB, IBXConst, CustApp;
47    
48     type
49     TIBGUIInterface = interface
50 tony 39 function ServerLoginDialog(var AServerName: string;
51 tony 33 var AUserName, APassword: string): Boolean;
52 tony 39 function LoginDialogEx(var ADatabaseName: string;
53 tony 33 var AUserName, APassword: string;
54     NameReadOnly: Boolean): Boolean;
55     procedure SetCursor;
56     procedure RestoreCursor;
57     end;
58 tony 39
59     {$IF FPC_FULLVERSION < 20700 }
60     RawByteString = AnsiString; {Needed for backwards compatibility}
61     {$ENDIF}
62 tony 33
63     TTraceFlag = (tfQPrepare, tfQExecute, tfQFetch, tfError, tfStmt, tfConnect,
64     tfTransact, tfBlob, tfService, tfMisc);
65     TTraceFlags = set of TTraceFlag;
66    
67     EIBError = class(EDatabaseError)
68     private
69     FSQLCode: Long;
70     FIBErrorCode: Long;
71     public
72     constructor Create(ASQLCode: Long; Msg: string); overload;
73     constructor Create(ASQLCode: Long; AIBErrorCode: Long; Msg: string); overload;
74     property SQLCode: Long read FSQLCode;
75     property IBErrorCode: Long read FIBErrorCode;
76     end;
77    
78     EIBInterBaseError = class(EIBError);
79     EIBClientError = class(EIBError);
80    
81     TIBDataBaseErrorMessage = (ShowSQLCode,
82     ShowIBMessage,
83     ShowSQLMessage);
84     TIBDataBaseErrorMessages = set of TIBDataBaseErrorMessage;
85     TIBClientError = (
86     ibxeUnknownError,
87     ibxeInterBaseMissing,
88     ibxeInterBaseInstallMissing,
89     ibxeIB60feature,
90     ibxeNotSupported,
91     ibxeNotPermitted,
92     ibxeFileAccessError,
93     ibxeConnectionTimeout,
94     ibxeCannotSetDatabase,
95     ibxeCannotSetTransaction,
96     ibxeOperationCancelled,
97     ibxeDPBConstantNotSupported,
98     ibxeDPBConstantUnknown,
99     ibxeTPBConstantNotSupported,
100     ibxeTPBConstantUnknown,
101     ibxeDatabaseClosed,
102     ibxeDatabaseOpen,
103     ibxeDatabaseNameMissing,
104     ibxeNotInTransaction,
105     ibxeInTransaction,
106     ibxeTimeoutNegative,
107     ibxeNoDatabasesInTransaction,
108     ibxeUpdateWrongDB,
109     ibxeUpdateWrongTR,
110     ibxeDatabaseNotAssigned,
111     ibxeTransactionNotAssigned,
112     ibxeXSQLDAIndexOutOfRange,
113     ibxeXSQLDANameDoesNotExist,
114     ibxeEOF,
115     ibxeBOF,
116     ibxeInvalidStatementHandle,
117     ibxeSQLOpen,
118     ibxeSQLClosed,
119     ibxeDatasetOpen,
120     ibxeDatasetClosed,
121     ibxeUnknownSQLDataType,
122     ibxeInvalidColumnIndex,
123     ibxeInvalidParamColumnIndex,
124     ibxeInvalidDataConversion,
125     ibxeColumnIsNotNullable,
126     ibxeBlobCannotBeRead,
127     ibxeBlobCannotBeWritten,
128     ibxeEmptyQuery,
129     ibxeCannotOpenNonSQLSelect,
130     ibxeNoFieldAccess,
131     ibxeFieldReadOnly,
132     ibxeFieldNotFound,
133     ibxeNotEditing,
134     ibxeCannotInsert,
135     ibxeCannotPost,
136     ibxeCannotUpdate,
137     ibxeCannotDelete,
138     ibxeCannotRefresh,
139     ibxeBufferNotSet,
140     ibxeCircularReference,
141     ibxeSQLParseError,
142     ibxeUserAbort,
143     ibxeDataSetUniDirectional,
144     ibxeCannotCreateSharedResource,
145     ibxeWindowsAPIError,
146     ibxeColumnListsDontMatch,
147     ibxeColumnTypesDontMatch,
148     ibxeCantEndSharedTransaction,
149     ibxeFieldUnsupportedType,
150     ibxeCircularDataLink,
151     ibxeEmptySQLStatement,
152     ibxeIsASelectStatement,
153     ibxeRequiredParamNotSet,
154     ibxeNoStoredProcName,
155     ibxeIsAExecuteProcedure,
156     ibxeUpdateFailed,
157     ibxeNotCachedUpdates,
158     ibxeNotLiveRequest,
159     ibxeNoProvider,
160     ibxeNoRecordsAffected,
161     ibxeNoTableName,
162     ibxeCannotCreatePrimaryIndex,
163     ibxeCannotDropSystemIndex,
164     ibxeTableNameMismatch,
165     ibxeIndexFieldMissing,
166     ibxeInvalidCancellation,
167     ibxeInvalidEvent,
168     ibxeMaximumEvents,
169     ibxeNoEventsRegistered,
170     ibxeInvalidQueueing,
171     ibxeInvalidRegistration,
172     ibxeInvalidBatchMove,
173     ibxeSQLDialectInvalid,
174     ibxeSPBConstantNotSupported,
175     ibxeSPBConstantUnknown,
176     ibxeServiceActive,
177     ibxeServiceInActive,
178     ibxeServerNameMissing,
179     ibxeQueryParamsError,
180     ibxeStartParamsError,
181     ibxeOutputParsingError,
182     ibxeUseSpecificProcedures,
183     ibxeSQLMonitorAlreadyPresent,
184     ibxeCantPrintValue,
185     ibxeEOFReached,
186     ibxeEOFInComment,
187     ibxeEOFInString,
188     ibxeParamNameExpected,
189     ibxeSuccess,
190     ibxeDelphiException,
191     ibxeNoOptionsSet,
192     ibxeNoDestinationDirectory,
193     ibxeNosourceDirectory,
194     ibxeNoUninstallFile,
195     ibxeOptionNeedsClient,
196     ibxeOptionNeedsServer,
197     ibxeInvalidOption,
198     ibxeInvalidOnErrorResult,
199     ibxeInvalidOnStatusResult,
200     ibxeDPBConstantUnknownEx,
201     ibxeTPBConstantUnknownEx,
202     ibxeSV5APIError,
203     ibxeThreadFailed,
204     ibxeFieldSizeError,
205     ibxeTransactionNotEnding,
206     ibxeDscInfoTokenMissing,
207     ibxeNoLoginDialog
208     );
209    
210     TStatusVector = array[0..19] of ISC_STATUS;
211     PStatusVector = ^TStatusVector;
212    
213     {TResultBuffer inspired by IBPP RB class - access a isc_dsql_sql_info result buffer}
214    
215     TResultBuffer = class
216     private
217     mBuffer: PChar;
218     mSize: short;
219     function FindToken(token: char): PChar; overload;
220     function FindToken(token: char; subtoken: char): PChar; overload;
221     public
222     constructor Create(aSize: integer = 1024);
223     destructor Destroy; override;
224     function Size: short;
225     procedure Reset;
226     function GetValue(token: char): integer; overload;
227     function GetValue(token: char; subtoken: char): integer; overload;
228     function GetCountValue(token: char): integer;
229     function GetBool(token: char): boolean;
230     function GetString(token: char; var data: string): integer;
231     function buffer: PChar;
232     end;
233    
234     const
235     IBPalette1 = 'Firebird'; {do not localize}
236     IBPalette2 = 'Firebird Admin'; {do not localize}
237     IBPalette3 = 'Firebird Data Controls'; {do not localize}
238    
239     IBLocalBufferLength = 512;
240     IBBigLocalBufferLength = IBLocalBufferLength * 2;
241     IBHugeLocalBufferLength = IBBigLocalBufferLength * 20;
242    
243     IBErrorMessages: array[TIBClientError] of string = (
244     SUnknownError,
245     SInterBaseMissing,
246     SInterBaseInstallMissing,
247     SIB60feature,
248     SNotSupported,
249     SNotPermitted,
250     SFileAccessError,
251     SConnectionTimeout,
252     SCannotSetDatabase,
253     SCannotSetTransaction,
254     SOperationCancelled,
255     SDPBConstantNotSupported,
256     SDPBConstantUnknown,
257     STPBConstantNotSupported,
258     STPBConstantUnknown,
259     SDatabaseClosed,
260     SDatabaseOpen,
261     SDatabaseNameMissing,
262     SNotInTransaction,
263     SInTransaction,
264     STimeoutNegative,
265     SNoDatabasesInTransaction,
266     SUpdateWrongDB,
267     SUpdateWrongTR,
268     SDatabaseNotAssigned,
269     STransactionNotAssigned,
270     SXSQLDAIndexOutOfRange,
271     SXSQLDANameDoesNotExist,
272     SEOF,
273     SBOF,
274     SInvalidStatementHandle,
275     SSQLOpen,
276     SSQLClosed,
277     SDatasetOpen,
278     SDatasetClosed,
279     SUnknownSQLDataType,
280     SInvalidColumnIndex,
281     SInvalidParamColumnIndex,
282     SInvalidDataConversion,
283     SColumnIsNotNullable,
284     SBlobCannotBeRead,
285     SBlobCannotBeWritten,
286     SEmptyQuery,
287     SCannotOpenNonSQLSelect,
288     SNoFieldAccess,
289     SFieldReadOnly,
290     SFieldNotFound,
291     SNotEditing,
292     SCannotInsert,
293     SCannotPost,
294     SCannotUpdate,
295     SCannotDelete,
296     SCannotRefresh,
297     SBufferNotSet,
298     SCircularReference,
299     SSQLParseError,
300     SUserAbort,
301     SDataSetUniDirectional,
302     SCannotCreateSharedResource,
303     SWindowsAPIError,
304     SColumnListsDontMatch,
305     SColumnTypesDontMatch,
306     SCantEndSharedTransaction,
307     SFieldUnsupportedType,
308     SCircularDataLink,
309     SEmptySQLStatement,
310     SIsASelectStatement,
311     SRequiredParamNotSet,
312     SNoStoredProcName,
313     SIsAExecuteProcedure,
314     SUpdateFailed,
315     SNotCachedUpdates,
316     SNotLiveRequest,
317     SNoProvider,
318     SNoRecordsAffected,
319     SNoTableName,
320     SCannotCreatePrimaryIndex,
321     SCannotDropSystemIndex,
322     STableNameMismatch,
323     SIndexFieldMissing,
324     SInvalidCancellation,
325     SInvalidEvent,
326     SMaximumEvents,
327     SNoEventsRegistered,
328     SInvalidQueueing,
329     SInvalidRegistration,
330     SInvalidBatchMove,
331     SSQLDialectInvalid,
332     SSPBConstantNotSupported,
333     SSPBConstantUnknown,
334     SServiceActive,
335     SServiceInActive,
336     SServerNameMissing,
337     SQueryParamsError,
338     SStartParamsError,
339     SOutputParsingError,
340     SUseSpecificProcedures,
341     SSQLMonitorAlreadyPresent,
342     SCantPrintValue,
343     SEOFReached,
344     SEOFInComment,
345     SEOFInString,
346     SParamNameExpected,
347     SSuccess,
348     SDelphiException,
349     SNoOptionsSet,
350     SNoDestinationDirectory,
351     SNosourceDirectory,
352     SNoUninstallFile,
353     SOptionNeedsClient,
354     SOptionNeedsServer,
355     SInvalidOption,
356     SInvalidOnErrorResult,
357     SInvalidOnStatusResult,
358     SDPBConstantUnknownEx,
359     STPBConstantUnknownEx,
360     SSV5APIError,
361     SThreadFailed,
362     SFieldSizeError,
363     STransactionNotEnding,
364     SDscInfoTokenMissing,
365     SNoLoginDialog
366     );
367    
368     const
369     IBGUIInterface: TIBGUIInterface = nil;
370    
371    
372     var
373     IBCS: TRTLCriticalSection;
374    
375     procedure IBAlloc(var P; OldSize, NewSize: Integer);
376    
377     procedure IBError(ErrMess: TIBClientError; const Args: array of const);
378     procedure IBDataBaseError;
379    
380     function StatusVector: PISC_STATUS;
381     function StatusVectorArray: PStatusVector;
382     function CheckStatusVector(ErrorCodes: array of ISC_STATUS): Boolean;
383     function StatusVectorAsText: string;
384    
385     procedure SetIBDataBaseErrorMessages(Value: TIBDataBaseErrorMessages);
386     function GetIBDataBaseErrorMessages: TIBDataBaseErrorMessages;
387    
388     implementation
389    
390     uses
391     IBIntf, IBHeader;
392    
393     var
394     IBDataBaseErrorMessages: TIBDataBaseErrorMessages;
395     threadvar
396     FStatusVector : TStatusVector;
397    
398     procedure IBAlloc(var P; OldSize, NewSize: Integer);
399     var
400     i: Integer;
401     begin
402     ReallocMem(Pointer(P), NewSize);
403     for i := OldSize to NewSize - 1 do PChar(P)[i] := #0;
404     end;
405    
406     procedure IBError(ErrMess: TIBClientError; const Args: array of const);
407     begin
408     raise EIBClientError.Create(Ord(ErrMess),
409     Format(IBErrorMessages[ErrMess], Args));
410     end;
411    
412     procedure IBDataBaseError;
413     var
414     sqlcode: Long;
415     IBErrorCode: Long;
416     local_buffer: array[0..IBHugeLocalBufferLength - 1] of char;
417     usr_msg: string;
418     status_vector: PISC_STATUS;
419     IBDataBaseErrorMessages: TIBDataBaseErrorMessages;
420     begin
421     usr_msg := '';
422    
423     { Get a local reference to the status vector.
424     Get a local copy of the IBDataBaseErrorMessages options.
425     Get the SQL error code }
426     status_vector := StatusVector;
427     IBErrorCode := StatusVectorArray[1];
428     IBDataBaseErrorMessages := GetIBDataBaseErrorMessages;
429     sqlcode := isc_sqlcode(status_vector);
430    
431     if (ShowSQLCode in IBDataBaseErrorMessages) then
432     usr_msg := usr_msg + 'SQLCODE: ' + IntToStr(sqlcode); {do not localize}
433     Exclude(IBDataBaseErrorMessages, ShowSQLMessage);
434     if (ShowSQLMessage in IBDataBaseErrorMessages) then
435     begin
436     isc_sql_interprete(sqlcode, local_buffer, IBLocalBufferLength);
437     if (ShowSQLCode in IBDataBaseErrorMessages) then
438     usr_msg := usr_msg + CRLF;
439     usr_msg := usr_msg + strpas(local_buffer);
440     end;
441    
442     if (ShowIBMessage in IBDataBaseErrorMessages) then
443     begin
444     if (ShowSQLCode in IBDataBaseErrorMessages) or
445     (ShowSQLMessage in IBDataBaseErrorMessages) then
446     usr_msg := usr_msg + CRLF;
447     while (isc_interprete(local_buffer, @status_vector) > 0) do
448     begin
449     if (usr_msg <> '') and (usr_msg[Length(usr_msg)] <> LF) then
450     usr_msg := usr_msg + CRLF;
451     usr_msg := usr_msg + strpas(local_buffer);
452     end;
453     end;
454     if (usr_msg <> '') and (usr_msg[Length(usr_msg)] = '.') then
455     Delete(usr_msg, Length(usr_msg), 1);
456     raise EIBInterBaseError.Create(sqlcode, IBErrorCode, usr_msg);
457     end;
458    
459     { Return the status vector for the current thread }
460     function StatusVector: PISC_STATUS;
461     begin
462     result := @FStatusVector;
463     end;
464    
465     function StatusVectorArray: PStatusVector;
466     begin
467     result := @FStatusVector;
468     end;
469    
470     function CheckStatusVector(ErrorCodes: array of ISC_STATUS): Boolean;
471     var
472     p: PISC_STATUS;
473     i: Integer;
474     procedure NextP(i: Integer);
475     begin
476     p := PISC_STATUS(PChar(p) + (i * SizeOf(ISC_STATUS)));
477     end;
478     begin
479     p := @FStatusVector;
480     result := False;
481     while (p^ <> 0) and (not result) do
482     case p^ of
483     3: NextP(3);
484     1, 4:
485     begin
486     NextP(1);
487     i := 0;
488     while (i <= High(ErrorCodes)) and (not result) do
489     begin
490     result := p^ = ErrorCodes[i];
491     Inc(i);
492     end;
493     NextP(1);
494     end;
495     else
496     NextP(2);
497     end;
498     end;
499    
500     function StatusVectorAsText: string;
501     var
502     p: PISC_STATUS;
503     function NextP(i: Integer): PISC_STATUS;
504     begin
505     p := PISC_STATUS(PChar(p) + (i * SizeOf(ISC_STATUS)));
506     result := p;
507     end;
508     begin
509     p := @FStatusVector;
510     result := '';
511     while (p^ <> 0) do
512     if (p^ = 3) then
513     begin
514     result := result + Format('%d %d %d', [p^, NextP(1)^, NextP(1)^]) + CRLF;
515     NextP(1);
516     end
517     else begin
518     result := result + Format('%d %d', [p^, NextP(1)^]) + CRLF;
519     NextP(1);
520     end;
521     end;
522    
523     { TResultBuffer }
524    
525     constructor TResultBuffer.Create(aSize: integer);
526     begin
527     inherited Create;
528     mSize := aSize;
529     GetMem(mBuffer,aSize);
530     FillChar(mBuffer^,mSize,255);
531     end;
532    
533     destructor TResultBuffer.Destroy;
534     begin
535     if mBuffer <> nil then FreeMem(mBuffer);
536     inherited;
537     end;
538    
539     function TResultBuffer.buffer: PChar;
540     begin
541     Result := mBuffer;
542     end;
543    
544     function TResultBuffer.FindToken(token: char): PChar;
545     var p: PChar;
546     len: integer;
547     begin
548     Result := nil;
549     p := mBuffer;
550    
551     while p^ <> char(isc_info_end) do
552     begin
553     if p^ = token then
554     begin
555     Result := p;
556     Exit;
557     end;
558     len := isc_vax_integer(p+1,2);
559     Inc(p,len+3);
560     end;
561     end;
562    
563     function TResultBuffer.FindToken(token: char; subtoken: char): PChar;
564     var p: PChar;
565     len, inlen: integer;
566     begin
567     Result := nil;
568     p := mBuffer;
569    
570     while p^ <> char(isc_info_end) do
571     begin
572     if p^ = token then
573     begin
574     {Found token, now find subtoken}
575     inlen := isc_vax_integer(p+1, 2);
576     Inc(p,3);
577     while inlen > 0 do
578     begin
579     if p^ = subtoken then
580     begin
581     Result := p;
582     Exit;
583     end;
584     len := isc_vax_integer(p+1, 2);
585     Inc(p,len + 3);
586     Dec(inlen,len + 3);
587     end;
588     Exit;
589     end;
590     len := isc_vax_integer(p+1, 2);
591     inc(p,len+3);
592     end;
593     end;
594    
595     function TResultBuffer.GetBool(token: char): boolean;
596     var aValue: integer;
597     p: PChar;
598     begin
599     p := FindToken(token);
600    
601     if p = nil then
602     IBError(ibxeDscInfoTokenMissing,[token]);
603    
604     aValue := isc_vax_integer(p+1, 4);
605     Result := aValue <> 0;
606     end;
607    
608     function TResultBuffer.GetCountValue(token: char): integer;
609     var len: integer;
610     p: PChar;
611     begin
612     {Specifically used on tokens like isc_info_insert_count and the like
613     which return detailed counts per relation. We sum up the values.}
614    
615     p := FindToken(token);
616    
617     if p = nil then
618     IBError(ibxeDscInfoTokenMissing,[token]);
619    
620     {len is the number of bytes in the following array}
621    
622     len := isc_vax_integer(p+1, 2);
623     Inc(p,3);
624     Result := 0;
625     while len > 0 do
626     begin
627     {Each array item is 6 bytes : 2 bytes for the relation_id which
628     we skip, and 4 bytes for the count value which we sum up across
629     all tables.}
630    
631     Inc(Result,isc_vax_integer(p+2, 4));
632     Inc(p,6);
633     Dec(len,6);
634     end;
635     end;
636    
637     function TResultBuffer.GetString(token: char; var data: string): integer;
638     var p: PChar;
639     begin
640     Result := 0;
641     p := FindToken(token);
642    
643     if p = nil then
644     IBError(ibxeDscInfoTokenMissing,[token]);
645    
646     Result := isc_vax_integer(p+1, 2);
647     SetString(data,p+3,Result);
648     end;
649    
650     function TResultBuffer.GetValue(token: char): integer;
651     var len: integer;
652     p: PChar;
653     begin
654     Result := 0;
655     p := FindToken(token);
656    
657     if p = nil then
658     IBError(ibxeDscInfoTokenMissing,[token]);
659    
660     len := isc_vax_integer(p+1, 2);
661     if (len <> 0) then
662     Result := isc_vax_integer(p+3, len);
663     end;
664    
665     function TResultBuffer.GetValue(token: char; subtoken: char): integer;
666     var len: integer;
667     p: PChar;
668     begin
669     Result := 0;
670     p := FindToken(token, subtoken);
671    
672     if p = nil then
673     IBError(ibxeDscInfoTokenMissing,[token]);
674    
675     len := isc_vax_integer(p+1, 2);
676     if (len <> 0) then
677     Result := isc_vax_integer(p+3, len);
678     end;
679    
680     function TResultBuffer.Size: short;
681     begin
682     Result := mSize;
683     end;
684    
685     procedure TResultBuffer.Reset;
686     begin
687     if mBuffer <> nil then FreeMem(mBuffer);
688     GetMem(mBuffer,mSize);
689     FillChar(mBuffer^,mSize,255);
690     end;
691    
692    
693     { EIBError }
694     constructor EIBError.Create(ASQLCode: Long; Msg: string);
695     begin
696     inherited Create(Msg);
697     FSQLCode := ASQLCode;
698     end;
699    
700     constructor EIBError.Create(ASQLCode: Long; AIBErrorCode: Long; Msg: string);
701     begin
702     inherited Create(Msg);
703     FSQLCode := ASQLCode;
704     FIBErrorCode := AIBErrorCode;
705     end;
706    
707     procedure SetIBDataBaseErrorMessages(Value: TIBDataBaseErrorMessages);
708     begin
709     EnterCriticalSection(IBCS);
710     try
711     IBDataBaseErrorMessages := Value;
712     finally
713     LeaveCriticalSection(IBCS);
714     end;
715     end;
716    
717     function GetIBDataBaseErrorMessages: TIBDataBaseErrorMessages;
718     begin
719     EnterCriticalSection(IBCS);
720     try
721     result := IBDataBaseErrorMessages;
722     finally
723     LeaveCriticalSection(IBCS);
724     end;
725     end;
726    
727     initialization
728     // IsMultiThread := True;
729     InitCriticalSection(IBCS);
730     IBDataBaseErrorMessages := [ShowSQLMessage, ShowIBMessage];
731    
732     finalization
733     DoneCriticalSection(IBCS);
734    
735     end.