Exemple #1
0
        // 检索书目记录下属的实体记录,返回少量必要的信息,可以提供后面实做删除时使用
        // parameters:
        //      strStyle    check_borrow_info,count_borrow_info,return_record_xml
        //                  当包含 check_borrow_info 时,发现第一个流通信息,本函数就立即返回-1
        //                  当包含 count_borrow_info 时,函数要统计全部流通信息的个数
        // return:
        //      -2  not exist entity dbname
        //      -1  error
        //      >=0 含有流通信息的实体记录个数, 当strStyle包含count_borrow_info时。
        public int SearchChildEntities(RmsChannel channel,
            string strBiblioRecPath,
            string strStyle,
            Delegate_checkRecord procCheckRecord,
            object param,
            out long lHitCount,
            out List<DeleteEntityInfo> entityinfos,
            out string strError)
        {
            strError = "";
            lHitCount = 0;
            entityinfos = new List<DeleteEntityInfo>();

            int nRet = 0;

            bool bCheckBorrowInfo = StringUtil.IsInList("check_borrow_info", strStyle);
            bool bCountBorrowInfo = StringUtil.IsInList("count_borrow_info", strStyle);
            bool bReturnRecordXml = StringUtil.IsInList("return_record_xml", strStyle);
            bool bOnlyGetCount = StringUtil.IsInList("only_getcount", strStyle);

            if (bCheckBorrowInfo == true
                && bCountBorrowInfo == true)
            {
                strError = "strStyle中check_borrow_info和count_borrow_info不能同时具备";
                return -1;
            }

            string strBiblioDbName = ResPath.GetDbName(strBiblioRecPath);
            string strBiblioRecId = ResPath.GetRecordId(strBiblioRecPath);

            // 获得书目库对应的实体库名
            string strItemDbName = "";
            nRet = this.GetItemDbName(strBiblioDbName,
                 out strItemDbName,
                 out strError);
            if (nRet == -1)
                goto ERROR1;

            // 2008/12/5 
            if (String.IsNullOrEmpty(strItemDbName) == true)
                return 0;


            // 检索实体库中全部从属于特定id的记录

            string strQueryXml = "<target list='"
                + StringUtil.GetXmlStringSimple(strItemDbName + ":" + "父记录")       // 2007/9/14 
                + "'><item><word>"
                + strBiblioRecId
                + "</word><match>exact</match><relation>=</relation><dataType>string</dataType><maxCount>-1</maxCount></item><lang>" + "zh" + "</lang></target>";

            long lRet = channel.DoSearch(strQueryXml,
                "entities",
                "", // strOuputStyle
                out strError);
            if (lRet == -1)
                goto ERROR1;

            if (lRet == 0)
            {
                strError = "没有找到属于书目记录 '" + strBiblioRecPath + "' 的任何实体记录";
                return 0;
            }

            lHitCount = lRet;

            // 仅返回命中条数
            if (bOnlyGetCount == true)
                return 0;

            int nResultCount = (int)lRet;

            if (nResultCount > 10000)
            {
                strError = "命中册记录数 " + nResultCount.ToString() + " 超过 10000, 暂时不支持针对它们的删除操作";
                goto ERROR1;
            }

            int nBorrowInfoCount = 0;

            int nStart = 0;
            int nPerCount = 100;
            for (; ; )
            {
                List<string> aPath = null;
                lRet = channel.DoGetSearchResult(
                    "entities",
                    nStart,
                    nPerCount,
                    "zh",
                    null,
                    out aPath,
                    out strError);
                if (lRet == -1)
                    goto ERROR1;

                if (aPath.Count == 0)
                {
                    strError = "aPath.Count == 0";
                    goto ERROR1;
                }

                // 获得每条记录
                for (int i = 0; i < aPath.Count; i++)
                {
                    string strMetaData = "";
                    string strXml = "";
                    byte[] timestamp = null;
                    string strOutputPath = "";

                    lRet = channel.GetRes(aPath[i],
                        out strXml,
                        out strMetaData,
                        out timestamp,
                        out strOutputPath,
                        out strError);
                    DeleteEntityInfo entityinfo = new DeleteEntityInfo();

                    if (lRet == -1)
                    {
                        /*
                        entityinfo.RecPath = aPath[i];
                        entityinfo.ErrorCode = channel.OriginErrorCode;
                        entityinfo.ErrorInfo = channel.ErrorInfo;

                        entityinfo.OldRecord = "";
                        entityinfo.OldTimestamp = null;
                        entityinfo.NewRecord = "";
                        entityinfo.NewTimestamp = null;
                        entityinfo.Action = "";
                         * */
                        if (channel.ErrorCode == ChannelErrorCode.NotFound)
                            continue;

                        strError = "获取实体记录 '" + aPath[i] + "' 时发生错误: " + strError;
                        goto ERROR1;
                        // goto CONTINUE;
                    }

                    entityinfo.RecPath = strOutputPath;
                    entityinfo.OldTimestamp = timestamp;
                    if (bReturnRecordXml == true)
                        entityinfo.OldRecord = strXml;

                    if (bCheckBorrowInfo == true
                        || bCountBorrowInfo == true
                        || procCheckRecord != null)
                    {
                        // 检查是否有借阅信息
                        // 把记录装入DOM
                        XmlDocument domExist = new XmlDocument();

                        try
                        {
                            domExist.LoadXml(strXml);
                        }
                        catch (Exception ex)
                        {
                            strError = "实体记录 '" + aPath[i] + "' 装载进入DOM时发生错误: " + ex.Message;
                            goto ERROR1;
                        }

                        if (procCheckRecord != null)
                        {
                            nRet = procCheckRecord(strOutputPath, 
                                domExist, 
                                timestamp, 
                                param,
                                out strError);
                            if (nRet != 0)
                                return nRet;
                        }

                        entityinfo.ItemBarcode = DomUtil.GetElementText(domExist.DocumentElement,
                            "barcode");

                        // TODO: 在日志恢复阶段调用本函数时,是否还有必要检查是否具有流通信息?似乎这时应强制删除为好

                        // 观察已经存在的记录是否有流通信息
                        string strDetail = "";
                        bool bHasCirculationInfo = IsEntityHasCirculationInfo(domExist, out strDetail);


                        if (bHasCirculationInfo == true)
                        {
                            if (bCheckBorrowInfo == true)
                            {
                                strError = "拟删除的册记录 '" + entityinfo.RecPath + "' 中包含有流通信息(" + strDetail + ")(此种情况可能不限于这一条),不能删除。因此全部删除操作均被放弃。";
                                goto ERROR1;
                            }
                            if (bCountBorrowInfo == true)
                                nBorrowInfoCount++;
                        }
                    }

                    // CONTINUE:
                    entityinfos.Add(entityinfo);
                }

                nStart += aPath.Count;
                if (nStart >= nResultCount)
                    break;
            }

            return nBorrowInfoCount;
        ERROR1:
            return -1;
        }
Exemple #2
0
        // 2016/11/15 改造为不用 GetRes() 获取记录
        // 检索书目记录下属的实体记录,返回少量必要的信息,可以提供后面实做删除时使用
        // parameters:
        //      strStyle    check_borrow_info,count_borrow_info,return_record_xml
        //                  当包含 check_borrow_info 时,发现第一个流通信息,本函数就立即返回-1
        //                  当包含 count_borrow_info 时,函数要统计全部流通信息的个数
        //                  当包含 libraryCodes: 时,表示仅获得所列分馆代码的册记录。注意多个馆代码之间用竖线分隔
        //                  当包含 limit: 时,定义最多取得记录的个数。例如希望最多取得 10 条,可以定义 limit:10
        // return:
        //      -2  not exist entity dbname
        //      -1  error
        //      >=0 含有流通信息的实体记录个数, 当strStyle包含count_borrow_info时。
        public int SearchChildEntities(RmsChannel channel,
            string strBiblioRecPath,
            string strStyle,
            Delegate_checkRecord procCheckRecord,
            object param,
            out long lHitCount,
            out List<DeleteEntityInfo> entityinfos,
            out string strError)
        {
            strError = "";
            lHitCount = 0;
            entityinfos = new List<DeleteEntityInfo>();

            int nRet = 0;

            bool bCheckBorrowInfo = StringUtil.IsInList("check_borrow_info", strStyle);
            bool bCountBorrowInfo = StringUtil.IsInList("count_borrow_info", strStyle);
            bool bReturnRecordXml = StringUtil.IsInList("return_record_xml", strStyle);
            bool bOnlyGetCount = StringUtil.IsInList("only_getcount", strStyle);

            if (bCheckBorrowInfo == true
                && bCountBorrowInfo == true)
            {
                strError = "strStyle中check_borrow_info和count_borrow_info不能同时具备";
                return -1;
            }

            string strLibraryCodeParam = StringUtil.GetParameterByPrefix(strStyle, "libraryCodes", ":");
            string strLimit = StringUtil.GetParameterByPrefix(strStyle, "limit", ":");

            string strBiblioDbName = ResPath.GetDbName(strBiblioRecPath);
            string strBiblioRecId = ResPath.GetRecordId(strBiblioRecPath);

            // 获得书目库对应的实体库名
            string strItemDbName = "";
            nRet = this.GetItemDbName(strBiblioDbName,
                 out strItemDbName,
                 out strError);
            if (nRet == -1)
                goto ERROR1;

            // 2008/12/5 
            if (String.IsNullOrEmpty(strItemDbName) == true)
                return 0;

            // 检索实体库中全部从属于特定id的记录
            string strQueryXml = "";
            if (string.IsNullOrEmpty(strLibraryCodeParam) == true)
            {
                strQueryXml = "<target list='"
                    + StringUtil.GetXmlStringSimple(strItemDbName + ":" + "父记录")       // 2007/9/14 
                    + "'><item><word>"
                    + strBiblioRecId
                    + "</word><match>exact</match><relation>=</relation><dataType>string</dataType><maxCount>-1</maxCount></item><lang>" + "zh" + "</lang></target>";
            }
            else
            {
                // 仅仅取得当前用户管辖的分馆的册记录
                List<string> codes = StringUtil.SplitList(strLibraryCodeParam, '|'); // sessioninfo.LibraryCodeList
                foreach (string strCode in codes)
                {
                    string strOneQueryXml = "<target list='"
         + StringUtil.GetXmlStringSimple(strItemDbName + ":" + "父记录+馆藏地点")
         + "'><item><word>"
         + StringUtil.GetXmlStringSimple(strBiblioRecId + "|" + strCode + "/")
         + "</word><match>left</match><relation>=</relation><dataType>string</dataType><maxCount>-1</maxCount></item><lang>" + "zh" + "</lang></target>";
                    if (string.IsNullOrEmpty(strQueryXml) == false)
                    {
                        Debug.Assert(String.IsNullOrEmpty(strQueryXml) == false, "");
                        strQueryXml += "<operator value='OR'/>";
                    }

                    strQueryXml += strOneQueryXml;
                }
                if (codes.Count > 0)
                {
                    strQueryXml = "<group>" + strQueryXml + "</group>";
                }
            }

            long lRet = channel.DoSearch(strQueryXml,
                "entities",
                "", // strOuputStyle
                out strError);
            if (lRet == -1)
                goto ERROR1;

            if (lRet == 0)
            {
                strError = "没有找到属于书目记录 '" + strBiblioRecPath + "' 的任何实体记录";
                return 0;
            }

            lHitCount = lRet;

            // 仅返回命中条数
            if (bOnlyGetCount == true)
                return 0;

            int nResultCount = (int)lRet;

            if (nResultCount > 10000)
            {
                strError = "命中册记录数 " + nResultCount.ToString() + " 超过 10000, 暂时不支持针对它们的删除操作";
                goto ERROR1;
            }

            string strColumnStyle = "id,xml,timestamp";

            int nLimit = -1;
            if (string.IsNullOrEmpty(strLimit) == false)
                Int32.TryParse(strLimit, out nLimit);

            int nBorrowInfoCount = 0;

            int nStart = 0;
            int nPerCount = 100;

            if (nLimit != -1 && nPerCount > nLimit)
                nPerCount = nLimit;
            for (; ; )
            {
#if NO
                List<string> aPath = null;
                lRet = channel.DoGetSearchResult(
                    "entities",
                    nStart,
                    nPerCount,
                    "zh",
                    null,
                    out aPath,
                    out strError);
                if (lRet == -1)
                    goto ERROR1;

                if (aPath.Count == 0)
                {
                    strError = "aPath.Count == 0";
                    goto ERROR1;
                }
#endif
                Record[] searchresults = null;
                lRet = channel.DoGetSearchResult(
    "entities",
    nStart,
    nPerCount,
    strColumnStyle,
    "zh",
    null,
    out searchresults,
    out strError);
                if (lRet == -1)
                    goto ERROR1;
                if (searchresults == null)
                {
                    strError = "searchresults == null";
                    goto ERROR1;
                }
                if (searchresults.Length == 0)
                {
                    strError = "searchresults.Length == 0";
                    goto ERROR1;
                }


                // 获得每条记录
                // for (int i = 0; i < aPath.Count; i++)
                int i = 0;
                foreach (Record record in searchresults)
                {
                    // EntityInfo info = new EntityInfo();
                    // info.OldRecPath = record.Path;

                    string strMetaData = "";
                    string strXml = "";
                    byte[] timestamp = null;
                    string strOutputPath = "";

                    DeleteEntityInfo entityinfo = new DeleteEntityInfo();

                    if (record.RecordBody == null || string.IsNullOrEmpty(record.RecordBody.Xml) == true)
                    {
                        lRet = channel.GetRes(record.Path,
                            out strXml,
                            out strMetaData,
                            out timestamp,
                            out strOutputPath,
                            out strError);
                        if (lRet == -1)
                        {
                            if (channel.ErrorCode == ChannelErrorCode.NotFound)
                                continue;

                            strError = "获取实体记录 '" + record.Path + "' 时发生错误: " + strError;
                            goto ERROR1;
                        }

                    }
                    else
                    {
                        strXml = record.RecordBody.Xml;
                        strOutputPath = record.Path;
                        timestamp = record.RecordBody.Timestamp;
                    }

                    entityinfo.RecPath = strOutputPath;
                    entityinfo.OldTimestamp = timestamp;
                    if (bReturnRecordXml == true)
                        entityinfo.OldRecord = strXml;

                    if (bCheckBorrowInfo == true
                        || bCountBorrowInfo == true
                        || procCheckRecord != null)
                    {
                        // 检查是否有借阅信息
                        // 把记录装入DOM
                        XmlDocument domExist = new XmlDocument();

                        try
                        {
                            domExist.LoadXml(strXml);
                        }
                        catch (Exception ex)
                        {
                            strError = "实体记录 '" + strOutputPath + "' 装载进入DOM时发生错误: " + ex.Message;
                            goto ERROR1;
                        }

                        if (procCheckRecord != null)
                        {
                            nRet = procCheckRecord(
                                nStart + i,
                                strOutputPath,
                                domExist,
                                timestamp,
                                param,
                                out strError);
                            if (nRet != 0)
                                return nRet;
                        }

                        entityinfo.ItemBarcode = DomUtil.GetElementText(domExist.DocumentElement,
                            "barcode");

                        // TODO: 在日志恢复阶段调用本函数时,是否还有必要检查是否具有流通信息?似乎这时应强制删除为好

                        // 观察已经存在的记录是否有流通信息
                        string strDetail = "";
                        bool bHasCirculationInfo = IsEntityHasCirculationInfo(domExist, out strDetail);

                        if (bHasCirculationInfo == true)
                        {
                            if (bCheckBorrowInfo == true)
                            {
                                strError = "拟删除的册记录 '" + entityinfo.RecPath + "' 中包含有流通信息(" + strDetail + ")(此种情况可能不限于这一条),不能删除。因此全部删除操作均被放弃。";
                                goto ERROR1;
                            }
                            if (bCountBorrowInfo == true)
                                nBorrowInfoCount++;
                        }
                    }

                    // CONTINUE:
                    entityinfos.Add(entityinfo);

                    i++;
                }

                nStart += searchresults.Length;
                if (nStart >= nResultCount)
                    break;
                if (nLimit != -1 && nStart >= nLimit)
                    break;
            }

            return nBorrowInfoCount;
        ERROR1:
            return -1;
        }