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/journaling/fbintf/client/FBAttachment.pas (file contents), Revision 363 by tony, Tue Dec 7 13:30:05 2021 UTC vs.
ibx/branches/udr/client/FBAttachment.pas (file contents), Revision 371 by tony, Wed Jan 5 15:21:22 2022 UTC

# Line 16 | Line 16
16   *
17   *  The Initial Developer of the Original Code is Tony Whyman.
18   *
19 < *  The Original Code is (C) 2016 Tony Whyman, MWA Software
19 > *  The Original Code is (C) 2016-2021 Tony Whyman, MWA Software
20   *  (http://www.mwasoftware.co.uk).
21   *
22   *  All Rights Reserved.
# Line 69 | Line 69 | type
69      Syntax:
70  
71      Transaction Start:
72 <    *S:<date/time>,<session id>,<transaction no.>,<string length>:<transaction Name>,<string length>:<TPB>,<default Completion>
72 >    *S:<date/time>,<attachmentid>,<session id>,<transaction no.>,<string length>:<transaction Name>,<string length>:<TPB>,<default Completion>
73  
74      Transaction Commit:
75 <    *C:<date/time>,<session id>,<transaction no.>
75 >    *C:<date/time>,<attachmentid>,<session id>,<transaction no.>
76  
77      Transaction Commit retaining :
78 <    *c:<date/time>,<session id>,<transaction no.><old transaction no.>
78 >    *c:<date/time>,<attachmentid>,<session id>,<transaction no.><old transaction no.>
79  
80      Transaction Rollback:
81 <    *R:<date/time>,<session id>,<transaction no.>
81 >    *R:<date/time>,<attachmentid>,<session id>,<transaction no.>
82  
83      Transaction Rollback retaining:
84 <    *r:<date/time>,<session id>,<transaction no.><old transaction no.>
84 >    *r:<date/time>,<attachmentid>,<session id>,<transaction no.><old transaction no.>
85  
86      Update/Insert/Delete
87 <    *Q:<date/time>,<session id>,<transaction no.>,<length of query text in bytes>:<query text>
87 >    *Q:<date/time>,<attachmentid>,<session id>,<transaction no.>,<length of query text in bytes>:<query text>
88  
89    }
90  
# Line 93 | Line 93 | type
93    TFBJournaling = class(TActivityHandler, IJournallingHook)
94    private
95      {Logfile}
96 <    const sQueryJournal          = '*Q:''%s'',%d,%d,%d:%s' + LineEnding;
97 <    const sTransStartJnl         = '*S:''%s'',%d,%d,%d:%s,%d:%s,%d' + LineEnding;
98 <    const sTransCommitJnl        = '*C:''%s'',%d,%d' + LineEnding;
99 <    const sTransCommitRetJnl     = '*c:''%s'',%d,%d,%d' + LineEnding;
100 <    const sTransRollBackJnl      = '*R:''%s'',%d,%d' + LineEnding;
101 <    const sTransRollBackRetJnl   = '*r:''%s'',%d,%d,%d' + LineEnding;
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 sTransCommitRetJnl     = '*c:''%s'',%d,%d,%d,%d' + LineEnding;
100 >    const sTransRollBackJnl      = '*R:''%s'',%d,%d,%d' + LineEnding;
101 >    const sTransRollBackRetJnl   = '*r:''%s'',%d,%d,%d,%d' + LineEnding;
102    private
103      FOptions: TJournalOptions;
104      FJournalFilePath: string;
# Line 125 | Line 125 | type
125      function GetJournalOptions: TJournalOptions;
126      function StartJournaling(aJournalLogFile: AnsiString): integer; overload;
127      function StartJournaling(aJournalLogFile: AnsiString; Options: TJournalOptions): integer; overload;
128 +    function StartJournaling(S: TStream; Options: TJournalOptions): integer; overload;
129      procedure StopJournaling(RetainJournal: boolean);
130    end;
131  
# Line 139 | Line 140 | type
140      FUserCharSetMap: array of TCharSetMap;
141      FSecDatabase: AnsiString;
142      FInlineBlobLimit: integer;
143 +    FAttachmentID: integer;
144    protected
145      FDatabaseName: AnsiString;
146      FRaiseExceptionOnConnectError: boolean;
# Line 217 | Line 219 | type
219      function GetEventHandler(Event: AnsiString): IEvents; overload;
220  
221      function GetSQLDialect: integer;
222 +    function GetAttachmentID: integer;
223      function CreateBlob(transaction: ITransaction; RelationName, ColumnName: AnsiString; BPB: IBPB=nil): IBlob; overload;
224      function CreateBlob(transaction: ITransaction; BlobMetaData: IBlobMetaData; BPB: IBPB=nil): IBlob; overload; virtual; abstract;
225      function OpenBlob(transaction: ITransaction; BlobMetaData: IBlobMetaData; BlobID: TISC_QUAD; BPB: IBPB=nil): IBlob; overload; virtual; abstract;
# Line 233 | Line 236 | type
236      function GetDBInformation(Requests: array of byte): IDBInformation; overload;
237      function GetDBInformation(Request: byte): IDBInformation; overload;
238      function GetDBInformation(Requests: IDIRB): IDBInformation; overload;
236    function GetAttachmentID: integer;
239      function GetConnectString: AnsiString;
240      function GetRemoteProtocol: AnsiString;
241      function GetAuthenticationMethod: AnsiString;
242      function GetSecurityDatabase: AnsiString;
243      function GetODSMajorVersion: integer;
244      function GetODSMinorVersion: integer;
245 +    function GetCharSetID: integer;
246      function HasDecFloatSupport: boolean; virtual;
247      function GetInlineBlobLimit: integer;
248      procedure SetInlineBlobLimit(limit: integer);
249      function HasBatchMode: boolean; virtual;
250      function HasTable(aTableName: AnsiString): boolean;
251 +    function HasFunction(aFunctionName: AnsiString): boolean;
252 +    function HasProcedure(aProcName: AnsiString): boolean;
253  
254    public
255      {Character Sets}
# Line 610 | Line 615 | end;
615  
616   procedure TFBJournaling.EndSession(RetainJournal: boolean);
617   begin
618 <  if JournalingActive then
618 >  if JournalingActive and (FJournalFilePath <> '') then
619    begin
620      FreeAndNil(FJournalFileStream);
621 <    if not RetainJournal then
621 >    if not (joNoServerTable in FOptions) and not RetainJournal then
622      try
623          GetAttachment.ExecuteSQL([isc_tpb_write,isc_tpb_wait,isc_tpb_consistency],
624               sqlCleanUpSession,[FSessionID]);
# Line 638 | Line 643 | var LogEntry: AnsiString;
643      TPBText: AnsiString;
644   begin
645    FDoNotJournal := true;
646 +  if not (joNoServerTable in FOptions) then
647    try
648      GetAttachment.ExecuteSQL(Tr,sqlRecordJournalEntry,[FSessionID,Tr.GetTransactionID,NULL]);
649    finally
# Line 645 | Line 651 | begin
651    end;
652    TPBText := Tr.getTPB.AsText;
653    LogEntry := Format(sTransStartJnl,[FBFormatDateTime(GetDateTimeFmt,Now),
654 +                                     GetAttachment.GetAttachmentID,
655                                       FSessionID,
656                                       Tr.GetTransactionID,
657                                       Length(Tr.TransactionName),
# Line 664 | Line 671 | begin
671      case Action of
672      TARollback:
673        begin
674 <        LogEntry := Format(sTransRollbackJnl,[FBFormatDateTime(GetDateTimeFmt,Now),FSessionID,TransactionID]);
674 >        LogEntry := Format(sTransRollbackJnl,[FBFormatDateTime(GetDateTimeFmt,Now),
675 >                                              GetAttachment.GetAttachmentID,
676 >                                              FSessionID,TransactionID]);
677          Result := true;
678        end;
679      TACommit:
680        begin
681 <        LogEntry := Format(sTransCommitJnl,[FBFormatDateTime(GetDateTimeFmt,Now),FSessionID,TransactionID]);
681 >        LogEntry := Format(sTransCommitJnl,[FBFormatDateTime(GetDateTimeFmt,Now),
682 >                                            GetAttachment.GetAttachmentID,
683 >                                            FSessionID,TransactionID]);
684          Result := true;
685        end;
686      end;
# Line 684 | Line 695 | begin
695      case Action of
696        TACommitRetaining:
697            LogEntry := Format(sTransCommitRetJnl,[FBFormatDateTime(GetDateTimeFmt,Now),
698 +                                  GetAttachment.GetAttachmentID,
699                                    FSessionID,Tr.GetTransactionID,OldTransactionID]);
700        TARollbackRetaining:
701            LogEntry := Format(sTransRollbackRetJnl,[FBFormatDateTime(GetDateTimeFmt,Now),
702 +                                      GetAttachment.GetAttachmentID,
703                                        FSessionID,Tr.GetTransactionID,OldTransactionID]);
704      end;
705      if assigned(FJournalFileStream) then
706        FJournalFileStream.Write(LogEntry[1],Length(LogEntry));
707  
708      FDoNotJournal := true;
709 +    if not (joNoServerTable in FOptions) then
710      try
711        GetAttachment.ExecuteSQL(Tr,sqlRecordJournalEntry,[FSessionID,Tr.GetTransactionID,OldTransactionID]);
712      finally
# Line 706 | Line 720 | var SQL: AnsiString;
720   begin
721    SQL := TQueryProcessor.Execute(Stmt);
722    LogEntry := Format(sQueryJournal,[FBFormatDateTime(GetDateTimeFmt,Now),
723 +                                      GetAttachment.GetAttachmentID,
724                                        FSessionID,
725                                        Stmt.GetTransaction.GetTransactionID,
726                                        Length(SQL),SQL]);
# Line 731 | Line 746 | end;
746   function TFBJournaling.StartJournaling(aJournalLogFile: AnsiString;
747    Options: TJournalOptions): integer;
748   begin
749 +  try
750 +    StartJournaling(TFileStream.Create(aJournalLogFile,fmCreate),Options);
751 +  finally
752 +    FJournalFilePath := aJournalLogFile;
753 +  end;
754 + end;
755 +
756 + function TFBJournaling.StartJournaling(S: TStream; Options: TJournalOptions
757 +  ): integer;
758 + begin
759    FOptions := Options;
760 +  if not (joNoServerTable in FOptions) then
761    with GetAttachment do
762    begin
763 <    if not HasTable(sJournalTableName) then
763 >    if  not HasTable(sJournalTableName) then
764      begin
765        ExecImmediate([isc_tpb_write,isc_tpb_wait,isc_tpb_consistency],sqlCreateJournalTable);
766        ExecImmediate([isc_tpb_write,isc_tpb_wait,isc_tpb_consistency],sqlCreateSequence);
767      end;
768      FSessionID := OpenCursorAtStart(sqlGetNextSessionID)[0].AsInteger;
769    end;
770 <  FJournalFilePath := aJournalLogFile;
745 <  FJournalFileStream := TFileStream.Create(FJournalFilePath,fmCreate);
770 >  FJournalFileStream := S;
771    Result := FSessionID;
772   end;
773  
# Line 765 | Line 790 | var DBInfo: IDBInformation;
790   begin
791    if not IsConnected then Exit;
792    DBInfo := GetDBInformation([isc_info_db_id,isc_info_ods_version,isc_info_ods_minor_version,
793 <                               isc_info_db_SQL_Dialect]);
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
# Line 775 | Line 800 | begin
800          FODSMajorVersion := getAsInteger;
801        isc_info_db_SQL_Dialect:
802          FSQLDialect := getAsInteger;
803 +      isc_info_attachment_id:
804 +        FAttachmentID := getAsInteger;
805        end;
806  
807    FCharSetID := 0;
# Line 831 | Line 858 | begin
858    FFirebirdAPI := api.GetAPI; {Keep reference to interface}
859    FSQLDialect := 3;
860    FDatabaseName := DatabaseName;
834  FDPB := DPB;
861    SetLength(FUserCharSetMap,0);
836  FRaiseExceptionOnConnectError := RaiseExceptionOnConnectError;
862    FODSMajorVersion := 0;
863    FODSMinorVersion := 0;
864    FInlineBlobLimit := DefaultMaxInlineBlobLimit;
865 +  FDPB := DPB;
866 +  FRaiseExceptionOnConnectError := RaiseExceptionOnConnectError;
867   end;
868  
869   function TFBAttachment.GenerateCreateDatabaseSQL(DatabaseName: AnsiString;  aDPB: IDPB): AnsiString;
# Line 1181 | Line 1208 | begin
1208    Result := FSQLDialect;
1209   end;
1210  
1211 + function TFBAttachment.GetAttachmentID: integer;
1212 + begin
1213 +  Result := FAttachmentID;
1214 + end;
1215 +
1216   function TFBAttachment.CreateBlob(transaction: ITransaction; RelationName,
1217    ColumnName: AnsiString; BPB: IBPB): IBlob;
1218   begin
# Line 1250 | Line 1282 | begin
1282      Result := GetDBInfo(getBuffer,getDataLength);
1283   end;
1284  
1253 function TFBAttachment.GetAttachmentID: integer;
1254 var Info: IDBInformation;
1255 begin
1256  Info := GetDBInformation(isc_info_attachment_id);
1257  if (Info.Count > 0) and (Info[0].getItemType = isc_info_attachment_id) then
1258    Result := Info[0].getAsInteger
1259  else
1260    Result := -1;
1261 end;
1262
1285   function TFBAttachment.GetConnectString: AnsiString;
1286   begin
1287    Result := FDatabaseName;
# Line 1290 | Line 1312 | begin
1312    Result := FODSMinorVersion;
1313   end;
1314  
1315 + function TFBAttachment.GetCharSetID: integer;
1316 + begin
1317 +  Result := FCharSetID;
1318 + end;
1319 +
1320   function TFBAttachment.HasDecFloatSupport: boolean;
1321   begin
1322    Result := false;
# Line 1320 | Line 1347 | begin
1347            [aTableName])[0].AsInteger > 0;
1348   end;
1349  
1350 + function TFBAttachment.HasFunction(aFunctionName: AnsiString): boolean;
1351 + begin
1352 +  Result := OpenCursorAtStart(
1353 +       'Select count(*) From RDB$FUNCTIONS Where RDB$FUNCTION_NAME = ?',
1354 +          [aFunctionName])[0].AsInteger > 0;
1355 + end;
1356 +
1357 + function TFBAttachment.HasProcedure(aProcName: AnsiString): boolean;
1358 + begin
1359 +  Result := OpenCursorAtStart(
1360 +       'Select count(*) From RDB$PROCEDURES Where RDB$PROCEDURE_NAME = ?',
1361 +          [aProcName])[0].AsInteger > 0;
1362 + end;
1363 +
1364   function TFBAttachment.HasDefaultCharSet: boolean;
1365   begin
1366    Result := FHasDefaultCharSet

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines