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

Comparing ibx/branches/udr/client/FBAttachment.pas (file contents):
Revision 371 by tony, Wed Jan 5 15:21:22 2022 UTC vs.
Revision 388 by tony, Wed Jan 19 13:58:37 2022 UTC

# Line 96 | Line 96 | type
96      const sQueryJournal          = '*Q:''%s'',%d,%d,%d,%d:%s' + LineEnding;
97      const sTransStartJnl         = '*S:''%s'',%d,%d,%d,%d:%s,%d:%s,%d' + LineEnding;
98      const sTransCommitJnl        = '*C:''%s'',%d,%d,%d' + LineEnding;
99 +    const sTransCommitFailJnl    = '*F:''%s'',%d,%d,%d' + LineEnding;
100      const sTransCommitRetJnl     = '*c:''%s'',%d,%d,%d,%d' + LineEnding;
101      const sTransRollBackJnl      = '*R:''%s'',%d,%d,%d' + LineEnding;
102 +    const sTransRollBackFailJnl  = '*f:''%s'',%d,%d,%d' + LineEnding;
103      const sTransRollBackRetJnl   = '*r:''%s'',%d,%d,%d,%d' + LineEnding;
104    private
105      FOptions: TJournalOptions;
# Line 115 | Line 117 | type
117    public
118      {IJournallingHook}
119      procedure TransactionStart(Tr: ITransaction);
120 <    function TransactionEnd( TransactionID: integer; Action: TTransactionAction): boolean;
120 >    function TransactionEnd( TransactionID: integer; Completion: TTrCompletionState): boolean;
121      procedure TransactionRetained(Tr: ITransaction; OldTransactionID: integer;
122        Action: TTransactionAction);
123      procedure ExecQuery(Stmt: IStatement);
124 +    procedure ExecImmediateJnl(sql: AnsiString; tr: ITransaction);
125    public
126      {Client side Journaling}
127      function JournalingActive: boolean;
# Line 141 | Line 144 | type
144      FSecDatabase: AnsiString;
145      FInlineBlobLimit: integer;
146      FAttachmentID: integer;
144  protected
145    FDatabaseName: AnsiString;
146    FRaiseExceptionOnConnectError: boolean;
147      FSQLDialect: integer;
148      FHasDefaultCharSet: boolean;
149      FCharSetID: integer;
150      FCodePage: TSystemCodePage;
151      FRemoteProtocol: AnsiString;
152      FAuthMethod: AnsiString;
153 +    FHasConnectionInfo: boolean;
154 +    procedure NeedDBInfo;
155 +    procedure NeedConnectionInfo;
156 +  protected
157 +    FDatabaseName: AnsiString;
158 +    FRaiseExceptionOnConnectError: boolean;
159      constructor Create(api: TFBClientAPI; DatabaseName: AnsiString; DPB: IDPB;
160        RaiseExceptionOnConnectError: boolean);
161      procedure CheckHandle; virtual; abstract;
162 +    procedure ClearCachedInfo;
163      function GenerateCreateDatabaseSQL(DatabaseName: AnsiString; aDPB: IDPB): AnsiString;
157    procedure GetODSAndConnectionInfo;
164      function GetDBInfo(ReqBuffer: PByte; ReqBufLen: integer): IDBInformation; virtual; abstract;
165      function IsConnected: boolean; virtual; abstract;
166      procedure EndAllTransactions;
167      procedure DPBFromCreateSQL(CreateSQL: AnsiString);
168      procedure SetParameters(SQLParams: ISQLParams; params: array of const);
169 +    procedure SetSQLDialect(aValue: integer);
170      procedure UseServerICUChanged; virtual;
171    public
172      destructor Destroy; override;
173 +    procedure Disconnect(Force: boolean); override;
174      function getFirebirdAPI: IFirebirdAPI;
175      function getDPB: IDPB;
176      function AllocateBPB: IBPB;
# Line 230 | Line 238 | type
238      function CreateArray(transaction: ITransaction; ArrayMetaData: IArrayMetaData): IArray; overload; virtual; abstract;
239      function OpenArray(transaction: ITransaction; RelationName, ColumnName: AnsiString; ArrayID: TISC_QUAD): IArray; overload;
240      function OpenArray(transaction: ITransaction; ArrayMetaData: IArrayMetaData; ArrayID: TISC_QUAD): IArray; overload; virtual; abstract;
241 <    property SQLDialect: integer read FSQLDialect;
241 >    property SQLDialect: integer read GetSQLDialect;
242      property DPB: IDPB read FDPB;
243    public
244      function GetDBInformation(Requests: array of byte): IDBInformation; overload;
# Line 264 | Line 272 | type
272        AllowReverseLookup:boolean; out CharSetID: integer);
273      function GetBlobMetaData(Transaction: ITransaction; tableName, columnName: AnsiString): IBlobMetaData; virtual; abstract;
274      function GetArrayMetaData(Transaction: ITransaction; tableName, columnName: AnsiString): IArrayMetaData; virtual; abstract;
275 <    property CharSetID: integer read FCharSetID;
275 >    property CharSetID: integer read GetCharSetID;
276      property CodePage: TSystemCodePage read FCodePage;
277  
278    public
# Line 478 | Line 486 | const
486      'process_name',
487      'trusted_role',
488      'org_filename',
489 <    'utf8_ilename',
489 >    'utf8_filename',
490      'ext_call_depth',
491      'auth_block',
492      'client_version',
# Line 642 | Line 650 | procedure TFBJournaling.TransactionStart
650   var LogEntry: AnsiString;
651      TPBText: AnsiString;
652   begin
645  FDoNotJournal := true;
653    if not (joNoServerTable in FOptions) then
654    try
655 +    FDoNotJournal := true;
656      GetAttachment.ExecuteSQL(Tr,sqlRecordJournalEntry,[FSessionID,Tr.GetTransactionID,NULL]);
657    finally
658      FDoNotJournal := false;
# Line 663 | Line 671 | begin
671   end;
672  
673   function TFBJournaling.TransactionEnd(TransactionID: integer;
674 <  Action: TTransactionAction): boolean;
674 >  Completion: TTrCompletionState): boolean;
675  
676   var LogEntry: AnsiString;
677   begin
678    Result := false;
679 <    case Action of
680 <    TARollback:
679 >    case Completion of
680 >    trRolledback:
681        begin
682          LogEntry := Format(sTransRollbackJnl,[FBFormatDateTime(GetDateTimeFmt,Now),
683                                                GetAttachment.GetAttachmentID,
684                                                FSessionID,TransactionID]);
685          Result := true;
686        end;
687 <    TACommit:
687 >
688 >    trRollbackFailed:
689 >      begin
690 >        LogEntry := Format(sTransRollbackFailJnl,[FBFormatDateTime(GetDateTimeFmt,Now),
691 >                                              GetAttachment.GetAttachmentID,
692 >                                              FSessionID,TransactionID]);
693 >        Result := true;
694 >      end;
695 >
696 >    trCommitted:
697        begin
698          LogEntry := Format(sTransCommitJnl,[FBFormatDateTime(GetDateTimeFmt,Now),
699                                              GetAttachment.GetAttachmentID,
700                                              FSessionID,TransactionID]);
701          Result := true;
702        end;
703 +
704 +    trCommitFailed:
705 +      begin
706 +        LogEntry := Format(sTransCommitFailJnl,[FBFormatDateTime(GetDateTimeFmt,Now),
707 +                                            GetAttachment.GetAttachmentID,
708 +                                            FSessionID,TransactionID]);
709 +        Result := true;
710 +      end;
711      end;
712      if assigned(FJournalFileStream) then
713        FJournalFileStream.Write(LogEntry[1],Length(LogEntry));
# Line 705 | Line 730 | begin
730      if assigned(FJournalFileStream) then
731        FJournalFileStream.Write(LogEntry[1],Length(LogEntry));
732  
708    FDoNotJournal := true;
733      if not (joNoServerTable in FOptions) then
734      try
735 +      FDoNotJournal := true;
736        GetAttachment.ExecuteSQL(Tr,sqlRecordJournalEntry,[FSessionID,Tr.GetTransactionID,OldTransactionID]);
737      finally
738        FDoNotJournal := false;
# Line 728 | Line 753 | begin
753      FJournalFileStream.Write(LogEntry[1],Length(LogEntry));
754   end;
755  
756 + procedure TFBJournaling.ExecImmediateJnl(sql: AnsiString; tr: ITransaction);
757 + var LogEntry: AnsiString;
758 + begin
759 +  LogEntry := Format(sQueryJournal,[FBFormatDateTime(GetDateTimeFmt,Now),
760 +                                      GetAttachment.GetAttachmentID,
761 +                                      FSessionID,
762 +                                      tr.GetTransactionID,
763 +                                      Length(sql),sql]);
764 +  if assigned(FJournalFileStream) then
765 +    FJournalFileStream.Write(LogEntry[1],Length(LogEntry));
766 + end;
767 +
768   function TFBJournaling.JournalingActive: boolean;
769   begin
770    Result := (FJournalFileStream <> nil) and not FDoNotJournal;
# Line 776 | Line 813 | begin
813    EndSession(RetainJournal);
814   end;
815  
779
780
781
816   { TFBAttachment }
817  
818 < procedure TFBAttachment.GetODSAndConnectionInfo;
819 < var DBInfo: IDBInformation;
786 <    i: integer;
787 <    Stmt: IStatement;
818 > procedure TFBAttachment.NeedConnectionInfo;
819 > var Stmt: IStatement;
820      ResultSet: IResultSet;
821      Param: IDPBItem;
822   begin
823 <  if not IsConnected then Exit;
824 <  DBInfo := GetDBInformation([isc_info_db_id,isc_info_ods_version,isc_info_ods_minor_version,
793 <                               isc_info_db_SQL_Dialect, isc_info_attachment_id]);
794 <  for i := 0 to DBInfo.GetCount - 1 do
795 <    with DBInfo[i] do
796 <      case getItemType of
797 <      isc_info_ods_minor_version:
798 <        FODSMinorVersion := getAsInteger;
799 <      isc_info_ods_version:
800 <        FODSMajorVersion := getAsInteger;
801 <      isc_info_db_SQL_Dialect:
802 <        FSQLDialect := getAsInteger;
803 <      isc_info_attachment_id:
804 <        FAttachmentID := getAsInteger;
805 <      end;
806 <
823 >  if not IsConnected or FHasConnectionInfo then Exit;
824 >  NeedDBInfo;
825    FCharSetID := 0;
826    FRemoteProtocol := '';
827    FAuthMethod := 'Legacy_Auth';
# Line 849 | Line 867 | begin
867      end;
868    end;
869    FHasDefaultCharSet := CharSetID2CodePage(FCharSetID,FCodePage) and (FCharSetID > 1);
870 +  FHasConnectionInfo := true;
871 + end;
872 +
873 + procedure TFBAttachment.NeedDBInfo;
874 + var DBInfo: IDBInformation;
875 +    i: integer;
876 + begin
877 +  if not IsConnected or (FAttachmentID > 0) then Exit;
878 +  DBInfo := GetDBInformation([isc_info_db_id,isc_info_ods_version,isc_info_ods_minor_version,
879 +                               isc_info_db_SQL_Dialect, isc_info_attachment_id]);
880 +  for i := 0 to DBInfo.GetCount - 1 do
881 +    with DBInfo[i] do
882 +      case getItemType of
883 +      isc_info_ods_minor_version:
884 +        FODSMinorVersion := getAsInteger;
885 +      isc_info_ods_version:
886 +        FODSMajorVersion := getAsInteger;
887 +      isc_info_db_SQL_Dialect:
888 +        FSQLDialect := getAsInteger;
889 +      isc_info_attachment_id:
890 +        FAttachmentID := getAsInteger;
891 +      end;
892   end;
893  
894   constructor TFBAttachment.Create(api: TFBClientAPI; DatabaseName: AnsiString;
# Line 859 | Line 899 | begin
899    FSQLDialect := 3;
900    FDatabaseName := DatabaseName;
901    SetLength(FUserCharSetMap,0);
902 <  FODSMajorVersion := 0;
863 <  FODSMinorVersion := 0;
902 >  ClearCachedInfo;
903    FInlineBlobLimit := DefaultMaxInlineBlobLimit;
904    FDPB := DPB;
905    FRaiseExceptionOnConnectError := RaiseExceptionOnConnectError;
906   end;
907  
908 + procedure TFBAttachment.ClearCachedInfo;
909 + begin
910 +  FHasDefaultCharSet := false;
911 +  FAttachmentID := 0;
912 +  FODSMajorVersion := 0;
913 +  FODSMinorVersion := 0;
914 +  FCodePage := CP_NONE;
915 +  FCharSetID := 0;
916 +  FRemoteProtocol := '';
917 +  FAuthMethod := '';
918 +  FSecDatabase := '';
919 +  FHasConnectionInfo := false;
920 + end;
921 +
922   function TFBAttachment.GenerateCreateDatabaseSQL(DatabaseName: AnsiString;  aDPB: IDPB): AnsiString;
923   var CreateParams: AnsiString;
924      DPBItem: IDPBItem;
# Line 997 | Line 1050 | begin
1050    end;
1051   end;
1052  
1053 + procedure TFBAttachment.SetSQLDialect(aValue: integer);
1054 + begin
1055 +  FSQLDialect := aValue;
1056 + end;
1057 +
1058   procedure TFBAttachment.UseServerICUChanged;
1059   begin
1060    // Do nothing by default
# Line 1008 | Line 1066 | begin
1066    inherited Destroy;
1067   end;
1068  
1069 + procedure TFBAttachment.Disconnect(Force: boolean);
1070 + begin
1071 +  inherited Disconnect(Force);
1072 +  ClearCachedInfo;
1073 + end;
1074 +
1075   function TFBAttachment.getFirebirdAPI: IFirebirdAPI;
1076   begin
1077    Result := FFirebirdAPI;
# Line 1030 | Line 1094 | end;
1094  
1095   procedure TFBAttachment.ExecImmediate(TPB: array of byte; sql: AnsiString;
1096    aSQLDialect: integer);
1097 + var tr: ITransaction;
1098   begin
1099 <  ExecImmediate(StartTransaction(TPB,taCommit),sql,aSQLDialect);
1099 >  tr := StartTransaction(TPB,taCommit);
1100 >  try
1101 >    ExecImmediate(tr,sql,aSQLDialect);
1102 >    tr.Commit;
1103 >  except
1104 >    tr.Rollback(true);
1105 >    raise;
1106 >  end;
1107   end;
1108  
1109   procedure TFBAttachment.ExecImmediate(transaction: ITransaction; sql: AnsiString);
# Line 1041 | Line 1113 | end;
1113  
1114   procedure TFBAttachment.ExecImmediate(TPB: array of byte; sql: AnsiString);
1115   begin
1116 <  ExecImmediate(StartTransaction(TPB,taCommit),sql,FSQLDialect);
1116 >  ExecImmediate(TPB,sql,FSQLDialect);
1117   end;
1118  
1119   function TFBAttachment.ExecuteSQL(TPB: array of byte; sql: AnsiString;
1120    SQLDialect: integer; params: array of const): IResults;
1121 + var tr: ITransaction;
1122   begin
1123 <  Result := ExecuteSQL(StartTransaction(TPB,taCommit),sql,SQLDialect,params);
1123 >  tr := StartTransaction(TPB,taCommit);
1124 >  try
1125 >    Result := ExecuteSQL(tr,sql,SQLDialect,params);
1126 >    tr.Commit;
1127 >  except
1128 >    tr.Rollback(true);
1129 >    raise;
1130 >  end;
1131   end;
1132  
1133   function TFBAttachment.ExecuteSQL(transaction: ITransaction; sql: AnsiString;
# Line 1063 | Line 1143 | end;
1143   function TFBAttachment.ExecuteSQL(TPB: array of byte; sql: AnsiString;
1144    params: array of const): IResults;
1145   begin
1146 <   Result := ExecuteSQL(StartTransaction(TPB,taCommit),sql,params);
1146 >   Result := ExecuteSQL(TPB,sql,FSQLDialect,params);
1147   end;
1148  
1149   function TFBAttachment.ExecuteSQL(transaction: ITransaction; sql: AnsiString;
1150    params: array of const): IResults;
1151   begin
1152 <  with Prepare(transaction,sql,FSQLDialect) do
1073 <  begin
1074 <    SetParameters(SQLParams,params);
1075 <    Result := Execute;
1076 <  end;
1152 >  Result := ExecuteSQL(transaction,sql,FSQLDialect,params);
1153   end;
1154  
1155   function TFBAttachment.OpenCursor(transaction: ITransaction; sql: AnsiString;
# Line 1166 | Line 1242 | end;
1242  
1243   function TFBAttachment.OpenCursorAtStart(sql: AnsiString; Scrollable: boolean;
1244    params: array of const): IResultSet;
1245 + var tr: ITransaction;
1246   begin
1247 <  Result := OpenCursorAtStart(StartTransaction([isc_tpb_read,isc_tpb_wait,isc_tpb_concurrency],taCommit),sql,FSQLDialect,
1248 <                   Scrollable,params);
1247 >  tr := StartTransaction([isc_tpb_read,isc_tpb_wait,isc_tpb_concurrency],taCommit);
1248 >  try
1249 >    Result := OpenCursorAtStart(tr,sql,FSQLDialect,Scrollable,params);
1250 >    tr.Commit;
1251 >  except
1252 >    tr.Rollback(true);
1253 >    raise;
1254 >  end;
1255   end;
1256  
1257   function TFBAttachment.OpenCursorAtStart(sql: AnsiString;
1258    params: array of const): IResultSet;
1259   begin
1260 <  Result := OpenCursorAtStart(StartTransaction([isc_tpb_read,isc_tpb_wait,isc_tpb_concurrency],taCommit),sql,FSQLDialect,
1178 <                   false,params);
1260 >  Result := OpenCursorAtStart(sql,false,params);
1261   end;
1262  
1263   function TFBAttachment.Prepare(transaction: ITransaction; sql: AnsiString;
# Line 1205 | Line 1287 | end;
1287  
1288   function TFBAttachment.GetSQLDialect: integer;
1289   begin
1290 +  NeedDBInfo;
1291    Result := FSQLDialect;
1292   end;
1293  
1294   function TFBAttachment.GetAttachmentID: integer;
1295   begin
1296 +  NeedDBInfo;
1297    Result := FAttachmentID;
1298   end;
1299  
# Line 1289 | Line 1373 | end;
1373  
1374   function TFBAttachment.GetRemoteProtocol: AnsiString;
1375   begin
1376 +  NeedConnectionInfo;
1377    Result := FRemoteProtocol;
1378   end;
1379  
1380   function TFBAttachment.GetAuthenticationMethod: AnsiString;
1381   begin
1382 +  NeedConnectionInfo;
1383    Result := FAuthMethod;
1384   end;
1385  
1386   function TFBAttachment.GetSecurityDatabase: AnsiString;
1387   begin
1388 +  NeedConnectionInfo;
1389    Result := FSecDatabase;
1390   end;
1391  
1392   function TFBAttachment.GetODSMajorVersion: integer;
1393   begin
1394 +  NeedDBInfo;
1395    Result := FODSMajorVersion;
1396   end;
1397  
1398   function TFBAttachment.GetODSMinorVersion: integer;
1399   begin
1400 +  NeedDBInfo;
1401    Result := FODSMinorVersion;
1402   end;
1403  
1404   function TFBAttachment.GetCharSetID: integer;
1405   begin
1406 +  NeedConnectionInfo;
1407    Result := FCharSetID;
1408   end;
1409  
# Line 1363 | Line 1453 | end;
1453  
1454   function TFBAttachment.HasDefaultCharSet: boolean;
1455   begin
1456 +  NeedConnectionInfo;
1457    Result := FHasDefaultCharSet
1458   end;
1459  
1460   function TFBAttachment.GetDefaultCharSetID: integer;
1461   begin
1462 +  NeedConnectionInfo;
1463    Result := FCharsetID;
1464   end;
1465  

Comparing ibx/branches/udr/client/FBAttachment.pas (property svn:eol-style):
Revision 371 by tony, Wed Jan 5 15:21:22 2022 UTC vs.
Revision 388 by tony, Wed Jan 19 13:58:37 2022 UTC

# Line 0 | Line 1
1 + native

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines