unit ServiceMethods_ClientMain; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, uRORemoteService, uROClient, uROBinMessage, uROWinInetHttpChannel, uDAScriptingProvider, uDADataTable, uDACDSDataTable, uDADataStreamer, uDABinAdapter, uDARemoteDataAdapter, ComCtrls, StdCtrls, ServiceMethodsLibrary_Intf, uDAClasses, uDAInterfaces, Spin, Grids, ValEdit, DB, DBCtrls, DBGrids, ExtCtrls, Buttons; type TServiceMethods_ClientMainForm = class(TForm) Channel: TROWinInetHTTPChannel; BinMessage: TROBinMessage; Service: TRORemoteService; Streamer: TDABinDataStreamer; PageControl: TPageControl; tsGetSchema: TTabSheet; tsGetData: TTabSheet; tsUpdateData: TTabSheet; tsExecuteCommand: TTabSheet; tsGetTableSchema: TTabSheet; tsGetCommandSchema: TTabSheet; tsSQLGetData: TTabSheet; tsSQLExecuteCommand: TTabSheet; Label1: TLabel; RunButton: TButton; Memo: TMemo; cbGetTableSchema: TComboBox; Label2: TLabel; Label5: TLabel; cbGetCommandSchema: TComboBox; Label6: TLabel; cbGetData: TComboBox; Label7: TLabel; Label8: TLabel; Label3: TLabel; cbIncludeSchema: TCheckBox; Label4: TLabel; spMaxRecord: TSpinEdit; cbExecuteCommand: TComboBox; Label9: TLabel; vleGetData: TValueListEditor; vleExecuteCommand: TValueListEditor; Label10: TLabel; Label11: TLabel; sqlIncludeSchema: TCheckBox; Label12: TLabel; sqlMaxRecords: TSpinEdit; Label13: TLabel; memoDQLGetData: TMemo; Label14: TLabel; MemoSQLExecuteCommand: TMemo; Label16: TLabel; LogMessage: TLabel; Panel1: TPanel; Panel2: TPanel; Label15: TLabel; cbUpdateData: TComboBox; DBGrid1: TDBGrid; DBNavigator1: TDBNavigator; DataSource: TDADataSource; ParamPanel: TPanel; vleUpdateData: TValueListEditor; Label17: TLabel; updateDataMaxRecord: TSpinEdit; RefreshButton: TBitBtn; Label19: TLabel; GetDataUserFilter: TEdit; Label18: TLabel; ClearLogButton: TButton; tsExecuteCommandEx: TTabSheet; Label20: TLabel; Label21: TLabel; cbExecuteCommandEx: TComboBox; vleExecuteCommandEx: TValueListEditor; procedure PageControlChange(Sender: TObject); procedure RunButtonClick(Sender: TObject); procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure FormShow(Sender: TObject); procedure cbGetDataChange(Sender: TObject); procedure cbExecuteCommandChange(Sender: TObject); procedure cbUpdateDataChange(Sender: TObject); procedure RefreshButtonClick(Sender: TObject); procedure ClearLogButtonClick(Sender: TObject); procedure cbExecuteCommandExChange(Sender: TObject); private { Private declarations } FService: IServiceMethods_Service; Schema: TDASchema; procedure Log(Str: string); procedure FillCB(ACombobox: Tcombobox; AItems: TDASQLCommandCollection); function isNeedSchema: boolean; procedure LogDataset(ADataset: TDACDSDataTable); procedure FillUpdateDataDataset; public { Public declarations } procedure GetSchema; procedure GetData; procedure UpdateData; procedure ExecuteCommand; procedure ExecuteCommandEx; procedure GetTableSchema; procedure GetCommandSchema; procedure SQLGetData; procedure SQLExecuteCommand; end; var ServiceMethods_ClientMainForm: TServiceMethods_ClientMainForm; implementation uses DataAbstract4_Intf, uDADelta, uROTypes, uROXMLIntf; {$R *.dfm} procedure TServiceMethods_ClientMainForm.PageControlChange( Sender: TObject); begin RunButton.Caption := PageControl.ActivePage.Caption; isNeedSchema; if PageControl.ActivePage = tsGetData then cbGetDataChange(cbGetData) else if PageControl.ActivePage = tsExecuteCommand then cbExecuteCommandChange(cbExecuteCommand) else if PageControl.ActivePage = tsExecuteCommandEx then cbExecuteCommandExChange(cbExecuteCommandEx) else if PageControl.ActivePage = tsUpdateData then cbUpdateDataChange(cbUpdateData); end; procedure TServiceMethods_ClientMainForm.RunButtonClick(Sender: TObject); begin if PageControl.ActivePage = tsGetSchema then GetSchema else if PageControl.ActivePage = tsGetData then GetData else if PageControl.ActivePage = tsUpdateData then UpdateData else if PageControl.ActivePage = tsExecuteCommand then ExecuteCommand else if PageControl.ActivePage = tsExecuteCommandEx then ExecuteCommandEx else if PageControl.ActivePage = tsGetTableSchema then GetTableSchema else if PageControl.ActivePage = tsGetCommandSchema then GetCommandSchema else if PageControl.ActivePage = tsSQLGetData then SQLGetData else if PageControl.ActivePage = tsSQLExecuteCommand then SQLExecuteCommand ; Log(''); end; procedure TServiceMethods_ClientMainForm.ExecuteCommand; var aRowsAffacted: integer; dataparam: DataParameterArray; i: integer; begin if isNeedSchema then Exit; Log('***ExecuteCommand***'); try dataparam := DataParameterArray.Create; try for i := 0 to vleExecuteCommand.Strings.Count - 1 do begin with dataparam.Add do begin Name := vleExecuteCommand.Keys[i + 1]; Value := vleExecuteCommand.Values[Name]; end; end; aRowsAffacted := FService.ExecuteCommand(cbExecuteCommand.Text, dataparam); finally dataparam.Free; end; log('aRowsAffacted:'#9 + intToStr(aRowsAffacted)); except on e: Exception do Log(e.Message); end; Log('*******************'); end; procedure TServiceMethods_ClientMainForm.GetCommandSchema; var str: string; strArr: StringArray; doc: IXMLDocument; List: IXMLNodeList; j, i: integer; node, ParamsNode, ParamNode: IXMLNode; begin if isNeedSchema then Exit; Log('***GetCommandSchema***'); StrArr := StringArray.Create; try strArr.Add(cbGetCommandSchema.Text); try str := FService.GetCommandSchema(StrArr); doc := NewROXmlDocument; doc.New; doc.XML := str; List := doc.DocumentNode.GetNodesByName('SchemaCommand'); for i := 0 to List.Count - 1 do begin Node := List.Nodes[i]; if Node = nil then continue; Log('Command: ' + Node.GetNodeValue('Name', '')); ParamsNode := Node.GetNodeByName('Params'); if ParamsNode = nil then Continue; for j := 0 to ParamsNode.GetAttributeValue('Count', 0) - 1 do begin ParamNode := ParamsNode.GetNodeByName('Item' + IntToStr(j)); if ParamNode = nil then Continue; Log('Params[' + IntToStr(j) + ']: ' + ParamNode.GetNodeValue('Name', '')); end; end; except on E: Exception do Log(E.Message); end; finally strArr.Free; end; Log('********************'); end; procedure TServiceMethods_ClientMainForm.GetData; var Stream: TMemoryStream; CDSDataTable: TDACDSDataTable; aTableRequestInfoArray: TableRequestInfoArray; aTableNameArray: StringArray; i: integer; aTableRequestInfo: TableRequestInfo; begin if isNeedSchema then exit; Log('***GetData***'); aTableNameArray := StringArray.Create; aTableRequestInfoArray := TableRequestInfoArray.Create; try aTableNameArray.Add(cbGetData.Text); aTableRequestInfo := aTableRequestInfoArray.Add; with aTableRequestInfo do begin IncludeSchema := cbIncludeSchema.checked; MaxRecords := spMaxRecord.Value; UserFilter := GetDataUserFilter.Text; for i := 0 to vleGetData.Strings.Count - 1 do with Parameters.Add do begin Name := vleGetData.Keys[i + 1]; Value := vleGetData.Values[Name]; end; end; try Stream := FService.GetData(aTableNameArray, aTableRequestInfoArray); if Stream <> nil then try CDSDataTable := TDACDSDataTable.Create(nil); try CDSDataTable.Name := 'TEST'; CDSDataTable.LocalDataStreamer := Streamer; CDSDataTable.RemoteFetchEnabled := False; Streamer.ReadDataset(Stream, CDSDataTable, True); log('RecordCount:'#9 + intToStr(CDSDataTable.RecordCount)); Log('FieldCount:'#9 + intToStr(CDSDataTable.FieldCount)); if (CDSDataTable.FieldCount <> 0) then LogDataset(CDSDataTable); finally CDSDataTable.Free; end; finally Stream.Free; end; except on e: Exception do Log(e.Message); end; finally aTableRequestInfoArray.Free; aTableNameArray.Free; end; Log('*************'); end; procedure TServiceMethods_ClientMainForm.GetSchema; var i: integer; begin cbGetTableSchema.Clear; cbGetCommandSchema.Clear; cbGetData.Clear; Log('***GetSchema***'); try Schema.LoadFromXml(FService.GetSchema('')); Log('Datasets.Count:'#9 + IntToStr(Schema.Datasets.Count)); for i := 0 to Schema.Datasets.Count - 1 do Log('Datasets[' + IntTostr(i) + ']:'#9 + Schema.Datasets[i].Name); FillCB(cbGetTableSchema, Schema.Datasets); FillCB(cbGetData, Schema.Datasets); FillCB(cbUpdateData, Schema.Datasets); Log('Commands.Count:'#9 + IntToStr(Schema.Commands.Count)); for i := 0 to Schema.Commands.Count - 1 do Log('Commands[' + IntTostr(i) + ']:'#9 + Schema.Commands[i].Name); FillCB(cbGetCommandSchema, Schema.Commands); FillCB(cbExecuteCommand, Schema.Commands); FillCB(cbExecuteCommandEx, Schema.Commands); except on E: Exception do Log(E.Message); end; Log('***************'); end; procedure TServiceMethods_ClientMainForm.GetTableSchema; var str: string; strArr: StringArray; doc: IXMLDocument; List: IXMLNodeList; j, i: integer; node, FieldsNode, FieldNode: IXMLNode; begin if isNeedSchema then Exit; Log('***GetTableSchema***'); StrArr := StringArray.Create; try strArr.Add(cbGetTableSchema.Text); try str := FService.GetTableSchema(StrArr); doc := NewROXmlDocument; doc.New; doc.XML := str; List := doc.DocumentNode.GetNodesByName('SchemaDataTable'); for i := 0 to List.Count - 1 do begin Node := List.Nodes[i]; if Node = nil then continue; Log('table: ' + Node.GetNodeValue('Name', '')); FieldsNode := Node.GetNodeByName('Fields'); if FieldsNode = nil then Continue; for j := 0 to FieldsNode.GetAttributeValue('Count', 0) - 1 do begin FieldNode := FieldsNode.GetNodeByName('Item' + IntToStr(j)); if FieldNode = nil then Continue; Log('Fields[' + IntToStr(j) + ']: ' + FieldNode.GetNodeValue('Name', '')); end; end; except on E: Exception do Log(E.Message); end; finally strArr.Free; end; Log('********************'); end; procedure TServiceMethods_ClientMainForm.SQLExecuteCommand; var aRowsAffacted: integer; begin Log('***SQLExecuteCommand***'); try aRowsAffacted := FService.SQLExecuteCommand(MemoSQLExecuteCommand.Text); log('aRowsAffacted:'#9 + intToStr(aRowsAffacted)); except on e: Exception do Log(e.Message); end; Log('*********************'); end; procedure TServiceMethods_ClientMainForm.SQLGetData; var Stream: TMemoryStream; CDSDataTable: TDACDSDataTable; begin Log('***SQLGetData***'); try Stream := FService.SQLGetData(memoDQLGetData.Text, sqlIncludeSchema.Checked, sqlMaxRecords.Value); if Stream <> nil then try CDSDataTable := TDACDSDataTable.Create(nil); try CDSDataTable.Name := 'TEST'; CDSDataTable.LocalDataStreamer := Streamer; CDSDataTable.RemoteFetchEnabled := False; Streamer.ReadDataset(Stream, CDSDataTable, True); log('RecordCount:'#9 + intToStr(CDSDataTable.RecordCount)); Log('FieldCount:'#9 + intToStr(CDSDataTable.FieldCount)); if (CDSDataTable.FieldCount <> 0) then LogDataset(CDSDataTable); finally CDSDataTable.Free; end; finally Stream.Free; end; except on e: Exception do Log(e.Message); end; end; procedure TServiceMethods_ClientMainForm.UpdateData; var stream1, stream: Binary; i, j: integer; begin if isNeedSchema then Exit; if DataSource.DataTable = nil then begin ShowMessage('Please select dataset from combobox'); Exit; end; Log('***UpdateData***'); Log('Delta.Count:'#9 + intToStr(DataSource.DataTable.Delta.Count)); with DataSource.DataTable.Delta do for i := 0 to Count - 1 do begin Log('----- Delta ' + IntToStr(i) + '-----'); with Changes[i] do for j := 0 to (LoggedFieldCount - 1) do Log(LoggedFieldNames[j] + ':'#9 + VarToStr(OldValueByName[LoggedFieldNames[j]]) + ' -> ' + VarToStr(NewValueByName[LoggedFieldNames[j]])); end; stream := binary.Create; try Streamer.Initialize(stream, aiWrite); DataSource.DataTable.WriteDeltaToStream(Streamer); Streamer.Finalize; try stream1 := FService.UpdateData(Stream); if Stream1 <> nil then try DataSource.DataTable.Delta.Clear(); Streamer.Initialize(stream1, aiRead); DataSource.DataTable.ReadDeltaFromStream(Streamer); Streamer.Finalize; DataSource.DataTable.MergeDelta; finally Stream1.Free; end; except on e: Exception do Log(e.Message); end; finally Stream.Free; end; Log('***************'); end; procedure TServiceMethods_ClientMainForm.Log(Str: string); begin Memo.Lines.Add(Str); end; procedure TServiceMethods_ClientMainForm.FormCreate(Sender: TObject); begin FService := Service as IServiceMethods_Service; Schema := TDASchema.Create(nil); end; procedure TServiceMethods_ClientMainForm.FormDestroy(Sender: TObject); begin if DataSource.DataTable <> nil then DataSource.DataTable.Free; Schema.Free; end; procedure TServiceMethods_ClientMainForm.FormShow(Sender: TObject); begin PageControl.ActivePage := tsGetSchema; PageControlChange(PageControl); end; procedure TServiceMethods_ClientMainForm.FillCB(ACombobox: Tcombobox; AItems: TDASQLCommandCollection); var i: integer; begin ACombobox.Items.Clear; for i := 0 to AItems.Count - 1 do ACombobox.Items.Add(AItems[i].Name); if ACombobox.Items.Count > 0 then ACombobox.ItemIndex := 0; end; function TServiceMethods_ClientMainForm.isNeedSchema: Boolean; begin Result := (Schema.Datasets.Count = 0) or (Schema.Commands.Count = 0); LogMessage.Visible := Result and (PageControl.ActivePage <> tsGetSchema) and (PageControl.ActivePage <> tsSQLGetData) and (PageControl.ActivePage <> tsSQLExecuteCommand); RunButton.Enabled := not LogMessage.Visible; end; procedure TServiceMethods_ClientMainForm.LogDataset( ADataset: TDACDSDataTable); var i: integer; s: string; begin log(''); s := ''; for i := 0 to ADataset.FieldCount - 1 do s := s + ADataset.Fields[i].Name + #9; Log(s); ADataset.first; while not ADataset.Eof do begin s := ''; for i := 0 to ADataset.FieldCount - 1 do s := s + ADataset.Fields[i].AsString + #9; Log(s); ADataset.next; end; Log(''); end; procedure TServiceMethods_ClientMainForm.cbGetDataChange(Sender: TObject); var fDataset: TDADataset; i: integer; begin vleGetData.Strings.Clear; try if cbGetData.text = '' then Exit; fDataset := Schema.Datasets.DatasetByName(cbGetData.Text); if fDataset = nil then Exit; for i := 0 to fDataset.Params.Count - 1 do if vleGetData.Strings.IndexOfName(fDataset.Params[i].Name) = -1 then vleGetData.InsertRow(fDataset.Params[i].Name, '', True); finally vleGetData.Visible := vleGetData.Strings.Count > 0; end; Log('*************SQL**************'); if fDataset.Statements.Count > 0 then Log(fDataset.Statements[0].SQL) else Log('SQL statement is not found. Probably this table is ExportedDataTable.'); Log('******************************'); end; procedure TServiceMethods_ClientMainForm.cbExecuteCommandChange( Sender: TObject); var fcommand: TDASQLCommand; i: integer; begin vleExecuteCommand.Strings.Clear; try if cbExecuteCommand.text = '' then Exit; fcommand := Schema.Commands.SQLCommandByName(cbExecuteCommand.Text); if fcommand = nil then Exit; for i := 0 to fcommand.Params.Count - 1 do if fcommand.Params[i].ParamType in [daptInput, daptInputOutput] then if vleExecuteCommand.Strings.IndexOfName(fcommand.Params[i].Name) = -1 then vleExecuteCommand.InsertRow(fcommand.Params[i].Name, '', True); finally vleExecuteCommand.Visible := vleExecuteCommand.Strings.Count > 0; end; Log('*************SQL**************'); Log(fcommand.Statements[0].SQL); Log('******************************'); end; procedure TServiceMethods_ClientMainForm.cbUpdateDataChange(Sender: TObject); var CDSDataTable: TDACDSDataTable; var i: integer; begin vleUpdateData.Strings.Clear; if cbUpdateData.text = '' then Exit; if DataSource.DataTable = nil then DataSource.DataTable := TDACDSDataTable.Create(nil); CDSDataTable := TDACDSDataTable(DataSource.DataTable); Log('Try to get data (call GetData)'); CDSDataTable.LogicalName := cbUpdateData.Text; FillUpdateDataDataset; try for i := 0 to CDSDataTable.Params.Count - 1 do if vleUpdateData.Strings.IndexOfName(CDSDataTable.Params[i].Name) = -1 then vleUpdateData.InsertRow(CDSDataTable.Params[i].Name, '', True); finally ParamPanel.Visible := vleUpdateData.Strings.Count > 0; end; end; procedure TServiceMethods_ClientMainForm.FillUpdateDataDataset; var Stream: TMemoryStream; aTableRequestInfoArray: TableRequestInfoArray; aTableNameArray: StringArray; i: integer; aTableRequestInfo: TableRequestInfo; CDSDataTable: TDACDSDataTable; begin CDSDataTable := TDACDSDataTable(DataSource.DataTable); if CDSDataTable = nil then Exit; CDSDataTable.Close; aTableNameArray := StringArray.Create; aTableRequestInfoArray := TableRequestInfoArray.Create; try aTableNameArray.Add(CDSDataTable.LogicalName); aTableRequestInfo := aTableRequestInfoArray.Add; with aTableRequestInfo do begin IncludeSchema := true; MaxRecords := updateDataMaxRecord.Value; UserFilter := ''; for i := 0 to vleUpdateData.Strings.Count - 1 do with Parameters.Add do begin Name := vleUpdateData.Keys[i + 1]; Value := vleUpdateData.Values[Name]; end; end; try Stream := FService.GetData(aTableNameArray, aTableRequestInfoArray); if Stream <> nil then try CDSDataTable.Name := 'TEST'; CDSDataTable.LocalDataStreamer := Streamer; CDSDataTable.RemoteFetchEnabled := False; Streamer.ReadDataset(Stream, CDSDataTable, True); finally Stream.Free; end; except on e: Exception do Log(e.Message); end; finally aTableRequestInfoArray.Free; aTableNameArray.Free; end; CDSDataTable.Open; end; procedure TServiceMethods_ClientMainForm.RefreshButtonClick( Sender: TObject); begin FillUpdateDataDataset; end; procedure TServiceMethods_ClientMainForm.ClearLogButtonClick( Sender: TObject); begin Memo.Lines.Clear; end; procedure TServiceMethods_ClientMainForm.ExecuteCommandEx; var aRowsAffacted: integer; dataparam, outputdataparam: DataParameterArray; i: integer; begin if isNeedSchema then Exit; Log('***ExecuteCommandEx***'); try dataparam := DataParameterArray.Create; try for i := 0 to vleExecuteCommandEx.Strings.Count - 1 do begin with dataparam.Add do begin Name := vleExecuteCommandEx.Keys[i + 1]; Value := vleExecuteCommandEx.Values[Name]; end; end; aRowsAffacted := FService.ExecuteCommandEx(cbExecuteCommandEx.Text, dataparam, outputdataparam); log('aRowsAffacted:'#9 + intToStr(aRowsAffacted)); Log('Output parameters count:'#9 + IntToStr(outputdataparam.Count)); for i := 0 to outputdataparam.Count - 1 do Log(outputdataparam.Items[i].Name + ':'#9 + VarToStr(outputdataparam.Items[i].Value)); finally outputdataparam.Free; dataparam.Free; end; except on e: Exception do Log(e.Message); end; Log('*******************'); end; procedure TServiceMethods_ClientMainForm.cbExecuteCommandExChange( Sender: TObject); var fcommand: TDASQLCommand; i: integer; begin vleExecuteCommandEx.Strings.Clear; try if cbExecuteCommandEx.text = '' then Exit; fcommand := Schema.Commands.SQLCommandByName(cbExecuteCommandEx.Text); if fcommand = nil then Exit; for i := 0 to fcommand.Params.Count - 1 do if fcommand.Params[i].ParamType in [daptInput, daptInputOutput] then if vleExecuteCommandEx.Strings.IndexOfName(fcommand.Params[i].Name) = -1 then vleExecuteCommandEx.InsertRow(fcommand.Params[i].Name, '', True); finally vleExecuteCommandEx.Visible := vleExecuteCommandEx.Strings.Count > 0; end; Log('*************SQL**************'); Log(fcommand.Statements[0].SQL); Log('******************************'); end; end.