/// <summary> /// 获得枚举接口 /// </summary> /// <returns>枚举接口</returns> public IEnumerator GetEnumerator() { Debug.Assert(m_loader != null, ""); if (this.CacheTable == null) { this.CacheTable = new Hashtable(); // 如果调主没有给出 CacheTable, 则临时分配一个 } List <string> new_recpaths = new List <string>(); // 缓存中没有包含的那些记录 foreach (string strRecPath in this.RecPaths) { Debug.Assert(string.IsNullOrEmpty(strRecPath) == false, ""); BiblioItem info = (BiblioItem)this.CacheTable[strRecPath]; if (info == null) { new_recpaths.Add(strRecPath); // 需要放入缓存,便于后面的发现 // 但放入缓存的是 .Content 为空的对象 if (info == null) { info = new BiblioItem(); info.RecPath = strRecPath; } this.CacheTable[strRecPath] = info; } } // 注: Hashtable 在这一段时间内不应该被修改。否则会破坏 m_loader 和 items 之间的锁定对应关系 m_loader.RecPaths = new_recpaths; var enumerator = m_loader.GetEnumerator(); // 开始循环 foreach (string strRecPath in this.RecPaths) { Debug.Assert(string.IsNullOrEmpty(strRecPath) == false, ""); BiblioItem info = null; if (this.CacheTable != null) { info = (BiblioItem)this.CacheTable[strRecPath]; } if (info == null || string.IsNullOrEmpty(info.Content) == true) { #if NO if (m_loader.Stop != null) { m_loader.Stop.SetMessage("正在获取书目记录 " + strRecPath); } #endif bool bRet = enumerator.MoveNext(); if (bRet == false) { Debug.Assert(false, "还没有到结尾, MoveNext() 不应该返回 false"); // TODO: 这时候也可以采用返回一个带没有找到的错误码的元素 yield break; } BiblioItem biblio = (BiblioItem)enumerator.Current; Debug.Assert(biblio.RecPath == strRecPath, "m_loader 和 items 的元素之间 记录路径存在严格的锁定对应关系"); // 需要放入缓存 if (info == null) { info = new BiblioItem(); info.RecPath = biblio.RecPath; } if (string.IsNullOrEmpty(biblio.Content) == true) { info.Content = "{null}"; // 2013/11/18 } else { info.Content = biblio.Content; } info.Metadata = biblio.Metadata; info.Timestamp = biblio.Timestamp; this.CacheTable[strRecPath] = info; yield return(info); } else { yield return(info); } } }
public IEnumerator GetEnumerator() { List <string> format_list = new List <string>(); int nContentIndex = format_list.Count; int nTimestampIndex = -1; int nMetadataIndex = -1; format_list.Add(this.Format); // if ((this.GetBiblioInfoStyle & dp2Circulation.GetBiblioInfoStyle.Timestamp) != 0) if (this.GetBiblioInfoStyle.HasFlag(GetBiblioInfoStyle.Timestamp) == true) // 新用法 { nTimestampIndex = format_list.Count; format_list.Add("timestamp"); } if ((this.GetBiblioInfoStyle & dp2Circulation.GetBiblioInfoStyle.Metadata) != 0) { nMetadataIndex = format_list.Count; format_list.Add("metadata"); } string[] formats = new string[format_list.Count]; format_list.CopyTo(formats); List <string> batch = new List <string>(); for (int index = 0; index < m_recpaths.Count; index++) { string s = m_recpaths[index]; batch.Add(s); // 每100个一批,或者最后一次 if (batch.Count >= 100 || (index == m_recpaths.Count - 1 && batch.Count > 0)) { REDO: string strCommand = "@path-list:" + StringUtil.MakePathList(batch); string[] results = null; byte[] timestamp = null; string strError = ""; long lRet = Channel.GetBiblioInfos( this.Stop, strCommand, "", formats, out results, out timestamp, out strError); if (lRet == -1) { throw new ChannelException(Channel.ErrorCode, strError); } if (lRet == 0) { if (lRet == 0 && String.IsNullOrEmpty(strError) == true) { foreach (string path in batch) { BiblioItem item = new BiblioItem(); item.RecPath = path; item.ErrorCode = ErrorCode.NotFound; item.ErrorInfo = "书目记录 '" + path + "' 不存在"; yield return(item); } goto CONTINUE; } // 如果results.Length表现正常,其实还可以继续处理 if (results != null && results.Length > 0) { } else { strError = "获得书目记录 '" + StringUtil.MakePathList(batch) + "' 时发生错误: " + strError; throw new Exception(strError); } } if (results == null) { strError = "results == null"; throw new Exception(strError); } for (int i = 0; i < results.Length / formats.Length; i++) { BiblioItem item = new BiblioItem(); item.RecPath = batch[i]; if (nContentIndex != -1) { item.Content = results[i * formats.Length + nContentIndex]; } if (nTimestampIndex != -1) { item.Timestamp = ByteArray.GetTimeStampByteArray(results[i * formats.Length + nTimestampIndex]); } if (nMetadataIndex != -1) { item.Metadata = results[i * formats.Length + nMetadataIndex]; } if (string.IsNullOrEmpty(item.Content) == true) { item.ErrorCode = ErrorCode.NotFound; item.ErrorInfo = "书目记录 '" + item.RecPath + "' 不存在"; } yield return(item); } CONTINUE: if (batch.Count > results.Length / formats.Length) { // 有本次没有获取到的记录 batch.RemoveRange(0, results.Length / formats.Length); if (index == m_recpaths.Count - 1) { goto REDO; // 当前已经是最后一轮了,需要继续做完 } // 否则可以留给下一轮处理 } else { batch.Clear(); } } } }
/// <summary> /// 获得枚举接口 /// </summary> /// <returns>枚举接口</returns> public IEnumerator GetEnumerator() { Debug.Assert(m_loader != null, ""); if (this.CacheTable == null) this.CacheTable = new Hashtable(); // 如果调主没有给出 CacheTable, 则临时分配一个 List<string> new_recpaths = new List<string>(); // 缓存中没有包含的那些记录 foreach (string strRecPath in this.RecPaths) { Debug.Assert(string.IsNullOrEmpty(strRecPath) == false, ""); BiblioItem info = (BiblioItem)this.CacheTable[strRecPath]; if (info == null) { new_recpaths.Add(strRecPath); // 需要放入缓存,便于后面的发现 // 但放入缓存的是 .Content 为空的对象 if (info == null) { info = new BiblioItem(); info.RecPath = strRecPath; } this.CacheTable[strRecPath] = info; } } // 注: Hashtable 在这一段时间内不应该被修改。否则会破坏 m_loader 和 items 之间的锁定对应关系 m_loader.RecPaths = new_recpaths; var enumerator = m_loader.GetEnumerator(); // 开始循环 foreach (string strRecPath in this.RecPaths) { Debug.Assert(string.IsNullOrEmpty(strRecPath) == false, ""); BiblioItem info = null; if (this.CacheTable != null) info = (BiblioItem)this.CacheTable[strRecPath]; if (info == null || string.IsNullOrEmpty(info.Content) == true) { #if NO if (m_loader.Stop != null) { m_loader.Stop.SetMessage("正在获取书目记录 " + strRecPath); } #endif bool bRet = enumerator.MoveNext(); if (bRet == false) { Debug.Assert(false, "还没有到结尾, MoveNext() 不应该返回 false"); // TODO: 这时候也可以采用返回一个带没有找到的错误码的元素 yield break; } BiblioItem biblio = (BiblioItem)enumerator.Current; Debug.Assert(biblio.RecPath == strRecPath, "m_loader 和 items 的元素之间 记录路径存在严格的锁定对应关系"); // 需要放入缓存 if (info == null) { info = new BiblioItem(); info.RecPath = biblio.RecPath; } if (string.IsNullOrEmpty(biblio.Content) == true) info.Content = "{null}"; // 2013/11/18 else info.Content = biblio.Content; info.Metadata = biblio.Metadata; info.Timestamp = biblio.Timestamp; this.CacheTable[strRecPath] = info; yield return info; } else yield return info; } }
public IEnumerator GetEnumerator() { List<string> format_list = new List<string>(); int nContentIndex = format_list.Count; int nTimestampIndex = -1; int nMetadataIndex = -1; format_list.Add(this.Format); // if ((this.GetBiblioInfoStyle & dp2Circulation.GetBiblioInfoStyle.Timestamp) != 0) if (this.GetBiblioInfoStyle.HasFlag(GetBiblioInfoStyle.Timestamp) == true) // 新用法 { nTimestampIndex = format_list.Count; format_list.Add("timestamp"); } if ((this.GetBiblioInfoStyle & dp2Circulation.GetBiblioInfoStyle.Metadata) != 0) { nMetadataIndex = format_list.Count; format_list.Add("metadata"); } string[] formats = new string[format_list.Count]; format_list.CopyTo(formats); List<string> batch = new List<string>(); for (int index = 0; index < m_recpaths.Count; index++) { string s = m_recpaths[index]; batch.Add(s); // 每100个一批,或者最后一次 if (batch.Count >= 100 || (index == m_recpaths.Count - 1 && batch.Count > 0)) { REDO: string strCommand = "@path-list:" + StringUtil.MakePathList(batch); string[] results = null; byte[] timestamp = null; string strError = ""; long lRet = Channel.GetBiblioInfos( this.Stop, strCommand, "", formats, out results, out timestamp, out strError); if (lRet == -1) { throw new ChannelException(Channel.ErrorCode, strError); } if (lRet == 0) { if (lRet == 0 && String.IsNullOrEmpty(strError) == true) { foreach (string path in batch) { BiblioItem item = new BiblioItem(); item.RecPath = path; item.ErrorCode = ErrorCode.NotFound; item.ErrorInfo = "书目记录 '" + path + "' 不存在"; yield return item; } goto CONTINUE; } // 如果results.Length表现正常,其实还可以继续处理 if (results != null && results.Length > 0) { } else { strError = "获得书目记录 '" + StringUtil.MakePathList(batch) + "' 时发生错误: " + strError; throw new Exception(strError); } } if (results == null) { strError = "results == null"; throw new Exception(strError); } for (int i = 0; i < results.Length / formats.Length; i++) { BiblioItem item = new BiblioItem(); item.RecPath = batch[i]; if (nContentIndex != -1) item.Content = results[i * formats.Length + nContentIndex]; if (nTimestampIndex != -1) item.Timestamp = ByteArray.GetTimeStampByteArray(results[i * formats.Length + nTimestampIndex]); if (nMetadataIndex != -1) item.Metadata = results[i * formats.Length + nMetadataIndex]; if (string.IsNullOrEmpty(item.Content) == true) { item.ErrorCode = ErrorCode.NotFound; item.ErrorInfo = "书目记录 '" + item.RecPath + "' 不存在"; } yield return item; } CONTINUE: if (batch.Count > results.Length / formats.Length) { // 有本次没有获取到的记录 batch.RemoveRange(0, results.Length / formats.Length); if (index == m_recpaths.Count - 1) goto REDO; // 当前已经是最后一轮了,需要继续做完 // 否则可以留给下一轮处理 } else batch.Clear(); } } }
// parameters: // lStartIndex 调用前已经做过的事项数。为了准确显示 Progress // return: // -2 获得书目摘要的权限不够 // -1 出错 // 0 用户中断 // 1 完成 internal int _fillBiblioSummaryColumn(List <ListViewItem> items, long lStartIndex, bool bDisplayMessage, bool bAutoSearch, out string strError) { strError = ""; int nRet = 0; if (m_bBiblioSummaryColumn == false) { return(0); } Debug.Assert(this.DbType == "item" || this.DbType == "order" || this.DbType == "issue" || this.DbType == "comment" || this.DbType == "arrive", ""); List <string> biblio_recpaths = new List <string>(); // 尺寸可能比 items 数组小,没有包含里面不具有 parent id 列的事项 List <int> colindex_list = new List <int>(); // 存储每个 item 对应的 parent id colindex。数组大小等于 items 数组大小 foreach (ListViewItem item in items) { #if NO string strRecPath = ListViewUtil.GetItemText(item, 0); // 根据记录路径获得数据库名 string strItemDbName = Global.GetDbName(strRecPath); // 根据数据库名获得 parent id 列号 int nCol = -1; object o = m_tableSummaryColIndex[strItemDbName]; if (o == null) { ColumnPropertyCollection temp = this.MainForm.GetBrowseColumnProperties(strItemDbName); nCol = temp.FindColumnByType("parent_id"); if (nCol == -1) { colindex_list.Add(-1); continue; // 这个实体库没有 parent id 列 } nCol += 2; if (this.m_bFirstColumnIsKey == true) { nCol++; // 2013/11/12 } m_tableSummaryColIndex[strItemDbName] = nCol; // 储存起来 } else { nCol = (int)o; } Debug.Assert(nCol > 0, ""); colindex_list.Add(nCol); // 获得 parent id string strText = ListViewUtil.GetItemText(item, nCol); string strBiblioRecPath = ""; // 看看是否已经是路径 ? if (strText.IndexOf("/") == -1) { // 获得对应的书目库名 strBiblioRecPath = this.MainForm.GetBiblioDbNameFromItemDbName(this.DbType, strItemDbName); if (string.IsNullOrEmpty(strBiblioRecPath) == true) { strError = "数据库名 '" + strItemDbName + "' 没有找到对应的书目库名"; return(-1); } strBiblioRecPath = strBiblioRecPath + "/" + strText; ListViewUtil.ChangeItemText(item, nCol, strBiblioRecPath); } else { strBiblioRecPath = strText; } #endif int nCol = -1; string strBiblioRecPath = ""; // 获得事项所从属的书目记录的路径 // return: // -1 出错 // 0 相关数据库没有配置 parent id 浏览列 // 1 找到 nRet = GetBiblioRecPath(item, bAutoSearch, // true 如果遇到没有 parent id 列的时候速度较慢 out nCol, out strBiblioRecPath, out strError); if (nRet == -1) { return(-1); } if (nRet == 0) { colindex_list.Add(-1); continue; } if (string.IsNullOrEmpty(strBiblioRecPath) == false && nCol == -1) { colindex_list.Add(0); } else { colindex_list.Add(nCol); } biblio_recpaths.Add(strBiblioRecPath); } CacheableBiblioLoader loader = new CacheableBiblioLoader(); loader.Channel = this.Channel; loader.Stop = this.stop; loader.Format = "summary"; loader.GetBiblioInfoStyle = GetBiblioInfoStyle.None; loader.RecPaths = biblio_recpaths; var enumerator = loader.GetEnumerator(); int i = 0; foreach (ListViewItem item in items) { Application.DoEvents(); // 出让界面控制权 if (stop != null && stop.State != 0) { strError = "用户中断"; return(0); } string strRecPath = ListViewUtil.GetItemText(item, 0); if (stop != null && bDisplayMessage == true) { stop.SetMessage("正在刷新浏览行 " + strRecPath + " 的书目摘要 ..."); stop.SetProgressValue(lStartIndex + i); } int nCol = colindex_list[i]; if (nCol == -1) { ListViewUtil.ChangeItemText(item, this.m_bFirstColumnIsKey == false ? 1 : 2, ""); ClearOneChange(item, true); // 清除内存中的修改 i++; continue; } try { bool bRet = enumerator.MoveNext(); if (bRet == false) { Debug.Assert(false, "还没有到结尾, MoveNext() 不应该返回 false"); // TODO: 这时候也可以采用返回一个带没有找到的错误码的元素 strError = "error 1"; return(-1); } } catch (ChannelException ex) { strError = ex.Message; if (ex.ErrorCode == ErrorCode.AccessDenied) { return(-2); } return(-1); } BiblioItem biblio = (BiblioItem)enumerator.Current; // Debug.Assert(biblio.RecPath == strRecPath, "m_loader 和 items 的元素之间 记录路径存在严格的锁定对应关系"); ListViewUtil.ChangeItemText(item, this.m_bFirstColumnIsKey == false ? 1 : 2, biblio.Content); ClearOneChange(item, true); // 清除内存中的修改 i++; } return(1); }
/// <summary> /// 获得枚举接口 /// </summary> /// <returns>枚举接口</returns> public IEnumerator GetEnumerator() { Debug.Assert(m_loader != null, ""); if (this.Prompt != null) { m_loader.Prompt += m_loader_Prompt; } try { #if NO if (this.CacheTable == null) { this.CacheTable = new Hashtable(); // 如果调主没有给出 CacheTable, 则临时分配一个 } #endif Hashtable tempTable = new Hashtable(); List <string> new_recpaths = new List <string>(); // 缓存中没有包含的那些记录 foreach (string strRecPath in this.RecPaths) { if (string.IsNullOrEmpty(strRecPath)) { throw new ArgumentException("RecPaths 中不应包含空元素"); } Debug.Assert(string.IsNullOrEmpty(strRecPath) == false, ""); BiblioItem info = null; if (this.CacheTable != null) { info = (BiblioItem)this.CacheTable[strRecPath]; if (info != null) { tempTable[strRecPath] = info; continue; } } if (info == null) { info = (BiblioItem)tempTable[strRecPath]; // 注: tempTable 自带去重效果 } if (info == null) { new_recpaths.Add(strRecPath); #if NO // 需要放入缓存,便于后面的发现 // 但放入缓存的是 .Content 为空的对象 if (info == null) { info = new BiblioItem(); info.RecPath = strRecPath; } this.CacheTable[strRecPath] = info; #endif info = new BiblioItem(); info.RecPath = strRecPath; tempTable[strRecPath] = info; } } // 注: Hashtable 在这一段时间内不应该被修改。否则会破坏 m_loader 和 items 之间的锁定对应关系 m_loader.RecPaths = new_recpaths; var enumerator = m_loader.GetEnumerator(); // 开始循环 foreach (string strRecPath in this.RecPaths) { Debug.Assert(string.IsNullOrEmpty(strRecPath) == false, ""); BiblioItem info = null; #if NO if (this.CacheTable != null) { info = (BiblioItem)this.CacheTable[strRecPath]; } #endif info = (BiblioItem)tempTable[strRecPath]; // 注: tempTable 自带去重效果 if (info != null && string.IsNullOrEmpty(info.Content) == false) { yield return(info); continue; } if (new_recpaths.IndexOf(strRecPath) != -1) // if (info == null || string.IsNullOrEmpty(info.Content) == true) { bool bRet = enumerator.MoveNext(); if (bRet == false) { Debug.Assert(false, "还没有到结尾, MoveNext() 不应该返回 false"); // TODO: 这时候也可以采用返回一个带没有找到的错误码的元素 yield break; } BiblioItem biblio = (BiblioItem)enumerator.Current; Debug.Assert(biblio.RecPath == strRecPath, "m_loader 和 items 的元素之间 记录路径存在严格的锁定对应关系"); // 需要放入缓存 if (info == null) { info = new BiblioItem(); info.RecPath = biblio.RecPath; } if (string.IsNullOrEmpty(biblio.Content) == true) { info.Content = "{null}"; // 2013/11/18 } else { info.Content = biblio.Content; } info.Metadata = biblio.Metadata; info.Timestamp = biblio.Timestamp; if (tempTable.ContainsKey(strRecPath) == false) { tempTable[strRecPath] = info; } if (this.CacheTable != null) { if (this.CacheTable.ContainsKey(strRecPath) == false) { this.CacheTable[strRecPath] = info; } } yield return(info); } else { info = (BiblioItem)tempTable[strRecPath]; // 注: tempTable 自带去重效果 if (info == null) { throw new Exception("tempTable 里面没有找到 '" + strRecPath + "'"); } yield return(info); } } } finally { if (this.Prompt != null) { m_loader.Prompt -= m_loader_Prompt; } } }