public int ExportOneRecord( RmsChannel channel, DigitalPlatform.Stop stop, string strServerUrl, string strRecPath, string strXmlBody, string strMetadata, byte[] baTimestamp, out string strError) { strError = ""; if (this.FileType == ExportFileType.XmlFile) { XmlDocument dom = new XmlDocument(); try { dom.LoadXml(strXmlBody); ResPath respathtemp = new ResPath(); respathtemp.Url = strServerUrl; respathtemp.Path = strRecPath; // DomUtil.SetAttr(dom.DocumentElement, "xmlns:dprms", DpNs.dprms); // 给根元素设置几个参数 DomUtil.SetAttr(dom.DocumentElement, "path", DpNs.dprms, respathtemp.FullPath); DomUtil.SetAttr(dom.DocumentElement, "timestamp", DpNs.dprms, ByteArray.GetHexTimeStampString(baTimestamp)); // DomUtil.SetAttr(dom.DocumentElement, "xmlns:marc", null); dom.DocumentElement.WriteTo(writer); } catch (Exception ex) { strError = ExceptionUtil.GetAutoText(ex); return(-1); } } if (this.FileType == ExportFileType.BackupFile) { Debug.Assert(channel != null, ""); // 将主记录和相关资源写入备份文件 int nRet = WriteRecordToBackupFile( this.m_owner, channel, stop, this.outputfile, strRecPath, // 记录路径 strMetadata, strXmlBody, baTimestamp, out strError); if (nRet == -1) { return(-1); } } return(0); }
// 根据 query string,获得指定一期的期记录数量 // query string 是调用前从册记录中 volume 等字段综合取得的 // parameters: // strBiblioPath 书目记录路径 // strQueryString 检索词。例如 “2005|1|1000|50”。格式为 年|期号|总期号|卷号。一般为 年|期号| 即可。 public static int GetIssueCount(this LibraryChannel channel, DigitalPlatform.Stop stop, string strBiblioRecPath, string strQueryString, out string strError) { strError = ""; string strBiblioRecordID = StringUtil.GetRecordId(strBiblioRecPath); string strStyle = "query:父记录+期号|" + strBiblioRecordID + "|" + strQueryString; DigitalPlatform.LibraryClient.localhost.EntityInfo[] issueinfos = null; long lRet = channel.GetIssues(stop, strBiblioRecPath, 0, 1, strStyle, channel.Lang, out issueinfos, out strError); if (lRet == -1) { return(-1); } return((int)lRet); }
// 内部调用 public static int GetNumber( DigitalPlatform.Stop stop, string strUrl, string strID, string strAuthor, bool bSelectPinyin, bool bSelectEntry, bool bOutputDebugInfo, ref Question[] questions, out string strNumber, out string strDebugInfo, out string strError) { strError = ""; strNumber = ""; strDebugInfo = ""; EndpointAddress address = new EndpointAddress(strUrl); GcatServiceClient client = new GcatServiceClient(CreateBasicHttpBinding0(), address); try { IAsyncResult soapresult = client.BeginGetNumber( strID, strAuthor, bSelectPinyin, bSelectEntry, bOutputDebugInfo, ref questions, null, null); for (; ;) { bool bRet = DoIdle(stop); // 出让控制权,避免CPU资源耗费过度 if (bRet == true) { strError = "用户中断"; return(-1); } if (soapresult.IsCompleted) { break; } } return(client.EndGetNumber( ref questions, out strNumber, out strDebugInfo, out strError, soapresult)); } catch (Exception ex) { strError = ConvertWebError(ex, strUrl); return(-1); } }
private void ChangePasswordDlg_Closed(object sender, System.EventArgs e) { if (stop != null) // 脱离关联 { stop.Unregister(); // 和容器关联 stop = null; } }
// parameters: // strAction 动作。为"new" "change" "delete" "onlydeletebiblio"之一。"delete"在删除书目记录的同时,会自动删除下属的实体记录。不过要求实体均未被借出才能删除。 // return: // -2 登录不成功 // -1 出错 // 0 成功 public static int UpdateRecord( DigitalPlatform.Stop stop, string strUrl, string strAuthString, string strAction, string strRecPath, string strFormat, string strRecord, string strTimestamp, out string strOutputRecPath, out string strOutputTimestamp, out string strError) { strError = ""; strOutputRecPath = ""; strOutputTimestamp = ""; EndpointAddress address = new EndpointAddress(strUrl); UnionCatalogServiceClient client = new UnionCatalogServiceClient(CreateBasicHttpBinding0(), address); try { IAsyncResult soapresult = client.BeginUpdateRecord( strAuthString, strAction, strRecPath, strFormat, strRecord, strTimestamp, null, null); for (; ;) { bool bRet = DoIdle(stop); // 出让控制权,避免CPU资源耗费过度 if (bRet == true) { strError = "用户中断"; return(-1); } if (soapresult.IsCompleted) { break; } } return(client.EndUpdateRecord( out strOutputRecPath, out strOutputTimestamp, out strError, soapresult)); } catch (Exception ex) { strError = ConvertWebError(ex, strUrl); return(-1); } }
private void ChangePasswordDlg_Load(object sender, System.EventArgs e) { textBox_url.Text = Url; textBox_userName.Text = UserName; stopManager.Initial(button_Cancel, label_message, null); stopManager.LinkReverseButton(button_OK); stop = new DigitalPlatform.Stop(); stop.Register(this.stopManager, true); // 和容器关联 }
public FileItemLoader(LibraryChannel channel, DigitalPlatform.Stop stop, string category, string filename) { this.Channel = channel; this.Stop = stop; this.Category = category; this.FileName = filename; //this.Style = style; //this.Lang = lang; }
public ResultSetLoader(LibraryChannel channel, DigitalPlatform.Stop stop, string resultsetName, string formatList, string lang = "zh") { this.Channel = channel; this.Stop = stop; this.ResultSetName = resultsetName; this.FormatList = formatList; this.Lang = lang; }
public DirItemLoader(LibraryChannel channel, DigitalPlatform.Stop stop, string path, string style, string lang = "zh") { this.Channel = channel; this.Stop = stop; this.Path = path; this.Style = style; this.Lang = lang; }
private void DtlpDupForm_FormClosed(object sender, FormClosedEventArgs e) { EventFinish.Set(); if (stop != null) // 脱离关联 { stop.Style = StopStyle.None; // 需要强制中断 stop.DoStop(); stop.Unregister(); // 和容器脱离关联 stop = null; } }
private void DupForm_Load(object sender, EventArgs e) { Debug.Assert(this.dom != null, "尚未Initial()"); stop = new DigitalPlatform.Stop(); if (this.stopManager != null) { stop.Register(this.stopManager, true); // 和容器关联 } // 自动启动查重 if (this.AutoBeginSearch == true) { API.PostMessage(this.Handle, WM_INITIAL, 0, 0); } }
public RecordLoader( RmsChannelCollection channels, DigitalPlatform.Stop stop, List <string> paths, string resultsetName, string formatList, string lang = "zh") { this.Channels = channels; this.Stop = stop; this.ResultSetName = resultsetName; this.FormatList = formatList; this.Lang = lang; this.Paths = paths; }
// 内部调用 // return: // -2 strID验证失败 // -1 出错 // 0 成功 public static int SplitHanzi( DigitalPlatform.Stop stop, GcatServiceClient client, string strID, string strText, out string [] tokens, out string strError) { strError = ""; tokens = null; try { IAsyncResult soapresult = client.BeginSplitHanzi( strID, strText, null, null); for (; ;) { bool bRet = DoIdle(stop); // 出让控制权,避免CPU资源耗费过度 if (bRet == true) { strError = "用户中断"; return(-1); } if (soapresult.IsCompleted) { break; } } return(client.EndSplitHanzi( out tokens, out strError, soapresult)); } catch (Exception ex) { strError = ConvertWebError(ex, client.Endpoint.Address.Uri.ToString()); return(-1); } }
// 包装后的版本 public static int SetPinyin( DigitalPlatform.Stop stop, string strUrl, string strID, string strPinyinXml, out string strError) { GcatServiceClient client = CreateChannel(strUrl); try { return(SetPinyin(stop, client, strID, strPinyinXml, out strError)); } finally { client.Close(); } }
// 包装后的版本 public static int SplitHanzi( DigitalPlatform.Stop stop, string strUrl, string strID, string strText, out string[] tokens, out string strError) { GcatServiceClient client = CreateChannel(strUrl); try { return(SplitHanzi(stop, client, strID, strText, out tokens, out strError)); } finally { client.Close(); } }
// 递归 public int Fill(TreeNode node, out string strError) { strError = ""; TreeNodeCollection children = null; if (node == null) { children = this.Nodes; } else { children = node.Nodes; } int i; // 填充根 if (node == null) { children.Clear(); for(i=0;i<Servers.Count;i++) { Server server = (Server)Servers[i]; TreeNode nodeNew = new TreeNode(server.Url, RESTYPE_SERVER, RESTYPE_SERVER); SetLoading(nodeNew); if (EnabledIndices != null && StringUtil.IsInList(nodeNew.ImageIndex, EnabledIndices) == false) nodeNew.ForeColor = ControlPaint.LightLight(nodeNew.ForeColor); children.Add(nodeNew); } return 0; } // 根以下的节点类型 ResPath respath = new ResPath(node); this.channel = Channels.GetChannel(respath.Url); Debug.Assert(channel != null, "Channels.GetChannel() 异常"); /* int nStart = 0; int nPerCount = -1; int nCount = 0; */ ResInfoItem [] items = null; #if NO DigitalPlatform.Stop stop = null; if (stopManager != null) { stop = new DigitalPlatform.Stop(); stop.Register(this.stopManager, true); // 和容器关联 stop.OnStop += new StopEventHandler(this.DoStop); stop.Initial("正在列目录: " + respath.FullPath); stop.BeginLoop(); } #endif DigitalPlatform.Stop stop = PrepareStop("正在列目录: " + respath.FullPath); long lRet = 0; try { lRet = channel.DoDir(respath.Path, this.Lang, null, // 不需要列出全部语言的名字 out items, out strError); } finally { EndStop(stop); } #if NO if (stopManager != null) { stop.EndLoop(); stop.OnStop -= new StopEventHandler(this.DoStop); stop.Initial(""); stop.Unregister(); // 和容器关联 } #endif this.channel = null; if (lRet == -1) { #if NO try { MessageBox.Show(this, "Channel::DoDir() Error: " + strError); } catch { // this可能已经不存在 return -1; } #endif if (node != null) { SetLoading(node); // 出错的善后处理,重新出现+号 node.Collapse(); } return -1; } if (items != null) { children.Clear(); //for(i=0;i<items.Length;i++) foreach(ResInfoItem res_item in items) { // ResInfoItem res_item = items[i]; TreeNode nodeNew = new TreeNode(res_item.Name, res_item.Type, res_item.Type); if (res_item.Type == RESTYPE_DB) { DbProperty prop = new DbProperty(); prop.TypeString = res_item.TypeString; // 类型字符串 nodeNew.Tag = prop; List<string> column_names = null; int nRet = GetBrowseColumns( node.Text, res_item.Name, out column_names, out strError); if (nRet == -1) return -1; prop.ColumnNames = column_names; } else { ItemProperty prop = new ItemProperty(); prop.TypeString = res_item.TypeString; // 类型字符串 nodeNew.Tag = prop; } if (res_item.HasChildren) SetLoading(nodeNew); if (EnabledIndices != null && StringUtil.IsInList(nodeNew.ImageIndex, EnabledIndices) == false) nodeNew.ForeColor = ControlPaint.LightLight(nodeNew.ForeColor); children.Add(nodeNew); } } return 0; }
// 登出 void menu_logout(object sender, System.EventArgs e) { if (this.SelectedNode == null) { MessageBox.Show(this, "尚未选择节点"); return; } ResPath respath = new ResPath(this.SelectedNode); this.channel = Channels.GetChannel(respath.Url); Debug.Assert(channel != null, "Channels.GetChannel() 异常"); #if NO DigitalPlatform.Stop stop = null; if (stopManager != null) { stop = new DigitalPlatform.Stop(); stop.Register(this.stopManager, true); // 和容器关联 stop.OnStop += new StopEventHandler(this.DoStop); stop.Initial("正在登出: " + respath.FullPath); stop.BeginLoop(); } #endif DigitalPlatform.Stop stop = PrepareStop("正在登出: " + respath.FullPath); string strError; // return: // -1 error // 0 login failed // 1 login succeed long nRet = channel.DoLogout( out strError); EndStop(stop); #if NO if (stopManager != null) { stop.EndLoop(); stop.OnStop -= new StopEventHandler(this.DoStop); stop.Initial(""); stop.Unregister(); // 和容器关联 } #endif this.channel = null; if (nRet == -1) { MessageBox.Show(this, strError); return; } // 刷新 //ResPath OldPath = new ResPath(this.SelectedNode); respath.Path = ""; ExpandPath(respath); // 选中服务器,以下节点清除 SetLoading(this.SelectedNode); if (this.SelectedNode != null) this.SelectedNode.Collapse(); //ExpandPath(OldPath); }
// 获得指定一期的封面图片 URI // parameters: // strBiblioPath 书目记录路径 // strQueryString 检索词。例如 “2005|1|1000|50”。格式为 年|期号|总期号|卷号。一般为 年|期号| 即可。 public static int GetIssueCoverImageUri(this LibraryChannel channel, DigitalPlatform.Stop stop, string strBiblioRecPath, string strQueryString, string strPreferredType, out string strUri, out string strError) { strUri = ""; strError = ""; string strBiblioRecordID = StringUtil.GetRecordId(strBiblioRecPath); string strStyle = "query:父记录+期号|" + strBiblioRecordID + "|" + strQueryString; DigitalPlatform.LibraryClient.localhost.EntityInfo[] issueinfos = null; long lRet = channel.GetIssues(stop, strBiblioRecPath, 0, 1, strStyle, channel.Lang, out issueinfos, out strError); if (lRet == -1) { return(-1); } if (lRet == 0) { return(0); // not found } EntityInfo info = issueinfos[0]; string strXml = info.OldRecord; string strIssueRecordPath = info.OldRecPath; if (string.IsNullOrEmpty(strXml)) { strError = "期记录 '" + strIssueRecordPath + "' 的 strXml 为空"; return(-1); } XmlDocument dom = new XmlDocument(); try { dom.LoadXml(strXml); } catch (Exception ex) { strError = "期记录 '" + strIssueRecordPath + "' XML 装入 DOM 时出错: " + ex.Message; return(-1); } string strObjectID = dp2StringUtil.GetCoverImageIDFromIssueRecord(dom, strPreferredType); if (string.IsNullOrEmpty(strObjectID)) { return(0); } strUri = strIssueRecordPath + "/object/" + strObjectID; return(1); }
private void CfgFileEditDlg_Load(object sender, System.EventArgs e) { button_export.Enabled = false; MemoryStream stream = null; string strMetaData; string strError = ""; string strMime = ""; Hashtable values = null; if (Obj != null) { if (this.Obj.Content != null) { stream = new MemoryStream(this.Obj.Content); this.Stream = stream; this.Stream.Seek(0, SeekOrigin.Begin); button_export.Enabled = true; } this.TimeStamp = this.Obj.TimeStamp; strMetaData = this.Obj.Metadata; // 观察mime // 取metadata values = StringUtil.ParseMetaDataXml(strMetaData, out strError); if (values == null) { MessageBox.Show(this, strError); return; } strMime = (string)values["mimetype"]; if (strMime == null || strMime == "") strMime = "text"; this.Mime = strMime; this.LocalPath = (string)values["localpath"]; if (this.LocalPath == null) this.LocalPath = ""; this.textBox_content.Text = ""; // string strFirstPart = StringUtil.GetFirstPartPath(ref strMime); if (this.IsText == true) { if (this.Stream != null) { this.Stream.Seek(0, SeekOrigin.Begin); using (StreamReader sr = new StreamReader(this.Stream, Encoding.UTF8)) { this.textBox_content.Text = ConvertCrLf(sr.ReadToEnd()); } } } else { } ////// button_OK.Enabled = false; this.textBox_content.SelectionStart = 0; this.textBox_content.SelectionLength = 0; return; } this.channel = Channels.GetChannel(this.ServerUrl); Debug.Assert(channel != null, "Channels.GetChannel() 异常"); DigitalPlatform.Stop stop = null; if (stopManager != null) { stop = new DigitalPlatform.Stop(); stop.Register(this.stopManager, true); // 和容器关联 stop.OnStop += new StopEventHandler(this.DoStop); stop.Initial("正在下载配置文件: " + this.Path); stop.BeginLoop(); } // string strContent = ""; byte[] baTimeStamp = null; string strOutputPath; string strStyle = "content,data,metadata,timestamp,outputpath"; // string strStyle = "attachment,data,metadata,timestamp,outputpath"; stream = new MemoryStream(); long lRet = channel.GetRes( this.Path, stream, stop, // stop, strStyle, null, // byte [] input_timestamp, out strMetaData, out baTimeStamp, out strOutputPath, out strError); /* long lRet = channel.GetRes(( this.Path, out strContent, out strMetaData, out baTimeStamp, out strOutputPath, out strError); */ if (stopManager != null) { stop.EndLoop(); stop.OnStop -= new StopEventHandler(this.DoStop); stop.Initial(""); } if (lRet == -1) { MessageBox.Show(this, strError); goto FINISH; } this.Stream = stream; this.Stream.Seek(0, SeekOrigin.Begin); button_export.Enabled = true; this.TimeStamp = baTimeStamp; // 观察mime // 取metadata values = StringUtil.ParseMetaDataXml(strMetaData, out strError); if (values == null) { MessageBox.Show(this, strError); goto FINISH; } strMime = (string)values["mimetype"]; if (strMime == null || strMime == "") strMime = "text"; this.Mime = strMime; this.LocalPath = (string)values["localpath"]; if (this.LocalPath == null) this.LocalPath = ""; // string strFirstPart = StringUtil.GetFirstPartPath(ref strMime); if (this.IsText == true) { this.Stream.Seek(0, SeekOrigin.Begin); using (StreamReader sr = new StreamReader(this.Stream, Encoding.UTF8)) { this.textBox_content.Text = ConvertCrLf(sr.ReadToEnd()); } // 注意,此后 this.Stream 被关闭 } else { //this.textBox_content.Text = "<二进制内容无法直接编辑>"; //this.textBox_content.ReadOnly = true; //this.button_format.Enabled = false; } ////// button_OK.Enabled = false; FINISH: if (stopManager != null && stop != null) { stop.Unregister(); // 和容器关联 stop = null; } this.channel = null; this.textBox_content.SelectionStart = 0; this.textBox_content.SelectionLength = 0; }
// 递归 public int Fill(TreeNode node) { TreeNodeCollection children = null; if (node == null) { children = this.Nodes; } else { children = node.Nodes; } int i; // 填充根 if (node == null) { children.Clear(); TreeNode nodeNew = new TreeNode(this.ServerUrl, ResTree.RESTYPE_SERVER, ResTree.RESTYPE_SERVER); ResTree.SetLoading(nodeNew); NodeInfo nodeinfo = new NodeInfo(); nodeinfo.TreeNode = nodeNew; nodeinfo.Expandable = true; nodeinfo.DefElement = GetDefElementString(nodeNew.ImageIndex); nodeinfo.NodeState |= NodeState.Object; nodeNew.Tag = nodeinfo; if (EnabledIndices != null && StringUtil.IsInList(nodeNew.ImageIndex, EnabledIndices) == false) nodeNew.ForeColor = ControlPaint.LightLight(nodeNew.ForeColor); children.Add(nodeNew); return 0; } // 根以下的节点类型 ResPath respath = new ResPath(node); string strPath = respath.Path; //if (node != null) // strPath = TreeViewUtil.GetPath(node); this.channel = Channels.GetChannel(this.ServerUrl); Debug.Assert(channel != null, "Channels.GetChannel() 异常"); ResInfoItem [] items = null; string strError = ""; DigitalPlatform.Stop stop = null; if (stopManager != null) { stop = new DigitalPlatform.Stop(); stop.Register(this.stopManager, true); // 和容器关联 stop.OnStop += new StopEventHandler(this.DoStop); stop.Initial("正在列目录: " + this.ServerUrl + "?" + strPath); stop.BeginLoop(); } long lRet = channel.DoDir(strPath, this.Lang, null, // 不需要列出全部语言的名字 out items, out strError); if (stopManager != null) { stop.EndLoop(); stop.OnStop -= new StopEventHandler(this.DoStop); stop.Initial(""); stop.Unregister(); // 和容器关联 } this.channel = null; if (lRet == -1) { try { MessageBox.Show(this, "Channel::DoDir() Error: " + strError); } catch { // this可能已经不存在 return -1; } if (node != null) { ResTree.SetLoading(node); // 出错的善后处理,重新出现+号 node.Collapse(); } return -1; } if (items != null) { children.Clear(); for(i=0;i<items.Length;i++) { // 忽略from类型节点 if (items[i].Type == ResTree.RESTYPE_FROM) continue; TreeNode nodeNew = new TreeNode(items[i].Name, items[i].Type, items[i].Type); NodeInfo nodeinfo = new NodeInfo(); nodeinfo.TreeNode = nodeNew; nodeinfo.Expandable = items[i].HasChildren; nodeinfo.DefElement = GetDefElementString(nodeNew.ImageIndex); nodeinfo.NodeState |= NodeState.Object; nodeinfo.Style = items[i].Style; nodeNew.Tag = nodeinfo; if (items[i].HasChildren) ResTree.SetLoading(nodeNew); if (EnabledIndices != null && StringUtil.IsInList(nodeNew.ImageIndex, EnabledIndices) == false) nodeNew.ForeColor = ControlPaint.LightLight(nodeNew.ForeColor); children.Add(nodeNew); } } return 0; }
DigitalPlatform.Stop PrepareStop(string strText) { if (stopManager == null) return null; DigitalPlatform.Stop stop = new DigitalPlatform.Stop(); stop.Register(this.stopManager, true); // 和容器关联 stop.OnStop += new StopEventHandler(this.DoStop); stop.Initial(strText); stop.BeginLoop(); return stop; }
private void DupForm_Load(object sender, EventArgs e) { Debug.Assert(this.dom != null, "尚未Initial()"); stop = new DigitalPlatform.Stop(); if (this.stopManager != null) stop.Register(this.stopManager, true); // 和容器关联 // 自动启动查重 if (this.AutoBeginSearch == true) { API.PostMessage(this.Handle, WM_INITIAL, 0, 0); } }
/* // 将内存对象创建为真正的服务器端对象 public int BuildRealObjects( string strDbName, DatabaseObject root, out string strError) { strError = ""; int nRet = 0; // 创建根 if (root.Type != -1) { if (root.Type == ResTree.RESTYPE_DB) goto DOCHILD; // 忽略本节点,但是继续作下级节点 // 缺省配置文件,忽略保存 if (root.IsDefaultFile() == true) return 0; MemoryStream stream = null; if (root.Type == ResTree.RESTYPE_FILE) stream = new MemoryStream(root.Content); string strPath = root.MakePath(strDbName); // 在服务器端创建对象 nRet = NewServerSideObject(strPath, root.Type, stream, root.TimeStamp, out strError); if (nRet == -1) return -1; } DOCHILD: // 递归 for(int i=0;i<root.Children.Count;i++) { DatabaseObject obj = (DatabaseObject)root.Children[i]; nRet = BuildRealObjects( strDbName, obj, out strError); if (nRet == -1) return -1; } return 0; } */ // 根据路径创建内存对象 public int CreateObject(DatabaseObject obj, string strPath, out string strError) { strError = ""; obj.Children.Clear(); if (obj.Type == ResTree.RESTYPE_FILE) { byte[] baTimeStamp = null; string strMetaData; string strOutputPath; this.channel = Channels.GetChannel(this.ServerUrl); Debug.Assert(channel != null, "Channels.GetChannel() 异常"); // string strStyle = "attachment,data,timestamp,outputpath"; string strStyle = "content,data,timestamp,outputpath"; using (MemoryStream stream = new MemoryStream()) { long lRet = channel.GetRes(strPath, stream, null, // stop, strStyle, null, // byte [] input_timestamp, out strMetaData, out baTimeStamp, out strOutputPath, out strError); if (lRet == -1) { // obj.SetData(null); obj.TimeStamp = null; return 0; // 继续处理 } obj.SetData(stream); obj.TimeStamp = baTimeStamp; } } if (obj.Type == ResTree.RESTYPE_DB || obj.Type == ResTree.RESTYPE_FOLDER) { this.channel = Channels.GetChannel(this.ServerUrl); Debug.Assert(channel != null, "Channels.GetChannel() 异常"); ResInfoItem[] items = null; DigitalPlatform.Stop stop = null; if (stopManager != null) { stop = new DigitalPlatform.Stop(); stop.Register(this.stopManager, true); // 和容器关联 stop.OnStop += new StopEventHandler(this.DoStop); stop.Initial("正在列目录: " + this.ServerUrl + "?" + strPath); stop.BeginLoop(); } long lRet = channel.DoDir(strPath, this.Lang, null, // 不需要返回全部语言的名字 out items, out strError); if (stopManager != null) { stop.EndLoop(); stop.OnStop -= new StopEventHandler(this.DoStop); stop.Initial(""); stop.Unregister(); // 和容器关联 } this.channel = null; if (lRet == -1) return -1; if (items == null) return 0; for (int i = 0; i < items.Length; i++) { // 忽略from类型节点 if (items[i].Type == ResTree.RESTYPE_FROM) continue; DatabaseObject child = new DatabaseObject(); child.Name = items[i].Name; child.Type = items[i].Type; child.Style = items[i].Style; child.Parent = obj; obj.Children.Add(child); int nRet = CreateObject(child, strPath + "/" + items[i].Name, out strError); if (nRet == -1) return -1; } } return 0; }
// 异步版本,可以中断 // return: // -3 需要回答问题 // -2 尚未登录(info.UserID为空) // -1 出错 // 0 成功 public int GetNumber( DigitalPlatform.Stop stop, string strAuthor, bool bSelectPinyin, bool bSelectEntry, bool bOutputDebugInfo, out string strNumber, out string strDebugInfo, out string strError) { strNumber = ""; strDebugInfo = ""; strError = ""; REDO: ws.GetNumberCompleted += new GetNumberCompletedEventHandler(ws_GetNumberCompleted); try { this.eventComplete.Reset(); ws.GetNumberAsync(strAuthor, bSelectPinyin, bSelectEntry, bOutputDebugInfo); while (true) { Application.DoEvents(); // 出让界面控制权 if (stop != null) { if (stop.State != 0) { strError = "用户中断1"; return(-1); } } bool bRet = this.eventComplete.WaitOne(10, true); if (bRet == true) { break; } } } finally { ws.GetNumberCompleted -= new GetNumberCompletedEventHandler(ws_GetNumberCompleted); } GetNumberCompletedEventArgs e = (GetNumberCompletedEventArgs)this.resultParam; if (e.Error != null) { strError = e.Error.Message; return(-1); } if (e.Cancelled == true) { strError = "用户中断2"; } else { strError = e.strError; } strNumber = e.strNumber; strDebugInfo = e.strDebugInfo; if (e.Result == -2) { if (DoNotLogin(ref strError) == 1) { goto REDO; } } return(e.Result); }
// 初始化数据库 void menu_initialDB(object sender, System.EventArgs e) { if (this.SelectedNode == null) { MessageBox.Show(this, "尚未选择要初始化的数据库节点"); return; } if (this.SelectedNode.ImageIndex != RESTYPE_DB) { MessageBox.Show(this, "所选择的节点不是数据库类型。请选择要初始化的数据库节点。"); return; } ResPath respath = new ResPath(this.SelectedNode); string strText = "你确实要初始化位于服务器 '"+respath.Url+"' 上的数据库 '"+respath.Path + "' 吗?\r\n\r\n警告:数据库一旦被初始化,其中包含的原有数据将全部被摧毁,并且无法恢复!"; DialogResult msgResult = MessageBox.Show(this, strText, "初始化数据库", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2); if (msgResult != DialogResult.OK) { MessageBox.Show(this, "初始化数据库操作被放弃..."); return; } this.channel = Channels.GetChannel(respath.Url); Debug.Assert(channel != null, "Channels.GetChannel() 异常"); string strError = ""; #if NO DigitalPlatform.Stop stop = null; if (stopManager != null) { stop = new DigitalPlatform.Stop(); stop.Register(this.stopManager, true); // 和容器关联 stop.OnStop += new StopEventHandler(this.DoStop); stop.Initial("正在初始化数据库: " + respath.FullPath); stop.BeginLoop(); } #endif DigitalPlatform.Stop stop = PrepareStop("正在初始化数据库: " + respath.FullPath); long lRet = channel.DoInitialDB(respath.Path, out strError); EndStop(stop); #if NO if (stopManager != null) { stop.EndLoop(); stop.OnStop -= new StopEventHandler(this.DoStop); stop.Initial(""); stop.Unregister(); // 和容器脱离关联 } #endif this.channel = null; if (lRet == -1) { MessageBox.Show(this, strError); } else { MessageBox.Show(this, "位于服务器'"+respath.Url+"'上的数据库 '"+respath.Path+"' 被成功初始化。"); } }
void RefreshDB(bool bClearAllKeyTables) { if (this.SelectedNode == null) { MessageBox.Show(this, "尚未选择要刷新定义的数据库节点"); return; } if (this.SelectedNode.ImageIndex != RESTYPE_DB) { MessageBox.Show(this, "所选择的节点不是数据库类型。请选择要刷新定义的数据库节点。"); return; } ResPath respath = new ResPath(this.SelectedNode); string strText = "确实要刷新位于服务器 '" + respath.Url + "' 上的数据库 '" + respath.Path + "' 的定义吗?\r\n\r\n注:刷新数据库定义,会为数据库增补在keys配置文件中新增的SQL表,不会损坏数据库中已有的数据。"; DialogResult msgResult = MessageBox.Show(this, strText, "刷新数据库定义", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2); if (msgResult != DialogResult.OK) { MessageBox.Show(this, "刷新数据库定义的操作被放弃..."); return; } this.channel = Channels.GetChannel(respath.Url); Debug.Assert(channel != null, "Channels.GetChannel() 异常"); string strError = ""; #if NO DigitalPlatform.Stop stop = null; if (stopManager != null) { stop = new DigitalPlatform.Stop(); stop.Register(this.stopManager, true); // 和容器关联 stop.OnStop += new StopEventHandler(this.DoStop); stop.Initial("正在刷新数据库定义: " + respath.FullPath ); stop.BeginLoop(); } #endif DigitalPlatform.Stop stop = PrepareStop("正在刷新数据库定义: " + respath.FullPath); long lRet = channel.DoRefreshDB( "begin", respath.Path, bClearAllKeyTables, out strError); EndStop(stop); #if NO if (stopManager != null) { stop.EndLoop(); stop.OnStop -= new StopEventHandler(this.DoStop); stop.Initial(""); stop.Unregister(); // 和容器脱离关联 } #endif this.channel = null; if (lRet == -1) { MessageBox.Show(this, strError); } else { MessageBox.Show(this, "位于服务器'" + respath.Url + "'上的数据库 '" + respath.Path + "' 被成功刷新了定义。"); } }
// 导入数据 int ImportData(bool bFastMode = false) { string strError = ""; string strTimeMessage = ""; int CHUNK_SIZE = 150 * 1024; // 70 if (this.SelectedNode == null) { strError = "尚未选择要要导入数据的数据库节点"; goto ERROR0; } if (this.SelectedNode.ImageIndex != RESTYPE_DB) { strError = "所选择的节点不是数据库类型。请选择要导入数据的数据库节点。"; goto ERROR0; } if (bFastMode == true) { DialogResult result = MessageBox.Show(this, "警告:\r\n在快速导入期间,相关数据库会进入一种锁定状态,对数据库的其他检索和修改操作暂时会被禁止,直到处理完成。\r\n\r\n请问确实要进行快速导入么?", "导入数据", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2); if (result == DialogResult.No) return 0; } OpenFileDialog dlg = new OpenFileDialog(); dlg.Title = "请指定要导入的数据文件"; dlg.FileName = ""; dlg.Filter = "备份文件 (*.dp2bak)|*.dp2bak|XML文件 (*.xml)|*.xml|ISO2709文件 (*.iso;*.mrc)|*.iso;*.mrc|All files (*.*)|*.*"; dlg.RestoreDirectory = true; if (dlg.ShowDialog() != DialogResult.OK) { return 0; } long lTotalCount = 0; ImportUtil import_util = new ImportUtil(); int nRet = import_util.Begin(this, this.AppInfo, dlg.FileName, out strError); if (nRet == -1 || nRet == 1) goto ERROR0; #if NO ResPath respath = new ResPath(this.SelectedNode); this.channel = Channels.GetChannel(respath.Url); Debug.Assert(channel != null, "Channels.GetChannel() 异常"); #endif // 缺省的目标数据库路径 ResPath default_target_respath = new ResPath(this.SelectedNode); RmsChannel cur_channel = Channels.CreateTempChannel(default_target_respath.Url); Debug.Assert(cur_channel != null, "Channels.GetChannel() 异常"); List<string> target_dburls = new List<string>(); #if NO DigitalPlatform.Stop stop = null; if (stopManager != null) { stop = new DigitalPlatform.Stop(); stop.Register(this.stopManager, true); // 和容器关联 stop.OnStop += new StopEventHandler(this.DoStop); stop.Initial("正在导入数据 " + respath.FullPath); stop.BeginLoop(); } #endif DigitalPlatform.Stop stop = PrepareStop("正在导入数据 ..."); // + default_target_respath.FullPath); stop.OnStop -= new StopEventHandler(this.DoStop); // 去掉缺省的回调函数 stop.OnStop += (sender1, e1) => { if (cur_channel != null) cur_channel.Abort(); }; stop.Style = StopStyle.EnableHalfStop; // API的间隙才让中断。避免获取结果集的中途,因为中断而导致 Session 失效,结果集丢失,进而无法 Retry 获取 ProgressEstimate estimate = new ProgressEstimate(); try // open import util { bool bDontPromptTimestampMismatchWhenOverwrite = false; DbNameMap map = new DbNameMap(); long lSaveOffs = -1; estimate.SetRange(0, import_util.Stream.Length); estimate.StartEstimate(); stop.SetProgressRange(0, import_util.Stream.Length); List<UploadRecord> records = new List<UploadRecord>(); int nBatchSize = 0; for (int index = 0; ; index++) { Application.DoEvents(); // 出让界面控制权 if (stop.State != 0) { DialogResult result = MessageBox.Show(this, "确实要中断当前批处理操作?", "导入数据", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2); if (result == DialogResult.Yes) { strError = "用户中断"; goto ERROR1; } else { stop.Continue(); } } //string strXml = ""; //string strResPath = ""; //string strTimeStamp = ""; UploadRecord record = null; if (import_util.FileType == ExportFileType.BackupFile) { if (lSaveOffs != -1) import_util.Stream.Seek(lSaveOffs, SeekOrigin.Begin); } nRet = import_util.ReadOneRecord(out record, out strError); if (nRet == -1) goto ERROR1; if (nRet == 1) break; if (import_util.FileType == ExportFileType.BackupFile) { // 保存每次读取后的文件指针位置 lSaveOffs = import_util.Stream.Position; } Debug.Assert(record != null, ""); #if NO XmlDocument dom = new XmlDocument(); try { dom.LoadXml(strXml); } catch (Exception ex) { strError = "XML装入DOM时出错: " + ex.Message; goto ERROR1; } string strResPath = DomUtil.GetAttr(DpNs.dprms, dom.DocumentElement, "path"); string strTimeStamp = DomUtil.GetAttr(DpNs.dprms, dom.DocumentElement, "timestamp"); #endif // 准备目标路径 { string strLongPath = record.Url + "?" + record.RecordBody.Path; #if NO // 根据原始路径准备即将写入的路径 // return: // -1 出错 // 0 用户放弃 // 1 成功 nRet = ImportUtil.PrepareOverwritePath( this.Servers, this.Channels, this, ref map, ref strLongPath, out strError); if (nRet == 0 || nRet == -1) goto ERROR1; #endif // 根据原始路径准备即将写入的路径 // return: // -1 出错 // 0 用户放弃 // 1 成功 // 2 要跳过本条 nRet = ImportUtil.PrepareOverwritePath( this, this.Servers, this.Channels, this.AppInfo, index, default_target_respath.FullPath, ref map, ref strLongPath, out strError); if (nRet == 0 || nRet == -1) goto ERROR1; if (nRet == 2) continue; ResPath respath = new ResPath(strLongPath); record.Url = respath.Url; record.RecordBody.Path = respath.Path; // 记载每个数据库的 URL string strDbUrl = GetDbUrl(strLongPath); if (target_dburls.IndexOf(strDbUrl) == -1) { // 每个数据库要进行一次快速模式的准备操作 if (bFastMode == true) { nRet = ManageKeysIndex(strDbUrl, "beginfastappend", "正在对数据库 "+strDbUrl+" 进行快速导入模式的准备工作 ...", out strError); if (nRet == -1) goto ERROR1; } target_dburls.Add(strDbUrl); } } bool bNeedPush = false; // 是否要把积累的记录推送出去进行写入? // 要进行以下检查: // 1) 当前记录和前一条记录之间,更换了服务器 // 2) 累积的记录尺寸超过要求 // 3) 当前记录是一条超大的记录 (这是因为要保持从文件中读出的顺序来写入(例如追加时候的号码增量顺序),就必须在单条写入本条前,先写入积累的那些记录) if (records.Count > 0) { if (record.TooLarge() == true) bNeedPush = true; else if (nBatchSize + record.RecordBody.Xml.Length > CHUNK_SIZE) bNeedPush = true; else { if (LastUrl(records) != record.Url) bNeedPush = true; } } if (bNeedPush == true) { // 准备 Channel Debug.Assert(records.Count > 0, ""); cur_channel = ImportUtil.GetChannel(this.Channels, stop, LastUrl(records), cur_channel); List<UploadRecord> save_records = new List<UploadRecord>(); save_records.AddRange(records); while (records.Count > 0) { // 将 XML 记录成批写入数据库 // return: // -1 出错 // >=0 本次已经写入的记录个数。本函数返回时 records 集合的元素数没有变化(但元素的Path和Timestamp会有变化),如果必要调主可截取records集合中后面未处理的部分再次调用本函数 nRet = ImportUtil.WriteRecords( this, stop, cur_channel, bFastMode, records, ref bDontPromptTimestampMismatchWhenOverwrite, out strError); if (nRet == -1) goto ERROR1; if (nRet == 0) { // TODO: 或可以改为单条写入 strError = "WriteRecords() error :" + strError; goto ERROR1; } Debug.Assert(nRet <= records.Count, ""); records.RemoveRange(0, nRet); lTotalCount += nRet; } // 上载对象 // return: // -1 出错 // 0 成功 nRet = import_util.UploadObjects( stop, cur_channel, save_records, ref bDontPromptTimestampMismatchWhenOverwrite, out strError); if (nRet == -1) goto ERROR1; nBatchSize = 0; stop.SetProgressValue(import_util.Stream.Position); stop.SetMessage("已经写入记录 " + lTotalCount.ToString() + " 条。" + "剩余时间 " + ProgressEstimate.Format(estimate.Estimate(import_util.Stream.Position)) + " 已经过时间 " + ProgressEstimate.Format(estimate.delta_passed)); } // 如果 记录的 XML 尺寸太大不便于成批上载,需要在单独直接上载 if (record.TooLarge() == true) { // 准备 Channel // ResPath respath = new ResPath(record.RecordBody.Path); cur_channel = ImportUtil.GetChannel(this.Channels, stop, record.Url, cur_channel); // 写入一条 XML 记录 // return: // -1 出错 // 0 邀请中断整个处理 // 1 成功 // 2 跳过本条,继续处理后面的 nRet = ImportUtil.WriteOneXmlRecord( this, stop, cur_channel, record, ref bDontPromptTimestampMismatchWhenOverwrite, out strError); if (nRet == -1) goto ERROR1; if (nRet == 0) goto ERROR1; List<UploadRecord> temp = new List<UploadRecord>(); temp.Add(record); // 上载对象 // return: // -1 出错 // 0 成功 nRet = import_util.UploadObjects( stop, cur_channel, temp, ref bDontPromptTimestampMismatchWhenOverwrite, out strError); if (nRet == -1) goto ERROR1; lTotalCount += 1; continue; } records.Add(record); if (record.RecordBody != null && record.RecordBody.Xml != null) nBatchSize += record.RecordBody.Xml.Length; } // 最后提交一次 if (records.Count > 0) { // 准备 Channel Debug.Assert(records.Count > 0, ""); cur_channel = ImportUtil.GetChannel(this.Channels, stop, LastUrl(records), cur_channel); List<UploadRecord> save_records = new List<UploadRecord>(); save_records.AddRange(records); while (records.Count > 0) { // 将 XML 记录成批写入数据库 // return: // -1 出错 // >=0 本次已经写入的记录个数。本函数返回时 records 集合的元素数没有变化(但元素的Path和Timestamp会有变化),如果必要调主可截取records集合中后面未处理的部分再次调用本函数 nRet = ImportUtil.WriteRecords( this, stop, cur_channel, bFastMode, records, ref bDontPromptTimestampMismatchWhenOverwrite, out strError); if (nRet == -1) goto ERROR1; if (nRet == 0) { strError = "WriteRecords() error :" + strError; goto ERROR1; } Debug.Assert(nRet <= records.Count, ""); records.RemoveRange(0, nRet); lTotalCount += nRet; } // 上载对象 // return: // -1 出错 // 0 成功 nRet = import_util.UploadObjects( stop, cur_channel, save_records, ref bDontPromptTimestampMismatchWhenOverwrite, out strError); if (nRet == -1) goto ERROR1; nBatchSize = 0; stop.SetProgressValue(import_util.Stream.Position); stop.SetMessage("已经写入记录 " + lTotalCount.ToString() + " 条。" + "剩余时间 " + ProgressEstimate.Format(estimate.Estimate(import_util.Stream.Position)) + " 已经过时间 " + ProgressEstimate.Format(estimate.delta_passed)); records.Clear(); nBatchSize = 0; } }// close import util finally { if (bFastMode == true) { foreach (string url in target_dburls) { string strQuickModeError = ""; nRet = ManageKeysIndex(url, "endfastappend", "正在对数据库 " + url + " 进行快速导入模式的收尾工作,请耐心等待 ...", out strQuickModeError); if (nRet == -1) MessageBox.Show(this, strQuickModeError); } } EndStop(stop); #if NO if (stopManager != null) { stop.EndLoop(); stop.OnStop -= new StopEventHandler(this.DoStop); stop.Initial(""); stop.Unregister(); // 和容器脱离关联 } #endif cur_channel.Close(); cur_channel = null; import_util.End(); } strTimeMessage = "总共耗费时间: " + estimate.GetTotalTime().ToString(); MessageBox.Show(this, "文件 " + dlg.FileName + " 内的数据已经成功导入下列数据库:\r\n\r\n" + StringUtil.MakePathList(target_dburls, "\r\n") + "\r\n\r\n共导入记录 " + lTotalCount.ToString() + " 条。\r\n\r\n" + strTimeMessage); return 0; ERROR0: MessageBox.Show(this, strError); return -1; ERROR1: MessageBox.Show(this, strError); // 使用了 lTotalCount 和 estimate 以后的报错 if (lTotalCount > 0) { strTimeMessage = "总共耗费时间: " + estimate.GetTotalTime().ToString(); MessageBox.Show(this, "文件 " + dlg.FileName + " 内的部分数据已经成功导入下列数据库:\r\n\r\n" + StringUtil.MakePathList(target_dburls, "\r\n") + "\r\n\r\n共导入记录 " + lTotalCount.ToString() + " 条。\r\n\r\n" + strTimeMessage); } return -1; }
private void CfgFileEditDlg_Load(object sender, System.EventArgs e) { button_export.Enabled = false; MemoryStream stream = null; string strMetaData; string strError = ""; string strMime = ""; Hashtable values = null; if (Obj != null) { if (this.Obj.Content != null) { stream = new MemoryStream(this.Obj.Content); this.Stream = stream; this.Stream.Seek(0, SeekOrigin.Begin); button_export.Enabled = true; } this.TimeStamp = this.Obj.TimeStamp; strMetaData = this.Obj.Metadata; // 观察mime // 取metadata values = StringUtil.ParseMetaDataXml(strMetaData, out strError); if (values == null) { MessageBox.Show(this, strError); return; } strMime = (string)values["mimetype"]; if (strMime == null || strMime == "") { strMime = "text"; } this.Mime = strMime; this.LocalPath = (string)values["localpath"]; if (this.LocalPath == null) { this.LocalPath = ""; } this.textBox_content.Text = ""; // string strFirstPart = StringUtil.GetFirstPartPath(ref strMime); if (this.IsText == true) { if (this.Stream != null) { this.Stream.Seek(0, SeekOrigin.Begin); using (StreamReader sr = new StreamReader(this.Stream, Encoding.UTF8)) { this.textBox_content.Text = ConvertCrLf(sr.ReadToEnd()); } } } else { } ////// button_OK.Enabled = false; this.textBox_content.SelectionStart = 0; this.textBox_content.SelectionLength = 0; return; } this.channel = Channels.GetChannel(this.ServerUrl); Debug.Assert(channel != null, "Channels.GetChannel() 异常"); DigitalPlatform.Stop stop = null; if (stopManager != null) { stop = new DigitalPlatform.Stop(); stop.Register(this.stopManager, true); // 和容器关联 stop.OnStop += new StopEventHandler(this.DoStop); stop.Initial("正在下载配置文件: " + this.Path); stop.BeginLoop(); } // string strContent = ""; byte[] baTimeStamp = null; string strOutputPath; string strStyle = "content,data,metadata,timestamp,outputpath"; // string strStyle = "attachment,data,metadata,timestamp,outputpath"; stream = new MemoryStream(); long lRet = channel.GetRes( this.Path, stream, stop, // stop, strStyle, null, // byte [] input_timestamp, out strMetaData, out baTimeStamp, out strOutputPath, out strError); /* * long lRet = channel.GetRes(( * this.Path, * out strContent, * out strMetaData, * out baTimeStamp, * out strOutputPath, * out strError); */ if (stopManager != null) { stop.EndLoop(); stop.OnStop -= new StopEventHandler(this.DoStop); stop.Initial(""); } if (lRet == -1) { MessageBox.Show(this, strError); goto FINISH; } this.Stream = stream; this.Stream.Seek(0, SeekOrigin.Begin); button_export.Enabled = true; this.TimeStamp = baTimeStamp; // 观察mime // 取metadata values = StringUtil.ParseMetaDataXml(strMetaData, out strError); if (values == null) { MessageBox.Show(this, strError); goto FINISH; } strMime = (string)values["mimetype"]; if (strMime == null || strMime == "") { strMime = "text"; } this.Mime = strMime; this.LocalPath = (string)values["localpath"]; if (this.LocalPath == null) { this.LocalPath = ""; } // string strFirstPart = StringUtil.GetFirstPartPath(ref strMime); if (this.IsText == true) { this.Stream.Seek(0, SeekOrigin.Begin); using (StreamReader sr = new StreamReader(this.Stream, Encoding.UTF8)) { this.textBox_content.Text = ConvertCrLf(sr.ReadToEnd()); } // 注意,此后 this.Stream 被关闭 } else { //this.textBox_content.Text = "<二进制内容无法直接编辑>"; //this.textBox_content.ReadOnly = true; //this.button_format.Enabled = false; } ////// button_OK.Enabled = false; FINISH: if (stopManager != null && stop != null) { stop.Unregister(); // 和容器关联 stop = null; } this.channel = null; this.textBox_content.SelectionStart = 0; this.textBox_content.SelectionLength = 0; }
int ManageKeysIndex( string strDbUrl, string strAction, string strMessage, out string strError) { strError = ""; ResPath respath = null; if (strDbUrl == null) { if (this.SelectedNode == null) { strError = "尚未选择要要操作的数据库节点"; goto ERROR1; } if (this.SelectedNode.ImageIndex != RESTYPE_DB) { strError = "所选择的节点不是数据库类型。请选择要操作的数据库节点。"; goto ERROR1; } respath = new ResPath(this.SelectedNode); } else respath = new ResPath(strDbUrl); this.channel = Channels.GetChannel(respath.Url); Debug.Assert(channel != null, "Channels.GetChannel() 异常"); #if NO DigitalPlatform.Stop stop = null; if (stopManager != null) { stop = new DigitalPlatform.Stop(); stop.Register(this.stopManager, true); // 和容器关联 stop.OnStop += new StopEventHandler(this.DoStop); stop.Initial("正在导出数据 " + respath.FullPath); stop.BeginLoop(); } #endif DigitalPlatform.Stop stop = PrepareStop( strMessage == null ? "正在对 " + respath.FullPath + " 进行管理操作 " + strAction + " ..." : strMessage); TimeSpan old_timeout = channel.Timeout; if (strAction == "endfastappend") { // 收尾阶段可能要耗费很长的时间 channel.Timeout = new TimeSpan(3, 0, 0); } try { long lRet = channel.DoRefreshDB( strAction, respath.Path, false, out strError); if (lRet == -1) { strError = "管理数据库 '" + respath.Path + "' 时出错: " + strError; goto ERROR1; } } finally { EndStop(stop); #if NO if (stopManager != null) { stop.EndLoop(); stop.OnStop -= new StopEventHandler(this.DoStop); stop.Initial(""); stop.Unregister(); // 和容器脱离关联 } #endif if (strAction == "endfastappend") { channel.Timeout = old_timeout; } this.channel = null; } return 0; ERROR1: return -1; }
private void button_OK_Click(object sender, System.EventArgs e) { string strMetaData = ""; // TODO: 一旦遇到问题,可以放开注释试验 // this.textBox_content.Text = RemoveSingle0a(this.textBox_content.Text); if (this.Obj != null) { if (this.IsText == true) { byte[] baContent = StringUtil.GetUtf8Bytes(this.textBox_content.Text, true); this.Obj.Content = baContent; } else { if (this.Stream != null) { this.Obj.Content = new byte[this.Stream.Length]; this.Stream.Seek(0, SeekOrigin.Begin); this.Stream.Read(this.Obj.Content, 0, (int)this.Stream.Length); } else { this.Obj.Content = null; } } StringUtil.ChangeMetaData(ref strMetaData, null, // string strID, this.LocalPath, // string strLocalPath, this.Mime, // string strMimeType, null, // string strLastModified, null, // string strPath, null); // string strTimestamp) this.Obj.Metadata = strMetaData; this.Obj.Changed = true; this.DialogResult = DialogResult.OK; this.Close(); return; } this.channel = Channels.GetChannel(this.ServerUrl); Debug.Assert(channel != null, "Channels.GetChannel() 异常"); DigitalPlatform.Stop stop = null; if (stopManager != null) { stop = new DigitalPlatform.Stop(); stop.Register(this.stopManager, true); // 和容器关联 stop.OnStop += new StopEventHandler(this.DoStop); stop.Initial("正在保存配置文件: " + this.Path); stop.BeginLoop(); } if (this.IsText == true) { // 更新stream对象内容 byte[] baContent = StringUtil.GetUtf8Bytes(this.textBox_content.Text, true); this.Stream = new MemoryStream(baContent); // !!! 什么时候释放? /* * this.Stream.SetLength(0); * StreamWriter sw = new StreamWriter(this.Stream, Encoding.UTF8); * sw.Write(this.textBox_content.Text); */ } if (this.Stream != null) { this.Stream.Seek(0, SeekOrigin.Begin); } // 保存配置文件 string strError = ""; byte[] baOutputTimestamp = null; string strOutputPath = ""; string strStyle = ""; if (this.checkBox_autoCreate.Checked == true) { if (strStyle != "") { strStyle += ","; } strStyle += "autocreatedir"; } StringUtil.ChangeMetaData(ref strMetaData, null, // string strID, this.LocalPath, // string strLocalPath, this.Mime, // string strMimeType, null, // string strLastModified, null, // string strPath, null); // string strTimestamp) string strRange = ""; if (this.Stream != null && this.Stream.Length != 0) { Debug.Assert(this.Stream.Length != 0, "test"); strRange = "0-" + Convert.ToString(this.Stream.Length - 1); } long lRet = channel.DoSaveResObject(this.Path, this.Stream, (this.Stream != null && this.Stream.Length != 0) ? this.Stream.Length : 0, strStyle, strMetaData, // strMetadata, strRange, true, this.TimeStamp, // timestamp, out baOutputTimestamp, out strOutputPath, out strError); /* * // 保存配置文件 * byte[] baOutputTimeStamp = null; * string strOutputPath = ""; * string strError = ""; * * * long lRet = channel.DoSaveTextRes(this.Path, * this.textBox_content.Text, * true, // bInlucdePreamble * "", // style * this.TimeStamp, * out baOutputTimeStamp, * out strOutputPath, * out strError); */ if (stopManager != null) { stop.EndLoop(); stop.OnStop -= new StopEventHandler(this.DoStop); stop.Initial(""); } if (lRet == -1) { MessageBox.Show(this, strError); goto FINISH; } this.TimeStamp = baOutputTimestamp; MessageBox.Show(this, "配置文件 '" + this.Path + "' 保存成功"); ///////////// FINISH: if (stopManager != null && stop != null) { stop.Unregister(); // 和容器关联 stop = null; } this.channel = null; this.DialogResult = DialogResult.OK; this.Close(); }
// 导出数据 void menu_export(object sender, System.EventArgs e) { string strError = ""; string strTimeMessage = ""; long lTotalCount = 0; // 总命中数 long lExportCount = 0; // 已经传出的数量 if (this.SelectedNode == null) { strError = "尚未选择要要导出数据的数据库节点"; goto ERROR1; } if (this.SelectedNode.ImageIndex != RESTYPE_DB) { strError = "所选择的节点不是数据库类型。请选择要导出数据的数据库节点。"; goto ERROR1; } ResPath respath = new ResPath(this.SelectedNode); // 询问导出数据的范围 ExportDataDialog data_range_dlg = new ExportDataDialog(); data_range_dlg.DbPath = respath.Path; data_range_dlg.AllRecords = true; data_range_dlg.StartPosition = FormStartPosition.CenterScreen; data_range_dlg.ShowDialog(this); if (data_range_dlg.DialogResult != DialogResult.OK) return; string strRange = "0-9999999999"; if (data_range_dlg.AllRecords == false) strRange = data_range_dlg.StartID + "-" + data_range_dlg.EndID; // 获得输出文件名 SaveFileDialog dlg = new SaveFileDialog(); dlg.Title = "请指定要保存的数据文件名"; dlg.CreatePrompt = false; dlg.OverwritePrompt = false; dlg.FileName = ""; dlg.FilterIndex = 1; dlg.Filter = "备份文件 (*.dp2bak)|*.dp2bak|XML文件 (*.xml)|*.xml|ISO2709文件 (*.iso;*.mrc)|*.iso;*.mrc|All files (*.*)|*.*"; dlg.RestoreDirectory = true; if (dlg.ShowDialog(this) != DialogResult.OK) return; ExportUtil export_util = new ExportUtil(); string strQueryXml = "<target list='" + respath.Path + ":" + "__id'><item><word>"+strRange+"</word><match>exact</match><relation>range</relation><dataType>number</dataType><maxCount>-1</maxCount></item><lang>chi</lang></target>"; RmsChannel cur_channel = Channels.CreateTempChannel(respath.Url); Debug.Assert(cur_channel != null, "Channels.GetChannel() 异常"); #if NO DigitalPlatform.Stop stop = null; if (stopManager != null) { stop = new DigitalPlatform.Stop(); stop.Register(this.stopManager, true); // 和容器关联 stop.OnStop += new StopEventHandler(this.DoStop); stop.Initial("正在导出数据 " + respath.FullPath); stop.BeginLoop(); } #endif DigitalPlatform.Stop stop = PrepareStop("正在导出数据 " + respath.FullPath); stop.OnStop -= new StopEventHandler(this.DoStop); // 去掉缺省的回调函数 stop.OnStop += (sender1, e1) => { if (cur_channel != null) cur_channel.Abort(); }; try { long lRet = cur_channel.DoSearch(strQueryXml, "default", out strError); if (lRet == -1) { strError = "检索数据库 '"+respath.Path+"' 时出错: " + strError; goto ERROR1; } if (lRet == 0) { strError = "数据库 '" + respath.Path + "' 中没有任何数据记录"; goto ERROR1; // not found } stop.Style = StopStyle.EnableHalfStop; // API的间隙才让中断。避免获取结果集的中途,因为中断而导致 Session 失效,结果集丢失,进而无法 Retry 获取 lTotalCount = lRet; // 总命中数 long lThisCount = lTotalCount; long lStart = 0; ProgressEstimate estimate = new ProgressEstimate(); estimate.SetRange(0, lTotalCount); estimate.StartEstimate(); stop.SetProgressRange(0, lTotalCount); int nRet = export_util.Begin(this, dlg.FileName, out strError); if (nRet == -1) goto ERROR1; DialogResult last_one_result = DialogResult.Yes; // 前一次对话框选择的方式 bool bDontAskOne = false; int nRedoOneCount = 0; DialogResult last_get_result = DialogResult.Retry; // 前一次对话框选择的方式 bool bDontAskGet = false; int nRedoGetCount = 0; for (; ; ) { Application.DoEvents(); // 出让界面控制权 if (stop.State != 0) { DialogResult result = MessageBox.Show(this, "确实要中断当前批处理操作?", "导出数据", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2); if (result == DialogResult.Yes) { strError = "用户中断"; goto ERROR1; } else { stop.Continue(); } } string strStyle = "id,xml,timestamp"; if (export_util.FileType == ExportFileType.BackupFile) strStyle = "id,xml,timestamp,metadata"; nRedoGetCount = 0; REDO_GET: Record[] searchresults = null; lRet = cur_channel.DoGetSearchResult( "default", lStart, lThisCount, strStyle, this.Lang, stop, out searchresults, out strError); if (lRet == -1) { if (stop.State != 0) // 已经中断 goto ERROR1; // 自动重试有次数限制,避免进入死循环 if (bDontAskGet == true && last_get_result == DialogResult.Retry && nRedoGetCount < 3) { nRedoGetCount++; goto REDO_GET; } DialogResult result = MessageDlg.Show(this, "获取检索结果时 (偏移量 " + lStart + ") 出错:\r\n---\r\n" + strError + "\r\n---\r\n\r\n是否重试获取操作?\r\n\r\n注:\r\n[重试] 重新获取\r\n[中断] 中断整个批处理", "导出数据", MessageBoxButtons.RetryCancel, MessageBoxDefaultButton.Button1, ref bDontAskOne, new string[] { "重试", "中断" }); last_get_result = result; if (result == DialogResult.Retry) { nRedoGetCount = 0; goto REDO_GET; } Debug.Assert(result == DialogResult.Cancel, ""); strError = "获取检索结果时出错: " + strError; goto ERROR1; } for (int i = 0; i < searchresults.Length; i++) { Record record = searchresults[i]; if (i == 0) { stop.SetMessage("正在输出记录 " + record.Path + ",已输出 " + lExportCount.ToString() + " 条。" + "剩余时间 " + ProgressEstimate.Format(estimate.Estimate(lExportCount)) + " 已经过时间 " + ProgressEstimate.Format(estimate.delta_passed)); } nRedoOneCount = 0; REDO_ONE: nRet = export_util.ExportOneRecord( cur_channel, stop, respath.Url, record.Path, record.RecordBody.Xml, record.RecordBody.Metadata, record.RecordBody.Timestamp, out strError); if (nRet == -1) { if (stop.State != 0) // 已经中断 goto ERROR1; // 重试、跳过、中断? // 重试的时候,注意保持文件最后位置,不要留下残余的尾部 // MessageBoxButtons.AbortRetryIgnore YesNoCancel if (bDontAskOne == true && last_one_result == DialogResult.No) continue; // TODO: 最好在日志文件中记载跳过的记录。或者批处理结束后显示出来 // 自动重试有次数限制,避免进入死循环 if (bDontAskOne == true && last_one_result == DialogResult.Yes && nRedoOneCount < 3) { nRedoOneCount++; goto REDO_ONE; } DialogResult result = MessageDlg.Show(this, "导出记录 '" + record.Path + "' 时出错:\r\n---\r\n" + strError + "\r\n---\r\n\r\n是否重试导出操作?\r\n\r\n注:\r\n[重试] 重新导出这条记录\r\n[跳过] 忽略导出这条记录,但继续后面的处理\r\n[中断] 中断整个批处理", "导出数据", MessageBoxButtons.YesNoCancel, MessageBoxDefaultButton.Button1, ref bDontAskOne, new string [] {"重试","跳过","中断"}); last_one_result = result; if (result == DialogResult.Yes) { nRedoOneCount = 0; goto REDO_ONE; } if (result == DialogResult.No) continue; Debug.Assert(result == DialogResult.Cancel, ""); goto ERROR1; } stop.SetProgressValue(lExportCount + 1); lExportCount++; } if (lStart + searchresults.Length >= lTotalCount) break; lStart += searchresults.Length; lThisCount -= searchresults.Length; } strTimeMessage = "总共耗费时间: " + estimate.GetTotalTime().ToString(); } finally { EndStop(stop); #if NO if (stopManager != null) { stop.EndLoop(); stop.OnStop -= new StopEventHandler(this.DoStop); stop.Initial(""); stop.Unregister(); // 和容器脱离关联 } #endif cur_channel.Close(); cur_channel = null; export_util.End(); } MessageBox.Show(this, "位于服务器 '" + respath.Url + "' 上的数据库 '" + respath.Path + "' 内共有记录 " + lTotalCount.ToString() + " 条,本次导出 " + lExportCount.ToString() + " 条。" + strTimeMessage); return; ERROR1: MessageBox.Show(this, strError); if (lExportCount > 0) MessageBox.Show(this, "数据库内共有记录 " + lTotalCount.ToString() + " 条,本次导出 " + lExportCount.ToString() + " 条"); }
private void button_OK_Click(object sender, System.EventArgs e) { string strMetaData = ""; // TODO: 一旦遇到问题,可以放开注释试验 // this.textBox_content.Text = RemoveSingle0a(this.textBox_content.Text); if (this.Obj != null) { if (this.IsText == true) { byte[] baContent = StringUtil.GetUtf8Bytes(this.textBox_content.Text, true); this.Obj.Content = baContent; } else { if (this.Stream != null) { this.Obj.Content = new byte[this.Stream.Length]; this.Stream.Seek(0, SeekOrigin.Begin); this.Stream.Read(this.Obj.Content, 0, (int)this.Stream.Length); } else { this.Obj.Content = null; } } StringUtil.ChangeMetaData(ref strMetaData, null, // string strID, this.LocalPath, // string strLocalPath, this.Mime, // string strMimeType, null, // string strLastModified, null, // string strPath, null); // string strTimestamp) this.Obj.Metadata = strMetaData; this.Obj.Changed = true; this.DialogResult = DialogResult.OK; this.Close(); return; } this.channel = Channels.GetChannel(this.ServerUrl); Debug.Assert(channel != null, "Channels.GetChannel() 异常"); DigitalPlatform.Stop stop = null; if (stopManager != null) { stop = new DigitalPlatform.Stop(); stop.Register(this.stopManager, true); // 和容器关联 stop.OnStop += new StopEventHandler(this.DoStop); stop.Initial("正在保存配置文件: " + this.Path); stop.BeginLoop(); } if (this.IsText == true) { // 更新stream对象内容 byte[] baContent = StringUtil.GetUtf8Bytes(this.textBox_content.Text, true); this.Stream = new MemoryStream(baContent); // !!! 什么时候释放? /* this.Stream.SetLength(0); StreamWriter sw = new StreamWriter(this.Stream, Encoding.UTF8); sw.Write(this.textBox_content.Text); */ } if (this.Stream != null) this.Stream.Seek(0, SeekOrigin.Begin); // 保存配置文件 string strError = ""; byte[] baOutputTimestamp = null; string strOutputPath = ""; string strStyle = ""; if (this.checkBox_autoCreate.Checked == true) { if (strStyle != "") strStyle += ","; strStyle += "autocreatedir"; } StringUtil.ChangeMetaData(ref strMetaData, null, // string strID, this.LocalPath, // string strLocalPath, this.Mime, // string strMimeType, null, // string strLastModified, null, // string strPath, null); // string strTimestamp) string strRange = ""; if (this.Stream != null && this.Stream.Length != 0) { Debug.Assert(this.Stream.Length != 0, "test"); strRange = "0-" + Convert.ToString(this.Stream.Length - 1); } long lRet = channel.DoSaveResObject(this.Path, this.Stream, (this.Stream != null && this.Stream.Length != 0) ? this.Stream.Length : 0, strStyle, strMetaData, // strMetadata, strRange, true, this.TimeStamp, // timestamp, out baOutputTimestamp, out strOutputPath, out strError); /* // 保存配置文件 byte[] baOutputTimeStamp = null; string strOutputPath = ""; string strError = ""; long lRet = channel.DoSaveTextRes(this.Path, this.textBox_content.Text, true, // bInlucdePreamble "", // style this.TimeStamp, out baOutputTimeStamp, out strOutputPath, out strError); */ if (stopManager != null) { stop.EndLoop(); stop.OnStop -= new StopEventHandler(this.DoStop); stop.Initial(""); } if (lRet == -1) { MessageBox.Show(this, strError); goto FINISH; } this.TimeStamp = baOutputTimestamp; MessageBox.Show(this, "配置文件 '" + this.Path + "' 保存成功"); ///////////// FINISH: if (stopManager != null && stop != null) { stop.Unregister(); // 和容器关联 stop = null; } this.channel = null; this.DialogResult = DialogResult.OK; this.Close(); }
// 本函数是将新的记录完整创建好以后再追加到 outputfile 末尾。能确保另一个并发的顺序读操作读入正确的内容 // return: // -1 出错 // 0 因 strXmlBody 为空,忽略此记录,并没有导出任何内容 // 1 导出了内容 static int SafeWriteRecordToBackupFile( IWin32Window owner, RmsChannel channel, DigitalPlatform.Stop stop, Stream outputfile, string strPath, // 记录路径 string strMetaData, string strXmlBody, byte[] body_timestamp, string strTempDir, out string strError) { if (string.IsNullOrEmpty(strTempDir)) { strError = "strTempDir 参数值不应为空"; return(-1); } string strTempFileName = Path.Combine(strTempDir, "~" + Guid.NewGuid().ToString()); try { using (FileStream temp_stream = File.Open( strTempFileName, FileMode.Create, FileAccess.ReadWrite, FileShare.None)) { // return: // -1 出错 // 0 因 strXmlBody 为空,忽略此记录,并没有导出任何内容 // 1 导出了内容 int nRet = WriteRecordToBackupFile( owner, channel, stop, temp_stream, strPath, // 记录路径 strMetaData, strXmlBody, body_timestamp, out strError); if (nRet == -1) { return(-1); } #if NO if (nRet == 1) { // 记忆 dump 前 outputfile 的当前位置 long lSavePosition = outputfile.Position; bool bDone = false; try { temp_stream.Seek(0, SeekOrigin.Begin); // TODO: Dump 中途是否允许灵敏中断?要注意中断以后截断目标文件 long lRet = StreamUtil.LockingDumpStream(temp_stream, outputfile, false, () => { if (stop != null && stop.State != 0) { return(true); } return(false); }); if (lRet == -1) { strError = "Dump 中途被用户中断"; return(-1); } else { bDone = true; } } finally { if (bDone == false) { outputfile.SetLength(lSavePosition); } } } #endif if (nRet == 1) { temp_stream.Seek(0, SeekOrigin.Begin); StreamUtil.LockingDumpStream(temp_stream, outputfile, false, null); } return(nRet); } } catch (Exception ex) { strError = "SafeWriteRecordToBackupFile() 出现异常: " + ExceptionUtil.GetExceptionText(ex); return(-1); } finally { File.Delete(strTempFileName); } }
// 获得资源。包装版本 -- 返回本地映射文件、Cache版本。 // return: // -1 出错。具体出错原因在this.ErrorCode中。this.ErrorInfo中有出错信息。 // 0 成功 public static long GetResLocalFile(this LibraryChannel channel, DigitalPlatform.Stop stop, CfgCache cache, string strPath, string strStyle, out string strOutputFilename, out string strMetaData, out byte[] baOutputTimeStamp, out string strOutputResPath, out string strError) { strOutputFilename = ""; byte[] cached_timestamp = null; string strTimeStamp; string strLocalName; string strResult = ""; string strFullPath = channel.Url + "?" + strPath; if (StringUtil.IsInList("forceget", strStyle) == true) { // 强制获取 StringUtil.RemoveFromInList("forceget", true, ref strStyle); goto GETDATA; } // 从cache中得到timestamp // return: // -1 error // 0 not found // 1 found int nRet = cache.FindLocalFile(strFullPath, out strLocalName, out strTimeStamp); if (nRet == -1) { strOutputResPath = ""; strMetaData = ""; baOutputTimeStamp = null; strError = "CfgCache 尚未初始化"; return(-1); } if (nRet == 1) { Debug.Assert(strLocalName != "", "FindLocalFile()返回的strLocalName为空"); if (strTimeStamp == "") { goto GETDATA; // 时间戳不对, 那就只好重新获取服务器端内容 } Debug.Assert(strTimeStamp != "", "FindLocalFile()获得的strTimeStamp为空"); cached_timestamp = ByteArray.GetTimeStampByteArray(strTimeStamp); // bExistInCache = true; } else { goto GETDATA; } // 探测时间戳关系 string strNewStyle = strStyle; /* * StringUtil.RemoveFromInList("data", * true, * ref strNewStyle); // 不要数据体 * */ StringUtil.RemoveFromInList("content,data,metadata", // 2012/12/31 BUG 以前忘记了加入content true, ref strNewStyle); // 不要数据体和metadata long lRet = channel.GetRes(stop, strPath, strNewStyle, out strResult, out strMetaData, out baOutputTimeStamp, out strOutputResPath, out strError); if (lRet == -1) { return(-1); } // 如果证明timestamp没有变化, 但是本次并未返回内容,则从cache中取原来的内容 if (ByteArray.Compare(baOutputTimeStamp, cached_timestamp) == 0) // 时间戳相等 { Debug.Assert(strLocalName != "", "strLocalName不应为空"); strOutputFilename = strLocalName; return(0); // 以无错误姿态返回 } GETDATA: // 重新正式获取内容 lRet = channel.GetRes( stop, strPath, strStyle, out strResult, out strMetaData, out baOutputTimeStamp, out strOutputResPath, out strError); if (lRet == -1) { return(-1); } // 因为时间戳不匹配而新获得了内容 // 保存到cache cache.PrepareLocalFile(strFullPath, out strLocalName); Debug.Assert(strLocalName != "", "PrepareLocalFile()返回的strLocalName为空"); // 写入文件,以便以后从cache获取 using (StreamWriter sw = new StreamWriter(strLocalName, false, // append System.Text.Encoding.UTF8)) { sw.Write(strResult); } Debug.Assert(baOutputTimeStamp != null, "下层GetRes()返回的baOutputTimeStamp为空"); nRet = cache.SetTimeStamp(strFullPath, ByteArray.GetHexTimeStampString(baOutputTimeStamp), out strError); if (nRet == -1) { return(-1); } strOutputFilename = strLocalName; return(lRet); }
// 将主记录和相关资源写入备份文件 // 本函数如果失败,会自动把本次写入的局部内容从文件末尾抹去 // TODO: 测试磁盘空间耗尽的情况 // return: // -1 出错 // 0 因 strXmlBody 为空,忽略此记录,并没有导出任何内容 // 1 导出了内容 static int WriteRecordToBackupFile( IWin32Window owner, RmsChannel channel, DigitalPlatform.Stop stop, Stream outputfile, string strPath, // 记录路径 string strMetaData, string strXmlBody, byte[] body_timestamp, out string strError) { strError = ""; if (string.IsNullOrEmpty(strXmlBody)) { strError = "strXmlBody 为空,忽略此记录"; return(0); } Debug.Assert(String.IsNullOrEmpty(strXmlBody) == false, "strXmlBody不能为空"); Debug.Assert(channel != null, ""); // string strPath = strDbName + "/" + strID; long lStart = outputfile.Position; // 记忆起始位置 bool bDone = false; try { byte[] length = new byte[8]; outputfile.LockingWrite(length, 0, 8); // 临时写点数据,占据记录总长度位置 ResPath respath = new ResPath(); respath.Url = channel.Url; respath.Path = strPath; // 加工元数据 StringUtil.ChangeMetaData(ref strMetaData, null, null, null, null, respath.FullPath, ByteArray.GetHexTimeStampString(body_timestamp)); // 2005/6/11 // 向backup文件中保存第一个 res long lRet = Backup.WriteFirstResToBackupFile( outputfile, strMetaData, strXmlBody); // 其余 string[] ids = null; // 得到Xml记录中所有<file>元素的id属性值 int nRet = GetFileIds(strXmlBody, out ids, out strError); if (nRet == -1) { // outputfile.SetLength(lStart); // 把本次追加写入的全部去掉 strError = "GetFileIds()出错,无法获得 XML 记录 (" + strPath + ") 中的 <dprms:file>元素的 id 属性, 因此保存记录失败,原因: " + strError; goto ERROR1; } nRet = WriteResToBackupFile( owner, channel, stop, outputfile, respath.Path, ids, out strError); if (nRet == -1) { // outputfile.SetLength(lStart); // 把本次追加写入的全部去掉 strError = "WriteResToBackupFile()出错,因此保存记录 (" + strPath + ") 失败,原因: " + strError; goto ERROR1; } /// // 写入总长度 long lTotalLength = outputfile.Position - lStart - 8; byte[] data = BitConverter.GetBytes(lTotalLength); // 返回记录最开头位置 outputfile.Seek(lStart - outputfile.Position, SeekOrigin.Current); Debug.Assert(outputfile.Position == lStart, ""); // outputfile.Seek(lStart, SeekOrigin.Begin); // 文件大了以后这句话的性能会很差 outputfile.LockingWrite(data, 0, 8); // 跳到记录末尾位置 outputfile.Seek(lTotalLength, SeekOrigin.Current); bDone = true; } finally { if (bDone == false) { outputfile.SetLength(lStart); // 把本次追加写入的全部去掉 outputfile.Seek(0, SeekOrigin.End); // 把文件指针恢复到文件末尾位置,便于下次调用继续写入 } } return(1); ERROR1: return(-1); }
public IEnumerator GetEnumerator() { string strError = ""; string strRange = "0-9999999999"; long lTotalCount = 0; // 总命中数 long lExportCount = 0; string strTimeMessage = ""; DigitalPlatform.Stop stop = this.Stop; StopStyle old_style = StopStyle.None; if (stop != null) { old_style = stop.Style; stop.Style = StopStyle.EnableHalfStop; // API的间隙才让中断。避免获取结果集的中途,因为中断而导致 Session 失效,结果集丢失,进而无法 Retry 获取 stop.OnStop += stop_OnStop; } ProgressEstimate estimate = new ProgressEstimate(); try { int i_path = 0; foreach (string path in this.Paths) { ResPath respath = new ResPath(path); string strQueryXml = "<target list='" + respath.Path + ":" + "__id'><item><word>" + strRange + "</word><match>exact</match><relation>range</relation><dataType>number</dataType><maxCount>-1</maxCount></item><lang>chi</lang></target>"; cur_channel = Channels.CreateTempChannel(respath.Url); Debug.Assert(cur_channel != null, "Channels.GetChannel() 异常"); try { long lRet = cur_channel.DoSearch(strQueryXml, "default", out strError); if (lRet == -1) { strError = "检索数据库 '" + respath.Path + "' 时出错: " + strError; throw new Exception(strError); } if (lRet == 0) { strError = "数据库 '" + respath.Path + "' 中没有任何数据记录"; continue; } lTotalCount += lRet; // 总命中数 estimate.SetRange(0, lTotalCount); if (i_path == 0) { estimate.StartEstimate(); } if (stop != null) { stop.SetProgressRange(0, lTotalCount); } SearchResultLoader loader = new SearchResultLoader(cur_channel, stop, this.ResultSetName, this.FormatList, this.Lang); loader.BatchSize = this.BatchSize; foreach (KernelRecord record in loader) { if (stop != null) { stop.SetProgressValue(lExportCount + 1); } lExportCount++; yield return(record); } strTimeMessage = "总共耗费时间: " + estimate.GetTotalTime().ToString(); } finally { cur_channel.Close(); cur_channel = null; } // MessageBox.Show(this, "位于服务器 '" + respath.Url + "' 上的数据库 '" + respath.Path + "' 内共有记录 " + lTotalCount.ToString() + " 条,本次导出 " + lExportCount.ToString() + " 条。" + strTimeMessage); i_path++; } } finally { if (stop != null) { stop.Style = old_style; stop.OnStop -= stop_OnStop; } } }
// 下载资源,保存到备份文件 static int WriteResToBackupFile( IWin32Window owner, RmsChannel channel, DigitalPlatform.Stop stop, Stream outputfile, string strXmlRecPath, string[] res_ids, out string strError) { strError = ""; long lRet; for (int i = 0; i < res_ids.Length; i++) { if (owner != null) { Application.DoEvents(); // 出让界面控制权 } if (stop != null && stop.State != 0) { if (owner != null) { DialogResult result = MessageBox.Show(owner, "确实要中断当前批处理操作?", "导出数据", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2); if (result == DialogResult.Yes) { strError = "用户中断"; return(-1); } else { stop.Continue(); } } else { strError = "用户中断"; return(-1); } } string strID = res_ids[i].Trim(); if (string.IsNullOrEmpty(strID)) { continue; } string strResPath = strXmlRecPath + "/object/" + strID; string strMetaData; if (stop != null) { stop.SetMessage("正在下载 " + strResPath); } byte[] baOutputTimeStamp = null; string strOutputPath; REDO_GETRES: lRet = channel.GetRes(strResPath, (Stream)null, // 故意不获取资源体 stop, "metadata,timestamp,outputpath", null, out strMetaData, // 但是要获得metadata out baOutputTimeStamp, out strOutputPath, out strError); if (lRet == -1) { if (channel.OriginErrorCode == rmsws_localhost.ErrorCodeValue.NotFoundObjectFile) { continue; // TODO: 返回警告信息 } if (owner != null) { // TODO: 允许重试 DialogResult redo_result = MessageBox.Show(owner, "获取记录 '" + strResPath + "' 时出现错误: " + strError + "\r\n\r\n重试,还是中断当前批处理操作?\r\n(Retry 重试;Cancel 中断批处理)", "导出数据", MessageBoxButtons.RetryCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1); if (redo_result == DialogResult.Cancel) { return(-1); } goto REDO_GETRES; } else { return(-1); } } long lResStart = 0; // 写res的头。 // 如果不能预先确知整个res的长度,可以用随便一个lTotalLength值调用本函数, // 但是需要记忆下函数所返回的lStart,最后调用EndWriteResToBackupFile()。 // 如果能预先确知整个res的长度,则最后不必调用EndWriteResToBackupFile() long lRet0 = Backup.BeginWriteResToBackupFile( outputfile, 0, // 未知 out lResStart); byte[] timestamp = baOutputTimeStamp; ResPath respath = new ResPath(); respath.Url = channel.Url; respath.Path = strOutputPath; // strResPath; // strMetaData还要加入资源id? StringUtil.ChangeMetaData(ref strMetaData, strID, null, null, null, respath.FullPath, ByteArray.GetHexTimeStampString(baOutputTimeStamp)); lRet = Backup.WriteResMetadataToBackupFile(outputfile, strMetaData); if (lRet == -1) { return(-1); } long lBodyStart = 0; // 写res body的头。 // 如果不能预先确知body的长度,可以用随便一个lBodyLength值调用本函数, // 但是需要记忆下函数所返回的lBodyStart,最后调用EndWriteResBodyToBackupFile()。 // 如果能预先确知body的长度,则最后不必调用EndWriteResBodyToBackupFile() lRet = Backup.BeginWriteResBodyToBackupFile( outputfile, 0, // 未知 out lBodyStart); if (lRet == -1) { return(-1); } if (stop != null) { stop.SetMessage("正在下载 " + strResPath + " 的数据体"); } REDO_GETRES_1: lRet = channel.GetRes(strResPath, outputfile, stop, "content,data,timestamp", //"content,data,timestamp" timestamp, out strMetaData, out baOutputTimeStamp, out strOutputPath, out strError); if (lRet == -1) { if (channel.ErrorCode == ChannelErrorCode.EmptyRecord || channel.ErrorCode == ChannelErrorCode.NotFoundObjectFile) // 2017/7/13 { // 空记录 } else { if (owner != null) { // TODO: 允许重试 DialogResult redo_result = MessageBox.Show(owner, "获取记录 '" + strResPath + "' 时出现错误: " + strError + "\r\n\r\n重试,还是中断当前批处理操作?\r\n(Retry 重试;Cancel 中断批处理)", "导出数据", MessageBoxButtons.RetryCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1); if (redo_result == DialogResult.Cancel) { return(-1); } goto REDO_GETRES_1; } else { return(-1); } } } long lBodyLength = outputfile.Position - lBodyStart - 8; // res body收尾 lRet = Backup.EndWriteResBodyToBackupFile( outputfile, lBodyLength, lBodyStart); if (lRet == -1) { return(-1); } long lTotalLength = outputfile.Position - lResStart - 8; lRet = Backup.EndWriteResToBackupFile( outputfile, lTotalLength, lResStart); if (lRet == -1) { return(-1); } } return(0); }
int GetDbStyle(string strDbName, out string strError) { strError = ""; this.channel = Channels.GetChannel(this.ServerUrl); Debug.Assert(channel != null, "Channels.GetChannel() 异常"); ResInfoItem[] items = null; DigitalPlatform.Stop stop = null; if (stopManager != null) { stop = new DigitalPlatform.Stop(); stop.Register(this.stopManager, true); // 和容器关联 stop.OnStop += new StopEventHandler(this.DoStop); stop.Initial("正在获得数据库 " + strDbName + "的风格参数"); stop.BeginLoop(); } long lRet = channel.DoDir("", // 列出全部数据库 this.Lang, null, // 不需要列出全部语言的名字 out items, out strError); if (stopManager != null) { stop.EndLoop(); stop.OnStop -= new StopEventHandler(this.DoStop); stop.Initial(""); stop.Unregister(); // 和容器关联 } this.channel = null; if (lRet == -1) return -1; if (items == null) return 0; // 数据库不存在 for (int i = 0; i < items.Length; i++) { // 忽略非数据库类型节点 if (items[i].Type != ResTree.RESTYPE_DB) continue; if (items[i].Name == strDbName) return items[i].Style; } return 0; // 数据库不存在 }
// 递归 public int Fill(TreeNode node) { TreeNodeCollection children = null; if (node == null) { children = this.Nodes; } else { children = node.Nodes; } int i; // 填充根 if (node == null) { children.Clear(); TreeNode nodeNew = new TreeNode(this.ServerUrl, ResTree.RESTYPE_SERVER, ResTree.RESTYPE_SERVER); ResTree.SetLoading(nodeNew); NodeInfo nodeinfo = new NodeInfo(); nodeinfo.TreeNode = nodeNew; nodeinfo.Expandable = true; nodeinfo.DefElement = GetDefElementString(nodeNew.ImageIndex); nodeinfo.NodeState |= NodeState.Object; nodeNew.Tag = nodeinfo; if (EnabledIndices != null && StringUtil.IsInList(nodeNew.ImageIndex, EnabledIndices) == false) { nodeNew.ForeColor = ControlPaint.LightLight(nodeNew.ForeColor); } children.Add(nodeNew); return(0); } // 根以下的节点类型 ResPath respath = new ResPath(node); string strPath = respath.Path; //if (node != null) // strPath = TreeViewUtil.GetPath(node); this.channel = Channels.GetChannel(this.ServerUrl); Debug.Assert(channel != null, "Channels.GetChannel() 异常"); ResInfoItem[] items = null; string strError = ""; DigitalPlatform.Stop stop = null; if (stopManager != null) { stop = new DigitalPlatform.Stop(); stop.Register(this.stopManager, true); // 和容器关联 stop.OnStop += new StopEventHandler(this.DoStop); stop.Initial("正在列目录: " + this.ServerUrl + "?" + strPath); stop.BeginLoop(); } long lRet = channel.DoDir(strPath, this.Lang, null, // 不需要列出全部语言的名字 out items, out strError); if (stopManager != null) { stop.EndLoop(); stop.OnStop -= new StopEventHandler(this.DoStop); stop.Initial(""); stop.Unregister(); // 和容器关联 } this.channel = null; if (lRet == -1) { try { MessageBox.Show(this, "Channel::DoDir() Error: " + strError); } catch { // this可能已经不存在 return(-1); } if (node != null) { ResTree.SetLoading(node); // 出错的善后处理,重新出现+号 node.Collapse(); } return(-1); } if (items != null) { children.Clear(); for (i = 0; i < items.Length; i++) { // 忽略from类型节点 if (items[i].Type == ResTree.RESTYPE_FROM) { continue; } TreeNode nodeNew = new TreeNode(items[i].Name, items[i].Type, items[i].Type); NodeInfo nodeinfo = new NodeInfo(); nodeinfo.TreeNode = nodeNew; nodeinfo.Expandable = items[i].HasChildren; nodeinfo.DefElement = GetDefElementString(nodeNew.ImageIndex); nodeinfo.NodeState |= NodeState.Object; nodeinfo.Style = items[i].Style; nodeNew.Tag = nodeinfo; if (items[i].HasChildren) { ResTree.SetLoading(nodeNew); } if (EnabledIndices != null && StringUtil.IsInList(nodeNew.ImageIndex, EnabledIndices) == false) { nodeNew.ForeColor = ControlPaint.LightLight(nodeNew.ForeColor); } children.Add(nodeNew); } } return(0); }
// 在服务器端创建对象 // return: // -1 错误 // 1 以及存在同名对象 // 0 正常返回 int NewServerSideObject(string strPath, int nType, Stream stream, byte[] baTimeStamp, out byte[] baOutputTimestamp, out string strError) { strError = ""; baOutputTimestamp = null; Debug.Assert(this.Channels != null, ""); this.channel = Channels.GetChannel(this.ServerUrl); Debug.Assert(channel != null, "Channels.GetChannel() 异常"); DigitalPlatform.Stop stop = null; if (stopManager != null) { stop = new DigitalPlatform.Stop(); stop.Register(this.stopManager, true); // 和容器关联 stop.OnStop += new StopEventHandler(this.DoStop); stop.Initial("正在创建新对象: " + this.ServerUrl + "?" + strPath); stop.BeginLoop(); } string strOutputPath = ""; string strStyle = ""; if (nType == ResTree.RESTYPE_FOLDER) strStyle = "createdir"; /* long lRet = channel.DoSaveTextRes(strPath, "", // content 暂时为空 true, // bInlucdePreamble strStyle, // style null, // baTimeStamp, out baOutputTimestamp, out strOutputPath, out strError); */ string strRange = ""; if (stream != null && stream.Length != 0) { Debug.Assert(stream.Length != 0, "test"); strRange = "0-" + Convert.ToString(stream.Length - 1); } long lRet = channel.DoSaveResObject(strPath, stream, (stream != null && stream.Length != 0) ? stream.Length : 0, strStyle, "", // strMetadata, strRange, true, baTimeStamp, // timestamp, out baOutputTimestamp, out strOutputPath, out strError); if (stopManager != null) { stop.EndLoop(); stop.OnStop -= new StopEventHandler(this.DoStop); stop.Initial(""); stop.Unregister(); // 和容器关联 } if (lRet == -1) { if (this.channel.ErrorCode == ChannelErrorCode.AlreadyExist) { this.channel = null; return 1; // 已经存在同名同类型对象 } this.channel = null; strError = "写入 '" + strPath + "' 发生错误: " + strError; return -1; } this.channel = null; return 0; }