ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/public/ibx/trunk/fbintf/client/FBAttachment.pas
(Generate patch)

Comparing ibx/trunk/fbintf/client/FBAttachment.pas (file contents):
Revision 143 by tony, Fri Feb 23 12:11:21 2018 UTC vs.
Revision 345 by tony, Mon Aug 23 14:22:29 2021 UTC

# Line 38 | Line 38 | unit FBAttachment;
38   interface
39  
40   uses
41 <  Classes, SysUtils, {$IFDEF WINDOWS} windows, {$ENDIF} IB,  FBParamBlock, FBActivityMonitor;
41 >  Classes, SysUtils, {$IFDEF WINDOWS} windows, {$ENDIF} IB,  FBParamBlock,
42 >  FBActivityMonitor, FBClientAPI;
43 >
44 > const
45 >  DefaultMaxInlineBlobLimit = 8192;
46  
47   type
48    TCharsetMap = record
# Line 58 | Line 62 | type
62      FODSMajorVersion: integer;
63      FODSMinorVersion: integer;
64      FUserCharSetMap: array of TCharSetMap;
65 +    FSecDatabase: AnsiString;
66 +    FInlineBlobLimit: integer;
67    protected
68      FDatabaseName: AnsiString;
69      FRaiseExceptionOnConnectError: boolean;
# Line 67 | Line 73 | type
73      FCodePage: TSystemCodePage;
74      FRemoteProtocol: AnsiString;
75      FAuthMethod: AnsiString;
76 <    constructor Create(DatabaseName: AnsiString; DPB: IDPB;
76 >    constructor Create(api: TFBClientAPI; DatabaseName: AnsiString; DPB: IDPB;
77        RaiseExceptionOnConnectError: boolean);
78      procedure CheckHandle; virtual; abstract;
79      function GenerateCreateDatabaseSQL(DatabaseName: AnsiString; aDPB: IDPB): AnsiString;
# Line 77 | Line 83 | type
83      procedure EndAllTransactions;
84      procedure DPBFromCreateSQL(CreateSQL: AnsiString);
85      procedure SetParameters(SQLParams: ISQLParams; params: array of const);
86 +    procedure UseServerICUChanged; virtual;
87    public
88      destructor Destroy; override;
89 +    function getFirebirdAPI: IFirebirdAPI;
90      function getDPB: IDPB;
91      function AllocateBPB: IBPB;
92      function AllocateDIRB: IDIRB;
# Line 111 | Line 119 | type
119      function Prepare(transaction: ITransaction; sql: AnsiString; aSQLDialect: integer): IStatement; overload; virtual; abstract;
120      function Prepare(transaction: ITransaction; sql: AnsiString): IStatement; overload;
121      function PrepareWithNamedParameters(transaction: ITransaction; sql: AnsiString;
122 <                       aSQLDialect: integer; GenerateParamNames: boolean=false): IStatement; overload; virtual; abstract;
122 >                       aSQLDialect: integer; GenerateParamNames: boolean=false;
123 >                       CaseSensitiveParams: boolean = false): IStatement; overload; virtual; abstract;
124      function PrepareWithNamedParameters(transaction: ITransaction; sql: AnsiString;
125 <                       GenerateParamNames: boolean=false): IStatement; overload;
125 >                       GenerateParamNames: boolean=false;
126 >                       CaseSensitiveParams: boolean = false): IStatement; overload;
127      function GetEventHandler(Events: TStrings): IEvents; overload; virtual; abstract;
128      function GetEventHandler(Event: AnsiString): IEvents; overload;
129  
130      function GetSQLDialect: integer;
131 +    function CreateBlob(transaction: ITransaction; RelationName, ColumnName: AnsiString; BPB: IBPB=nil): IBlob; overload;
132 +    function CreateBlob(transaction: ITransaction; BlobMetaData: IBlobMetaData; BPB: IBPB=nil): IBlob; overload; virtual; abstract;
133      function OpenBlob(transaction: ITransaction; BlobMetaData: IBlobMetaData; BlobID: TISC_QUAD; BPB: IBPB=nil): IBlob; overload; virtual; abstract;
134 +    function OpenBlob(transaction: ITransaction; RelationName, ColumnName: AnsiString; BlobID: TISC_QUAD; BPB: IBPB=nil): IBlob; overload;
135      function OpenBlob(transaction: ITransaction; Field: ISQLData; BPB: IBPB=nil): IBlob; overload;
136 +    function CreateArray(transaction: ITransaction; RelationName, ColumnName: AnsiString
137 +      ): IArray; overload;
138 +    function CreateArray(transaction: ITransaction; ArrayMetaData: IArrayMetaData): IArray; overload; virtual; abstract;
139 +    function OpenArray(transaction: ITransaction; RelationName, ColumnName: AnsiString; ArrayID: TISC_QUAD): IArray; overload;
140 +    function OpenArray(transaction: ITransaction; ArrayMetaData: IArrayMetaData; ArrayID: TISC_QUAD): IArray; overload; virtual; abstract;
141      property SQLDialect: integer read FSQLDialect;
142      property DPB: IDPB read FDPB;
143 < public
144 <  function GetDBInformation(Requests: array of byte): IDBInformation; overload;
145 <  function GetDBInformation(Request: byte): IDBInformation; overload;
146 <  function GetDBInformation(Requests: IDIRB): IDBInformation; overload;
147 <  function GetConnectString: AnsiString;
148 <  function GetRemoteProtocol: AnsiString;
149 <  function GetAuthenticationMethod: AnsiString;
150 <  function GetODSMajorVersion: integer;
151 <  function GetODSMinorVersion: integer;
152 <  {Character Sets}
153 <  function HasDefaultCharSet: boolean;
154 <  function GetDefaultCharSetID: integer;
155 <  function GetCharsetName(CharSetID: integer): AnsiString;
156 <  function CharSetID2CodePage(CharSetID: integer; var CodePage: TSystemCodePage): boolean;
157 <  function CodePage2CharSetID(CodePage: TSystemCodePage; var CharSetID: integer): boolean;
158 <  function CharSetName2CharSetID(CharSetName: AnsiString; var CharSetID: integer): boolean;
159 <  function CharSetWidth(CharSetID: integer; var Width: integer): boolean;
160 <  procedure RegisterCharSet(CharSetName: AnsiString; CodePage: TSystemCodePage;
161 <    AllowReverseLookup:boolean; out CharSetID: integer);
162 <  property CharSetID: integer read FCharSetID;
163 <  property CodePage: TSystemCodePage read FCodePage;
143 >  public
144 >    function GetDBInformation(Requests: array of byte): IDBInformation; overload;
145 >    function GetDBInformation(Request: byte): IDBInformation; overload;
146 >    function GetDBInformation(Requests: IDIRB): IDBInformation; overload;
147 >    function GetConnectString: AnsiString;
148 >    function GetRemoteProtocol: AnsiString;
149 >    function GetAuthenticationMethod: AnsiString;
150 >    function GetSecurityDatabase: AnsiString;
151 >    function GetODSMajorVersion: integer;
152 >    function GetODSMinorVersion: integer;
153 >    function HasDecFloatSupport: boolean; virtual;
154 >    function GetInlineBlobLimit: integer;
155 >    procedure SetInlineBlobLimit(limit: integer);
156 >    function HasBatchMode: boolean; virtual;
157 >
158 >  public
159 >    {Character Sets}
160 >    function HasDefaultCharSet: boolean;
161 >    function GetDefaultCharSetID: integer;
162 >    function GetCharsetName(CharSetID: integer): AnsiString;
163 >    function CharSetID2CodePage(CharSetID: integer; var CodePage: TSystemCodePage): boolean;
164 >    function CodePage2CharSetID(CodePage: TSystemCodePage; var CharSetID: integer): boolean;
165 >    function CharSetName2CharSetID(CharSetName: AnsiString; var CharSetID: integer): boolean;
166 >    function CharSetWidth(CharSetID: integer; var Width: integer): boolean;
167 >    procedure RegisterCharSet(CharSetName: AnsiString; CodePage: TSystemCodePage;
168 >      AllowReverseLookup:boolean; out CharSetID: integer);
169 >    function GetBlobMetaData(Transaction: ITransaction; tableName, columnName: AnsiString): IBlobMetaData; virtual; abstract;
170 >    function GetArrayMetaData(Transaction: ITransaction; tableName, columnName: AnsiString): IArrayMetaData; virtual; abstract;
171 >    property CharSetID: integer read FCharSetID;
172 >    property CodePage: TSystemCodePage read FCodePage;
173 >
174 >  public
175 >    {Time Zone Support}
176 >    function GetTimeZoneServices: ITimeZoneServices; virtual;
177 >    function HasTimeZoneSupport: boolean; virtual;
178 >
179 >  end;
180 >
181 >  { TDPBItem }
182 >
183 >  TDPBItem = class(TParamBlockItem,IDPBItem)
184 >  public
185 >   function getParamTypeName: AnsiString; override;
186 >  end;
187 >
188 >  { TDPB }
189 >
190 >  TDPB = class (TCustomParamBlock<TDPBItem,IDPBItem>, IDPB)
191 >  protected
192 >   function LookupItemType(ParamTypeName: AnsiString): byte; override;
193 >  public
194 >    constructor Create(api: TFBClientAPI);
195 >    function GetParamTypeName(ParamType: byte): Ansistring;
196 >    {$IFDEF FPC}
197 >    function IDPB.GetDPBParamTypeName = GetParamTypeName;
198 >    {$ELSE}
199 >    function GetDPBParamTypeName(ParamType: byte): Ansistring;
200 >    {$ENDIF}
201    end;
202  
203   implementation
# Line 223 | Line 278 | const
278    (CharsetID: 69; CharSetName: 'GB18030'; CharSetWidth: 4; CodePage: 54936; AllowReverseLookup: true)
279   );
280  
281 + const
282 +  isc_dpb_last_dpb_constant = isc_dpb_decfloat_traps;
283 +
284 +  DPBConstantNames: array[1..isc_dpb_last_dpb_constant] of string = (
285 +    'cdd_pathname',
286 +    'allocation',
287 +    'journal',
288 +    'page_size',
289 +    'num_buffers',
290 +    'buffer_length',
291 +    'debug',
292 +    'garbage_collect',
293 +    'verify',
294 +    'sweep',
295 +    'enable_journal',
296 +    'disable_journal',
297 +    'dbkey_scope',
298 +    'number_of_users',
299 +    'trace',
300 +    'no_garbage_collect',
301 +    'damaged',
302 +    'license',
303 +    'sys_user_name',
304 +    'encrypt_key',
305 +    'activate_shadow',
306 +    'sweep_interval',
307 +    'delete_shadow',
308 +    'force_write',
309 +    'begin_log',
310 +    'quit_log',
311 +    'no_reserve',
312 +    'user_name',
313 +    'password',
314 +    'password_enc',
315 +    'sys_user_name_enc',
316 +    'interp',
317 +    'online_dump',
318 +    'old_file_size',
319 +    'old_num_files',
320 +    'old_file',
321 +    'old_start_page',
322 +    'old_start_seqno',
323 +    'old_start_file',
324 +    'drop_walfile',
325 +    'old_dump_id',
326 +    'wal_backup_dir',
327 +    'wal_chkptlen',
328 +    'wal_numbufs',
329 +    'wal_bufsize',
330 +    'wal_grp_cmt_wait',
331 +    'lc_messages',
332 +    'lc_ctype',
333 +    'cache_manager',
334 +    'shutdown',
335 +    'online',
336 +    'shutdown_delay',
337 +    'reserved',
338 +    'overwrite',
339 +    'sec_attach',
340 +    'disable_wal',
341 +    'connect_timeout',
342 +    'dummy_packet_interval',
343 +    'gbak_attach',
344 +    'sql_role_name',
345 +    'set_page_buffers',
346 +    'working_directory',
347 +    'sql_dialect',
348 +    'set_db_readonly',
349 +    'set_db_sql_dialect',
350 +    'gfix_attach',
351 +    'gstat_attach',
352 +    'set_db_charset',
353 +    'gsec_attach',
354 +    'address_path' ,
355 +    'process_id',
356 +    'no_db_triggers',
357 +    'trusted_auth',
358 +    'process_name',
359 +    'trusted_role',
360 +    'org_filename',
361 +    'utf8_ilename',
362 +    'ext_call_depth',
363 +    'auth_block',
364 +    'client_version',
365 +    'remote_protocol',
366 +    'host_name',
367 +    'os_user',
368 +    'specific_auth_data',
369 +    'auth_plugin_list',
370 +    'auth_plugin_name',
371 +    'config',
372 +    'nolinger',
373 +    'reset_icu',
374 +    'map_attach',
375 +    'session_time_zone',
376 +    'set_db_replica',
377 +    'set_bind',
378 +    'decfloat_round',
379 +    'decfloat_traps'
380 +    );
381  
382  
383  
# Line 252 | Line 407 | begin
407    FCharSetID := 0;
408    FRemoteProtocol := '';
409    FAuthMethod := 'Legacy_Auth';
410 +  FSecDatabase := 'Default';
411    if FODSMajorVersion > 11 then
412    begin
413      Stmt := Prepare(StartTransaction([isc_tpb_read,isc_tpb_nowait,isc_tpb_concurrency],taCommit),
414 <                    'Select MON$CHARACTER_SET_ID, MON$REMOTE_PROTOCOL, MON$AUTH_METHOD From MON$ATTACHMENTS '+
415 <                    'Where MON$ATTACHMENT_ID = CURRENT_CONNECTION');
414 >                    'Select MON$CHARACTER_SET_ID, MON$REMOTE_PROTOCOL, MON$AUTH_METHOD, MON$SEC_DATABASE From MON$ATTACHMENTS, MON$DATABASE '+
415 >                    'Where MON$ATTACHMENT_ID = CURRENT_CONNECTION ');
416      ResultSet := Stmt.OpenCursor;
417      if ResultSet.FetchNext then
418      begin
419        FCharSetID := ResultSet[0].AsInteger;
420 <      FRemoteProtocol := ResultSet[1].AsString;
421 <      FAuthMethod := ResultSet[2].AsString;
420 >      FRemoteProtocol := Trim(ResultSet[1].AsString);
421 >      FAuthMethod := Trim(ResultSet[2].AsString);
422 >      FSecDatabase := Trim(ResultSet[3].AsString);
423      end
424    end
425    else
# Line 275 | Line 432 | begin
432      if ResultSet.FetchNext then
433      begin
434        FCharSetID := ResultSet[0].AsInteger;
435 <      FRemoteProtocol := ResultSet[1].AsString;
435 >      FRemoteProtocol := Trim(ResultSet[1].AsString);
436      end
437    end
438    else
# Line 294 | Line 451 | begin
451    FHasDefaultCharSet := CharSetID2CodePage(FCharSetID,FCodePage) and (FCharSetID > 1);
452   end;
453  
454 < constructor TFBAttachment.Create(DatabaseName: AnsiString; DPB: IDPB;
455 <  RaiseExceptionOnConnectError: boolean);
454 > constructor TFBAttachment.Create(api: TFBClientAPI; DatabaseName: AnsiString;
455 >  DPB: IDPB; RaiseExceptionOnConnectError: boolean);
456   begin
457    inherited Create;
458 <  FFirebirdAPI := FirebirdAPI; {Keep reference to interface}
458 >  FFirebirdAPI := api.GetAPI; {Keep reference to interface}
459    FSQLDialect := 3;
460    FDatabaseName := DatabaseName;
461    FDPB := DPB;
# Line 306 | Line 463 | begin
463    FRaiseExceptionOnConnectError := RaiseExceptionOnConnectError;
464    FODSMajorVersion := 0;
465    FODSMinorVersion := 0;
466 +  FInlineBlobLimit := DefaultMaxInlineBlobLimit;
467   end;
468  
469   function TFBAttachment.GenerateCreateDatabaseSQL(DatabaseName: AnsiString;  aDPB: IDPB): AnsiString;
# Line 439 | Line 597 | begin
597    end;
598   end;
599  
600 + procedure TFBAttachment.UseServerICUChanged;
601 + begin
602 +  // Do nothing by default
603 + end;
604 +
605   destructor TFBAttachment.Destroy;
606   begin
607    Disconnect(true);
608    inherited Destroy;
609   end;
610  
611 + function TFBAttachment.getFirebirdAPI: IFirebirdAPI;
612 + begin
613 +  Result := FFirebirdAPI;
614 + end;
615 +
616   function TFBAttachment.getDPB: IDPB;
617   begin
618    Result := FDPB;
# Line 452 | Line 620 | end;
620  
621   function TFBAttachment.AllocateBPB: IBPB;
622   begin
623 <  Result := TBPB.Create;
623 >  Result := TBPB.Create(FFirebirdAPI as TFBClientAPI);
624   end;
625  
626   function TFBAttachment.AllocateDIRB: IDIRB;
627   begin
628 <  Result := TDIRB.Create;
628 >  Result := TDIRB.Create(FFirebirdAPI as TFBClientAPI);
629   end;
630  
631   procedure TFBAttachment.ExecImmediate(TPB: array of byte; sql: AnsiString;
# Line 580 | Line 748 | begin
748   end;
749  
750   function TFBAttachment.PrepareWithNamedParameters(transaction: ITransaction;
751 <  sql: AnsiString; GenerateParamNames: boolean): IStatement;
751 >  sql: AnsiString; GenerateParamNames: boolean; CaseSensitiveParams: boolean): IStatement;
752   begin
753 <  Result := PrepareWithNamedParameters(transaction,sql,FSQLDialect,GenerateParamNames);
753 >  Result := PrepareWithNamedParameters(transaction,sql,FSQLDialect,GenerateParamNames,CaseSensitiveParams);
754   end;
755  
756   function TFBAttachment.GetEventHandler(Event: AnsiString): IEvents;
# Line 602 | Line 770 | begin
770    Result := FSQLDialect;
771   end;
772  
773 + function TFBAttachment.CreateBlob(transaction: ITransaction; RelationName,
774 +  ColumnName: AnsiString; BPB: IBPB): IBlob;
775 + begin
776 +  Result := CreateBlob(transaction,GetBlobMetaData(Transaction,RelationName,ColumnName),BPB);
777 + end;
778 +
779 + function TFBAttachment.OpenBlob(transaction: ITransaction; RelationName,
780 +  ColumnName: AnsiString; BlobID: TISC_QUAD; BPB: IBPB): IBlob;
781 + begin
782 +  Result := OpenBlob(Transaction,
783 +                GetBlobMetaData(Transaction,RelationName,ColumnName),
784 +                BlobID,BPB);
785 + end;
786 +
787   function TFBAttachment.OpenBlob(transaction: ITransaction; Field: ISQLData;
788    BPB: IBPB): IBlob;
789   begin
790    Result := OpenBlob(Transaction,Field.GetBlobMetadata, Field.AsQuad,BPB);
791   end;
792  
793 + function TFBAttachment.CreateArray(transaction: ITransaction; RelationName,
794 +  ColumnName: AnsiString): IArray;
795 + begin
796 +  Result := CreateArray(transaction,GetArrayMetaData(transaction,RelationName,ColumnName));
797 + end;
798 +
799 + function TFBAttachment.OpenArray(transaction: ITransaction; RelationName,
800 +  ColumnName: AnsiString; ArrayID: TISC_QUAD): IArray;
801 + begin
802 +  Result := OpenArray(transaction,
803 +    GetArrayMetaData(transaction,RelationName,ColumnName),ArrayID);
804 + end;
805 +
806   function TFBAttachment.GetDBInformation(Requests: array of byte
807    ): IDBInformation;
808   var ReqBuffer: PByte;
# Line 659 | Line 854 | begin
854    Result := FAuthMethod;
855   end;
856  
857 + function TFBAttachment.GetSecurityDatabase: AnsiString;
858 + begin
859 +  Result := FSecDatabase;
860 + end;
861 +
862   function TFBAttachment.GetODSMajorVersion: integer;
863   begin
864    Result := FODSMajorVersion;
# Line 669 | Line 869 | begin
869    Result := FODSMinorVersion;
870   end;
871  
872 + function TFBAttachment.HasDecFloatSupport: boolean;
873 + begin
874 +  Result := false;
875 + end;
876 +
877 + function TFBAttachment.GetInlineBlobLimit: integer;
878 + begin
879 +  Result := FInlineBlobLimit;
880 + end;
881 +
882 + procedure TFBAttachment.SetInlineBlobLimit(limit: integer);
883 + begin
884 +  if limit > 32*1024 then
885 +     FInlineBlobLimit := 32*1024
886 +  else
887 +    FInlineBlobLimit := limit;
888 + end;
889 +
890 + function TFBAttachment.HasBatchMode: boolean;
891 + begin
892 +  Result := false;
893 + end;
894 +
895   function TFBAttachment.HasDefaultCharSet: boolean;
896   begin
897    Result := FHasDefaultCharSet
# Line 748 | Line 971 | var i: integer;
971   begin
972    Result := false;
973    for i := Low(CharSetMap) to High(CharSetMap) do
974 <    if AnsiCompareStr(CharSetMap[i].CharSetName, CharSetName) = 0 then
974 >    if AnsiCompareText(CharSetMap[i].CharSetName, CharSetName) = 0 then
975      begin
976        CharSetID := CharSetMap[i].CharSetID;
977        Result := true;
# Line 756 | Line 979 | begin
979      end;
980  
981      for i := 0 to Length(FUserCharSetMap) - 1 do
982 <      if AnsiCompareStr(FUserCharSetMap[i].CharSetName, CharSetName) = 0 then
982 >      if AnsiCompareText(FUserCharSetMap[i].CharSetName, CharSetName) = 0 then
983        begin
984          CharSetID := FUserCharSetMap[i].CharSetID;
985          Result := true;
# Line 813 | Line 1036 | begin
1036    CharSetID := CharSets[0].AsInteger;
1037   end;
1038  
1039 + function TFBAttachment.GetTimeZoneServices: ITimeZoneServices;
1040 + begin
1041 +  IBError(ibxeNotSupported,[]);
1042 + end;
1043 +
1044 + function TFBAttachment.HasTimeZoneSupport: boolean;
1045 + begin
1046 +  Result := false;
1047 + end;
1048 +
1049 + { TDPBItem }
1050 +
1051 + function TDPBItem.getParamTypeName: AnsiString;
1052 + begin
1053 +  Result := DPBPrefix + DPBConstantNames[getParamType];
1054 + end;
1055 +
1056 + { TDPB }
1057 +
1058 + constructor TDPB.Create(api: TFBClientAPI);
1059 + begin
1060 +  inherited Create(api);
1061 +  FDataLength := 1;
1062 +  FBuffer^ := isc_dpb_version1;
1063 + end;
1064 +
1065 + function TDPB.GetParamTypeName(ParamType: byte): Ansistring;
1066 + begin
1067 +  if ParamType <= isc_dpb_last_dpb_constant then
1068 +    Result := DPBConstantNames[ParamType]
1069 +  else
1070 +    Result := '';
1071 + end;
1072 +
1073 + {$IFNDEF FPC}
1074 + function TDPB.GetDPBParamTypeName(ParamType: byte): Ansistring;
1075 + begin
1076 +  Result := GetParamTypeName(ParamType);
1077 + end;
1078 + {$ENDIF}
1079 +
1080 + function TDPB.LookupItemType(ParamTypeName: AnsiString): byte;
1081 + var i: byte;
1082 + begin
1083 +  Result := 0;
1084 +  ParamTypeName := LowerCase(ParamTypeName);
1085 +  if (Pos(DPBPrefix, ParamTypeName) = 1) then
1086 +    Delete(ParamTypeName, 1, Length(DPBPrefix));
1087 +
1088 +  for i := 1 to isc_dpb_last_dpb_constant do
1089 +    if (ParamTypeName = DPBConstantNames[i]) then
1090 +    begin
1091 +      Result := i;
1092 +      break;
1093 +    end;
1094 + end;
1095 +
1096   end.
1097  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines