コード例 #1
0
ファイル: LocationResultset.cs プロジェクト: renyh1013/dp2
        const int _removeDup_batchSize = 10000; // 利用 hashtable 进行局部去重的每批个数

        // 从 dp2Kernel 端获取结果集
        // parameters:
        //      strStyle    tobibliorecpath 将实体\期\订购\评注 记录路径转换为书目记录路径,并去重
        int GetResultset(RmsChannel channel,
            string strResultsetName,
            DpResultSet resultset,
            out string strError)
        {
            strError = "";

            m_biblioDbNameTable.Clear();

            Hashtable temp_table = new Hashtable();

            string strFormat = "id,cols,format:@coldef://parent"; // "id,xml";

            SearchResultLoader loader = new SearchResultLoader(channel,
                null,
                strResultsetName,
                strFormat);
            loader.ElementType = "Record";

#if DETAIL_LOG
            this.WriteErrorLog("开始从 dp2kernel 获取结果集");
#endif

            int hashtable_removedup_loops = 0;  // 利用 hashtable 去重的轮次。如果只有一轮,则可以免去最后的结果集文件去重
            try
            {
                foreach (Record rec in loader)
                {
                    this._app_down.Token.ThrowIfCancellationRequested();

                    {
                        if (rec.RecordBody != null
                            && rec.RecordBody.Result != null
                            && rec.RecordBody.Result.ErrorCode != ErrorCodeValue.NoError)
                        {
#if NO
                        strError = "获得结果集位置偏移 " + (lStart + j).ToString() + " 时出错,该记录已被忽略: " + rec.RecordBody.Result.ErrorString;
                        this.AppendResultText(strError + "\r\n");
#endif
                            continue;
                        }

                        string strBiblioRecPath = "";

#if NO
                            // 从册记录XML中获得书目记录路径
                            // return:
                            //      -1  出错
                            //      1   成功
                            int nRet = GetBiblioRecPath(
                                rec.Path,
                                rec.RecordBody.Xml,
                                out strBiblioRecPath,
                                out strError);
                            if (nRet == -1)
                                return -1;
#endif
                        if (rec.Cols == null || rec.Cols.Length == 0)
                        {
#if NO
                        strError = "获得结果集位置偏移 " + (lStart + j).ToString() + " 时出错: rec.Cols 为空";
                        this.AppendResultText(strError + "\r\n");
#endif
                            continue;
                        }

                        // return:
                        //      -1  出错
                        //      1   成功
                        int nRet = GetBiblioRecPathByParentID(
                            rec.Path,
                            rec.Cols[0],
                            out strBiblioRecPath,
                            out strError);
                        if (nRet == -1)
                            return -1;

                        // 缓冲并局部去重。局部去重可以减轻后面全局去重的压力
                        if (temp_table.Contains(strBiblioRecPath) == false)
                        {
                            temp_table.Add(strBiblioRecPath, null);
                            if (temp_table.Count > _removeDup_batchSize)
                            {
                                FlushTable(temp_table, resultset);
                                temp_table.Clear();
                                hashtable_removedup_loops++;
                            }
                        }

                        //DpRecord record = new DpRecord(rec.Path);
                        //item_paths.Add(record);
                    }
                }
            }
            catch (Exception ex)
            {
                strError = ex.Message;
                return -1;
            }

            // if (bToBiblioRecPath == true)
            {
                // 最后一批
                if (temp_table.Count > 0)
                {
                    FlushTable(temp_table, resultset);
                    temp_table.Clear();
                    hashtable_removedup_loops++;
                }

                resultset.Idle += new IdleEventHandler(biblio_paths_Idle);  // 2016/1/23 原来这里是 -=,令人费解
                try
                {
#if DETAIL_LOG
                this.WriteErrorLog("开始排序结果集, count=" + resultset.Count);
#endif

                    // 归并后写入结果集文件
                    resultset.QuickSort();
                    resultset.Sorted = true;

                    if (hashtable_removedup_loops > 1)
                    {
                        // 全局去重
#if DETAIL_LOG
                    this.WriteErrorLog("开始对结果集去重, count=" + resultset.Count);
#endif
                        resultset.RemoveDup();

#if DETAIL_LOG
                    this.WriteErrorLog("结束对结果集去重, count=" + resultset.Count);
#endif
                    }
                }
                finally
                {
                    resultset.Idle -= new IdleEventHandler(biblio_paths_Idle);
                }
            }

            return 0;
        }
コード例 #2
0
ファイル: RecordLoader.cs プロジェクト: zszqwe/dp2
        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;
                }
            }
        }
コード例 #3
0
ファイル: LibraryApplication.cs プロジェクト: renyh1013/dp2
        // 获得读者记录, 为登录用途。注意,本函数不检查是否符合。
        // 该函数的特殊性在于,它可以用多种检索入口,而不仅仅是条码号
        // parameters:
        //      strQueryWord 登录名
        //          0) 如果以"RI:"开头,表示利用 参考ID 进行检索
        //          1) 如果以"NB:"开头,表示利用姓名生日进行检索。姓名和生日之间间隔以'|'。姓名必须完整,生日为8字符形式
        //          2) 如果以"EM:"开头,表示利用email地址进行检索。注意 email 本身应该是 email:xxxx 这样的形态。也就是说,整个加起来是 EM:email:xxxxx
        //          3) 如果以"TP:"开头,表示利用电话号码进行检索
        //          4) 如果以"ID:"开头,表示利用身份证号进行检索
        //          5) 如果以"CN:"开头,表示利用证件号码进行检索
        //          6) 否则用证条码号进行检索
        // return:
        //      -2  当前没有配置任何读者库,或者可以操作的读者库
        //      -1  error
        //      0   not found
        //      1   命中1条
        //      >1  命中多于1条
        int GetReaderRecXmlForLogin(
            RmsChannel channel,
            string strLibraryCodeList,
            string strQueryWord,
            int nMaxHitCount,
            string strFormatList,
            out List<KernelRecord> records,
            out string strError)
        {
            strError = "";
            records = new List<KernelRecord>();

            int nRet = 0;
            LibraryApplication app = this;
            string strFrom = "证条码";
            string strMatch = "exact";

            // 构造检索式
            string strQueryXml = "";

            strQueryWord = strQueryWord.Trim();

            string strPrefix = "";
            string strName = "";

            SplitLoginName(strQueryWord, out strPrefix, out strName);

            bool bBarcode = false;

            // 注意如果这里增补新的prefix, 函数 SplitLoginName() 也要同步修改
            // 没有前缀
            if (strPrefix == "")
            {
                bBarcode = true;
                strFrom = "证条码";
                strMatch = "exact";
            }
            else if (strPrefix == "NB:")
            {
                bBarcode = false;
                strFrom = "姓名生日";
                strMatch = "left";
                strQueryWord = strName;
            }
            else if (strPrefix == "EM:")
            {
                bBarcode = false;
                strFrom = "Email";
                strMatch = "exact";
                strQueryWord = strName;  // 2016/4/11 注 strName 内容应为 email:xxxxx
            }
            else if (strPrefix == "TP:")
            {
                bBarcode = false;
                strFrom = "电话";
                strMatch = "exact";
                strQueryWord = strName;
            }
            else if (strPrefix == "ID:")
            {
                bBarcode = false;
                strFrom = "身份证号";
                strMatch = "exact";
                strQueryWord = strName;
            }
            else if (strPrefix == "CN:")
            {
                bBarcode = false;
                strFrom = "证号";
                strMatch = "exact";
                strQueryWord = strName;
            }
            else if (strPrefix == "RI:")
            {
                bBarcode = false;
                strFrom = "参考ID";
                strMatch = "exact";
                strQueryWord = strName;
            }
            else
            {
                strError = "未知的登录名前缀 '" + strPrefix + "'";
                return -1;
            }

            List<string> dbnames = new List<string>();
            // 获得读者库名列表
            // parameters:
            //      strReaderDbNames    库名列表字符串。如果为空,则表示全部读者库
            // return:
            //      -1  出错
            //      >=0 dbnames 中包含的读者库名数量
            nRet = GetDbNameList("",
                strLibraryCodeList,
                out dbnames,
                out strError);
            if (nRet == -1)
                return -1;

            if (dbnames.Count == 0)
            {
                if (app.ReaderDbs.Count == 0)
                    strError = "当前尚没有配置读者库";
                else
                    strError = "当前没有可以操作的读者库";
                return -2;
            }

            {
                int i = 0;
                foreach (string strDbName in dbnames)
                {
                    if (string.IsNullOrEmpty(strDbName) == true)
                        continue;

                    Debug.Assert(String.IsNullOrEmpty(strDbName) == false, "");

                    // 最多100条
                    // 2007/4/5 改造 加上了 GetXmlStringSimple()
                    string strOneDbQuery = "<target list='"
                        + StringUtil.GetXmlStringSimple(strDbName + ":" + strFrom)       // 2007/9/14 
                        + "'><item><word>"
                        + StringUtil.GetXmlStringSimple(strQueryWord)
                        + "</word><match>" + strMatch + "</match><relation>=</relation><dataType>string</dataType><maxCount>" + nMaxHitCount + "</maxCount></item><lang>zh</lang></target>";

                    if (string.IsNullOrEmpty(strQueryXml) == false)
                    {
                        Debug.Assert(String.IsNullOrEmpty(strQueryXml) == false, "");
                        strQueryXml += "<operator value='OR'/>";
                    }

                    strQueryXml += strOneDbQuery;
                    i++;
                }

                if (i > 1)
                {
                    strQueryXml = "<group>" + strQueryXml + "</group>";
                }
            }

            if (String.IsNullOrEmpty(strQueryXml) == true)
            {
                strError = "尚未配置读者库";
                return -1;
            }

            long lRet = channel.DoSearch(strQueryXml,
                "default",
                "", // strOuputStyle
                out strError);
            if (lRet == -1)
            {
                strError = "channel.DoSearch() error : " + strError;
                return -1;
            }

            // not found
            if (lRet == 0)
            {
                strError = "没有找到";
                return 0;
            }

            long lHitCount = lRet;

            if (lHitCount > 1 && bBarcode == true)
            {
                strError = "系统错误: 证条码号为 '" + strQueryWord + "' 的读者记录多于一个";
                return -1;
            }

            try
            {
                SearchResultLoader loader = new SearchResultLoader(channel,
                null,
                "default",
                strFormatList);

                foreach (KernelRecord record in loader)
                {
                    records.Add(record);
                    if (nMaxHitCount >= 0 && records.Count >= nMaxHitCount)
                        break;
                }

                return records.Count;
            }
            catch (Exception ex)
            {
                strError = ex.Message;
                return -1;
            }
        }