Beispiel #1
0
        // 追加文本
        // 多线程:安全
        internal void AppendText(string strRefID,
                                 string strText)
        {
            if (String.IsNullOrEmpty(strText) == true)
            {
                return;
            }
            if (m_resultset == null)
            {
                return;
            }

            m_lock.EnterWriteLock();
            try
            {
                // 打开当天的内容文件
                string strError = "";
                int    nRet     = PrepareContentFileName(out strError);
                if (nRet == -1)
                {
                    throw new Exception(strError);
                }

                DpRecord record = new DpRecord(strRefID);
                record.BrowseText = strText;
                m_resultset.Add(record);
            }
            finally
            {
                m_lock.ExitWriteLock();
            }
        }
Beispiel #2
0
        // parameters:
        //      bChangeVersion  是否修改版本号
        //      lNewVersion 返回修改后的新版本号。如果bChangeVersion==false, 此参数也返回没有发生过变化的版本号
        //      strContent  返回已经删除的记录的内容
        int DeleteItem(DpResultSet resultset,
                       string strRefID,
                       bool bChangeVersion,
                       bool bAllowDeleteNotifyItem,
                       out long lNewVersion,
                       out string strContent,
                       out string strError)
        {
            strError    = "";
            lNewVersion = 0;
            strContent  = "";

            for (long i = 0; i < resultset.Count; i++)
            {
                DpRecord record = resultset[i];

                if (record.ID == strRefID)
                {
                    strContent = record.BrowseText;
                    if (bAllowDeleteNotifyItem == false &&
                        string.IsNullOrEmpty(strContent) == false)
                    {
                        XmlDocument dom = new XmlDocument();
                        try
                        {
                            dom.LoadXml(strContent);
                        }
                        catch (Exception ex)
                        {
                            strError = "记录内容装入XMLDOM时出错: " + ex.Message;
                            return(-1);
                        }
                        string strClass = DomUtil.GetAttr(dom.DocumentElement, "class");
                        strClass.Replace(" ", ",");
                        if (StringUtil.IsInList("notify", strClass) == true)
                        {
                            strError = "notify事项不允许删除";
                            return(-1);
                        }
                    }

                    resultset.RemoveAt((int)i);
                    if (resultset == this.m_resultset)
                    {
                        if (bChangeVersion == true)
                        {
                            this.ContentFileVersion = DateTime.Now.Ticks;   // 文件版本发生变化
                        }
                        lNewVersion = this.ContentFileVersion;
                    }
                    return(1);   // deleted
                }
            }

            strError = "refid为 '" + strRefID + "' 的事项没有找到";
            return(0);   // not found
        }
Beispiel #3
0
        void FlushTable(Hashtable temp_table, DpResultSet resultset)
        {
            foreach (string path in temp_table.Keys)
            {
                this._app_down.Token.ThrowIfCancellationRequested();

                DpRecord record_bibliorecpath = new DpRecord(path);
                resultset.Add(record_bibliorecpath);
            }
        }
Beispiel #4
0
        ChatInfo GetInfo(
            DpResultSet resultset,
            long nStart,
            long nCount,
            bool bDisplayAllIP)
        {
            ChatInfo info = new ChatInfo();

            info.Name = this.Name;

            long nMax = 0;

            if (nCount == -1)
            {
                nMax = resultset.Count;
            }
            else
            {
                nMax = Math.Min(resultset.Count, nStart + nCount);
            }

            if (nMax - nStart > MAX_COUNT_PER_GET)
            {
                nMax = nStart + MAX_COUNT_PER_GET;
            }

            string strResult = "";

            for (long i = nStart; i < nMax; i++)
            {
                DpRecord record = resultset[i];
                if (bDisplayAllIP == true)
                {
                    strResult += record.BrowseText;
                }
                else
                {
                    strResult += MaskIP(record.BrowseText);
                }
            }

            info.ResultText = strResult;
            info.NextStart  = nMax;  // 结束位置
            info.TotalLines = resultset.Count;
            if (resultset == this.m_resultset)
            {
                info.ResultVersion = this.ContentFileVersion;
            }
            else
            {
                info.ResultVersion = 0; // 暂时无法给出
            }

            return(info);
        }
Beispiel #5
0
        // 获取指纹信息,追加到结果集文件的尾部
        // parameters:
        //      update_table   key为读者记录路径
        void AppendFingerprintInfo(
            LibraryChannel channel,
            DpResultSet resultset,
            Hashtable update_table,
            CancellationToken token)
        {
            List <string> lines = new List <string>();

            foreach (string recpath in update_table.Keys)
            {
                lines.Add(recpath);
            }

            BrowseLoader loader = new BrowseLoader();

            loader.RecPaths = lines;
            loader.Channel  = channel;
            loader.Format   = $"id,cols,format:cfgs/browse_{this.BrowseStyle}";
            loader.Prompt  += this.Loader_Prompt;

            foreach (DigitalPlatform.LibraryClient.localhost.Record record in loader)
            {
                token.ThrowIfCancellationRequested();

                this.ShowMessage("追加 " + record.Path);

                if (record.Cols == null || record.Cols.Length < 3)
                {
                    string strError = $"record.Cols error ... 有可能是因为读者库缺乏配置文件 cfgs/browse_{this.BrowseStyle}";
                    // TODO: 并发操作的情况下,会在中途出现读者记录被别的前端修改的情况,这里似乎可以continue
                    throw new Exception(strError);
                }

                // 如果证条码号为空,无法建立对照关系,要跳过
                if (string.IsNullOrEmpty(record.Cols[1]) == true)
                {
                    continue;
                }

                DpRecord item = new DpRecord(record.Path);
                // timestamp | barcode | fingerprint
                item.BrowseText = record.Cols[0] + "|" + record.Cols[1] + "|" + record.Cols[2];
                resultset.Add(item);
            }
        }
Beispiel #6
0
        // 将内存数组写入结果集文件
        public static int WriteToResulsetFile(
            KeyValueCollection items,
            string strResultsetFilename,
            out string strError)
        {
            strError = "";

            DpResultSet resultset = new DpResultSet(false, false);

            resultset.Create(strResultsetFilename,
                             strResultsetFilename + ".index");

            bool bDone = false;

            try
            {
                foreach (KeyValue item in items)
                {
                    DpRecord record = new DpRecord(item.Value);
                    record.BrowseText = item.Key;
                    resultset.Add(record);
                }
                bDone = true;
                return(0);
            }
            finally
            {
                if (bDone == true)
                {
                    string strTemp1 = "";
                    string strTemp2 = "";
                    resultset.Detach(out strTemp1,
                                     out strTemp2);
                }
                else
                {
                    // 否则文件会被删除
                    resultset.Close();
                }
            }
        }
Beispiel #7
0
        // return:
        //      -2  remoting服务器连接失败。驱动程序尚未启动
        //      -1  出错
        //      >=0 实际发送给接口程序的事项数目
        static int CreateFingerprintCache(DpResultSet resultset,
                                          out string strError)
        {
            strError = "";
            int nRet = 0;

            ShowMessage("加入高速缓存");

            try
            {
                if (resultset == null)
                {
                    // 清空以前的全部缓存内容,以便重新建立
                    // return:
                    //      -2  remoting服务器连接失败。驱动程序尚未启动
                    //      -1  出错
                    //      0   成功
                    nRet = AddItems(
                        //channel,
                        null,
                        out strError);
                    if (nRet == -1)
                    {
                        return(-1);
                    }
                    if (nRet == -2)
                    {
                        return(-2);
                    }

                    return(0);
                }

                int  nSendCount = 0;
                long nCount     = resultset.Count;
                List <FingerprintItem> items = new List <FingerprintItem>();
                for (long i = 0; i < nCount; i++)
                {
                    DpRecord record = resultset[i];

                    string strTimestamp   = "";
                    string strBarcode     = "";
                    string strFingerprint = "";
                    ParseResultItemString(record.BrowseText,
                                          out strTimestamp,
                                          out strBarcode,
                                          out strFingerprint);
                    // TODO: 注意读者证条码号为空的,不要发送出去


                    FingerprintItem item = new FingerprintItem();
                    item.ReaderBarcode     = strBarcode;
                    item.FingerprintString = strFingerprint;

                    items.Add(item);
                    if (items.Count >= 100)
                    {
                        // return:
                        //      -2  remoting服务器连接失败。驱动程序尚未启动
                        //      -1  出错
                        //      0   成功
                        nRet = AddItems(
                            //channel,
                            items,
                            out strError);
                        if (nRet == -1)
                        {
                            return(-1);
                        }
                        if (nRet == -2)
                        {
                            return(-2);
                        }
                        nSendCount += items.Count;
                        items.Clear();
                    }
                }

                if (items.Count > 0)
                {
                    // return:
                    //      -2  remoting服务器连接失败。驱动程序尚未启动
                    //      -1  出错
                    //      0   成功
                    nRet = AddItems(
                        //channel,
                        items,
                        out strError);
                    if (nRet == -1)
                    {
                        return(-1);
                    }
                    if (nRet == -2)
                    {
                        return(-2);
                    }
                    nSendCount += items.Count;
                }

                // Console.Beep(); // 表示读取成功
                return(nSendCount);
            }
            finally
            {
            }
        }
Beispiel #8
0
        // 根据结果集文件初始化指纹高速缓存
        // parameters:
        //      resultset   用于初始化的结果集对象。如果为 null,表示希望清空指纹高速缓存
        //                  一般可用 null 调用一次,然后用多个 resultset 对象逐个调用一次
        // return:
        //      -1  出错
        //      >=0 实际发送给接口程序的事项数目
        int CreateFingerprintCache(DpResultSet resultset,
                                   out string strError)
        {
            strError = "";
            int nRet = 0;

            this.ShowMessage("加入高速缓存");

            try
            {
                if (resultset == null)
                {
                    // 清空以前的全部缓存内容,以便重新建立
                    // return:
                    //      0   成功
                    //      其他  失败。错误码
                    nRet = this.AddItems(
                        null,
                        out strError);
                    if (nRet != 0)
                    {
                        return(-1);
                    }

                    return(0);
                }

                int  nSendCount = 0;
                long nCount     = resultset.Count;
                List <FingerprintItem> items = new List <FingerprintItem>();
                for (long i = 0; i < nCount; i++)
                {
                    DpRecord record = resultset[i];

                    //string strTimestamp = "";
                    //string strBarcode = "";
                    //string strFingerprint = "";
                    ParseResultItemString(record.BrowseText,
                                          out string strTimestamp,
                                          out string strBarcode,
                                          out string strFingerprint);
                    // TODO: 注意读者证条码号为空的,不要发送出去


                    FingerprintItem item = new FingerprintItem
                    {
                        ReaderBarcode     = strBarcode,
                        FingerprintString = strFingerprint
                    };

                    items.Add(item);
                    if (items.Count >= 100)
                    {
                        // return:
                        //      0   成功
                        //      其他  失败。错误码
                        nRet = this.AddItems(
                            items,
                            out strError);
                        if (nRet != 0)
                        {
                            return(-1);
                        }

                        nSendCount += items.Count;
                        items.Clear();
                    }
                }

                if (items.Count > 0)
                {
                    // return:
                    //      0   成功
                    //      其他  失败。错误码
                    nRet = this.AddItems(
                        items,
                        out strError);
                    if (nRet != 0)
                    {
                        return(-1);
                    }

                    nSendCount += items.Count;
                }

                // Console.Beep(); // 表示读取成功
                return(nSendCount);
            }
            finally
            {
            }
        }
Beispiel #9
0
        void FlushTable(Hashtable temp_table, DpResultSet resultset)
        {
            foreach (string path in temp_table.Keys)
            {
                this._app_down.Token.ThrowIfCancellationRequested();

                DpRecord record_bibliorecpath = new DpRecord(path);
                resultset.Add(record_bibliorecpath);
            }
        }
Beispiel #10
0
 static void FlushTable(Hashtable temp_table, DpResultSet resultset)
 {
     foreach (string path in temp_table.Keys)
     {
         DpRecord record_bibliorecpath = new DpRecord(path);
         resultset.Add(record_bibliorecpath);
     }
 }
Beispiel #11
0
        // 从 dp2Library(其实也可以说dp2Kernel) 端获取结果集
        // parameters:
        //      strStyle    tobibliorecpath 将实体\期\订购\评注 记录路径转换为书目记录路径,并去重
        int GetResultset(LibraryChannel channel,
            string strResultsetName,
            string strResultsetFilename,
            string strStyle,
            out int nCount,
            out string strError)
        {
            strError = "";
            nCount = 0;

            long lStart = 0;
            long lRet = 0;

            m_biblioDbNameTable.Clear();

            bool bToBiblioRecPath = StringUtil.IsInList("tobibliorecpath", strStyle);
#if NO
            DpResultSet item_paths = null;
            if (bToBiblioRecPath == true)
                item_paths = new DpResultSet(true); // 临时文件会自动丢弃
#endif

            DpResultSet resultset = new DpResultSet(false, false);
            resultset.Create(strResultsetFilename,
                strResultsetFilename + ".index");

            bool bDone = false;
            try
            {

                Hashtable temp_table = new Hashtable();

                for (; ; )
                {
                    if (this.m_bClosed == true || this.Stopped == true)
                    {
                        strError = "中断";
                        return -1;
                    }

                    Thread.Sleep(1);

                    // List<string> aPath = null;
                    Record[] searchresults = null;
                    string strGetStyle = "id";
                    if (bToBiblioRecPath == true)
                        strGetStyle = "id,cols,format:@coldef://parent"; // "id,xml";

                    lRet = channel.GetSearchResult(
                        null,
                        strResultsetName,
                        lStart,
                        -1, // 100
                        strGetStyle,
                        "zh",
                        out searchresults,
                        out strError);
                    if (lRet == -1)
                        return -1;

                    long lHitCount = lRet;

                    for (int j = 0; j < searchresults.Length; j++)
                    {
                        if ((j % 10) == 9)
                            this.SetProgressText("从检索结果中获得记录路径 " + (lStart + j + 1).ToString() + " 条");

                        Record rec = searchresults[j];

                        if (bToBiblioRecPath == false)
                        {
                            DpRecord record = new DpRecord(rec.Path);
                            resultset.Add(record);
                        }
                        else
                        {
                            if (rec.RecordBody != null
                                && rec.RecordBody.Result != null
                                && rec.RecordBody.Result.ErrorCode != ErrorCodeValue.NoError)
                            {
                                strError = "获得结果集位置偏移 " + (lStart + j).ToString() + " 时出错,该记录已被忽略: " + rec.RecordBody.Result.ErrorString;
                                this.AppendResultText(strError + "\r\n");
                                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)
                            {
                                strError = "获得结果集位置偏移 " + (lStart + j).ToString() + " 时出错: rec.Cols 为空";
                                this.AppendResultText(strError + "\r\n");
                                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 > 1000)
                                {
                                    FlushTable(temp_table, resultset);
                                    temp_table.Clear();
                                }
                            }

                            //DpRecord record = new DpRecord(rec.Path);
                            //item_paths.Add(record);
                        }
                    }

                    if (searchresults.Length <= 0  // < 100
                        )
                        break;

                    lStart += searchresults.Length;
                    nCount += searchresults.Length;

                    if (lStart >= lHitCount)
                        break;
                }

                if (bToBiblioRecPath == true)
                {
#if NO
                    Hashtable temp_table = new Hashtable();
                    for (int j = 0; j < item_paths.Count; j++)
                    {
                        // Debug.WriteLine("output " + j.ToString());
                        DpRecord record = item_paths[j];
                        string strPath = record.ID;

                        Record rec = searchresults[j];


                        XmlDocument itemdom = null;
                        int nRet = OpacApplication.LoadToDom(rec.RecordBody.Xml,
                            out itemdom,
                            out strError);
                        if (nRet == -1)
                        {
                            strError = "装载记录 '" + strPath + "' 进入XML DOM时发生错误: " + strError;
                            return -1;
                        }

                        string strBiblioDbName = "";
                        string strDbName = ResPath.GetDbName(strPath);
                        string strDbType = this.App.GetDbType(strDbName,
                            out strBiblioDbName);
                        if (strDbType == null)
                        {
                            strError = "数据库 '" + strDbName + "' 的类型无法识别";
                            return -1;
                        }

                        string strParentID = DomUtil.GetElementText(itemdom.DocumentElement,
                            "parent");
                        string strBiblioRecPath = strBiblioDbName + "/" + strParentID;

                        // 缓冲并局部去重
                        if (temp_table.Contains(strBiblioRecPath) == false)
                        {
                            temp_table.Add(strBiblioRecPath, null);
                            if (temp_table.Count > 1000)
                            {
                                FlushTable(temp_table, resultset);
                                temp_table.Clear();
                            }
                        }

                        if ((j % 10) == 9)
                            this.SetProgressText("已转换写入书目记录路径 " + (j + 1).ToString() + " 条");


                        if ((j % 1000) == 999)
                            this.AppendResultText("已转换写入书目记录路径 "+(j+1).ToString()+" 条" + "\r\n");

                        /*
                        DpRecord record_bibliorecpath = new DpRecord(strBiblioRecPath);
                        resultset.Add(record_bibliorecpath);
                         * */
                    }

#endif

                    if (temp_table.Count > 0)
                    {
                        FlushTable(temp_table, resultset);
                        temp_table.Clear();
                    }

                    // 归并后写入结果集文件
                    resultset.Idle += new IdleEventHandler(biblio_paths_Idle);  // 2016/1/23 原来这里是 -=,令人费解
                    try
                    {
                        this.SetProgressText("正在排序");

                        this.AppendResultText("开始排序。事项数 " + resultset.Count + "\r\n");
                        resultset.QuickSort();
                        this.AppendResultText("结束排序。事项数 " + resultset.Count + "\r\n");

                        this.SetProgressText("正在去重");
                        resultset.Sorted = true;    // 2012/5/30

                        this.AppendResultText("开始去重。事项数 " + resultset.Count + "\r\n");
                        resultset.RemoveDup();
                        this.AppendResultText("结束去重。事项数 " + resultset.Count + "\r\n");
                    }
                    catch (InterruptException /*ex*/)
                    {
                        strError = "中断";
                        return -1;
                    }
                    finally
                    {
                        resultset.Idle -= new IdleEventHandler(biblio_paths_Idle);
                    }
                }

                this.SetProgressText("输出结果集完成");
                bDone = true;
            }
            finally
            {
                if (bDone == true)
                {
                    string strTemp1 = "";
                    string strTemp2 = "";
                    resultset.Detach(out strTemp1,
                        out strTemp2);
                }
                else
                {
                    // 否则文件会被删除
                    resultset.Close();
                }
            }

            return 0;
        }
Beispiel #12
0
        // 获取指纹信息,追加到结果集文件的尾部
        // parameters:
        //      update_table   key为读者记录路径
        int AppendFingerprintInfo(DpResultSet resultset,
            Hashtable update_table,
            out string strError)
        {
            strError = "";
            int nRet = 0;

            // 需要获得更新的事项,然后追加到结果集文件的尾部
            // 注意,需要定期彻底重建结果集文件,以便回收多余空间
            List<string> lines = new List<string>();
            foreach (string recpath in update_table.Keys)
            {
                lines.Add(recpath);
                if (lines.Count >= 100)
                {
                    List<DigitalPlatform.CirculationClient.localhost.Record> records = null;
                    nRet = GetSomeFingerprintData(lines,
    out records,
    out strError);
                    if (nRet == -1)
                        return -1;
                    foreach (DigitalPlatform.CirculationClient.localhost.Record record in records)
                    {
                        if (record.Cols == null || record.Cols.Length < 3)
                        {
                            strError = "record.Cols error ... 有可能是因为读者库缺乏配置文件 cfgs/browse_fingerprint";
                            // TODO: 并发操作的情况下,会在中途出现读者记录被别的前端修改的情况,这里似乎可以continue
                            return -1;
                        }

                        // 如果证条码号为空,无法建立对照关系,要跳过
                        if (string.IsNullOrEmpty(record.Cols[1]) == true)
                            continue;

                        DpRecord item = new DpRecord(record.Path);
                        // timestamp | barcode | fingerprint
                        item.BrowseText = record.Cols[0] + "|" + record.Cols[1] + "|" + record.Cols[2];
                        resultset.Add(item);
                    }
                    lines.Clear();
                }
            }

            if (lines.Count > 0)
            {
                List<DigitalPlatform.CirculationClient.localhost.Record> records = null;
                nRet = GetSomeFingerprintData(lines,
out records,
out strError);
                if (nRet == -1)
                    return -1;
                foreach (DigitalPlatform.CirculationClient.localhost.Record record in records)
                {
                    if (record.Cols == null || record.Cols.Length < 3)
                    {
                        strError = "record.Cols error ... 有可能是因为读者库缺乏配置文件 cfgs/browse_fingerprint";
                        // TODO: 并发操作的情况下,会在中途出现读者记录被别的前端修改的情况,这里似乎可以continue
                        return -1;
                    }
                    DpRecord item = new DpRecord(record.Path);
                    // timestamp | barcode | fingerprint
                    item.BrowseText = record.Cols[0] + "|" + record.Cols[1] + "|" + record.Cols[2];
                    resultset.Add(item);
                }
            }

            return 0;
        }
Beispiel #13
0
        // 从结果集中提取指定范围的记录
        // parameter:
        //		lStart	开始序号
        //		lLength	长度. -1表示从lStart到末尾
        //		strLang	语言
        //		strStyle	样式,以逗号分隔,id:表示取id,cols表示取浏览格式
        //              如果包含 format:cfgs/browse 这样的子串,表示指定浏览格式
        //		aRecord	得到的记录数组,成员为类型为Record
        //      strError    out参数,返回出错信息
        // result:
        //		-1	出错
        //		>=0	结果集的总数
        public long API_GetRecords(
            DpResultSet resultSet,
            long lStart,
            long lLength,
            string strLang,
            string strStyle,
            out Record[] records,
            out string strError)
        {
            records  = null;
            strError = "";

            // DpResultSet resultSet = this.DefaultResultSet;
            if (resultSet == null)
            {
                strError = "GetRecords()出错, resultSet 为 null";
                return(-1);
            }

            long lTotalPackageLength = 0;   // 累计计算要输出的XML记录占据的空间

            long lOutputLength;
            // 检查lStart lLength和resultset.Count之间的关系,
            // 和每批返回最大元素数限制, 综合得出一个合适的尺寸
            // return:
            //		-1  出错
            //		0   成功
            int nRet = ConvertUtil.GetRealLength((int)lStart,
                                                 (int)lLength,
                                                 (int)resultSet.Count,
                                                 SessionInfo.MaxRecordsCountPerApi,//nMaxCount,
                                                 out lOutputLength,
                                                 out strError);

            if (nRet == -1)
            {
                return(-1);
            }

            bool bKeyCount = StringUtil.IsInList("keycount", strStyle, true);
            bool bKeyID    = StringUtil.IsInList("keyid", strStyle, true);

            bool bHasID   = StringUtil.IsInList("id", strStyle, true);
            bool bHasCols = StringUtil.IsInList("cols", strStyle, true);
            bool bHasKey  = StringUtil.IsInList("key", strStyle, true);

            if (bKeyID == true &&
                bHasID == false && bHasCols == false && bHasKey == false)
            {
                strError = "strStyle包含了keyid但是没有包含id/key/cols中任何一个,导致API不返回任何内容,操作无意义";
                return(-1);
            }

            bool bXml             = StringUtil.IsInList("xml", strStyle, true);
            bool bWithResMetadata = StringUtil.IsInList("withresmetadata", strStyle, true);
            bool bTimestamp       = StringUtil.IsInList("timestamp", strStyle, true);
            bool bMetadata        = StringUtil.IsInList("metadata", strStyle, true);

            string strFormat = StringUtil.GetStyleParam(strStyle, "format");

            List <Record> results = new List <Record>(100);

            long lPos = -1; // 中间保持不透明的值

            for (long i = 0; i < lOutputLength; i++)
            {
                DpRecord dpRecord = null;

                long lIndex = lStart + i;
                if (lIndex == lStart)
                {
                    dpRecord = resultSet.GetFirstRecord(
                        lIndex,
                        false,
                        out lPos);
                }
                else
                {
                    // 取元素比[]操作速度快
                    dpRecord = resultSet.GetNextRecord(
                        ref lPos);
                }
                if (dpRecord == null)
                {
                    break;
                }

                Record record = new Record();

                if (bKeyCount == true)
                {
                    record.Path    = dpRecord.ID;
                    record.Cols    = new string[1];
                    record.Cols[0] = dpRecord.Index.ToString();

#if NO
                    lTotalPackageLength += record.Path.Length;
                    lTotalPackageLength += record.Cols[0].Length;
                    if (lTotalPackageLength > QUOTA_SIZE &&
                        i > 0)
                    {
                        // 响应包的尺寸已经超过 1M,并且已经至少包含了一条记录
                        break;
                    }
#endif
                    goto CONTINUE;
                }

                DbPath   path = new DbPath(dpRecord.ID);
                Database db   = this.app.Dbs.GetDatabaseSafety(path.Name);
                if (db == null)
                {
                    strError = "GetDatabaseSafety()从库id '" + path.Name + "' 找数据库对象失败";
                    return(-1);
                }

                // 如果有必要获得记录体
                string strXml      = "";
                string strMetadata = "";
                byte[] baTimestamp = null;
                if (bXml == true || bTimestamp == true || bMetadata == true)
                {
                    // 获得一条记录的 XML 字符串
                    // return:
                    //		-1  出错
                    //		-4  未找到记录
                    //      -10 记录局部未找到
                    //		0   成功
                    long lRet = GetXmlBody(
                        db,
                        path.ID,
                        bXml,
                        bTimestamp,
                        bMetadata,
                        bWithResMetadata,
                        out strXml,
                        out strMetadata,
                        out baTimestamp,
                        out strError);
                    if (lRet <= -1)
                    {
                        record.RecordBody           = new RecordBody();
                        record.RecordBody.Xml       = strXml;
                        record.RecordBody.Metadata  = strMetadata;
                        record.RecordBody.Timestamp = baTimestamp;

                        Result result = new Result();
                        result.Value       = -1;
                        result.ErrorCode   = KernelApplication.Ret2ErrorCode((int)lRet);
                        result.ErrorString = strError;

                        record.RecordBody.Result = result;
                        goto CONTINUE;
                        // return lRet;
                    }

#if NO
                    lTotalPackageLength += strXml.Length;
                    if (string.IsNullOrEmpty(strMetadata) == false)
                    {
                        lTotalPackageLength += strMetadata.Length;
                    }
                    if (baTimestamp != null)
                    {
                        lTotalPackageLength += baTimestamp.Length * 2;
                    }
                    if (lTotalPackageLength > QUOTA_SIZE &&
                        i > 0)
                    {
                        // 响应包的尺寸已经超过 1M,并且已经至少包含了一条记录
                        break;
                    }
#endif

                    record.RecordBody           = new RecordBody();
                    record.RecordBody.Xml       = strXml;
                    record.RecordBody.Metadata  = strMetadata;
                    record.RecordBody.Timestamp = baTimestamp;
                }

                if (bKeyID == true)
                {
                    // string strID = "";
                    string strKey = "";

                    // strID = dpRecord.ID;
                    strKey = dpRecord.BrowseText;

                    /*
                     * string strText = dpRecord.ID;
                     * nRet = strText.LastIndexOf(",");
                     * if (nRet != -1)
                     * {
                     *  strKey = strText.Substring(0, nRet);
                     *  strID = strText.Substring(nRet + 1);
                     * }
                     * else
                     *  strID = strText;
                     * */

                    if (bHasID == true)
                    {
                        // GetCaptionSafety()函数先找到指定语言的库名;
                        // 如果没有找到,就找截短形态的语言的库名;
                        // 再找不到,就用第一种语言的库名。
                        // 如果连一种语言也没有,则返回库id
                        record.Path = db.GetCaptionSafety(strLang) + "/" + path.CompressedID;
                        // lTotalPackageLength += record.Path.Length;
                    }

                    if (bHasKey == true)
                    {
                        record.Keys = BuildKeyFromArray(strKey);
                        // lTotalPackageLength += GetLength(record.Keys);
                    }

                    if (bHasCols == true)
                    {
                        string[] cols;
                        nRet = db.GetCols(
                            strFormat,
                            path.ID10,
                            strXml,
                            0,
                            out cols);
                        // 2013/1/14
                        if (nRet == -1)
                        {
                            if (cols != null && cols.Length > 0)
                            {
                                strError = cols[0];
                            }
                            else
                            {
                                strError = "GetCols() error";
                            }
                            return(-1);
                        }
                        record.Cols = cols;

                        // lTotalPackageLength += nRet;
                    }

                    goto CONTINUE;
                }

                {
                    if (bHasID == true)
                    {
                        // GetCaptionSafety()函数先找到指定语言的库名;
                        // 如果没有找到,就找截短形态的语言的库名;
                        // 再找不到,就用第一种语言的库名。
                        // 如果连一种语言也没有,则返回库id
                        record.Path = db.GetCaptionSafety(strLang) + "/" + path.CompressedID;
                        // lTotalPackageLength += record.Path.Length;
                    }

                    // 在不是keyid的风格下(例如keycount,空),cols全部是浏览列
                    if (bHasCols == true)
                    {
                        string[] cols;
                        nRet = db.GetCols(
                            strFormat,
                            path.ID10,
                            strXml,
                            0,
                            out cols);
                        // 2013/1/14
                        if (nRet == -1)
                        {
                            if (cols != null && cols.Length > 0)
                            {
                                strError = cols[0];
                            }
                            else
                            {
                                strError = "GetCols() error";
                            }
                            return(-1);
                        }
                        record.Cols = cols;
                        // lTotalPackageLength += nRet;
                    }
                }

CONTINUE:
                lTotalPackageLength += GetLength(record);
                if (lTotalPackageLength > QUOTA_SIZE &&
                    i > 0)
                {
                    // 响应包的尺寸已经超过 1M,并且已经至少包含了一条记录
                    break;
                }
                // records[i] = record;
                results.Add(record);
                Thread.Sleep(0);    // 降低CPU耗用?
            }

            records = new Record[results.Count];
            results.CopyTo(records);

            return(resultSet.Count);
        }
Beispiel #14
0
        // 初始化一个读者库的指纹缓存
        // return:
        //      -1  出错
        //      >=0 实际发送给接口程序的事项数目
        static int BuildOneDbCache(
            LibraryChannel channel,
            string strDir,
            string strReaderDbName,
            CancellationToken token,
            out string strError)
        {
            strError = "";
            int nRet = 0;

            DpResultSet resultset = null;
            bool        bCreate   = false;

            Hashtable timestamp_table = new Hashtable();    // recpath --> fingerprint timestamp

            ShowMessage(strReaderDbName);

            // 结果集文件名
            string strResultsetFilename = Path.Combine(strDir, strReaderDbName);

            if (File.Exists(strResultsetFilename) == false)
            {
                resultset = new DpResultSet(false, false);
                resultset.Create(strResultsetFilename,
                                 strResultsetFilename + ".index");
                bCreate = true;
            }
            else
            {
                bCreate = false;
            }

            // *** 第一阶段, 创建新的结果集文件;或者获取全部读者记录中的指纹时间戳

            bool bDone = false;    // 创建情形下 是否完成了写入操作

            try
            {
                /*
                 * long lRet = Channel.SearchReader(stop,
                 * strReaderDbName,
                 * "1-9999999999",
                 * -1,
                 * "__id",
                 * "left",
                 * this.Lang,
                 * null,   // strResultSetName
                 * "", // strOutputStyle
                 * out strError);
                 */
                long lRet = channel.SearchReader(null,  // stop,
                                                 strReaderDbName,
                                                 "",
                                                 -1,
                                                 "指纹时间戳",
                                                 "left",
                                                 ClientInfo.Lang,
                                                 null, // strResultSetName
                                                 "",   // strOutputStyle
                                                 out strError);
                if (lRet == -1)
                {
                    if (channel.ErrorCode == ErrorCode.AccessDenied)
                    {
                        strError = "用户 " + channel.UserName + " 权限不足: " + strError;
                    }
                    return(-1);
                }

                if (lRet == 0)
                {
                    // TODO: 这时候如果以前有结果集文件还会残留,但不会影响功能正确性,可以改进为把残留的结果集文件删除
                    return(0);
                }

                long lHitCount = lRet;

                ResultSetLoader loader = new ResultSetLoader(channel,
                                                             null,
                                                             null,
                                                             bCreate == true ? "id,cols,format:cfgs/browse_fingerprint" : "id,cols,format:cfgs/browse_fingerprinttimestamp",
                                                             ClientInfo.Lang);
                loader.Prompt += Loader_Prompt;

                foreach (DigitalPlatform.LibraryClient.localhost.Record record in loader)
                {
                    token.ThrowIfCancellationRequested();

                    ShowMessage("正在处理读者记录 " + record.Path);

                    if (bCreate == true)
                    {
                        if (record.Cols == null || record.Cols.Length < 3)
                        {
                            strError = "record.Cols error ... 有可能是因为读者库缺乏配置文件 cfgs/browse_fingerprint";
                            return(-1);
                        }
                        if (string.IsNullOrEmpty(record.Cols[0]) == true)
                        {
                            continue;   // 读者记录中没有指纹信息
                        }
                        DpRecord item = new DpRecord(record.Path);
                        // timestamp | barcode | fingerprint
                        item.BrowseText = record.Cols[0] + "|" + record.Cols[1] + "|" + record.Cols[2];
                        resultset.Add(item);
                    }
                    else
                    {
                        if (record.Cols == null || record.Cols.Length < 1)
                        {
                            strError = "record.Cols error ... 有可能是因为读者库缺乏配置文件 cfgs/browse_fingerprinttimestamp";
                            return(-1);
                        }
                        if (record.Cols.Length < 2)
                        {
                            strError = "record.Cols error ... 需要刷新配置文件 cfgs/browse_fingerprinttimestamp 到最新版本";
                            return(-1);
                        }
                        if (string.IsNullOrEmpty(record.Cols[0]) == true)
                        {
                            continue;   // 读者记录中没有指纹信息
                        }
                        // 记载时间戳
                        // timestamp | barcode
                        timestamp_table[record.Path] = record.Cols[0] + "|" + record.Cols[1];
                    }
                }

#if NO
                // stop.SetProgressRange(0, lHitCount);

                long lStart = 0;
                long lCount = lHitCount;
                DigitalPlatform.LibraryClient.localhost.Record[] searchresults = null;

                // 装入浏览格式
                for (; ;)
                {
                    token.ThrowIfCancellationRequested();


                    lRet = channel.GetSearchResult(
                        null,
                        null,   // strResultSetName
                        lStart,
                        lCount,
                        bCreate == true ? "id,cols,format:cfgs/browse_fingerprint" : "id,cols,format:cfgs/browse_fingerprinttimestamp",
                        ClientInfo.Lang,
                        out searchresults,
                        out strError);
                    if (lRet == -1)
                    {
                        return(-1);
                    }

                    if (lRet == 0)
                    {
                        strError = "GetSearchResult() return 0";
                        return(-1);
                    }

                    Debug.Assert(searchresults != null, "");
                    Debug.Assert(searchresults.Length > 0, "");

                    for (int i = 0; i < searchresults.Length; i++)
                    {
                        DigitalPlatform.LibraryClient.localhost.Record record = searchresults[i];
                        if (bCreate == true)
                        {
                            if (record.Cols == null || record.Cols.Length < 3)
                            {
                                strError = "record.Cols error ... 有可能是因为读者库缺乏配置文件 cfgs/browse_fingerprint";
                                return(-1);
                            }
                            if (string.IsNullOrEmpty(record.Cols[0]) == true)
                            {
                                continue;   // 读者记录中没有指纹信息
                            }
                            DpRecord item = new DpRecord(record.Path);
                            // timestamp | barcode | fingerprint
                            item.BrowseText = record.Cols[0] + "|" + record.Cols[1] + "|" + record.Cols[2];
                            resultset.Add(item);
                        }
                        else
                        {
                            if (record.Cols == null || record.Cols.Length < 1)
                            {
                                strError = "record.Cols error ... 有可能是因为读者库缺乏配置文件 cfgs/browse_fingerprinttimestamp";
                                return(-1);
                            }
                            if (record.Cols.Length < 2)
                            {
                                strError = "record.Cols error ... 需要刷新配置文件 cfgs/browse_fingerprinttimestamp 到最新版本";
                                return(-1);
                            }
                            if (string.IsNullOrEmpty(record.Cols[0]) == true)
                            {
                                continue;   // 读者记录中没有指纹信息
                            }
                            // 记载时间戳
                            // timestamp | barcode
                            timestamp_table[record.Path] = record.Cols[0] + "|" + record.Cols[1];
                        }
                    }

                    lStart += searchresults.Length;
                    lCount -= searchresults.Length;

                    //stop.SetMessage(strReaderDbName + " 包含记录 " + lHitCount.ToString() + " 条,已装入 " + lStart.ToString() + " 条");

                    if (lStart >= lHitCount || lCount <= 0)
                    {
                        break;
                    }
                    //stop.SetProgressValue(lStart);
                }
#endif

                if (bCreate == true)
                {
                    bDone = true;
                }

                if (bCreate == true)
                {
                    // return:
                    //      -2  remoting服务器连接失败。驱动程序尚未启动
                    //      -1  出错
                    //      >=0 实际发送给接口程序的事项数目
                    nRet = CreateFingerprintCache(resultset,
                                                  out strError);
                    if (nRet == -1 || nRet == -2)
                    {
                        return(-1);
                    }

                    return(nRet);
                }
            }
            finally
            {
                if (bCreate == true)
                {
                    Debug.Assert(resultset != null, "");
                    if (bDone == true)
                    {
                        resultset.Detach(out string strTemp1,
                                         out string strTemp2);
                    }
                    else
                    {
                        // 否则文件会被删除
                        resultset.Close();
                    }
                }
            }

            // 比对时间戳,更新结果集文件
            Hashtable update_table = new Hashtable();   // 需要更新的事项。recpath --> 1
            resultset = new DpResultSet(false, false);
            resultset.Attach(strResultsetFilename,
                             strResultsetFilename + ".index");
            try
            {
                long nCount = resultset.Count;
                for (long i = 0; i < nCount; i++)
                {
                    token.ThrowIfCancellationRequested();


                    DpRecord record = resultset[i];

                    string strRecPath = record.ID;

                    ShowMessage("比对 " + strRecPath);

                    // timestamp | barcode
                    string strNewTimestamp = (string)timestamp_table[strRecPath];
                    if (strNewTimestamp == null)
                    {
                        // 最新状态下,读者记录已经不存在,需要从结果集中删除
                        resultset.RemoveAt((int)i);
                        i--;
                        nCount--;
                        continue;
                    }

                    // 拆分出证条码号 2013/1/28
                    string strNewBarcode = "";
                    nRet = strNewTimestamp.IndexOf("|");
                    if (nRet != -1)
                    {
                        strNewBarcode   = strNewTimestamp.Substring(nRet + 1);
                        strNewTimestamp = strNewTimestamp.Substring(0, nRet);
                    }

                    // 最新读者记录中已经没有指纹信息。例如读者记录中的指纹元素被删除了
                    if (string.IsNullOrEmpty(strNewTimestamp) == true)
                    {
                        // 删除现有事项
                        resultset.RemoveAt((int)i);
                        i--;
                        nCount--;

                        timestamp_table.Remove(strRecPath);
                        continue;
                    }

                    // 取得结果集文件中的原有时间戳字符串
                    string strText = record.BrowseText; // timestamp | barcode | fingerprint
                    nRet = strText.IndexOf("|");
                    if (nRet == -1)
                    {
                        strError = "browsetext 错误,没有 '|' 字符";
                        return(-1);
                    }
                    string strOldTimestamp = strText.Substring(0, nRet);
                    // timestamp | barcode | fingerprint
                    string strOldBarcode = strText.Substring(nRet + 1);
                    nRet = strOldBarcode.IndexOf("|");
                    if (nRet != -1)
                    {
                        strOldBarcode = strOldBarcode.Substring(0, nRet);
                    }

                    // 时间戳发生变化,需要更新事项
                    if (strNewTimestamp != strOldTimestamp ||
                        strNewBarcode != strOldBarcode)
                    {
                        // 如果证条码号为空,无法建立对照关系,要跳过
                        if (string.IsNullOrEmpty(strNewBarcode) == false)
                        {
                            update_table[strRecPath] = 1;
                        }

                        // 删除现有事项
                        resultset.RemoveAt((int)i);
                        i--;
                        nCount--;
                    }
                    timestamp_table.Remove(strRecPath);
                }

                // 循环结束后,timestamp_table中剩余的是当前结果集文件中没有包含的那些读者记录路径

                if (update_table.Count > 0)
                {
                    // 获取指纹信息,追加到结果集文件的尾部
                    // parameters:
                    //      update_table   key为读者记录路径
                    AppendFingerprintInfo(
                        channel,
                        resultset,
                        update_table,
                        token);
                }

                // 如果服务器端新增了指纹信息,需要获取后追加到结果集文件尾部
                if (timestamp_table.Count > 0)
                {
                    // 获取指纹信息,追加到结果集文件的尾部
                    // parameters:
                    //      update_table   key为读者记录路径
                    AppendFingerprintInfo(
                        channel,
                        resultset,
                        timestamp_table,
                        token);
                }

                // return:
                //      -2  remoting服务器连接失败。驱动程序尚未启动
                //      -1  出错
                //      >=0 实际发送给接口程序的事项数目
                nRet = CreateFingerprintCache(resultset,
                                              out strError);
                if (nRet == -1 || nRet == -2)
                {
                    return(-1);
                }

                return(nRet);
            }
            finally
            {
                resultset.Detach(out string strTemp1, out string strTemp2);
            }
        }
Beispiel #15
0
        const int MAX_COUNT_PER_GET = 100;  // 每次最多可以获取的行数

        // 获得任务当前信息
        // 多线程:安全
        // parameters:
        //      bDisplayAllIP   是否显示全部IP地址。如果为false,表示只显示访客的IP地址,并且是掩盖部分的
        // return:
        //      -1  error
        //      0   file not found
        //      1   succeed
        public int GetInfo(
            string strDate,
            long nStart,
            long nCount,
            bool bDisplayAllIP,
            out ChatInfo info,
            out string strError)
        {
            strError = "";
            info     = null;

            if (strDate != this.Date)
            {
                // 要获得不是当天的内容
                string strFileName = PathUtil.MergePath(DataDirectory, strDate);
                if (File.Exists(strFileName) == false)
                {
                    strError = "日期为 '" + strDate + "' 的文件不存在";
                    return(0);
                }

                DpResultSet resultset = new DpResultSet(false, false);

                resultset.Attach(strFileName,
                                 strFileName + ".index");
                try
                {
                    info = GetInfo(
                        resultset,
                        nStart,
                        nCount,
                        bDisplayAllIP);
                }
                finally
                {
                    string strTemp1 = "";
                    string strTemp2 = "";
                    resultset.Detach(out strTemp1,
                                     out strTemp2);
                }

                FileInfo fi = new FileInfo(strFileName);
                info.ResultVersion = fi.LastWriteTimeUtc.Ticks;
                return(1);
            }
            else
            {
                m_lock.EnterReadLock();
                try
                {
                    // 打开当天的内容文件
                    int nRet = PrepareContentFileName(out strError);
                    if (nRet == -1)
                    {
                        return(-1);
                    }

#if NO
                    ChatInfo info = new ChatInfo();
                    info.Name = this.Name;

                    long nMax = 0;
                    if (nCount == -1)
                    {
                        nMax = m_resultset.Count;
                    }
                    else
                    {
                        nMax = Math.Min(m_resultset.Count, nStart + nCount);
                    }

                    if (nMax - nStart > MAX_COUNT_PER_GET)
                    {
                        nMax = nStart + MAX_COUNT_PER_GET;
                    }

                    string strResult = "";
                    for (long i = nStart; i < nMax; i++)
                    {
                        DpRecord record = m_resultset[i];
                        if (bDisplayAllIP == true)
                        {
                            strResult += record.BrowseText;
                        }
                        else
                        {
                            strResult += RemoveIP(record.BrowseText);
                        }
                    }

                    info.ResultText    = strResult;
                    info.NextStart     = nMax; // 结束位置
                    info.TotalLines    = m_resultset.Count;
                    info.ResultVersion = this.ContentFileVersion;

                    return(info);
#endif
                    info = GetInfo(
                        this.m_resultset,
                        nStart,
                        nCount,
                        bDisplayAllIP);
                    return(1);
                }
                finally
                {
                    m_lock.ExitReadLock();
                }
            }
        }
Beispiel #16
0
        // 创建二级节点
        // parameters:
        //      strPureFilename 一级节点的结果集纯文件名。用于构造定位信息
        //      strConverStyle  对 key 字符串的加工方法
        static int BuildSegments(
            string strSubNodeFilename,
            string strPureFilename,
            NodeInfo info,
            KeyValueCollection items,
            string strConvertStyle,
            out string strError)
        {
            strError = "";

            List <Segment> segments      = new List <Segment>();
            KeyValue       prev_item     = null;
            int            nSegmentCount = 0; // 当前段落中的个数
            int            i             = 0;

            foreach (KeyValue item in items)
            {
                if (string.IsNullOrEmpty(strConvertStyle) == false)
                {
                    item.Key = ConvertKey(strConvertStyle, item.Key);
                }

                if (prev_item == null)
                {
                    goto CONTINUE;
                }

                if (prev_item.Key == item.Key)
                {
                }
                else
                {
                    if (nSegmentCount > 0)
                    {
                        // 创建一段
                        segments.Add(new Segment(prev_item.Key, i - nSegmentCount, nSegmentCount));
                        nSegmentCount = 0;
                    }
                }

CONTINUE:
                prev_item = item;
                i++;
                nSegmentCount++;
            }

            // 最后一段
            if (nSegmentCount > 0)
            {
                segments.Add(new Segment(prev_item.Key, i - nSegmentCount, nSegmentCount));
            }

            info.SubCount = segments.Count;

            // 创建成一个一个的结果集分段观察命令,写入结果集文件
            DpResultSet resultset = new DpResultSet(false, false);

            resultset.Create(strSubNodeFilename,
                             strSubNodeFilename + ".index");

            bool bDone = false;

            try
            {
                foreach (Segment segment in segments)
                {
                    string   strCommand = segment.Start.ToString() + "," + segment.Length.ToString();
                    DpRecord record     = new DpRecord(strCommand);
                    record.BrowseText = segment.Name;
                    resultset.Add(record);
                }
                bDone = true;
                info.SubNodePureName = strPureFilename;
                return(0);
            }
            finally
            {
                if (bDone == true)
                {
                    string strTemp1 = "";
                    string strTemp2 = "";
                    resultset.Detach(out strTemp1,
                                     out strTemp2);
                }
                else
                {
                    // 否则文件会被删除
                    resultset.Close();
                }
            }
        }
Beispiel #17
0
        const int _upload_batchSize = 1000; // 上传结果集每批个数

        // 写入 dp2kernel 成为永久结果集
        int UploadPermanentResultset(RmsChannel channel,
                                     string strResultsetName,
                                     DpResultSet resultset,
                                     out string strError)
        {
            strError = "";

            // resultset.Clear();  // testing

            List <RecordBody> records = new List <RecordBody>();

            // 结果集为空,也要在 dp2kernel 端创建一个结果集对象
            if (resultset.Count == 0)
            {
                long lRet = channel.DoWriteRecords(null,
                                                   records.ToArray(),
                                                   "createResultset,name:#" + strResultsetName + ",clear,permanent",
                                                   out RecordBody[] results,
                                                   out strError);
                if (lRet == -1)
                {
                    return(-1);
                }
                return(0);
            }

#if DETAIL_LOG
            this.WriteErrorLog("开始上传结果集到 dp2kernel");
#endif

            long lPos   = -1; // 中间保持不透明的值
            bool bFirst = true;
            for (long i = 0; i < resultset.Count; i++)
            {
                DpRecord dpRecord = null;

                long lIndex = i;
                if (lIndex == 0)
                {
                    dpRecord = resultset.GetFirstRecord(
                        lIndex,
                        false,
                        out lPos);
                }
                else
                {
                    // 取元素比[]操作速度快
                    dpRecord = resultset.GetNextRecord(
                        ref lPos);
                }
                if (dpRecord == null)
                {
                    break;
                }

                RecordBody record = new RecordBody();
                record.Path = dpRecord.ID;
                records.Add(record);

                if (records.Count >= _upload_batchSize || (i >= resultset.Count - 1 && records.Count > 0))
                {
                    this._app_down.Token.ThrowIfCancellationRequested();

#if DETAIL_LOG
                    this.WriteErrorLog("一批 " + records.Count);
#endif
                    RecordBody[] results = null;
                    long         lRet    = channel.DoWriteRecords(null,
                                                                  records.ToArray(),
                                                                  "createResultset,name:#~" + strResultsetName + (bFirst ? ",clear" : ""),
                                                                  out results,
                                                                  out strError);
                    if (lRet == -1)
                    {
                        return(-1);
                    }
                    bFirst = false;
                    records.Clear();
                }
            }

            // 最后一次执行改名、排序
            {
                long lRet = channel.DoWriteRecords(null,
                                                   null,
                                                   "renameResultset,oldname:#~" + strResultsetName + ",newname:#" + strResultsetName + ",permanent,sort",
                                                   out RecordBody[] results,
                                                   out strError);
                if (lRet == -1)
                {
                    return(-1);
                }
            }
#if DETAIL_LOG
            this.WriteErrorLog("结束上传结果集");
#endif
            return(0);
        }
Beispiel #18
0
        // 创建FilterInfo数组
        // parameters:
        //      strSelectedPath 选定状态的节点的路径。为 {resultsetname}/{offsetstring} 形态
        public static FilterInfo[] BuildFilterInfos(
            string strBaseResultsetName,
            long lBaseResultCount,
            string strSelectedPath,
            // Hashtable keyname_table,
            GetCaption func_getcaption,
            List <NodeInfo> nodeinfos,
            string strTempDir,
            int nMaxSubNodeCount)
        {
            List <FilterInfo> results = new List <FilterInfo>();

            string strSelectedResultsetName = "";
            string strSelectedOffset        = "";

            ParseSelectedPath(strSelectedPath,
                              out strSelectedResultsetName,
                              out strSelectedOffset);

            if (string.IsNullOrEmpty(strBaseResultsetName) == false)
            {
                // 初始结果集
                FilterInfo info = new FilterInfo();
                results.Add(info);

                info.Name  = func_getcaption("初始结果集");
                info.Count = lBaseResultCount.ToString();
                info.Url   = "./searchbiblio.aspx?base=" + HttpUtility.UrlEncode(strBaseResultsetName);

                if (string.IsNullOrEmpty(strSelectedPath) == true)
                {
                    info.Selected = true;
                }
            }

            foreach (NodeInfo node in nodeinfos)
            {
                // 一级节点
                FilterInfo info = new FilterInfo();
                results.Add(info);

                // 将内部名字翻译为当前语言的名字
                info.Name  = func_getcaption(node.Name);
                info.Count = node.Count.ToString();
                info.Url   = "./searchbiblio.aspx?resultset=" + HttpUtility.UrlEncode(node.ResultSetPureName) + "&base=" + HttpUtility.UrlEncode(strBaseResultsetName) + "&title=" + HttpUtility.UrlEncode(RemoveHead(info.Name));
                if (string.IsNullOrEmpty(strSelectedOffset) == true)
                {
                    if (strSelectedResultsetName == node.ResultSetPureName)
                    {
                        info.Selected = true;
                    }
                }

                // 一级节点的下级导航信息
                info.Type = node.SubNodePureName + "," + node.SubCount + "," + node.SubStart;

                // 二级节点
                if (node.SubCount > 0 && string.IsNullOrEmpty(node.SubNodePureName) == false)
                {
                    string strResultsetFilename = Path.Combine(strTempDir, node.SubNodePureName);

                    List <FilterInfo> sub_results = new List <FilterInfo>();

                    // 如果起始位置不是0
                    if (node.SubStart > 0)
                    {
                        FilterInfo sub_info = new FilterInfo();
                        sub_results.Add(sub_info);

                        int nStart = node.SubStart - nMaxSubNodeCount;
                        if (nStart < 0)
                        {
                            nStart = 0;
                        }
                        sub_info.Name  = "前页...";
                        sub_info.Count = "";
                        sub_info.Url   = node.SubNodePureName + "," + nStart.ToString();
                        sub_info.Type  = "nav"; // 表示导航命令
                    }

                    int nTail = Math.Min(node.SubStart + nMaxSubNodeCount, node.SubCount);

                    {
                        DpResultSet resultset = new DpResultSet(false, false);
                        resultset.Attach(strResultsetFilename,
                                         strResultsetFilename + ".index");
                        try
                        {
                            for (int i = node.SubStart; i < nTail; i++)
                            {
                                DpRecord record = resultset[i];

                                string   strOffset = record.ID;
                                string[] parts     = strOffset.Split(new char[] { ',' });
                                if (parts.Length != 2)
                                {
                                    continue;
                                }

                                FilterInfo sub_info = new FilterInfo();
                                sub_results.Add(sub_info);

                                sub_info.Index = (i + 1).ToString();
                                sub_info.Name  = record.BrowseText;
                                sub_info.Count = parts[1];
                                sub_info.Url   = "./searchbiblio.aspx?resultset=" + HttpUtility.UrlEncode(node.ResultSetPureName) + "&offset=" + strOffset + "&base=" + HttpUtility.UrlEncode(strBaseResultsetName) + "&title=" + HttpUtility.UrlEncode(RemoveHead(info.Name) + "/" + sub_info.Name);

                                if (string.IsNullOrEmpty(strSelectedOffset) == false &&
                                    strSelectedResultsetName == node.ResultSetPureName && strSelectedOffset == strOffset)
                                {
                                    sub_info.Selected = true;
                                }
                            }
                        }
                        finally
                        {
                            string strTemp1 = "";
                            string strTemp2 = "";
                            resultset.Detach(out strTemp1, out strTemp2);
                        }
                    }

                    // 如果没有显示完,则最后包含一个翻页或者延展的锚点
                    if (nTail < node.SubCount)
                    {
                        FilterInfo sub_info = new FilterInfo();
                        sub_results.Add(sub_info);

                        sub_info.Name  = "更多...";
                        sub_info.Count = "";
                        // sub_info.Url = "./searchbiblio.aspx?resultset=" + HttpUtility.UrlEncode(node.SubNodePureName) + "&more=" + nMaxSubNodeCount.ToString();
                        sub_info.Url  = node.SubNodePureName + "," + nTail.ToString();
                        sub_info.Type = "nav";  // 表示导航命令

                        if (strSelectedResultsetName == node.ResultSetPureName && strSelectedOffset == "nav")
                        {
                            sub_info.Selected = true;
                        }
                    }
                    else
                    {
                        // 如果“更多”没有显示出来,则把选择点定位到最后一个元素
                        if (strSelectedResultsetName == node.ResultSetPureName && strSelectedOffset == "nav" &&
                            sub_results.Count > 0)
                        {
                            sub_results[sub_results.Count - 1].Selected = true;
                        }
                    }

#if NO
                    info.Children = new FilterInfo[sub_results.Count];
                    sub_results.CopyTo(info.Children);
#endif
                    info.Children = sub_results.ToArray();
                }
            }

            // 对results中的对象进行排序
            results.Sort(new FilterInfoComparer());
            // 去掉名字中的{}部分
            foreach (FilterInfo info in results)
            {
                string strName = info.Name;
                info.Name = RemoveHead(strName);
            }

#if NO
            FilterInfo[] a = new FilterInfo[results.Count];
            results.CopyTo(a);
            return(a);
#endif
            return(results.ToArray());
        }
Beispiel #19
0
        // 获取指纹信息,追加到结果集文件的尾部
        // parameters:
        //      update_table   key为读者记录路径
        static void AppendFingerprintInfo(
            LibraryChannel channel,
            DpResultSet resultset,
            Hashtable update_table,
            CancellationToken token)
        {
            List <string> lines = new List <string>();

            foreach (string recpath in update_table.Keys)
            {
                lines.Add(recpath);
            }

            BrowseLoader loader = new BrowseLoader();

            loader.RecPaths = lines;
            loader.Channel  = channel;
            loader.Format   = "id,cols,format:cfgs/browse_fingerprint";
            loader.Prompt  += Loader_Prompt;

            foreach (DigitalPlatform.LibraryClient.localhost.Record record in loader)
            {
                token.ThrowIfCancellationRequested();

                ShowMessage("追加 " + record.Path);

                if (record.Cols == null || record.Cols.Length < 3)
                {
                    string strError = "record.Cols error ... 有可能是因为读者库缺乏配置文件 cfgs/browse_fingerprint";
                    // TODO: 并发操作的情况下,会在中途出现读者记录被别的前端修改的情况,这里似乎可以continue
                    throw new Exception(strError);
                }

                // 如果证条码号为空,无法建立对照关系,要跳过
                if (string.IsNullOrEmpty(record.Cols[1]) == true)
                {
                    continue;
                }

                DpRecord item = new DpRecord(record.Path);
                // timestamp | barcode | fingerprint
                item.BrowseText = record.Cols[0] + "|" + record.Cols[1] + "|" + record.Cols[2];
                resultset.Add(item);
            }
#if NO
            // 需要获得更新的事项,然后追加到结果集文件的尾部
            // 注意,需要定期彻底重建结果集文件,以便回收多余空间
            List <string> lines = new List <string>();
            foreach (string recpath in update_table.Keys)
            {
                lines.Add(recpath);
                if (lines.Count >= 100)
                {
                    List <DigitalPlatform.LibraryClient.localhost.Record> records = null;
                    GetSomeFingerprintData(
                        channel,
                        lines,
                        token,
                        out records);

                    foreach (DigitalPlatform.LibraryClient.localhost.Record record in records)
                    {
                        if (record.Cols == null || record.Cols.Length < 3)
                        {
                            strError = "record.Cols error ... 有可能是因为读者库缺乏配置文件 cfgs/browse_fingerprint";
                            // TODO: 并发操作的情况下,会在中途出现读者记录被别的前端修改的情况,这里似乎可以continue
                            return(-1);
                        }

                        // 如果证条码号为空,无法建立对照关系,要跳过
                        if (string.IsNullOrEmpty(record.Cols[1]) == true)
                        {
                            continue;
                        }

                        DpRecord item = new DpRecord(record.Path);
                        // timestamp | barcode | fingerprint
                        item.BrowseText = record.Cols[0] + "|" + record.Cols[1] + "|" + record.Cols[2];
                        resultset.Add(item);
                    }
                    lines.Clear();
                }
            }

            if (lines.Count > 0)
            {
                List <DigitalPlatform.LibraryClient.localhost.Record> records = null;
                GetSomeFingerprintData(
                    channel,
                    lines,
                    token,
                    out records);

                foreach (DigitalPlatform.LibraryClient.localhost.Record record in records)
                {
                    if (record.Cols == null || record.Cols.Length < 3)
                    {
                        strError = "record.Cols error ... 有可能是因为读者库缺乏配置文件 cfgs/browse_fingerprint";
                        // TODO: 并发操作的情况下,会在中途出现读者记录被别的前端修改的情况,这里似乎可以continue
                        return(-1);
                    }
                    DpRecord item = new DpRecord(record.Path);
                    // timestamp | barcode | fingerprint
                    item.BrowseText = record.Cols[0] + "|" + record.Cols[1] + "|" + record.Cols[2];
                    resultset.Add(item);
                }
            }

            return(0);
#endif
        }
Beispiel #20
0
        // 外部调用
        public static int AddToResultset(List<string> aPath,
            string strResultsetFilename,
            bool bInsertAtFirst,
            out string strError)
        {
            strError = "";
            DpResultSet resultset = null;
            bool bCreate = false;
            try
            {
                if (File.Exists(strResultsetFilename) == true)
                {
                    resultset = new DpResultSet(false, false);
                    resultset.Attach(strResultsetFilename,
            strResultsetFilename + ".index");
                }
                else
                {
                    bCreate = true;
                    resultset = new DpResultSet(false, false);
                    resultset.Create(strResultsetFilename,
                        strResultsetFilename + ".index");
                }
            }
            catch (Exception ex)
            {
                strError = (bCreate == true ? "创建" : "打开")
                + "结果集(文件为'" + strResultsetFilename + "')发生错误: " + ex.Message;
                return -1;
            }

            bool bDone = false;
            try
            {
                for (int j = 0; j < aPath.Count; j++)
                {
                    Thread.Sleep(1);
                    DpRecord record = new DpRecord(aPath[j]);
                    if (bInsertAtFirst == true)
                        resultset.Insert(0, record);
                    else
                        resultset.Add(record);
                }

                bDone = true;
            }
            finally
            {
                if (bDone == true || bCreate == false)
                {
                    string strTemp1 = "";
                    string strTemp2 = "";
                    resultset.Detach(out strTemp1,
                        out strTemp2);
                }
                else
                {
                    // 否则文件会被删除
                    resultset.Close();
                }
            }

            return 0;
        }
Beispiel #21
0
        // 从结果集中提取指定范围的记录
        // parameter:
        //		strRanges	范围
        //		strStyle	样式,以逗号分隔,id:表示取id,cols表示取浏览格式,xml表示取xml记录体
        //		strLang     语言版本,用来获得记录路径
        //		richRecords	得到的记录数组,成员为类型为Record
        // result:
        //		-1  出错
        //		>=0	结果集的总数
        public long API_GetRichRecords(
            DpResultSet resultset,
            string strRanges,
            string strLang,
            string strStyle,
            out RichRecord[] richRecords,
            out string strError)
        {
            strError    = "";
            richRecords = null;

            int nCurCount = 0;
            List <RichRecord> aRichRecord = new List <RichRecord>();

            string strFormat = StringUtil.GetStyleParam(strStyle, "format");

            RangeList rangeList = new RangeList(strRanges);

            for (int i = 0; i < rangeList.Count; i++)
            {
                RangeItem rangeItem = (RangeItem)rangeList[i];
                int       nStart    = (int)rangeItem.lStart;
                int       nLength   = (int)rangeItem.lLength;
                if (nLength == 0)
                {
                    continue;
                }

                // long lPos = 0;  // 应该用快速方式,不应用[]??? 2006/3/29

                for (int j = 0; j < nLength; j++)
                {
                    int nRet = 0;

                    DpRecord   dpRecord   = resultset[j + nStart];
                    RichRecord richRecord = new RichRecord();

                    DbPath   dbpath = new DbPath(dpRecord.ID);
                    Database db     = this.app.Dbs.GetDatabaseSafety(dbpath.Name);
                    if (db == null)  //也应放到本条的记录出错信息里
                    {
                        strError = "没有找到数据库'" + dbpath.Name + "',换语言版本时出错";
                        richRecord.Result.Value       = -1;
                        richRecord.Result.ErrorCode   = KernelApplication.Ret2ErrorCode(nRet);
                        richRecord.Result.ErrorString = strError;
                    }
                    else
                    {
                        // 记录路径
                        if (StringUtil.IsInList("id", strStyle, true) == true ||
                            StringUtil.IsInList("path", strStyle, true) == true)
                        {
                            richRecord.Path = db.GetCaptionSafety(strLang) + "/" + dbpath.CompressedID;
                        }

                        // 浏览列
                        if (StringUtil.IsInList("cols", strStyle, true) == true)
                        {
                            string[] cols = null;

                            nRet = db.GetCols(
                                strFormat,
                                dbpath.ID10,
                                "",
                                0,
                                out cols);
                            // 2013/1/14
                            if (nRet == -1)
                            {
                                if (cols != null && cols.Length > 0)
                                {
                                    strError = cols[0];
                                }
                                else
                                {
                                    strError = "GetCols() error";
                                }
                                return(-1);
                            }

                            richRecord.Cols = cols;
                        }

                        bool bXml       = false;
                        bool bTimestamp = false;

                        if (StringUtil.IsInList("xml", strStyle, true) == true)
                        {
                            bXml = true;
                        }

                        if (StringUtil.IsInList("timestamp", strStyle, true) == true)
                        {
                            bTimestamp = true;
                        }

                        if (bXml == true ||
                            bTimestamp == true)
                        {
                            string strGetStyle = "";   //"data,timestamp"; // ,outputpath, metadata

                            if (bTimestamp == true)
                            {
                                StringUtil.SetInList(ref strGetStyle, "timestamp", true);
                            }

                            if (bXml == true)
                            {
                                StringUtil.SetInList(ref strGetStyle, "data", true);
                            }

                            int nStart0      = 0;
                            int nLength0     = -1;
                            int nMaxLength   = 300 * 1024;  // 每次最多获取300K
                            int nTotalLength = 0;

                            string strOutputID = "";

                            byte[] baTotal = null;

                            byte[] baOutputTimestamp = null;
                            int    nAdditionError    = 0;

                            string strMetadata = "";

                            for (; ;)
                            {
                                byte[] baData = null;

                                long lRet = db.GetXml(dbpath.ID,
                                                      "", // strXPath,
                                                      nStart0,
                                                      nLength0,
                                                      nMaxLength,
                                                      strGetStyle,
                                                      out baData,
                                                      out strMetadata,
                                                      out strOutputID,
                                                      out baOutputTimestamp,
                                                      true,
                                                      out nAdditionError,
                                                      out strError);
                                if (lRet <= -1)
                                {
                                    richRecord.Result.Value       = -1;
                                    richRecord.Result.ErrorCode   = KernelApplication.Ret2ErrorCode(nAdditionError); // nRet?
                                    richRecord.Result.ErrorString = strError;
                                    goto CONTINUE;
                                }

                                nTotalLength = (int)lRet;

                                // 如果数据体太大
                                if (nTotalLength > QUOTA_SIZE)
                                {
                                    richRecord.Result.Value       = -1;
                                    richRecord.Result.ErrorCode   = ErrorCodeValue.CommonError;
                                    richRecord.Result.ErrorString = "数据超过1M";
                                    goto CONTINUE;
                                }

                                baTotal = ByteArray.Add(baTotal, baData);

                                nStart0 += baData.Length;

                                if (nStart0 >= nTotalLength)
                                {
                                    break;
                                }
                            }

                            // 记录体
                            // 转换成字符串
                            if (StringUtil.IsInList("xml", strStyle, true) == true)
                            {
                                richRecord.Xml = ByteArray.ToString(baTotal);
                            }

                            // 时间戳?
                            if (StringUtil.IsInList("timestamp", strStyle, true) == true)
                            {
                                richRecord.baTimestamp = baOutputTimestamp;
                            }

                            // string strOutputPath = strDbName + "/" + strOutputID;
                        }

                        // 记录体
                        if (StringUtil.IsInList("xml", strStyle, true) == true)
                        {
                            /*
                             * nRet = db.GetXmlDataSafety(dbpath.ID,
                             *  out richRecord.Xml,
                             *  out strError);
                             * if (nRet <= -1)
                             * {
                             *  richRecord.Result.Value = -1;
                             *  richRecord.Result.ErrorCode = RmswsApplication.Ret2ErrorCode(nRet);
                             *  richRecord.Result.ErrorString = strError;
                             * }
                             * */
                        }
                    }

CONTINUE:

                    aRichRecord.Add(richRecord);

                    Thread.Sleep(0);

                    nCurCount++;

                    // 如果超出最大范围,则停止
                    if (nCurCount >= SessionInfo.MaxRecordsCountPerApi)
                    {
                        break;
                    }
                }
            }

            richRecords = new RichRecord[aRichRecord.Count];
            for (int i = 0; i < richRecords.Length; i++)
            {
                richRecords[i] = aRichRecord[i];
            }

            return(resultset.Count);
        }
Beispiel #22
0
        // 初始化一个读者库的指纹缓存
        // return:
        //      -1  出错
        //      >=0 实际发送给接口程序的事项数目
        int BuildOneDbCache(
            string strReaderDbName,
            out string strError)
        {
            strError = "";
            int nRet = 0;

            DpResultSet resultset = null;
            bool bCreate = false;

            Hashtable timestamp_table = new Hashtable();    // recpath --> fingerprint timestamp

            string strDir = this.MainForm.FingerPrintCacheDir;  // PathUtil.MergePath(this.MainForm.DataDir, "fingerprintcache");
            PathUtil.CreateDirIfNeed(strDir);

            // 结果集文件名
            string strResultsetFilename = PathUtil.MergePath(strDir, strReaderDbName);

            if (File.Exists(strResultsetFilename) == false)
            {
                resultset = new DpResultSet(false, false);
                resultset.Create(strResultsetFilename,
                    strResultsetFilename + ".index");
                bCreate = true;
            }
            else
                bCreate = false;

            // *** 第一阶段, 创建新的结果集文件;或者获取全部读者记录中的指纹时间戳

            bool bDone = false;    // 创建情形下 是否完成了写入操作
            try
            {
                /*
                long lRet = Channel.SearchReader(stop,
        strReaderDbName,
        "1-9999999999",
        -1,
        "__id",
        "left",
        this.Lang,
        null,   // strResultSetName
        "", // strOutputStyle
        out strError);
                */
                long lRet = Channel.SearchReader(stop,
strReaderDbName,
"",
-1,
"指纹时间戳",
"left",
this.Lang,
null,   // strResultSetName
"", // strOutputStyle
out strError);
                if (lRet == -1)
                {
                    if (Channel.ErrorCode == ErrorCode.AccessDenied)
                        strError = "用户 "+Channel.UserName+" 权限不足: " + strError;
                    return -1;
                }

                if (lRet == 0)
                {
                    // TODO: 这时候如果以前有结果集文件还会残留,但不会影响功能正确性,可以改进为把残留的结果集文件删除
                    return 0;
                }

                long lHitCount = lRet;
                stop.SetProgressRange(0, lHitCount);

                long lStart = 0;
                long lCount = lHitCount;
                DigitalPlatform.CirculationClient.localhost.Record[] searchresults = null;

                // 装入浏览格式
                for (; ; )
                {
                    Application.DoEvents();	// 出让界面控制权

                    if (stop != null && stop.State != 0)
                    {
                        strError = "用户中断";
                        return -1;
                    }


                    lRet = Channel.GetSearchResult(
                        stop,
                        null,   // strResultSetName
                        lStart,
                        lCount,
                        bCreate == true ? "id,cols,format:cfgs/browse_fingerprint" : "id,cols,format:cfgs/browse_fingerprinttimestamp",
                        this.Lang,
                        out searchresults,
                        out strError);
                    if (lRet == -1)
                        return -1;

                    if (lRet == 0)
                    {
                        strError = "GetSearchResult() return 0";
                        return -1;
                    }

                    Debug.Assert(searchresults != null, "");
                    Debug.Assert(searchresults.Length > 0, "");

                    for (int i = 0; i < searchresults.Length; i++)
                    {
                        DigitalPlatform.CirculationClient.localhost.Record record = searchresults[i];
                        if (bCreate == true)
                        {
                            if (record.Cols == null || record.Cols.Length < 3)
                            {
                                strError = "record.Cols error ... 有可能是因为读者库缺乏配置文件 cfgs/browse_fingerprint";
                                return -1;
                            }
                            if (string.IsNullOrEmpty(record.Cols[0]) == true)
                                continue;   // 读者记录中没有指纹信息
                            DpRecord item = new DpRecord(record.Path);
                            // timestamp | barcode | fingerprint
                            item.BrowseText = record.Cols[0] + "|" + record.Cols[1] + "|" + record.Cols[2];
                            resultset.Add(item);
                        }
                        else
                        {
                            if (record.Cols == null || record.Cols.Length < 1)
                            {
                                strError = "record.Cols error ... 有可能是因为读者库缺乏配置文件 cfgs/browse_fingerprinttimestamp";
                                return -1;
                            }
                            if (record.Cols.Length < 2)
                            {
                                strError = "record.Cols error ... 需要刷新配置文件 cfgs/browse_fingerprinttimestamp 到最新版本";
                                return -1;
                            }
                            if (string.IsNullOrEmpty(record.Cols[0]) == true)
                                continue;   // 读者记录中没有指纹信息

                            // 记载时间戳
                            // timestamp | barcode 
                            timestamp_table[record.Path] = record.Cols[0] + "|" + record.Cols[1];
                        }
                    }

                    lStart += searchresults.Length;
                    lCount -= searchresults.Length;

                    stop.SetMessage(strReaderDbName + " 包含记录 " + lHitCount.ToString() + " 条,已装入 " + lStart.ToString() + " 条");

                    if (lStart >= lHitCount || lCount <= 0)
                        break;
                    stop.SetProgressValue(lStart);

                }

                if (bCreate == true)
                    bDone = true;

                if (bCreate == true)
                {
                    // return:
                    //      -2  remoting服务器连接失败。驱动程序尚未启动
                    //      -1  出错
                    //      >=0 实际发送给接口程序的事项数目
                    nRet = CreateFingerprintCache(resultset,
    out strError);
                    if (nRet == -1 || nRet == -2)
                        return -1;

                    return nRet;
                }
            }
            finally
            {
                if (bCreate == true)
                {
                    Debug.Assert(resultset != null, "");
                    if (bDone == true)
                    {
                        string strTemp1 = "";
                        string strTemp2 = "";
                        resultset.Detach(out strTemp1,
                            out strTemp2);
                    }
                    else
                    {
                        // 否则文件会被删除
                        resultset.Close();
                    }
                }
            }

            // 比对时间戳,更新结果集文件
            Hashtable update_table = new Hashtable();   // 需要更新的事项。recpath --> 1
            resultset = new DpResultSet(false, false);
            resultset.Attach(strResultsetFilename,
    strResultsetFilename + ".index");
            try
            {
                long nCount = resultset.Count;
                for (long i = 0; i < nCount; i++)
                {
                    DpRecord record = resultset[i];

                    string strRecPath = record.ID;
                    // timestamp | barcode 
                    string strNewTimestamp = (string)timestamp_table[strRecPath];
                    if (strNewTimestamp == null)
                    {
                        // 最新状态下,读者记录已经不存在,需要从结果集中删除
                        resultset.RemoveAt((int)i);
                        i--;
                        nCount--;
                        continue;
                    }

                    // 拆分出证条码号 2013/1/28
                    string strNewBarcode = "";
                    nRet = strNewTimestamp.IndexOf("|");
                    if (nRet != -1)
                    {
                        strNewBarcode = strNewTimestamp.Substring(nRet + 1);
                        strNewTimestamp = strNewTimestamp.Substring(0, nRet);
                    }

                    // 最新读者记录中已经没有指纹信息。例如读者记录中的指纹元素被删除了
                    if (string.IsNullOrEmpty(strNewTimestamp) == true)
                    {
                        // 删除现有事项
                        resultset.RemoveAt((int)i);
                        i--;
                        nCount--;

                        timestamp_table.Remove(strRecPath);
                        continue;
                    }

                    // 取得结果集文件中的原有时间戳字符串
                    string strText = record.BrowseText; // timestamp | barcode | fingerprint
                    nRet = strText.IndexOf("|");
                    if (nRet == -1)
                    {
                        strError = "browsetext 错误,没有 '|' 字符";
                        return -1;
                    }
                    string strOldTimestamp = strText.Substring(0, nRet);
                    // timestamp | barcode | fingerprint
                    string strOldBarcode = strText.Substring(nRet + 1);
                    nRet = strOldBarcode.IndexOf("|");
                    if (nRet != -1)
                    {
                        strOldBarcode = strOldBarcode.Substring(0, nRet);
                    }

                    // 时间戳发生变化,需要更新事项
                    if (strNewTimestamp != strOldTimestamp
                        || strNewBarcode != strOldBarcode)
                    {
                        // 如果证条码号为空,无法建立对照关系,要跳过
                        if (string.IsNullOrEmpty(strNewBarcode) == false)
                            update_table[strRecPath] = 1;

                        // 删除现有事项
                        resultset.RemoveAt((int)i);
                        i--;
                        nCount--;
                    }
                    timestamp_table.Remove(strRecPath);
                }

                // 循环结束后,timestamp_table中剩余的是当前结果集文件中没有包含的那些读者记录路径

                if (update_table.Count > 0)
                {
                    // 获取指纹信息,追加到结果集文件的尾部
                    // parameters:
                    //      update_table   key为读者记录路径
                    nRet = AppendFingerprintInfo(resultset,
                        update_table,
                        out strError);
                    if (nRet == -1)
                        return -1;
                }

                // 如果服务器端新增了指纹信息,需要获取后追加到结果集文件尾部
                if (timestamp_table.Count > 0)
                {
                    // 获取指纹信息,追加到结果集文件的尾部
                    // parameters:
                    //      update_table   key为读者记录路径
                    nRet = AppendFingerprintInfo(resultset,
                        timestamp_table,
                        out strError);
                    if (nRet == -1)
                        return -1;
                }

                // return:
                //      -2  remoting服务器连接失败。驱动程序尚未启动
                //      -1  出错
                //      >=0 实际发送给接口程序的事项数目
                nRet = CreateFingerprintCache(resultset,
            out strError);
                if (nRet == -1 || nRet == -2)
                    return -1;

                return nRet;
            }
            finally
            {
                string strTemp1 = "";
                string strTemp2 = "";
                resultset.Detach(out strTemp1, out strTemp2);
            }
        }