home *** CD-ROM | disk | FTP | other *** search
- unit frs_ibase_object;
-
- {*************************************************************************
-
- UNIT: frs_Ibase_object.pas
- DESCRIPTION: This unit allows calls to gds32 via an
- object-oriented interface. This technique
- works well with Delphi's code insight/code
- completion. It also allows simplified error
- checking.
-
- AUTHOR: Paul Reeves
- Fleet River Software
- http://www.fleetriver.demon.co.uk
- **************************************************************************}
-
- interface
-
- uses frs_ibase, windows, sysutils;
-
- //Most of the functions have been declared herre - but not all!
- type
-
- Tisc_array_get_slice = function(
- status_vector : PSTATUS_VECTOR;
- db_handle : pisc_db_handle;
- trans_handle : pisc_tr_handle;
- array_id : PISC_QUAD;
- desc : PISC_ARRAY_DESC;
- dest_array : Pointer;
- slice_length : PISC_LONG
- ) : ISC_STATUS; stdcall;
-
- Tisc_array_lookup_bounds = function (
- status_vector : PSTATUS_VECTOR;
- db_handle : pisc_db_handle;
- trans_handle: pisc_tr_handle;
- table_name: PChar;
- column_name : PChar;
- desc: PISC_ARRAY_DESC
- ): ISC_STATUS; stdcall;
-
- Tisc_array_lookup_desc = function (
- status_vector : PSTATUS_VECTOR;
- db_handle : pisc_db_handle;
- trans_handle: pisc_tr_handle;
- table_name: PChar;
- column_name : PChar;
- desc : PISC_ARRAY_DESC
- ) : ISC_STATUS; stdcall;
-
- Tisc_array_put_slice = function (
- status_vector : PSTATUS_VECTOR;
- db_handle : pisc_db_handle;
- trans_handle: pisc_tr_handle;
- array_id: PISC_QUAD;
- desc: PISC_ARRAY_DESC;
- source_array: Pointer;
- slice_length: PISC_LONG
- ) : ISC_STATUS; stdcall;
-
- Tisc_array_set_desc = function (
- status_vector : PSTATUS_VECTOR;
- table_name: PChar;
- column_name : PChar;
- sql_dtype : PSmallint;
- sql_length: PSmallint;
- dimensions: PSmallint;
- desc: PISC_ARRAY_DESC
- ) : ISC_STATUS; stdcall;
-
- Tisc_attach_database = function (
- status_vector : PSTATUS_VECTOR;
- db_name_length: Short;
- db_name : PChar;
- db_handle : pisc_db_handle;
- parm_buffer_length: Short;
- parm_buffer : PChar
- ) : ISC_STATUS; stdcall;
-
- Tisc_blob_default_desc = procedure (
- desc : ISC_BLOB_DESC;
- table_name : PChar;
- column_name : PChar
- ); stdcall;
-
- Tisc_blob_gen_bpb = function (
- status_vector : PSTATUS_VECTOR;
- to_desc : PISC_BLOB_DESC;
- from_desc : PISC_BLOB_DESC;
- bpb_buffer_length : Byte;
- bpb_buffer : Pointer;
- bpb_length : PByte
- ) : ISC_STATUS; stdcall;
-
- Tisc_blob_info = function (
- status_vector : PSTATUS_VECTOR;
- blob_handle : pisc_blob_handle;
- item_list_buffer_length : Smallint;
- item_list_buffer : Pointer;
- result_buffer_length : Smallint;
- result_buffer : Pointer
- ) : ISC_STATUS; stdcall;
-
- Tisc_blob_lookup_desc = function (
- status_vector : PSTATUS_VECTOR;
- db_handle : pisc_db_handle;
- trans_handle : pisc_tr_handle;
- tablename : PChar;
- colname : PChar;
- blobdesc : ISC_BLOB_DESC;
- global : PChar
- ) : ISC_STATUS; stdcall;
-
- Tisc_blob_set_desc = function (
- status_vector : PSTATUS_VECTOR;
- table_name : PChar;
- column_name : PChar;
- subtype : Smallint;
- charset : Smallint;
- segment_size : Smallint;
- desc : PISC_BLOB_DESC
- ) : ISC_STATUS; stdcall;
-
- Tisc_cancel_blob = function (
- status_vector : PSTATUS_VECTOR;
- blob_handle : pisc_blob_handle
- ) : ISC_STATUS; stdcall;
-
- Tisc_cancel_events = function (
- status_vector : PSTATUS_VECTOR;
- db_handle : pisc_db_handle;
- event_id : pisc_long
- ) : ISC_STATUS; stdcall;
-
- Tisc_close_blob = function (
- status_vector : PSTATUS_VECTOR;
- blob_handle : pisc_blob_handle
- ) : ISC_STATUS; stdcall;
-
- Tisc_commit_retaining = function (
- status_vector : PSTATUS_VECTOR;
- trans_handle : pisc_tr_handle
- ) : ISC_STATUS; stdcall;
-
- Tisc_commit_transaction = function (
- status_vector : PSTATUS_VECTOR;
- trans_handle : pisc_tr_handle
- ) : ISC_STATUS; stdcall;
-
- {This function is not in on-line help}
- Tisc_create_blob = function (
- status_vector : PSTATUS_VECTOR;
- db_handle : pisc_db_handle;
- trans_handle : pisc_tr_handle;
- blob_handle : pisc_blob_handle;
- pblob_id : PISC_QUAD
- ) : ISC_STATUS; stdcall;
-
- Tisc_create_blob2 = function (
- status_vector : PSTATUS_VECTOR;
- db_handle : pisc_db_handle;
- trans_handle : pisc_tr_handle;
- blob_handle : pisc_blob_handle;
- pblob_id : PISC_QUAD;
- bpb_length : Smallint;
- bpb_address : PChar
- ) : ISC_STATUS; stdcall;
-
- Tisc_database_info = function (
- status_vector : PSTATUS_VECTOR;
- db_handle : pisc_db_handle;
- item_list_buffer_length : Smallint;
- item_list_buffer : Pointer;
- result_buffer_length : Smallint;
- result_buffer : Pointer
- ) : ISC_STATUS;stdcall;
-
- Tisc_decode_date = procedure (
- ib_date : PISC_QUAD;
- tm_date : PTM
- ) ; stdcall;
-
- Tisc_detach_database = function (
- status_vector : PSTATUS_VECTOR;
- db_handle : pisc_db_handle
- ) : ISC_STATUS; stdcall;
-
- Tisc_drop_database = function (
- status_vector : PSTATUS_VECTOR;
- db_handle : pisc_db_handle
- ) : ISC_STATUS; stdcall;
-
- Tisc_dsql_allocate_statement = function (
- status_vector : PSTATUS_VECTOR;
- db_handle : pisc_db_handle;
- stmt_handle : pisc_stmt_handle
- ) : ISC_STATUS; stdcall;
-
- Tisc_dsql_allocate_statement2 = function (
- status_vector : PSTATUS_VECTOR;
- db_handle : pisc_db_handle;
- stmt_handle : pisc_stmt_handle
- ) : ISC_STATUS; stdcall;
-
- Tisc_dsql_describe = function (
- status_vector : PSTATUS_VECTOR;
- stmt_handle : pisc_stmt_handle;
- dialect : Word;
- xsqlda : PXSQLDA
- ) : ISC_STATUS; stdcall;
-
- Tisc_dsql_describe_bind = function (
- status_vector : PSTATUS_VECTOR;
- stmt_handle : pisc_stmt_handle;
- dialect : Word;
- xsqlda : PXSQLDA
- ) : ISC_STATUS; stdcall;
-
- Tisc_dsql_execute = function (
- status_vector : PSTATUS_VECTOR;
- trans_handle : pisc_tr_handle;
- stmt_handle : pisc_stmt_handle;
- dialect : Word;
- xsqlda : PXSQLDA
- ) : ISC_STATUS; stdcall;
-
- Tisc_dsql_execute2 = function (
- status_vector : PSTATUS_VECTOR;
- trans_handle : pisc_tr_handle;
- stmt_handle : pisc_stmt_handle;
- dialect : Word;
- in_xsqlda : PXSQLDA;
- out_xsqlda : PXSQLDA
- ) : ISC_STATUS; stdcall;
-
- Tisc_dsql_execute_immediate = function (
- status_vector : PSTATUS_VECTOR;
- db_handle : pisc_db_handle;
- trans_handle : pisc_tr_handle;
- length : Word;
- statement : PChar;
- dialect : Word;
- xsqlda : PXSQLDA
- ) : ISC_STATUS; stdcall;
-
- Tisc_dsql_exec_immed2 = function (
- status_vector : PSTATUS_VECTOR;
- db_handle : pisc_db_handle;
- trans_handle : pisc_tr_handle;
- length : Word;
- statement : PChar;
- dialect : Word;
- in_xsqlda : PXSQLDA;
- out_xsqlda : PXSQLDA
- ) : ISC_STATUS; stdcall;
-
- Tisc_dsql_fetch = function (
- status_vector : PSTATUS_VECTOR;
- stmt_handle : pisc_stmt_handle;
- dialect : Word;
- xsqlda : PXSQLDA
- ) : ISC_STATUS; stdcall;
-
- Tisc_dsql_free_statement = function (
- status_vector : PSTATUS_VECTOR;
- stmt_handle : pisc_stmt_handle;
- option : Word
- ) : ISC_STATUS; stdcall;
-
- Tisc_dsql_prepare = function (
- status_vector : PSTATUS_VECTOR;
- trans_handle : pisc_tr_handle;
- stmt_handle : pisc_stmt_handle;
- length : Word;
- statement : PChar;
- dialect : Word;
- xsqlda : PXSQLDA
- ) : ISC_STATUS; stdcall;
-
- Tisc_dsql_set_cursor_name = function (
- status_vector : PSTATUS_VECTOR;
- stmt_handle : pisc_stmt_handle;
- cursor_name : PChar;
- cursor_type : Word
- ) : ISC_STATUS; stdcall;
-
- Tisc_dsql_sql_info = function (
- status_vector : PSTATUS_VECTOR;
- stmt_handle : pisc_stmt_handle;
- item_length : Word;
- items : PChar;
- buffer_length : Word;
- buffer : PChar
- ) : ISC_STATUS; stdcall;
-
- Tisc_encode_date = procedure (
- tm_date : PTM;
- ib_date : PISC_QUAD
- ); stdcall;
-
- Tisc_event_block = function (
- event_buffer : Pointer;
- result_buffer : Pointer;
- count : short;
- name1 : PChar
- ) : Longint; stdcall;
-
- Tisc_event_counts = procedure (
- status_vector : PSTATUS_VECTOR;
- buffer_length : Word;
- event_buffer : PChar;
- result_buffer : PChar
- ); stdcall;
-
- Tisc_get_segment = function (
- status_vector : PSTATUS_VECTOR;
- blob_handle : pisc_blob_handle;
- actual_seg_length : PWord;
- seg_buffer_length : Word;
- seg_buffer : Pointer
- ) : ISC_STATUS; stdcall;
-
- Tisc_interprete = function (
- buffer : PChar;
- status_vector_ptr : PPSTATUS_VECTOR
- ) : ISC_STATUS; stdcall;
-
- Tisc_open_blob2 = function (
- status_vector : PSTATUS_VECTOR;
- db_handle : pisc_db_handle;
- trans_handle : pisc_tr_handle;
- blob_handle : pisc_blob_handle;
- blob_id : PISC_QUAD;
- bpb_length : Word;
- bpb_address : Pointer
- ) : ISC_STATUS; stdcall;
-
- Tisc_prepare_transaction = function (
- status_vector : PSTATUS_VECTOR;
- trans_handle : pisc_tr_handle
- ) : ISC_STATUS; stdcall;
-
- Tisc_prepare_transaction2 = function (
- status_vector : PSTATUS_VECTOR;
- trans_handle : pisc_tr_handle;
- msg_length : Word;
- msg : PChar
- ) : ISC_STATUS; stdcall;
-
- Tisc_print_status = procedure (
- status_vector_ptr : PSTATUS_VECTOR
- ); stdcall;
-
- Tisc_print_sqlerror = procedure (
- SQLCODE : ISC_LONG;
- status_vector_ptr : PSTATUS_VECTOR
- ); stdcall;
-
- Tisc_put_segment = function (
- status_vector : PSTATUS_VECTOR;
- blob_handle : pisc_blob_handle;
- seg_buffer_length : Word;
- seg_buffer_address : Pointer
- ) : ISC_STATUS; stdcall;
-
- Tisc_que_events = function (
- status_vector : PSTATUS_VECTOR;
- db_handle : pisc_db_handle;
- event_id : PISC_LONG;
- length : Word;
- event_buffer : PChar;
- event_function : Tisc_callback;
- event_function_arg : Pointer
- ) : ISC_STATUS; stdcall;
-
- Tisc_rollback_transaction = function (
- status_vector : PSTATUS_VECTOR;
- trans_handle : pisc_tr_handle
- ) : ISC_STATUS; stdcall;
-
- Tisc_sqlcode = function (
- status_vector : PSTATUS_VECTOR
- ) : ISC_LONG; stdcall;
-
- Tisc_sql_interprete = procedure (
- sqlcode : ISC_LONG;
- buffer : PChar;
- buffer_length : short
- ); stdcall;
-
- Tisc_start_multiple = function (
- status_vector : PSTATUS_VECTOR;
- trans_handle : pisc_tr_handle;
- db_handle_count : short;
- teb_vector_address : PISC_TEB
- ) : ISC_STATUS; stdcall;
-
- Tisc_start_transaction = function (
- status_vector : PSTATUS_VECTOR;
- trans_handle : pisc_tr_handle;
- db_handle_count : short;
- db_handle : pisc_db_handle;
- tpb_length : Word;
- tpb_addr : PChar
- ) : ISC_STATUS; stdcall;
-
- Tisc_transaction_info = function (
- status_vector : PSTATUS_VECTOR;
- trans_handle : pisc_tr_handle;
- item_list_buffer_length : Smallint;
- item_list_buffer : Pointer;
- result_buffer_length : Smallint;
- result_buffer : Pointer
- ) : ISC_STATUS; stdcall;
-
- Tisc_vax_integer = function (
- result_buffer : PChar;
- result_length : SmallInt
- ) : ISC_LONG; stdcall;
-
- Tisc_version = function (
- db_handle : pisc_db_handle;
- function_name : Tisc_callback;
- user_arg : Pointer
- ) : Integer; stdcall;
-
- Tisc_wait_for_event = function (
- status_vector : PSTATUS_VECTOR;
- db_handle : pisc_db_handle;
- length : short;
- event_buffer : PChar;
- result_buffer : PChar
- ) : ISC_STATUS; stdcall;
-
-
- {---------------------------------------------------------------------------------------------}
- { DYNAMIC LIBRARY LOADING }
- {---------------------------------------------------------------------------------------------}
- type
- TGDSFunctionNames = array[0..35] of PChar;
-
- const
- GDSFunctionName : TGDSFunctionNames = (
- 'isc_attach_database',
- 'isc_blob_info',
- 'isc_commit_retaining',
- 'isc_commit_transaction',
- 'isc_database_info',
- 'isc_decode_date',
- 'isc_detach_database',
- 'isc_drop_database',
- 'isc_dsql_allocate_statement',
- 'isc_dsql_allocate_statement2',
- 'isc_dsql_describe',
- 'isc_dsql_describe_bind',
- 'isc_dsql_execute',
- 'isc_dsql_execute2',
- 'isc_dsql_execute_immediate',
- 'isc_dsql_exec_immed2',
- 'isc_dsql_fetch',
- 'isc_dsql_free_statement',
- 'isc_dsql_prepare',
- 'isc_dsql_set_cursor_name',
- 'isc_dsql_sql_info',
- 'isc_encode_date',
- 'isc_get_segment',
- 'isc_interprete',
- 'isc_open_blob2',
- 'isc_prepare_transaction',
- 'isc_prepare_transaction2',
- 'isc_print_status',
- 'isc_print_sqlerror',
- 'isc_put_segment',
- 'isc_rollback_transaction',
- 'isc_sqlcode',
- 'isc_sql_interprete',
- 'isc_start_multiple',
- 'isc_transaction_info',
- 'isc_vax_integer'
- );
- const
- KILOBYTE=1024;
-
- type
- Tfrs_IBErrorEvent = procedure(Status: ISC_STATUS_VECTOR; ErrorMessage: String; Var RaiseException:Boolean) of object;
-
- TParamBlock = array [0..KILOBYTE-1] of Char;
- TLargePB = array [0..(4*KILOBYTE)-1] of Char;
- TSmallPB = array [0..(KILOBYTE div 4)-1] of Char;
-
- TFetchStatus = ( fsUnFetchable, fsFetchable, fsFetching, fsFetched);
-
- Tfrs_GDS = class(TObject)
- private
- FErrorCode: ISC_STATUS;
- FErrorMessages: String; //concatenation of error messages.
- FDBName: String;
- FFetchCode: ISC_STATUS; //
- FFetchStatus: TFetchStatus;
- FLibHandle: THandle;
- FOnIBErrorEvent : Tfrs_IBErrorEvent;
- FRaiseException: Boolean;
- FTEB: ISC_TEB;
-
- FDBHandle: Tisc_db_handle;
- FStatusVector: ISC_STATUS_VECTOR;
- FStmtHandle: Tisc_stmt_handle;
- FTxnHandle: Tisc_tr_handle;
-
- procedure SetFetchCode(const Value: ISC_STATUS);
- protected
- Procedure DoIBErrorEvent(Status: ISC_STATUS_VECTOR; ErrorMessage: String; Var RaiseExcept: Boolean); virtual;
- function GetErrorCode: ISC_STATUS;
- Procedure HandleIBErrors; Virtual;
- Procedure SetErrorCode(AErrorCode:ISC_STATUS); virtual;
- public
- //NOTE!!! - Only the most regularly used functions are declared here.
- isc_attach_database : Tisc_attach_database;
- isc_blob_info : Tisc_blob_info;
- isc_close_blob : Tisc_close_blob;
- isc_commit_retaining : Tisc_commit_retaining;
- isc_commit_transaction : Tisc_commit_transaction;
- isc_create_blob2 : Tisc_create_blob2;
- isc_database_info : Tisc_database_info;
- isc_decode_date : Tisc_decode_date;
- isc_detach_database : Tisc_detach_database;
- isc_drop_database : Tisc_drop_database;
- isc_dsql_allocate_statement : Tisc_dsql_allocate_statement;
- isc_dsql_allocate_statement2 : Tisc_dsql_allocate_statement2;
- isc_dsql_describe : Tisc_dsql_describe;
- isc_dsql_describe_bind : Tisc_dsql_describe_bind;
- isc_dsql_execute : Tisc_dsql_execute;
- isc_dsql_execute2 : Tisc_dsql_execute2;
- isc_dsql_execute_immediate : Tisc_dsql_execute_immediate;
- isc_dsql_exec_immed2 : Tisc_dsql_exec_immed2;
- isc_dsql_fetch : Tisc_dsql_fetch;
- isc_dsql_free_statement : Tisc_dsql_free_statement;
- isc_dsql_prepare : Tisc_dsql_prepare;
- isc_dsql_set_cursor_name : Tisc_dsql_set_cursor_name;
- isc_dsql_sql_info : Tisc_dsql_sql_info;
- isc_encode_date : Tisc_encode_date;
- isc_get_segment : Tisc_get_segment;
- isc_interprete : Tisc_interprete;
- isc_open_blob2 : Tisc_open_blob2;
- isc_prepare_transaction : Tisc_prepare_transaction;
- isc_prepare_transaction2 : Tisc_prepare_transaction2;
- isc_print_status : Tisc_print_status;
- isc_print_sqlerror : Tisc_print_sqlerror;
- isc_put_segment : Tisc_put_segment;
- isc_rollback_transaction : Tisc_rollback_transaction;
- isc_sqlcode : Tisc_sqlcode;
- isc_sql_interprete : Tisc_sql_interprete;
- isc_start_multiple : Tisc_start_multiple;
- isc_transaction_info : Tisc_transaction_info;
- isc_vax_integer : Tisc_vax_integer;
-
-
- //These variables need to be public - so they can be directly referenced
- FDPB: TParamBlock; //parameter block for database connection
- FDPBLen: Integer; //length of Paramblock
- FTPB: TParamBlock; //parameter block for transaction
- FTPBLen: Integer; //length of Paramblock
- InPutDataArea : PXSQLDA;//Input XSQLDA
- OutPutDataArea : PXSQLDA;//Output XSQLDA
-
- Constructor create;
- Destructor destroy; override;
-
- // procedure MemAlloc(var P; OldSize, NewSize: Integer);
- function XSQLDA_LENGTH(n: Word): Longint;
- procedure AllocateSQLData(var AXSQLDA: PXSQLDA);
- procedure FreeSQLData(var AXSQLDA: PXSQLDA);
- procedure InitSQLDA(var AXSQLDA: PXSQLDA; Columns: Integer);
-
- procedure BuildPBString( var PB: array of char; var PBLen: Integer; item: byte; contents: string);
- procedure BuildPBInteger( var PB: array of char; var PBLen: Integer; item: byte; contents: Integer);
- procedure BuildPBBoolean( var PB: array of char; var PBLen: Integer; item: byte; contents: Boolean);
- procedure BuildPBAddConstant(var PB: array of char; var PBLen: Integer; item: byte);
-
- procedure DatabaseOpen; virtual;
- procedure DatabaseClose; virtual;
-
- procedure TransactionStart; virtual;
- procedure TransactionCommit; virtual;
- procedure TransactionRetain; virtual;
- procedure TransactionRollback; virtual;
-
- Function IBDateStrToDateTime(DateTimeStr: String): TDateTime;
-
- Property DBHandle: Tisc_db_handle read FDBHandle write FDBHandle;
- Property DBName: String read FDBName write FDBName;
- Property ErrorCode: ISC_STATUS read GetErrorCode write SetErrorCode;
- Property ErrorMessages: String read FErrorMessages;
- Property FetchCode: ISC_STATUS read FFetchCode write SetFetchCode;
- property FetchStatus: TFetchStatus read FFetchStatus;
- Property OnIBError : Tfrs_IBErrorEvent read FOnIBErrorEvent write FonIBErrorEvent;
- property StatusVector: ISC_STATUS_VECTOR read FStatusVector;
- Property StmtHandle: Tisc_stmt_handle read FStmtHandle write FStmtHandle;
- Property TEB: ISC_TEB read FTEB write FTEB;
- Property TxnHandle: Tisc_tr_handle read FTxnHandle write FTxnHandle;
- end;
-
- Tfrs_GDSClass = class(Tfrs_GDS);
-
-
- {Exception Classes}
- EIBError = class(Exception);
-
- var
- frs_GDS: Tfrs_GDS;
-
- implementation
-
- function LoadProcAddress(LibraryHandle: THandle;FunctionName: PChar): pointer;
- begin
- result:=GetProcAddress(LibraryHandle, FunctionName);
- if @result = nil then
- raise EIBError.Create('Failed to load '+FunctionName+' from '+IBASE_DLL);
- end;
-
-
- {======= Tfrs_GDS =============}
- Constructor Tfrs_GDS.Create;
- var i: integer;
-
- const LOADFAIL = 'Failed to lookup ';
- {Note: This constructor automatically loads every function it knows about.
- It is called in the initialization section. (See below.)
- However, the design is intended to allow dynamic loading by making
- simple modifications. }
- begin
-
- FLibHandle := LoadLibrary(IBASE_DLL);
- if FLibHandle < 32 then raise EIBError.Create('Unable to load '+IBASE_DLL);
-
- i:=0;
- @Isc_Attach_Database:=LoadProcAddress(FLibHandle,GDSFunctionName[i]); inc(i);
- @Isc_Blob_Info:=LoadProcAddress(FLibHandle,GDSFunctionName[i]); inc(i);
- @isc_commit_retaining:=LoadProcAddress(FLibHandle,GDSFunctionName[i]); inc(i);
- @isc_commit_transaction:=LoadProcAddress(FLibHandle,GDSFunctionName[i]); inc(i);
- @isc_database_info:=LoadProcAddress(FLibHandle,GDSFunctionName[i]); inc(i);
- @isc_decode_date:=LoadProcAddress(FLibHandle,GDSFunctionName[i]); inc(i);
- @isc_detach_database:=LoadProcAddress(FLibHandle,GDSFunctionName[i]); inc(i);
- @isc_drop_database:=LoadProcAddress(FLibHandle,GDSFunctionName[i]); inc(i);
- @isc_dsql_allocate_statement:=LoadProcAddress(FLibHandle,GDSFunctionName[i]); inc(i);
- @isc_dsql_allocate_statement2:=LoadProcAddress(FLibHandle,GDSFunctionName[i]); inc(i);
- @isc_dsql_describe:=LoadProcAddress(FLibHandle,GDSFunctionName[i]); inc(i);
- @isc_dsql_describe_bind:=LoadProcAddress(FLibHandle,GDSFunctionName[i]); inc(i);
- @isc_dsql_execute:=LoadProcAddress(FLibHandle,GDSFunctionName[i]); inc(i);
- @isc_dsql_execute2:=LoadProcAddress(FLibHandle,GDSFunctionName[i]); inc(i);
- @isc_dsql_execute_immediate:=LoadProcAddress(FLibHandle,GDSFunctionName[i]); inc(i);
- @isc_dsql_exec_immed2:=LoadProcAddress(FLibHandle,GDSFunctionName[i]); inc(i);
- @isc_dsql_fetch:=LoadProcAddress(FLibHandle,GDSFunctionName[i]); inc(i);
- @isc_dsql_free_statement:=LoadProcAddress(FLibHandle,GDSFunctionName[i]); inc(i);
- @isc_dsql_prepare:=LoadProcAddress(FLibHandle,GDSFunctionName[i]); inc(i);
- @isc_dsql_set_cursor_name:=LoadProcAddress(FLibHandle,GDSFunctionName[i]); inc(i);
- @isc_dsql_sql_info:=LoadProcAddress(FLibHandle,GDSFunctionName[i]); inc(i);
- @isc_encode_date:=LoadProcAddress(FLibHandle,GDSFunctionName[i]); inc(i);
- @isc_get_segment:=LoadProcAddress(FLibHandle,GDSFunctionName[i]); inc(i);
- @isc_interprete:=LoadProcAddress(FLibHandle,GDSFunctionName[i]); inc(i);
- @isc_open_blob2:=LoadProcAddress(FLibHandle,GDSFunctionName[i]); inc(i);
- @isc_prepare_transaction:=LoadProcAddress(FLibHandle,GDSFunctionName[i]); inc(i);
- @isc_prepare_transaction2:=LoadProcAddress(FLibHandle,GDSFunctionName[i]); inc(i);
- @isc_print_status:=LoadProcAddress(FLibHandle,GDSFunctionName[i]); inc(i);
- @isc_print_sqlerror:=LoadProcAddress(FLibHandle,GDSFunctionName[i]); inc(i);
- @isc_put_segment:=LoadProcAddress(FLibHandle,GDSFunctionName[i]); inc(i);
- @isc_rollback_transaction:=LoadProcAddress(FLibHandle,GDSFunctionName[i]); inc(i);
- @isc_sqlcode:=LoadProcAddress(FLibHandle,GDSFunctionName[i]); inc(i);
- @isc_sql_interprete:=LoadProcAddress(FLibHandle,GDSFunctionName[i]); inc(i);
- @isc_start_multiple:=LoadProcAddress(FLibHandle,GDSFunctionName[i]); inc(i);
- @isc_transaction_info:=LoadProcAddress(FLibHandle,GDSFunctionName[i]); inc(i);
- @isc_vax_integer:=LoadProcAddress(FLibHandle,GDSFunctionName[i]); //inc(i);
-
- //init statusvector
- for i:=low(FStatusVector) to high(FStatusVector) do
- FstatusVector[i]:=0;
-
- FDBHandle:=Nil;
- FTxnHandle:=Nil;
- FStmtHandle:=Nil;
-
- //init DPB
- fillchar(FDPB,sizeof(FDPB),#0);
- FDPB[0] := char(isc_dpb_version1);
- inc(FDPBLen);
-
- //init TPB
- fillchar(FTPB,sizeof(FTPB),#0);
- FTPB[0] := char(isc_tpb_version3);
- inc(FTPBLen);
-
- //init TEB
- with FTEB do begin
- db_ptr := @FDBhandle;
- tpb_len := 0;
- tpb_ptr := nil;
- end;
-
-
- InputDataArea:=Nil;
- OutputDataArea:=Nil;
- InitSQLDA(InPutDataArea,1);
- InitSQLDA(OutPutDataArea,1);
-
- end;
-
- Destructor Tfrs_GDS.Destroy;
- begin
- FreeLibrary(FLibHandle);
- inherited destroy;
- end;
-
- procedure Tfrs_GDS.DoIBErrorEvent(Status: ISC_STATUS_VECTOR; ErrorMessage: String;
- var RaiseExcept: Boolean);
- begin
- //By assigning code to the event it is possible
- //to check the error and handle it or raise it.
- if (assigned(FOnIBErrorEvent)) then
- FOnIbErrorEvent(FStatusVector,FErrorMessages,RaiseExcept);
- end;
-
- function Tfrs_GDS.GetErrorCode: ISC_STATUS;
- begin
- result:=FErrorCode;
- end;
-
- procedure Tfrs_GDS.HandleIBErrors;
- var
- buffer: array[0..511] of char;
- lastMsg: string;
- pStatus: PSTATUS_VECTOR;
- begin
- fillchar(buffer,512,#0);
- pStatus:=@FStatusVector;
- FRaiseException := True;
- begin
- FErrorMessages:='';//clear the old errors;
- repeat
- FErrorCode := isc_interprete( @buffer, @pstatus);
- if lastMsg <> strPas( buffer) then begin
- lastMsg := strPas( buffer);
- if length( FErrorMessages) <> 0 then FErrorMessages := FErrorMessages+#13#10;
- FErrorMessages := FErrorMessages+lastMsg;
- end;
- until
- FErrorCode = 0;
- //If an event method has been assigned then it can test the error and decide whether to
- //raise it or not. The default is to raise it.
- DoIBErrorEvent(FStatusVector,FErrorMessages,FRaiseException);
- if FRaiseException then raise EIBError.Create(FErrorMessages);
- end;
- end;
-
- procedure Tfrs_GDS.AllocateSQLData(var AXSQLDA: PXSQLDA);
- var
- i: integer;
- datatype: smallint;
- begin
- for i := 0 to AXSQLDA^.sqld -1 do begin
- datatype:= AXSQLDA.sqlvar[i].sqltype and (not SQL_NULL);
- if datatype=SQL_VARYING then begin
- getmem(AXSQLDA.sqlvar[i].sqlData,AXSQLDA.sqlvar[i].sqllen +2 );
- FillChar(AXSQLDA.sqlvar[i].sqlData^, AXSQLDA.sqlvar[i].sqllen+2, #0);
- end
- else
- if datatype = SQL_BLOB then begin
- AXSQLDA.sqlvar[i].sqllen:=sizeof(ISC_QUAD);
- getmem(AXSQLDA.sqlvar[i].sqlData,AXSQLDA.sqlvar[i].sqllen);
- FillChar(AXSQLDA.sqlvar[i].sqlData^, AXSQLDA.sqlvar[i].sqllen, #0);
- end
- else begin
- getmem(AXSQLDA.sqlvar[i].sqlData,AXSQLDA.sqlvar[i].sqllen);
- FillChar(AXSQLDA.sqlvar[i].sqlData^, AXSQLDA.sqlvar[i].sqllen, #0);
- end;
- getmem(AXSQLDA.sqlvar[i].sqlind,sizeof(smallint)); //allocate var to hold null status
- FillChar(AXSQLDA.sqlvar[i].sqlind^, sizeof(smallint), #0);
- end;
- AXSQLDA^.sqln:=AXSQLDA^.sqld;
- end;
-
- procedure Tfrs_GDS.FreeSQLData(var AXSQLDA: PXSQLDA);
- var
- i,columns: integer;
- begin
- if assigned(AXSQLDA) then begin
- columns:=AXSQLDA^.sqln; //sqln is set when allocation is completed
- for i := 0 to columns -1 do begin
- if (AXSQLDA.sqlvar[i].sqltype and (not SQL_NULL)) = SQL_VARYING then
- reallocmem(AXSQLDA^.sqlvar[i].sqlData,0)
- else
- reallocmem(AXSQLDA^.sqlvar[i].sqlData,0);
- reallocmem(AXSQLDA^.sqlvar[i].sqlind,0);
- end;
- ReallocMem(AXSQLDA,0);
- end;
- AXSQLDA:=Nil;
- end;
-
- procedure Tfrs_GDS.InitSQLDA(var AXSQLDA: PXSQLDA; Columns: Integer);
- begin
- ReallocMem(AXSQLDA, XSQLDA_LENGTH(Columns));
- FillChar(AXSQLDA^, XSQLDA_LENGTH(Columns), #0);
- AXSQLDA^.SQLn := Columns; //this is critical - we allocate SQLVAR memory on the basis if this!
- AXSQLDA^.version:=SQLDA_VERSION1;
- end;
-
- {procedure Tfrs_GDS.MemAlloc(var P; OldSize, NewSize: Integer);
- var
- i: Integer;
- begin
- ReallocMem(Pointer(P), NewSize);
- for i := OldSize to NewSize - 1 do PChar(P)[i] := #0;
- end;
- }
- function Tfrs_GDS.XSQLDA_LENGTH(n: Word): Longint;
- begin
- XSQLDA_LENGTH := (SizeOf(XSQLDA) + (n - 1) * SizeOf(XSQLVAR));
- end;
-
- procedure Tfrs_GDS.BuildPBString( var PB: array of char; var PBLen: Integer; item: byte; contents: string);
- //Add a string value to a parameter block
- var
- len: Integer;
- begin
- {PBLen is the current size of the populated array, as well as the indicator}
- PB[PBLen] := char(item);
- inc(PBLen);
- len:=Length(Contents);
- PB[PBLen] := char(len);
- inc(PBLen);
- StrPCopy(@PB[PBLen],Contents);
- inc(PBLen,len);
- end;
-
- procedure Tfrs_GDS.BuildPBInteger( var PB: array of char; var PBLen: Integer; item: byte; contents: Integer);
- //Add an integer value to a parameter block
- var
- s: string;
- j: integer;
- len: Integer;
- begin
- PB[PBLen] := char(item);
- inc(PBLen);
- len:=sizeof(Integer);
- PB[PBLen] := char(len);
- inc(PBLen);
- s:=IntToStr(contents);
- j:=lo(contents);
- PB[PBLen] := Char(j);
- j:=hi(contents);
- PB[PBLen+1]:=Char(j);
- inc(PBLen,len);
- end;
-
- procedure Tfrs_GDS.BuildPBBoolean( var PB: array of char; var PBLen: Integer; item: byte; contents: Boolean);
- //Add a boolean value to a parameter block
- var
- len: Integer;
- begin
- PB[PBLen] := char(item);
- inc(PBLen);
- len:=sizeof(Boolean);
- PB[PBLen] := char(len);
- inc(PBLen);
- PB[PBLen] := Char(Contents);
- inc(PBLen,len);
- end;
-
- procedure Tfrs_GDS.BuildPBAddConstant(var PB: array of char; var PBLen: Integer; item: byte);
- //Add a Constant value to a parameter block
- begin
- PB[PBLen] := char(item);
- inc(PBLen);
- end;
-
- procedure Tfrs_GDS.SetErrorCode(AErrorCode: ISC_STATUS);
- begin
- FErrorCode:=AErrorCode;
- if FErrorCode <> 0 then
- HandleIBErrors
- else //clear old errormessage stack
- FErrorMessages:='';
- if FStatusVector[0]=1 then begin
- FStatusVector[0]:=0;
- end;
- end;
-
- procedure Tfrs_GDS.DatabaseClose;
- begin
- if assigned(FDBHandle) then
- if assigned(FTxnHandle) then
- raise EIBError.create('Transaction active. Cannot close database connection.')
- else begin
- ErrorCode := isc_detach_database( @FStatusVector, @FDbHandle);
- FDBHandle:=Nil;
- end;
-
- end;
-
- procedure Tfrs_GDS.DatabaseOpen;
- begin
- ErrorCode:=isc_attach_database(@FStatusVector,Length(FDBName),PChar(FDBName),@FDBHandle,FDPBLen,@FDPB);
- end;
-
- procedure Tfrs_GDS.TransactionCommit;
- begin
- if assigned(FTxnHandle) then begin
- errorcode:=isc_commit_transaction(@FStatusVector, @FTXnHandle);
- FTxnHandle:=Nil;
- end;
-
- // Tidy up statement handle resources
- try
- if assigned(FStmtHandle) then try
- isc_dsql_free_statement(@FStatusVector, @FStmtHandle, DSQL_Drop);
- except
- //do nothing
- end;
- finally
- FStmtHandle:=nil;
- end;
-
- //Clear OutputdataArea, but save InputDataArea
- try
- FreeSQLData(OutputDataArea);
- except
- //if there is an error, don't tell us about it - it is not critical
- //
- end;
-
- end;
-
- procedure Tfrs_GDS.TransactionRetain;
- begin
- //here, we want to see the error if the commit retaining fails
- if assigned(FTxnHandle) then
- ErrorCode:=isc_commit_retaining(@FStatusVector, @FTxnHandle)
- end;
-
- procedure Tfrs_GDS.TransactionRollback;
- begin
- //if this raises an error then ignore it - as it means that
- //we have probably lost our connection, and the txn will be rolled back anyway.
- if assigned(FTxnHandle) then begin
- isc_rollback_transaction(@FStatusVector, @FTxnHandle);
- FTxnHandle:=Nil;
- end;
-
- // Tidy up statement handle resources
- try
- if assigned(FStmtHandle) then try
- isc_dsql_free_statement(@FStatusVector, @FStmtHandle, DSQL_Drop);
- except
- //do nothing
- end;
- finally
- FStmtHandle:=nil;
- end;
-
- //Clear OutputdataArea, but save InputDataArea
- try
- FreeSQLData(OutputDataArea);
- except
- //if there is an error, don't tell us about it - it is not critical
- //
- end;
-
- end;
-
- procedure Tfrs_GDS.TransactionStart;
- begin
- if not assigned(FTxnHandle) then begin
-
- //Set up TEB
- with FTEB do begin
- db_ptr := @FDBhandle;
- tpb_len := 0;
- tpb_ptr := Nil
- end;
-
- //code here for tpb, if necessary
- //if FTPB[1]<>char(0) then
-
- errorcode:=isc_start_multiple(@FStatusVector, @FTxnHandle, 1, @FTEB);
-
- end;
- end;
-
- procedure Tfrs_GDS.SetFetchCode(const Value: ISC_STATUS);
- begin
- FFetchCode:=Value;
- case FFetchCode of
- 0 : FFetchStatus:=fsFetching{success};
- 100 : begin
- FFetchStatus:=fsFetched;
- ErrorCode:=isc_dsql_free_statement(@FStatusVector, @FStmtHandle, DSQL_close);
- end;
- else
- errorcode:=FFetchCode;
- end;
-
- end;
-
- Function Tfrs_GDS.IBDateStrToDateTime(DateTimeStr: String): TDateTime;
- {IBDateStr must be in the format of mm/dd/yyyy hh:nn:ss}
- var
- DT: TDateTime;
- Yr, Mn, Dy, Hr, Mt, Sc, Ms: Word;
- OldShortDateFormat: string;
- const
- MidnightStr: string =' 00:00:00:000';
- begin
- OldShortDateFormat:=ShortDateFormat;
- ShortDateFormat:='mm/dd/yyyy';
- try
- If uppercase(DateTimeStr)='TODAY' then
- DateTimeStr:=DateTimeToStr(Date)+MidnightStr
- else
- if uppercase(DateTimeStr)='YESTERDAY' then
- DateTimeStr:=DateTimeToStr(Date-1)+MidnightStr
- else
- if uppercase(DateTimeStr)='TOMORROW' then
- DateTimeStr:=DateTimeToStr(Date+1)+MidnightStr
- else
- if uppercase(DateTimeStr)='NOW' then
- DateTimeStr:=DateTimeToStr(Now)+':000';
- finally
- ShortDateFormat:=OldShortDateFormat;
- end;
-
- //Time24Hour:=True;
- Mn:=StrToInt(copy(DateTimeStr,1,2));
- Dy:=StrToInt(copy(DateTimeStr,4,2));
- Yr:=StrToInt(copy(DateTimeStr,7,4));
- Hr:=StrToInt(copy(DateTimeStr,12,2));
- Mt:=StrToInt(copy(DateTimeStr,15,2));
- Sc:=StrToInt(copy(DateTimeStr,18,2));
- Ms:=StrToInt(copy(DateTimeStr,21,3));
- DT:=EncodeDate(Yr,Mn,Dy);
- Result:=DT;
- DT:=EncodeTime(Hr,Mt,Sc,Ms);
- Result:=Result+DT;
- end;
-
- initialization
- frs_GDS:=Tfrs_GDS.create;
- finalization
- frs_GDS.free;
-
- end.
-