1.kbmMWConfiguration自動備份配置文件的問題還沒有修正。
下面是以前寫過的內容,再一次在新聞組中提出這個問題:
kbmMW提供一個強大的配置信息管理對象,前期譯過這個對象的介紹,在使用過程中,發現一個問題, 就是TkbmMWCustomConfigurationStorage.BackupMaxCount屬性,當設置為0時,也會生成配置信息的備份文件,在最新的kbmMW 5.05.11版本中,每運行一次就生成一個配置文件,對此,修正了代碼。
打開單元文件 kbmMWGlobal,找到下面這個方法:
function kbmMWBackupFile, .... if not FileExists(AFile) then begin Result:=AFile; exit; end; if AMaxBackups<=0 then//判斷AMaxbackups來決定是否生成備份文件: begin Result:=AFile; exit; end; ...
TSysConnectionParam = class//(TkbmMWConfigurableObject) private [kbmMW_Config('QueryServiceVersion',mwcdReadWrite)] FQueryServiceVersion: string; [kbmMW_Config('QueryServiceName',mwcdReadWrite)] FQueryServiceName: string; [kbmMW_Config('SessionName',mwcdReadWrite)] FSessionName: string; [kbmMW_Config('FileServiceVersion',mwcdReadWrite)] FFileServiceVersion: string; [kbmMW_Config('FileServiceName',mwcdReadWrite)] FFileServiceName: string; public property SessionName: string read FSessionName write FSessionName; property QueryServiceName: string read FQueryServiceName write FQueryServiceName; property QueryServiceVersion: string read FQueryServiceVersion write FQueryServiceVersion; property FileServiceName:string read FFileServiceName write FFileServiceName; property FileServiceVersion:string read FFileServiceVersion write FFileServiceVersion; end;
這個TSysConnectionParam不從TkbmMWConfigurableObject繼承,否則在android平台,出這個錯誤:Type (TSysConnectionParam@6260DC60) not registered as a known type.
說明TkbmMWConfigurableObject還是存在跨平台的問題。
既然不能從TkbmMWConfigurableObject繼承,怎么實現一個自動讀取與保存的配置對象呢,按Configuration REST easy with kbmMW #7。
為配置對象重載AfterConstruction與BeforeDestruction方法,實現自動保存與讀取配置對象!
public procedure AfterConstruction; override; procedure BeforeDestruction; override;
{ TSysConnectionParam } procedure TSysConnectionParam.AfterConstruction; begin inherited; Config.ReadConfig(Self); end; procedure TSysConnectionParam.BeforeDestruction; begin Config.WriteConfig(Self); inherited; end;
現在,TSysConnectionParam的實例在建立與釋放時,就能自動讀取與保存參數,在Win32及Android下測試通過。
雖然TkbmMWConfigurableObject存在跨平台問題,但用上面方法來跳過,也是很好的方案,畢竟可以跨平台使用kbmMWConfiguration Frame!
procedure Tmainform.Button3Click(Sender: TObject); begin kbmMWClientQuery1.Close; kbmMWClientQuery2.Close; kbmMWClientQuery1.Open; kbmMWClientQuery2.Open; kbmMWClientQuery1.AppendRecord([1,'1']); kbmMWClientQuery1.AppendRecord([1,'2']);//t1表在數據庫中主鍵重復錯 kbmMWClientQuery2.AppendRecord([1,'1']); kbmMWClientQuery2.AppendRecord([1,'2']);//t2表在數據庫中主鍵重復錯 kbmMWClientTransactionResolver1.Resolve([kbmMWClientQuery1,kbmMWClientQuery2]); end;
上面是測試代碼,同時提交兩個ClientQuery,每個表都有主鍵重復錯誤,造成提交失敗的場景,這時候,客戶端會產生異常:stream read error.
已經反饋到官方新聞組,但作者還讓我寫個demo,已經發給他,等處理。注意:這個問題在上一版本中就存在。
4.更新主鍵遇到的問題
這個是朋友在學習過程中遇到的,整理出測試項目,大體情況是這樣的:
現在有表t1,FID是主鍵,假設有如下記錄
FID FName
1 1
2 2
把第一條記錄,FID改成2,提交,這時候主鍵重復,提交失敗,這時候kbmMW的工作結果是對的
FID FName
1 1
2 2
現在把第一條記錄的FID改成3,提交,這時候沒有了主鍵重復問題,提交成功,這時候kbmMW的工作結果也是對的。
FID FName
3 1
2 2
現在把第一條記錄的任務字段改變值,如FName改成2,提交失敗,這個結果不對的。問題就在這里。
FID FName
3 2
2 2
這是按上面的測試方法寫的代碼,重顯問題:
procedure Tmainform.Button4Click(Sender: TObject); begin //這是一個bug Label1.Caption := ''; Memo1.Lines.Clear; // 刪除所有記錄 kbmMWClientQuery1.Close; kbmMWClientQuery1.Open; kbmMWClientQuery1.DeleteRecords; kbmMWClientQuery1.Resolve; kbmMWClientQuery1.AppendRecord([1, '1']); kbmMWClientQuery1.AppendRecord([2, '2']); kbmMWClientQuery1.Resolve; // keyfield // // 1,2 2,2 3,2 3,1 // 2,2 2,2 2,2 2,2 // error ok error kbmMWClientQuery1.Close; kbmMWClientQuery1.Open; kbmMWClientQuery1.First; kbmMWClientQuery1.Edit; kbmMWClientQuery1.FieldByName('fid').AsInteger := 2;//主鍵重復 if not kbmMWClientTransactionResolver1.Resolve([kbmMWClientQuery1]) then begin DataSource3.DataSet := kbmMWClientQuery1.InfoTable; Label1.Caption := kbmMWClientQuery1.InfoTable.FieldByName('kbmMW_ErrorMessage').AsString; Memo1.Lines.Add('Step 1: Modify the primary key to generate an error, the submission failed,it''s right. '+kbmMWClientQuery1.InfoTable.FieldByName('kbmMW_ErrorMessage').AsString); end; kbmMWClientQuery1.First; kbmMWClientQuery1.Edit; kbmMWClientQuery1.FieldByName('fid').AsInteger := 3;//設置主鍵不重復 if not kbmMWClientTransactionResolver1.Resolve([kbmMWClientQuery1]) then begin DataSource3.DataSet := kbmMWClientQuery1.InfoTable; Label1.Caption := kbmMWClientQuery1.InfoTable.FieldByName('kbmMW_ErrorMessage').AsString; Memo1.Lines.Add('Step 2: Modify the primary key to resolve the error and submit successfully,it''s right. '+kbmMWClientQuery1.InfoTable.FieldByName('kbmMW_ErrorMessage').AsString); end else begin Memo1.Lines.Add('Step 2: step 2:Modify the primary key to resolve the error and submit successfully,it''s right.'); Label1.Caption := 'Resolve OK.'; end; kbmMWClientQuery1.First; kbmMWClientQuery1.Edit; kbmMWClientQuery1.FieldByName('fname').AsString := '1';//無法修改這條記錄了!這是bug. if not kbmMWClientTransactionResolver1.Resolve([kbmMWClientQuery1]) then begin DataSource3.DataSet := kbmMWClientQuery1.InfoTable; Label1.Caption := kbmMWClientQuery1.InfoTable.FieldByName('kbmMW_ErrorMessage').AsString; Memo1.Lines.Add('Step 3: Modify any field and cannot submit,it''s bug. '+kbmMWClientQuery1.InfoTable.FieldByName('kbmMW_ErrorMessage').AsString); end else begin Label1.Caption := 'Resolve OK.'; end; end;
5.洞主測試rest上傳文件服務需要修正下面兩個方法,並已經提交給作者,等待修正。
function TkbmMWHTTPMultiPart.GetAsBytes:TBytes; var p:PByte; i:integer; begin SetLength(Result,FDataLength); p:=PByte(FOwner.FStream.Memory); inc(p,FDataOfs); Move(p^,Result[0],FDataLength); end; function TkbmMWHTTPMultiPart.GetAsString:string; begin Result:=TkbmMWPlatformMarshal.UTF8Decode(GetData,FDataLength); end;
這是xalion寫的上傳文件服務的例子,必須學習了!
6.Scheduler存在的問題
WaitRuns: FileService的SameFile方法,不等取得本地文件的CheckSum,造成執行結果錯誤,這個問題在5.04.30解決過,不知為何又回來了,問題出在WaitRuns上,不等Scheduler執行。
SynchronizedAfterRun:利用Scheduler在線程中執行一個查詢,然后在SynchronizedAfterRun使用查詢回來的數據集,偶爾會出現找不到字段的問題。感覺與WaitRuns存在的問題有關系。
7.Q友冰雨反應Resolve問題KbmMW V5.06.2,修改數據,kbmwclntrnsctnrslvrTR.Resolve([kbmwclntqryMain]),保存的時候,變成insert語句,導致主鍵重復。KbmMW V5.06.1 beta版本已經發現了這個問題,退回前一個正式版,目前正常了。
