Пример #1
0
        // 进行查重
        // parameters:
        //      sessioninfo 仅仅用来存放DupResultSet,不应该用来sessioninfo.GetChannel(),而要用channel来进行检索操作
        //      channel
        //      strOriginBiblioRecPath  发起的书目记录路径
        //      strOriginBiblioRecXml   发起的书目记录XML
        //      strProjectName  查重方案名
        //      strStyle    includeoriginrecord输出结果中包含发起记录(缺省为不包含)
        // return:
        //      -1  error
        //      0   not found
        //      其他    命中记录条数
        public LibraryServerResult SearchDup(
            SessionInfo sessioninfo1,
            RmsChannel channel,
            string strOriginBiblioRecPath,
            string strOriginBiblioRecXml,
            string strProjectName,
            string strStyle,
            out string strUsedProjectName)
        {
            string strError = "";
            int    nRet     = 0;

            strUsedProjectName = "";

            string strDebugInfo = "";

            strStyle = strStyle.ToLower();
            bool bIncludeOriginRecord = StringUtil.IsInList("includeoriginrecord", strStyle);

            LibraryServerResult result = new LibraryServerResult();

            // 如果没有给出方案名,则需要在<default>元素中找到一个书目库的缺省查重方案
            if (String.IsNullOrEmpty(strProjectName) == true)
            {
                if (String.IsNullOrEmpty(strOriginBiblioRecPath) == true)
                {
                    strError = "既没有给出查重方案名,也没有给出记录路径,无法进行查重";
                    goto ERROR1;
                }
                string strOriginBiblioDbName = ResPath.GetDbName(strOriginBiblioRecPath);

                XmlNode nodeDefault = this.LibraryCfgDom.DocumentElement.SelectSingleNode("//dup/default[@origin='" + strOriginBiblioDbName + "']");
                if (nodeDefault == null)
                {
                    strError = "在没有明确指定查重方案名的情况下,本希望通过相关书目库的缺省查重方案名进行查重。但目前系统没有为书目库 '" + strOriginBiblioDbName + "' 定义缺省查重方案名,无法进行查重";
                    goto ERROR1;
                }

                string strDefaultProjectName = DomUtil.GetAttr(nodeDefault, "project");
                if (String.IsNullOrEmpty(strDefaultProjectName) == true)
                {
                    strError = "书目库 '" + strOriginBiblioDbName + "' 的<default>元素中未定义project属性值";
                    goto ERROR1;
                }

                strProjectName = strDefaultProjectName;
            }

            strUsedProjectName = strProjectName;

            // 获得查重方案定义节点
            // return:
            //      -1  出错
            //      0   not found
            //      1   found
            nRet = GetDupProjectNode(strProjectName,
                                     out XmlNode nodeProject,
                                     out strError);
            if (nRet == 0 || nRet == -1)
            {
                goto ERROR1;
            }

            Debug.Assert(nodeProject != null, "");

            DupResultSet alldatabase_set = null;    // 所有库的结果集

            XmlNodeList nodeDatabases = nodeProject.SelectNodes("database");

            // 循环,针对每个数据库进行检索
            for (int i = 0; i < nodeDatabases.Count; i++)
            {
                XmlNode nodeDatabase    = nodeDatabases[i];
                string  strDatabaseName = DomUtil.GetAttr(nodeDatabase, "name");
                string  strThreshold    = DomUtil.GetAttr(nodeDatabase, "threshold");
                int     nThreshold      = 0;
                try
                {
                    nThreshold = Convert.ToInt32(strThreshold);
                }
                catch
                {
                }

                List <AccessKeyInfo> aKeyLine = null;
                // 模拟创建检索点,以获得检索点列表
                // return:
                //      -1  error
                //      0   succeed
                nRet = GetKeys(
                    // sessioninfo.Channels,
                    channel,
                    strOriginBiblioRecPath,
                    strOriginBiblioRecXml,
                    out aKeyLine,
                    out strError);
                if (nRet == -1)
                {
                    goto ERROR1;
                }

                DupResultSet onedatabase_set = null;    // 一个库的结果集
                try
                {
                    XmlNodeList accesspoints = nodeDatabase.SelectNodes("accessPoint");
                    // <accessPoint>循环
                    for (int j = 0; j < accesspoints.Count; j++)
                    {
                        XmlNode accesspoint = accesspoints[j];

                        string strFrom = DomUtil.GetAttr(accesspoint, "name");

                        // 获得from所对应的key
                        List <string> keys = GetKeyByFrom(aKeyLine,
                                                          strFrom);
                        if (keys.Count == 0)
                        {
                            continue;
                        }

                        string strWeight      = DomUtil.GetAttr(accesspoint, "weight");
                        string strSearchStyle = DomUtil.GetAttr(accesspoint, "searchStyle");

                        int nWeight = 0;
                        try
                        {
                            nWeight = Convert.ToInt32(strWeight);
                        }
                        catch
                        {
                            // 警告定义问题?
                        }

                        for (int k = 0; k < keys.Count; k++)
                        {
                            string strKey = (string)keys[k];
                            if (strKey == "")
                            {
                                continue;
                            }

                            DupResultSet dupset = null;
                            try
                            {
                                // 针对一个from进行检索
                                // return:
                                //      -1  error
                                //      0   not found
                                //      1   found
                                nRet = SearchOneFrom(
                                    // sessioninfo.Channels,
                                    channel,
                                    strDatabaseName,
                                    strFrom,
                                    strKey,
                                    strSearchStyle,
                                    nWeight,
                                    nThreshold,
                                    5000,   // ???
                                    (bIncludeOriginRecord == false) ? strOriginBiblioRecPath : null,
                                    out dupset,
                                    out strError);

                                if (nRet == -1)
                                {
                                    // ??? 警告检索错误?
                                    continue;
                                }

                                if (onedatabase_set == null)
                                {
                                    onedatabase_set = dupset;
                                    dupset          = null; // 避免出 try 范围时被释放。因为内容已经转移给 onedatabase_set 了
                                    continue;
                                }

                                if (nRet == 0)
                                {
                                    continue;
                                }

                                Debug.Assert(dupset != null, "");

                                if (onedatabase_set.Sorted == true)
                                {
                                    onedatabase_set.EnsureCreateIndex(getTempFileName);
                                }
                                else
                                {
                                    onedatabase_set.Sort(getTempFileName);
                                }
                                // dupset.EnsureCreateIndex(getTempFileName);
                                // 2017/4/14
                                dupset.Sort(getTempFileName);   // Sort() 里面自动确保了创建 Index

                                // 将dupset和前一个set归并
                                // 归并可以参考ResultSet中的Merge算法
                                DupResultSet tempset = new DupResultSet();
                                tempset.Open(false, getTempFileName);
                                // 功能: 合并两个数组
                                // parameters:
                                //		strStyle	运算风格 OR , AND , SUB
                                //		sourceLeft	源左边结果集
                                //		sourceRight	源右边结果集
                                //		targetLeft	目标左边结果集
                                //		targetMiddle	目标中间结果集
                                //		targetRight	目标右边结果集
                                //		bOutputDebugInfo	是否输出处理信息
                                //		strDebugInfo	处理信息
                                // return
                                //		-1	出错
                                //		0	成功
                                nRet = DupResultSet.Merge("OR",
                                                          onedatabase_set,
                                                          dupset,
                                                          null, // targetLeft,
                                                          tempset,
                                                          null, // targetRight,
                                                          false,
                                                          out strDebugInfo,
                                                          out strError);
                                if (nRet == -1)
                                {
                                    goto ERROR1;
                                }

                                {
                                    if (onedatabase_set != null)
                                    {
                                        onedatabase_set.Dispose();
                                    }
                                    onedatabase_set        = tempset;
                                    onedatabase_set.Sorted = true;  // 归并后产生的结果集自然是符合顺序的
                                }
                            }
                            finally
                            {
                                if (dupset != null)
                                {
                                    dupset.Dispose();
                                }
                            }
                        } // end of k loop
                    }     // end of j loop


                    if (alldatabase_set == null)
                    {
                        alldatabase_set = onedatabase_set;
                        onedatabase_set = null; // 避免出 try 范围时被释放。因为内容已经转移给 alldatabase_set 了
                        continue;
                    }

                    // 合并
                    if (onedatabase_set != null)
                    {
                        DupResultSet tempset0 = new DupResultSet();
                        tempset0.Open(false, getTempFileName);

                        if (alldatabase_set.Sorted == true)
                        {
                            alldatabase_set.EnsureCreateIndex(getTempFileName);
                        }
                        else
                        {
                            alldatabase_set.Sort(getTempFileName);
                        }
                        // onedatabase_set.EnsureCreateIndex(getTempFileName);
                        // 2017/4/14
                        onedatabase_set.Sort(getTempFileName);   // Sort() 里面自动确保了创建 Index

                        nRet = DupResultSet.Merge("OR",
                                                  alldatabase_set,
                                                  onedatabase_set,
                                                  null, // targetLeft,
                                                  tempset0,
                                                  null, // targetRight,
                                                  false,
                                                  out strDebugInfo,
                                                  out strError);
                        if (nRet == -1)
                        {
                            goto ERROR1;
                        }

                        {
                            if (alldatabase_set != null)
                            {
                                alldatabase_set.Dispose();
                            }

                            alldatabase_set        = tempset0;
                            alldatabase_set.Sorted = true;
                        }
                    }
                }
                finally
                {
                    if (onedatabase_set != null)
                    {
                        onedatabase_set.Dispose();
                    }
                }
            }

            // 最后要按照 Weight和Threshold的差额 对结果集进行排序,便于输出
            if (alldatabase_set != null)
            {
                alldatabase_set.SortStyle = DupResultSetSortStyle.OverThreshold;
                alldatabase_set.Sort(getTempFileName);
            }

            {
                if (sessioninfo1.DupResultSet != null)
                {
                    sessioninfo1.DupResultSet.Dispose();
                }
                sessioninfo1.DupResultSet = alldatabase_set;
            }

            if (alldatabase_set != null)
            {
                result.Value = alldatabase_set.Count;
            }
            else
            {
                result.Value = 0;
            }
            return(result);

ERROR1:
            result.Value     = -1;
            result.ErrorCode = ErrorCode.SystemError;
            result.ErrorInfo = strError;
            return(result);
        }
Пример #2
0
        // 获得查重检索命中结果
        // parameters:
        //      lStart  返回命中结果集起始位置
        //      lCount  返回命中结果集的记录个数
        //      strBrowseInfoStyle  所返回的DupSearchResult中包含哪些信息
        //              "cols"  包含浏览列
        //              "excludecolsoflowthreshold" 不包含权值低于阈值的行的浏览列。要在同时包含cols时才起作用
        //      searchresults   包含记录信息的DupSearchResult数组
        public LibraryServerResult GetDupSearchResult(
            SessionInfo sessioninfo,
            long lStart,
            long lCount,
            string strBrowseInfoStyle,
            out DupSearchResult[] searchresults)
        {
            string strError = "";

            searchresults = null;
            int nRet = 0;

            LibraryServerResult result = new LibraryServerResult();

            RmsChannel channel = sessioninfo.Channels.GetChannel(this.WsUrl);

            if (channel == null)
            {
                strError = "get channel error";
                goto ERROR1;
            }

            DupResultSet dupset = sessioninfo.DupResultSet;

            if (dupset == null)
            {
                strError = "查重结果集不存在";
                goto ERROR1;
            }

            dupset.EnsureCreateIndex(getTempFileName);

            int nCount = (int)lCount;
            int nStart = (int)lStart;

            if (nCount == -1)
            {
                nCount = (int)dupset.Count - nStart;
                if (nCount < 0)
                {
                    nCount = 0;
                }
            }
            else
            {
                if (nCount > (int)dupset.Count - nStart)
                {
                    nCount = (int)dupset.Count - nStart;

                    if (nCount < 0)
                    {
                        nCount = 0;
                    }
                }
            }

            bool bDetail = (StringUtil.IsInList("detail", strBrowseInfoStyle));

            bool bExcludeCols = (StringUtil.IsInList("excludecolsoflowthreshold", strBrowseInfoStyle) == true);

            bool bCols = (StringUtil.IsInList("cols", strBrowseInfoStyle) == true);

            List <string> pathlist = new List <string>();

            List <DupSearchResult> results = new List <DupSearchResult>();

            for (int i = 0; i < nCount; i++)                        // BUG nStart +
            {
                DupLineItem item = (DupLineItem)dupset[nStart + i]; // changed

                DupSearchResult result_item = new DupSearchResult();
                results.Add(result_item);

                result_item.Path      = item.Path;
                result_item.Weight    = item.Weight;
                result_item.Threshold = item.Threshold;
                if (bDetail)
                {
                    result_item.Detail = item.Detail;
                }

                // paths[i] = item.Path;
                if (bCols == true)
                {
                    if (bExcludeCols == true && item.Weight < item.Threshold)
                    {
                    }
                    else
                    {
                        pathlist.Add(item.Path);
                    }
                }
            }

            if (pathlist.Count > 0)
            {
                // string[] paths = new string[pathlist.Count];
                string[] paths = StringUtil.FromListString(pathlist);

                nRet = channel.GetBrowseRecords(paths,
                                                "cols",
                                                out ArrayList aRecord,
                                                out strError);
                if (nRet == -1)
                {
                    strError = "GetBrowseRecords() error: " + strError;
                    goto ERROR1;
                }

                int j = 0;
                for (int i = 0; i < results.Count; i++)
                {
                    DupSearchResult result_item = results[i];
                    if (result_item.Path != pathlist[j])
                    {
                        continue;
                    }

                    string[] cols = (string[])aRecord[j];

                    results[i].Cols = cols;   // style中不包含id
                    j++;
                    if (j >= pathlist.Count)
                    {
                        break;
                    }
                }
            }

            searchresults = new DupSearchResult[results.Count];
            results.CopyTo(searchresults);

            result.Value = searchresults.Length;
            return(result);

ERROR1:
            result.Value     = -1;
            result.ErrorCode = ErrorCode.SystemError;
            result.ErrorInfo = strError;
            return(result);
        }
Пример #3
0
        // 获得实用库信息
        public LibraryServerResult GetUtilInfo(
            SessionInfo sessioninfo,
            string strAction,
            string strDbName,
            string strFrom,
            string strKey,
            string strValueAttrName,
            out string strValue)
        {
            string strError = "";

            strValue = "";
            int nRet = 0;

            LibraryServerResult result = new LibraryServerResult();

            /*
             * if (String.IsNullOrEmpty(strKeyAttrName) == true)
             *  strKeyAttrName = "k";
             * */

            if (String.IsNullOrEmpty(strValueAttrName) == true)
            {
                strValueAttrName = "v";
            }


            RmsChannel channel = sessioninfo.Channels.GetChannel(this.WsUrl);

            if (channel == null)
            {
                strError = "get channel error";
                goto ERROR1;
            }

            string strPath = "";
            string strXml  = "";

            byte[] timestamp = null;

            // 检索实用库记录的路径和记录体
            // return:
            //      -1  error(注:检索命中多条情况被当作错误返回)
            //      0   not found
            //      1   found
            nRet = SearchUtilPathAndRecord(
                // sessioninfo.Channels,
                channel,
                strDbName,
                strKey,
                strFrom,
                out strPath,
                out strXml,
                out timestamp,
                out strError);
            if (nRet == -1)
            {
                goto ERROR1;
            }
            if (nRet == 0)
            {
                result.ErrorCode = ErrorCode.NotFound;
                result.ErrorInfo = "库名为 '" + strDbName + "' 途径为 '" + strFrom + "' 键值为 '" + strKey + "' 的记录没有找到";
                result.Value     = 0;
                return(result);
            }

            // 如果动作为获得整个记录
            if (strAction == "getrecord")
            {
                strValue = strXml;

                result.Value = 1;
                return(result);
            }

            XmlDocument domRecord = new XmlDocument();

            try
            {
                domRecord.LoadXml(strXml);
            }
            catch (Exception ex)
            {
                strError = "装载路径为'" + strPath + "'的xml记录时出错: " + ex.Message;
                goto ERROR1;
            }

            strValue = DomUtil.GetAttr(domRecord.DocumentElement, strValueAttrName);

            result.Value = 1;
            return(result);

ERROR1:
            result.Value     = -1;
            result.ErrorCode = ErrorCode.SystemError;
            result.ErrorInfo = strError;
            return(result);
        }
Пример #4
0
        // 设置实用库信息
        //      strRootElementName  根元素名。如果为空,系统自会用<r>作为根元素
        //      strKeyAttrName  key属性名。如果为空,系统自动会用k
        //      strValueAttrName    value属性名。如果为空,系统自动会用v

        public LibraryServerResult SetUtilInfo(
            SessionInfo sessioninfo,
            string strAction,
            string strDbName,
            string strFrom,
            string strRootElementName,
            string strKeyAttrName,
            string strValueAttrName,
            string strKey,
            string strValue)
        {
            string strError = "";
            int    nRet     = 0;

            LibraryServerResult result = new LibraryServerResult();

            string strPath = "";
            string strXml  = "";

            byte[] timestamp = null;

            bool bRedo = false;

            if (String.IsNullOrEmpty(strRootElementName) == true)
            {
                strRootElementName = "r";   // 最简单的缺省模式
            }
            if (String.IsNullOrEmpty(strKeyAttrName) == true)
            {
                strKeyAttrName = "k";
            }

            if (String.IsNullOrEmpty(strValueAttrName) == true)
            {
                strValueAttrName = "v";
            }

            RmsChannel channel = sessioninfo.Channels.GetChannel(this.WsUrl);

            if (channel == null)
            {
                strError = "get channel error";
                goto ERROR1;
            }

            // 检索实用库记录的路径和记录体
            // return:
            //      -1  error(注:检索命中多条情况被当作错误返回)
            //      0   not found
            //      1   found
            nRet = SearchUtilPathAndRecord(
                // sessioninfo.Channels,
                channel,
                strDbName,
                strKey,
                strFrom,
                out strPath,
                out strXml,
                out timestamp,
                out strError);
            if (nRet == -1)
            {
                goto ERROR1;
            }

            // 如果动作为直接设置整个记录
            if (strAction == "setrecord")
            {
                if (nRet == 0)
                {
                    strPath = strDbName + "/?";
                }

                strXml = strValue;
            }
            else
            {
                // 根据若干信息构造出记录
                if (nRet == 0)
                {
                    strPath = strDbName + "/?";

                    // strXml = "<" + strRootElementName + " " + strKeyAttrName + "='" + strKey + "' " + strValueAttrName + "='" + strValue + "'/>";

                    // 2011/12/11
                    XmlDocument dom = new XmlDocument();
                    dom.LoadXml("<" + strRootElementName + "/>");
                    DomUtil.SetAttr(dom.DocumentElement, strKeyAttrName, strKey);
                    DomUtil.SetAttr(dom.DocumentElement, strValueAttrName, strValue);
                    strXml = dom.DocumentElement.OuterXml;
                }
                else
                {
                    string strPartXml = "/xpath/<locate>@" + strValueAttrName + "</locate><create>@" + strValueAttrName + "</create>";
                    strPath += strPartXml;
                    strXml   = strValue;
                }
            }

#if NO
            RmsChannel channel = sessioninfo.Channels.GetChannel(this.WsUrl);
            if (channel == null)
            {
                strError = "get channel error";
                goto ERROR1;
            }
#endif

            byte[] baOutputTimeStamp = null;
            string strOutputPath     = "";
            int    nRedoCount        = 0;
REDO:
            long lRet = channel.DoSaveTextRes(strPath,
                                              strXml,
                                              false,                  // bInlucdePreamble
                                              "ignorechecktimestamp", // style
                                              timestamp,
                                              out baOutputTimeStamp,
                                              out strOutputPath,
                                              out strError);
            if (lRet == -1)
            {
                if (bRedo == true)
                {
                    if (channel.ErrorCode == ChannelErrorCode.TimestampMismatch &&
                        nRedoCount < 10)
                    {
                        timestamp = baOutputTimeStamp;
                        nRedoCount++;
                        goto REDO;
                    }
                }

                goto ERROR1;
            }

            result.Value = 1;
            return(result);

ERROR1:
            result.Value     = -1;
            result.ErrorCode = ErrorCode.SystemError;
            result.ErrorInfo = strError;
            return(result);
        }
Пример #5
0
        // (根据一定排架体系)检索出某一类的同类书的索取号
        // parameters:
        //      strArrangeGroupName 排架体系名。如果为"!xxx"形式,表示通过馆藏地点名来暗示排架体系名
        public LibraryServerResult SearchOneClassCallNumber(
            SessionInfo sessioninfo,
            string strArrangeGroupName,
            string strClass,
            string strResultSetName,
            out string strQueryXml)
        {
            strQueryXml = "";

            string strError = "";

            LibraryServerResult result = new LibraryServerResult();

            if (String.IsNullOrEmpty(strArrangeGroupName) == true)
            {
                strError = "strArrangeGroupName参数值不能为空";
                goto ERROR1;
            }

            if (strArrangeGroupName[0] == '!')
            {
                string strTemp = GetArrangeGroupName(strArrangeGroupName.Substring(1));

                if (strTemp == null)
                {
                    strError = "馆藏地点名 " + strArrangeGroupName.Substring(1) + " 没有找到对应的排架体系名";
                    goto ERROR1;
                }
                strArrangeGroupName = strTemp;
            }

            // <location>元素数组
            XmlNodeList nodes = this.LibraryCfgDom.DocumentElement.SelectNodes("//callNumber/group[@name='" + strArrangeGroupName + "']/location");

            if (nodes.Count == 0)
            {
                strError = "library.xml中尚未配置有关 '" + strArrangeGroupName + "' 的<callNumber>/<group>/<location>相关参数";
                goto ERROR1;
            }

            string strTargetList = "";

            // 遍历所有实体库
            for (int i = 0; i < this.ItemDbs.Count; i++)
            {
                string strItemDbName = this.ItemDbs[i].DbName;

                if (String.IsNullOrEmpty(strItemDbName) == true)
                {
                    continue;
                }

                if (String.IsNullOrEmpty(strTargetList) == false)
                {
                    strTargetList += ";";
                }
                strTargetList += strItemDbName + ":索取类号";
            }

            int nCount = 0;

            // 构造检索式
            for (int i = 0; i < nodes.Count; i++)
            {
                XmlNode node            = nodes[i];
                string  strLocationName = DomUtil.GetAttr(node, "name");

                if (String.IsNullOrEmpty(strLocationName) == true)
                {
                    continue;
                }

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

                strLocationName = strLocationName.Replace("*", "%");

                /*
                 * strQueryXml += "<item><word>"
                 + StringUtil.GetXmlStringSimple(strLocationName + "|" + strClass)
                 + "</word><match>exact</match><relation>=</relation><dataType>string</dataType><maxCount>-1</maxCount></item><lang>zh</lang>";
                 * */
                strQueryXml += "<item><word>"
                               + StringUtil.GetXmlStringSimple(strLocationName + "|" + strClass + "/")
                               + "</word><match>left</match><relation>=</relation><dataType>string</dataType><maxCount>-1</maxCount></item><lang>zh</lang>";

                nCount++;
            }

            strQueryXml = "<target list='"
                          + StringUtil.GetXmlStringSimple(strTargetList) // 2007/9/14
                          + "'>" + strQueryXml + "</target>";

            RmsChannel channel = sessioninfo.Channels.GetChannel(this.WsUrl);

            if (channel == null)
            {
                strError = "get channel error";
                goto ERROR1;
            }

            long lRet = channel.DoSearch(strQueryXml,
                                         strResultSetName, // "default",
                                         "keyid",          // "", // strOuputStyle
                                         out strError);

            if (lRet == -1)
            {
                goto ERROR1;
            }

            if (lRet == 0)
            {
                result.Value     = 0;
                result.ErrorInfo = "not found";
                result.ErrorCode = ErrorCode.NotFound;
                return(result);
            }


            result.Value = lRet;
            return(result);

ERROR1:
            result.Value     = -1;
            result.ErrorCode = ErrorCode.SystemError;
            result.ErrorInfo = strError;
            return(result);
        }
Пример #6
0
        // 将刚从dt1000升级上来的读者和实体记录进行交叉处理
        // parameters:
        //      nStart      从第几个借阅的册事项开始处理
        //      nCount      共处理几个借阅的册事项
        //      nProcessedBorrowItems   [out]本次处理了多少个借阅册事项
        //      nTotalBorrowItems   [out]当前读者一共包含有多少个借阅册事项
        // result.Value
        //      -1  错误。
        //      0   成功。
        //      1   有警告
        public LibraryServerResult CrossRefBorrowInfo(
            // RmsChannelCollection Channels,
            RmsChannel channel,
            string strReaderBarcode,
            int nStart,
            int nCount,
            out int nProcessedBorrowItems,
            out int nTotalBorrowItems)
        {
            string strError = "";

            nTotalBorrowItems     = 0;
            nProcessedBorrowItems = 0;

            int    nRet       = 0;
            string strWarning = "";
            int    nRedoCount = 0;

            // string strCheckError = "";

            LibraryServerResult result = new LibraryServerResult();

            // int nErrorCount = 0;

REDO_CHANGE_READERREC:

            // 加读者记录锁
#if DEBUG_LOCK_READER
            this.WriteErrorLog("CrossRefBorrowInfo 开始为读者加写锁 '" + strReaderBarcode + "'");
#endif
            this.ReaderLocks.LockForWrite(strReaderBarcode);

            try // 读者记录锁定范围开始
            {
                // 读入读者记录
                string strReaderXml           = "";
                string strOutputReaderRecPath = "";
                byte[] reader_timestamp       = null;
                nRet = this.GetReaderRecXml(
                    // Channels,
                    channel,
                    strReaderBarcode,
                    out strReaderXml,
                    out strOutputReaderRecPath,
                    out reader_timestamp,
                    out strError);
                if (nRet == 0)
                {
                    result.Value     = -1;
                    result.ErrorInfo = "读者证条码号 '" + strReaderBarcode + "' 不存在";
                    result.ErrorCode = ErrorCode.ReaderBarcodeNotFound;
                    return(result);
                }
                if (nRet == -1)
                {
                    strError = "读入读者记录时发生错误: " + strError;
                    goto ERROR1;
                }

                XmlDocument readerdom = null;
                nRet = LibraryApplication.LoadToDom(strReaderXml,
                                                    out readerdom,
                                                    out strError);
                if (nRet == -1)
                {
                    strError = "装载读者记录进入XML DOM时发生错误: " + strError;
                    goto ERROR1;
                }

                bool bReaderRecChanged = false;

                // 修改读者记录中overdues/overdue中的价格单位,并加入id
                // return:
                //      -1  error
                //      0   not changed
                //      1   changed
                nRet = ModifyReaderRecord(
                    ref readerdom,
                    out strWarning,
                    out strError);
                if (nRet == -1)
                {
                    goto ERROR1;
                }
                if (nRet == 1)
                {
                    bReaderRecChanged = true;
                }

                // TODO: strWarning内容如何处理?
                XmlNodeList nodesBorrow = readerdom.DocumentElement.SelectNodes("borrows/borrow");

                nTotalBorrowItems = nodesBorrow.Count;

                if (nTotalBorrowItems == 0)
                {
                    result.Value     = 0;
                    result.ErrorInfo = "读者记录中没有借还信息。";
                    return(result);
                }

                if (nStart >= nTotalBorrowItems)
                {
                    strError = "nStart参数值" + nStart.ToString() + "大于当前读者记录中的借阅册个数" + nTotalBorrowItems.ToString();
                    goto ERROR1;
                }

                nProcessedBorrowItems = 0;
                for (int i = nStart; i < nTotalBorrowItems; i++)
                {
                    if (nCount != -1 && nProcessedBorrowItems >= nCount)
                    {
                        break;
                    }

                    // 一个API最多做10条
                    if (nProcessedBorrowItems >= 10)
                    {
                        break;
                    }

                    XmlNode nodeBorrow = nodesBorrow[i];

                    string strItemBarcode = DomUtil.GetAttr(nodeBorrow, "barcode");

                    nProcessedBorrowItems++;

                    if (String.IsNullOrEmpty(strItemBarcode) == true)
                    {
                        strWarning += "读者记录中<borrow>元素barcode属性值不能为空; ";
                        continue;
                    }

                    string strBorrowDate   = DomUtil.GetAttr(nodeBorrow, "borrowDate");
                    string strBorrowPeriod = DomUtil.GetAttr(nodeBorrow, "borrowPeriod");

                    if (String.IsNullOrEmpty(strBorrowDate) == true)
                    {
                        strWarning += "读者记录中<borrow>元素borrowDate属性不能为空; ";
                        continue;
                    }


                    if (String.IsNullOrEmpty(strBorrowPeriod) == true)
                    {
                        strWarning += "读者记录中<borrow>元素borrowPeriod属性不能为空; ";
                        continue;
                    }

                    // 把实体记录借阅信息详细化
                    // return:
                    //      0   册条码号没有找到对应的册记录
                    //      1   成功
                    nRet = ModifyEntityRecord(
                        // Channels,
                        channel,
                        null,   // strEntityRecPath
                        strItemBarcode,
                        strReaderBarcode,
                        strBorrowDate,
                        strBorrowPeriod,
                        out strError);
                    if (nRet == -1)
                    {
                        strWarning += "ModifyEntityRecord() [strItemBarcode='" + strItemBarcode + "' strReaderBarcode='" + strReaderBarcode + "'] error : " + strError + "; ";
                        continue;
                    }

                    // 2008/10/7
                    if (nRet == 0)
                    {
                        strWarning += "册条码号 '" + strItemBarcode + "' 对应的记录不存在; ";
                        continue;
                    }
                }


                if (bReaderRecChanged == true)
                {
                    byte[] output_timestamp = null;
                    string strOutputPath    = "";

#if NO
                    RmsChannel channel = Channels.GetChannel(this.WsUrl);
                    if (channel == null)
                    {
                        strError = "get channel error";
                        goto ERROR1;
                    }
#endif

                    // 写回读者记录
                    long lRet = channel.DoSaveTextRes(strOutputReaderRecPath,
                                                      readerdom.OuterXml,
                                                      false,
                                                      "content", // ,ignorechecktimestamp
                                                      reader_timestamp,
                                                      out output_timestamp,
                                                      out strOutputPath,
                                                      out strError);
                    if (lRet == -1)
                    {
                        if (channel.ErrorCode == ChannelErrorCode.TimestampMismatch)
                        {
                            nRedoCount++;
                            if (nRedoCount > 10)
                            {
                                strError = "写回读者记录的时候,遇到时间戳冲突,并因此重试10次,仍失败...";
                                goto ERROR1;
                            }
                            goto REDO_CHANGE_READERREC;
                        }
                        goto ERROR1;
                    }

                    // 及时更新时间戳
                    reader_timestamp = output_timestamp;
                }
            }
            finally
            {
                this.ReaderLocks.UnlockForWrite(strReaderBarcode);
#if DEBUG_LOCK_READER
                this.WriteErrorLog("CrossRefBorrowInfo 结束为读者加写锁 '" + strReaderBarcode + "'");
#endif
            }

            if (String.IsNullOrEmpty(strWarning) == false)
            {
                result.Value     = 1;
                result.ErrorInfo = strWarning;
            }
            else
            {
                result.Value = 0;
            }

            return(result);

ERROR1:
            result.Value     = -1;
            result.ErrorInfo = strError;
            result.ErrorCode = ErrorCode.SystemError;
            return(result);
        }
Пример #7
0
        // 获得种次号尾号
        public LibraryServerResult GetOneClassTailNumber(
            SessionInfo sessioninfo,
            string strArrangeGroupName,
            string strClass,
            out string strTailNumber)
        {
            strTailNumber = "";

            string strError = "";

            LibraryServerResult result = new LibraryServerResult();

            if (String.IsNullOrEmpty(strArrangeGroupName) == true)
            {
                strError = "strArrangeGroupName参数值不能为空";
                goto ERROR1;
            }

            RmsChannel channel = sessioninfo.Channels.GetChannel(this.WsUrl);

            if (channel == null)
            {
                strError = "get channel error";
                goto ERROR1;
            }

            string strPath = "";
            string strXml  = "";

            byte[] timestamp = null;
            // 检索尾号记录的路径和记录体
            // return:
            //      -1  error
            //      0   not found
            //      1   found
            int nRet = SearchOneClassTailNumberPathAndRecord(
                // sessioninfo.Channels,
                channel,
                strArrangeGroupName,
                strClass,
                out strPath,
                out strXml,
                out timestamp,
                out strError);

            if (nRet == -1)
            {
                goto ERROR1;
            }

            if (nRet == 0)
            {
                result.ErrorCode = ErrorCode.NotFound;
                result.ErrorInfo = strError;
                result.Value     = 0;
                return(result);
            }

            XmlDocument dom = new XmlDocument();

            try
            {
                dom.LoadXml(strXml);
            }
            catch (Exception ex)
            {
                strError = "尾号记录 '" + strPath + "' XML装入DOM时发生错误: " + ex.Message;
                goto ERROR1;
            }

            strTailNumber = DomUtil.GetAttr(dom.DocumentElement, "v");

            result.Value = 1;
            return(result);

ERROR1:
            result.Value     = -1;
            result.ErrorCode = ErrorCode.SystemError;
            result.ErrorInfo = strError;
            return(result);
        }
Пример #8
0
        // 设置种次号尾号
        public LibraryServerResult SetOneClassTailNumber(
            SessionInfo sessioninfo,
            string strAction,
            string strArrangeGroupName,
            string strClass,
            string strTestNumber,
            out string strOutputNumber)
        {
            strOutputNumber = "";

            string strError = "";

            LibraryServerResult result = new LibraryServerResult();

            RmsChannel channel = sessioninfo.Channels.GetChannel(this.WsUrl);

            if (channel == null)
            {
                strError = "get channel error";
                goto ERROR1;
            }

            string strPath = "";
            string strXml  = "";

            byte[] timestamp = null;
            // 检索尾号记录的路径和记录体
            // return:
            //      -1  error
            //      0   not found
            //      1   found
            int nRet = SearchOneClassTailNumberPathAndRecord(
                // sessioninfo.Channels,
                channel,
                strArrangeGroupName,
                strClass,
                out strPath,
                out strXml,
                out timestamp,
                out strError);

            if (nRet == -1)
            {
                goto ERROR1;
            }

            string strZhongcihaoDbName = GetTailDbName(strArrangeGroupName);

            if (String.IsNullOrEmpty(strZhongcihaoDbName) == true)
            {
                // TODO: 这里报错还需要精确一些,对于带有'!'的馆藏地点名
                strError = "无法通过排架体系名 '" + strArrangeGroupName + "' 获得种次号库名";
                goto ERROR1;
            }

            // byte[] baOutputTimestamp = null;
            bool bNewRecord = false;
            long lRet       = 0;

#if NO
            RmsChannel channel = sessioninfo.Channels.GetChannel(this.WsUrl);
            if (channel == null)
            {
                strError = "get channel error";
                goto ERROR1;
            }
#endif

            byte[] output_timestamp = null;
            string strOutputPath    = "";

            if (strAction == "conditionalpush")
            {
                if (nRet == 0)
                {
                    // 新创建记录
                    strPath = strZhongcihaoDbName + "/?";
                    strXml  = "<r c='" + strClass + "' v='" + strTestNumber + "'/>";

                    bNewRecord = true;
                }
                else
                {
                    string strPartXml = "/xpath/<locate>@v</locate><action>Push</action>";
                    strPath += strPartXml;
                    strXml   = strTestNumber;

                    bNewRecord = false;
                }

                lRet = channel.DoSaveTextRes(strPath,
                                             strXml,
                                             false,
                                             "content",
                                             timestamp, // timestamp,
                                             out output_timestamp,
                                             out strOutputPath,
                                             out strError);
                if (lRet == -1)
                {
                    strError = "保存尾号记录时出错: " + strError;
                    goto ERROR1;
                }

                if (bNewRecord == true)
                {
                    strOutputNumber = strTestNumber;
                }
                else
                {
                    strOutputNumber = strError;
                }

                goto END1;
            }
            else if (strAction == "increase")
            {
                string strDefaultNumber = strTestNumber;

                if (nRet == 0)
                {
                    // 新创建记录
                    strPath = strZhongcihaoDbName + "/?";
                    strXml  = "<r c='" + strClass + "' v='" + strDefaultNumber + "'/>";

                    bNewRecord = true;
                }
                else
                {
                    string strPartXml = "/xpath/<locate>@v</locate><action>+AddInteger</action>";
                    strPath += strPartXml;
                    strXml   = "1";

                    bNewRecord = false;
                }

                //
                lRet = channel.DoSaveTextRes(strPath,
                                             strXml,
                                             false,
                                             "content",
                                             timestamp, // timestamp,
                                             out output_timestamp,
                                             out strOutputPath,
                                             out strError);
                if (lRet == -1)
                {
                    strError = "保存尾号记录时出错: " + strError;
                    goto ERROR1;
                }

                if (bNewRecord == true)
                {
                    strOutputNumber = strDefaultNumber;
                }
                else
                {
                    strOutputNumber = strError;
                }

                goto END1;
            }
            else if (strAction == "save")
            {
                string strTailNumber = strTestNumber;

                if (nRet == 0)
                {
                    strPath = strZhongcihaoDbName + "/?";
                }
                else
                {
                    // 覆盖记录
                    if (String.IsNullOrEmpty(strPath) == true)
                    {
                        strError = "记录存在时strPath居然为空";
                        goto ERROR1;
                    }
                }

                strXml = "<r c='" + strClass + "' v='" + strTailNumber + "'/>";

                lRet = channel.DoSaveTextRes(strPath,
                                             strXml,
                                             false,
                                             "content",
                                             timestamp, // timestamp,
                                             out output_timestamp,
                                             out strOutputPath,
                                             out strError);
                if (lRet == -1)
                {
                    if (channel.ErrorCode == ChannelErrorCode.TimestampMismatch)
                    {
                        strError = "尾号记录时间戳不匹配,说明可能被他人修改过。详细原因: " + strError;
                        goto ERROR1;
                    }

                    strError = "保存尾号记录时出错: " + strError;
                    goto ERROR1;
                }
            }
            else
            {
                strError = "无法识别的strAction参数值 '" + strAction + "'";
                goto ERROR1;
            }

END1:
            result.Value = 1;
            return(result);

ERROR1:
            result.Value     = -1;
            result.ErrorCode = ErrorCode.SystemError;
            result.ErrorInfo = strError;
            return(result);
        }
Пример #9
0
        // 检索同类记录
        public LibraryServerResult SearchUsedZhongcihao(
            SessionInfo sessioninfo,
            string strZhongcihaoGroupName,
            string strClass,
            string strResultSetName,
            out string strQueryXml)
        {
            strQueryXml = "";

            string strError = "";

            LibraryServerResult result = new LibraryServerResult();

            if (String.IsNullOrEmpty(strZhongcihaoGroupName) == true)
            {
                strError = "strZhongcihaoGroupName参数值不能为空";
                goto ERROR1;
            }

            if (strZhongcihaoGroupName[0] == '!')
            {
                string strTemp = GetZhongcihaoGroupName(strZhongcihaoGroupName.Substring(1));

                if (strTemp == null)
                {
                    strError = "书目库名 " + strZhongcihaoGroupName.Substring(1) + " 没有找到对应的种次号组名";
                    goto ERROR1;
                }
                strZhongcihaoGroupName = strTemp;
            }


            XmlNodeList nodes = this.LibraryCfgDom.DocumentElement.SelectNodes("//zhongcihao/group[@name='" + strZhongcihaoGroupName + "']/database");

            if (nodes.Count == 0)
            {
                strError = "library.xml中尚未配置有关 '" + strZhongcihaoGroupName + "'的<zhongcihao>/<group>/<database>相关参数";
                goto ERROR1;
            }

            // 构造检索式
            for (int i = 0; i < nodes.Count; i++)
            {
                XmlNode node      = nodes[i];
                string  strDbName = DomUtil.GetAttr(node, "name");

                if (string.IsNullOrEmpty(strDbName) == true)
                {
                    strError = "<database>元素必须有非空的name属性值";
                    goto ERROR1;
                }

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

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

                strQueryXml += "<target list='"
                               + StringUtil.GetXmlStringSimple(strDbName + ":" + "索取号") // 2007/9/14
                               + "'><item><word>"
                               + StringUtil.GetXmlStringSimple(strClass) + "/"
                               + "</word><match>left</match><relation>=</relation><dataType>string</dataType><maxCount>-1</maxCount></item><lang>zh</lang></target>";
            }

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

            RmsChannel channel = sessioninfo.Channels.GetChannel(this.WsUrl);

            if (channel == null)
            {
                strError = "get channel error";
                goto ERROR1;
            }

            long lRet = channel.DoSearch(strQueryXml,
                                         strResultSetName, // "default",
                                         "keyid",          // strOuputStyle
                                         out strError);

            if (lRet == -1)
            {
                goto ERROR1;
            }

            if (lRet == 0)
            {
                result.Value     = 0;
                result.ErrorInfo = "not found";
                result.ErrorCode = ErrorCode.NotFound;
                return(result);
            }


            result.Value = lRet;
            return(result);

ERROR1:
            result.Value     = -1;
            result.ErrorCode = ErrorCode.SystemError;
            result.ErrorInfo = strError;
            return(result);
        }
Пример #10
0
        // parameters:
        //      strBrowseInfoStyle  返回的特性。cols 返回实体记录的浏览列
        public LibraryServerResult GetCallNumberSearchResult(
            SessionInfo sessioninfo,
            string strArrangeGroupName,
            string strResultSetName,
            long lStart,
            long lCount,
            string strBrowseInfoStyle,
            string strLang,
            out CallNumberSearchResult[] searchresults)
        {
            string strError = "";

            searchresults = null;

            LibraryServerResult result = new LibraryServerResult();
            // int nRet = 0;
            long lRet = 0;

            if (String.IsNullOrEmpty(strArrangeGroupName) == true)
            {
                strError = "strArrangeGroupName参数值不能为空";
                goto ERROR1;
            }

            if (strArrangeGroupName[0] == '!')
            {
                string strTemp = GetArrangeGroupName(strArrangeGroupName.Substring(1));

                if (strTemp == null)
                {
                    strError = "馆藏地点名 " + strArrangeGroupName.Substring(1) + " 没有找到对应的排架体系名";
                    goto ERROR1;
                }
                strArrangeGroupName = strTemp;
            }

            RmsChannel channel = sessioninfo.Channels.GetChannel(this.WsUrl);

            if (channel == null)
            {
                result.Value     = -1;
                result.ErrorInfo = "get channel error";
                result.ErrorCode = ErrorCode.SystemError;
                return(result);
            }


            if (String.IsNullOrEmpty(strResultSetName) == true)
            {
                strResultSetName = "default";
            }

            bool bCols = StringUtil.IsInList("cols", strBrowseInfoStyle);

            string strBrowseStyle = "keyid,id,key";

            if (bCols == true)
            {
                strBrowseStyle += ",cols,format:cfgs/browse_callnumber";
            }

            Record[] origin_searchresults = null; //

            lRet = channel.DoGetSearchResult(
                strResultSetName,
                lStart,
                lCount,
                strBrowseStyle, // "id",
                strLang,
                null,
                out origin_searchresults,
                out strError);
            if (lRet == -1)
            {
                goto ERROR1;
            }

            long lResultCount = lRet;

            searchresults = new CallNumberSearchResult[origin_searchresults.Length];

            for (int i = 0; i < origin_searchresults.Length; i++)
            {
                CallNumberSearchResult item = new CallNumberSearchResult();

                Record record = origin_searchresults[i];
                item.ItemRecPath = record.Path;
                searchresults[i] = item;

                string strLocation = "";
                item.CallNumber = BuildAccessNoKeyString(record.Keys, out strLocation);

                if (bCols == true && record.Cols != null)
                {
                    if (record.Cols.Length > 0)
                    {
                        item.ParentID = record.Cols[0];
                    }
                    if (record.Cols.Length > 1)
                    {
                        item.Location = record.Cols[1];
                    }
                    if (record.Cols.Length > 2)
                    {
                        item.Barcode = record.Cols[2];
                    }
                }

                if (string.IsNullOrEmpty(item.Location) == true)
                {
                    item.Location = strLocation;    // 用从keys中得来的代替。可能有大小写的差异 --- keys中都是大写
                }
#if NO
                if (bCols == true)
                {
                    // 继续填充其余成员
                    string strXml        = "";
                    string strMetaData   = "";
                    byte[] timestamp     = null;
                    string strOutputPath = "";

                    lRet = channel.GetRes(item.ItemRecPath,
                                          out strXml,
                                          out strMetaData,
                                          out timestamp,
                                          out strOutputPath,
                                          out strError);
                    if (lRet == -1)
                    {
                        item.ErrorInfo = "获取记录 '" + item.ItemRecPath + "' 出错: " + strError;
                        continue;
                    }

                    XmlDocument dom = new XmlDocument();
                    try
                    {
                        dom.LoadXml(strXml);
                    }
                    catch (Exception ex)
                    {
                        item.ErrorInfo = "记录 '" + item.ItemRecPath + "' XML装载到DOM时出错: " + ex.Message;
                        continue;
                    }

                    /*
                     * item.CallNumber = DomUtil.GetElementText(dom.DocumentElement,
                     *  "accessNo");
                     * */
                    item.ParentID = DomUtil.GetElementText(dom.DocumentElement,
                                                           "parent");
                    item.Location = DomUtil.GetElementText(dom.DocumentElement,
                                                           "location");
                    item.Barcode = DomUtil.GetElementText(dom.DocumentElement,
                                                          "barcode");
                }
#endif
            }

            result.Value = lResultCount;
            return(result);

ERROR1:
            result.Value     = -1;
            result.ErrorCode = ErrorCode.SystemError;
            result.ErrorInfo = strError;
            return(result);
        }
Пример #11
0
        public LibraryServerResult GetZhongcihaoSearchResult(
            SessionInfo sessioninfo,
            string strZhongcihaoGroupName,
            string strResultSetName,
            long lStart,
            long lCount,
            string strBrowseInfoStyle,
            string strLang,
            out ZhongcihaoSearchResult[] searchresults)
        {
            string strError = "";

            searchresults = null;

            LibraryServerResult result = new LibraryServerResult();
            int  nRet = 0;
            long lRet = 0;

            if (String.IsNullOrEmpty(strZhongcihaoGroupName) == true)
            {
                strError = "strZhongcihaoGroupName参数值不能为空";
                goto ERROR1;
            }

            if (strZhongcihaoGroupName[0] == '!')
            {
                string strTemp = GetZhongcihaoGroupName(strZhongcihaoGroupName.Substring(1));

                if (strTemp == null)
                {
                    strError = "书目库名 " + strZhongcihaoGroupName.Substring(1) + " 没有找到对应的种次号组名";
                    goto ERROR1;
                }
                strZhongcihaoGroupName = strTemp;
            }

            RmsChannel channel = sessioninfo.Channels.GetChannel(this.WsUrl);

            if (channel == null)
            {
                result.Value     = -1;
                result.ErrorInfo = "get channel error";
                result.ErrorCode = ErrorCode.SystemError;
                return(result);
            }

            //
            XmlNode nodeNsTable = this.LibraryCfgDom.DocumentElement.SelectSingleNode("//zhongcihao/nstable");

            XmlNamespaceManager mngr = null;

            if (nodeNsTable != null)
            {
                // 准备名字空间环境
                nRet = PrepareNs(
                    nodeNsTable,
                    out mngr,
                    out strError);
                if (nRet == -1)
                {
                    goto ERROR1;
                }
            }

            // 构造数据库定义和库名的对照表
            XmlNodeList nodes = this.LibraryCfgDom.DocumentElement.SelectNodes("//zhongcihao/group[@name='" + strZhongcihaoGroupName + "']/database");

            if (nodes.Count == 0)
            {
                strError = "library.xml中尚未配置有关 '" + strZhongcihaoGroupName + "'的<zhongcihao>/<group>/<database>相关参数";
                goto ERROR1;
            }

            Hashtable db_prop_table = new Hashtable();

            for (int i = 0; i < nodes.Count; i++)
            {
                XmlNode node = nodes[i];

                DbZhongcihaoProperty prop = new DbZhongcihaoProperty();
                prop.DbName      = DomUtil.GetAttr(node, "name");
                prop.NumberXPath = DomUtil.GetAttr(node, "rightxpath");
                prop.TitleXPath  = DomUtil.GetAttr(node, "titlexpath");
                prop.AuthorXPath = DomUtil.GetAttr(node, "authorxpath");

                db_prop_table[prop.DbName] = prop;
            }

            if (String.IsNullOrEmpty(strResultSetName) == true)
            {
                strResultSetName = "default";
            }

            Record[] origin_searchresults = null; //

            lRet = channel.DoGetSearchResult(
                strResultSetName,
                lStart,
                lCount,
                "id",
                strLang,
                null,
                out origin_searchresults,
                out strError);
            if (lRet == -1)
            {
                goto ERROR1;
            }

            long lResultCount = lRet;

            searchresults = new ZhongcihaoSearchResult[origin_searchresults.Length];

            for (int i = 0; i < origin_searchresults.Length; i++)
            {
                ZhongcihaoSearchResult item = new ZhongcihaoSearchResult();

                item.Path        = origin_searchresults[i].Path;
                searchresults[i] = item;

                // 继续填充其余成员
                string strXml        = "";
                string strMetaData   = "";
                byte[] timestamp     = null;
                string strOutputPath = "";

                lRet = channel.GetRes(item.Path,
                                      out strXml,
                                      out strMetaData,
                                      out timestamp,
                                      out strOutputPath,
                                      out strError);
                if (lRet == -1)
                {
                    item.Zhongcihao = "获取记录 '" + item.Path + "' 出错: " + strError;
                    continue;
                }

                string strDbName = ResPath.GetDbName(item.Path);

                DbZhongcihaoProperty prop = (DbZhongcihaoProperty)db_prop_table[strDbName];
                if (prop == null)
                {
                    item.Zhongcihao = "数据库名 '" + strDbName + "' 不在定义的种次号特性(<zhongcihao>/<group>/<database>)中";
                    continue;
                }

                string strNumber = "";
                string strTitle  = "";
                string strAuthor = "";

                nRet = GetRecordProperties(
                    strXml,
                    prop,
                    mngr,
                    out strNumber,
                    out strTitle,
                    out strAuthor,
                    out strError);
                if (nRet == -1)
                {
                    item.Zhongcihao = strError;
                    continue;
                }

                item.Zhongcihao = strNumber;
                item.Cols       = new string[2];
                item.Cols[0]    = strTitle;
                item.Cols[1]    = strAuthor;
            }


            result.Value = lResultCount;
            return(result);

ERROR1:
            result.Value     = -1;
            result.ErrorCode = ErrorCode.SystemError;
            result.ErrorInfo = strError;
            return(result);
        }
Пример #12
0
        public LibraryServerResult GetZhongcihaoSearchResult(
            SessionInfo sessioninfo,
            string strZhongcihaoGroupName,
            string strResultSetName,
            long lStart,
            long lCount,
            string strBrowseInfoStyle,
            string strLang,
            out ZhongcihaoSearchResult[] searchresults)
        {
            string strError = "";

            searchresults = null;

            LibraryServerResult result = new LibraryServerResult();
            // int nRet = 0;
            long lRet = 0;

            if (String.IsNullOrEmpty(strZhongcihaoGroupName) == true)
            {
                strError = "strZhongcihaoGroupName参数值不能为空";
                goto ERROR1;
            }

            if (strZhongcihaoGroupName[0] == '!')
            {
                string strTemp = GetZhongcihaoGroupName(strZhongcihaoGroupName.Substring(1));

                if (strTemp == null)
                {
                    strError = "书目库名 " + strZhongcihaoGroupName.Substring(1) + " 没有找到对应的种次号组名";
                    goto ERROR1;
                }
                strZhongcihaoGroupName = strTemp;
            }

            RmsChannel channel = sessioninfo.Channels.GetChannel(this.WsUrl);

            if (channel == null)
            {
                result.Value     = -1;
                result.ErrorInfo = "get channel error";
                result.ErrorCode = ErrorCode.SystemError;
                return(result);
            }

            /*
             *
             * //
             * XmlNode nodeNsTable = this.LibraryCfgDom.DocumentElement.SelectSingleNode("//zhongcihao/nstable");
             *
             * XmlNamespaceManager mngr = null;
             *
             * if (nodeNsTable != null)
             * {
             * // 准备名字空间环境
             * nRet = PrepareNs(
             * nodeNsTable,
             * out mngr,
             * out strError);
             * if (nRet == -1)
             * goto ERROR1;
             * }
             *
             * // 构造数据库定义和库名的对照表
             * XmlNodeList nodes = this.LibraryCfgDom.DocumentElement.SelectNodes("//zhongcihao/group[@name='" + strZhongcihaoGroupName + "']/database");
             * if (nodes.Count == 0)
             * {
             * strError = "library.xml中尚未配置有关 '" + strZhongcihaoGroupName + "'的<zhongcihao>/<group>/<database>相关参数";
             * goto ERROR1;
             * }
             *
             * Hashtable db_prop_table = new Hashtable();
             *
             * for (int i = 0; i < nodes.Count; i++)
             * {
             * XmlNode node = nodes[i];
             *
             * DbZhongcihaoProperty prop = new DbZhongcihaoProperty();
             * prop.DbName = DomUtil.GetAttr(node, "name");
             * prop.NumberXPath = DomUtil.GetAttr(node, "rightxpath");
             * prop.TitleXPath = DomUtil.GetAttr(node, "titlexpath");
             * prop.AuthorXPath = DomUtil.GetAttr(node, "authorxpath");
             *
             * db_prop_table[prop.DbName] = prop;
             * }
             * */
            bool   bCols          = (StringUtil.IsInList("cols", strBrowseInfoStyle) == true);
            string strBrowseStyle = "keyid,key,id";

            if (bCols == true)
            {
                strBrowseStyle += ",cols";
            }

            if (String.IsNullOrEmpty(strResultSetName) == true)
            {
                strResultSetName = "default";
            }

            Record[] origin_searchresults = null; //

            lRet = channel.DoGetSearchResult(
                strResultSetName,
                lStart,
                lCount,
                strBrowseStyle, // "id",
                strLang,
                null,
                out origin_searchresults,
                out strError);
            if (lRet == -1)
            {
                goto ERROR1;
            }

            long lResultCount = lRet;

            searchresults = new ZhongcihaoSearchResult[origin_searchresults.Length];

            for (int i = 0; i < origin_searchresults.Length; i++)
            {
                ZhongcihaoSearchResult item = new ZhongcihaoSearchResult();

                Record origin_item = origin_searchresults[i];

                item.Path        = origin_item.Path;
                searchresults[i] = item;
                item.Zhongcihao  = BuildZhongcihaoString(origin_item.Keys);
                item.Cols        = origin_item.Cols;
            }


#if NO
            List <string> pathlist = new List <string>();

            searchresults = new ZhongcihaoSearchResult[origin_searchresults.Length];

            for (int i = 0; i < origin_searchresults.Length; i++)
            {
                ZhongcihaoSearchResult item = new ZhongcihaoSearchResult();

                item.Path        = origin_searchresults[i].Path;
                searchresults[i] = item;
                item.Zhongcihao  = BuildZhongcihaoString(origin_searchresults[i].Keys);

                if (bCols == true)
                {
                    pathlist.Add(item.Path);
                }
            }

            if (pathlist.Count > 0)
            {
                // string[] paths = new string[pathlist.Count];
                string[] paths = StringUtil.FromListString(pathlist);

                ArrayList aRecord = null;

                nRet = channel.GetBrowseRecords(paths,
                                                "cols",
                                                out aRecord,
                                                out strError);
                if (nRet == -1)
                {
                    strError = "GetBrowseRecords() error: " + strError;
                    goto ERROR1;
                }

                int j = 0;
                for (int i = 0; i < searchresults.Length; i++)
                {
                    ZhongcihaoSearchResult result_item = searchresults[i];
                    if (result_item.Path != pathlist[j])
                    {
                        continue;
                    }

                    string[] cols = (string[])aRecord[j];

                    result_item.Cols = cols;   // style中不包含id
                    j++;
                    if (j >= pathlist.Count)
                    {
                        break;
                    }
                }
            }
#endif

            result.Value = lResultCount;
            return(result);

ERROR1:
            result.Value     = -1;
            result.ErrorCode = ErrorCode.SystemError;
            result.ErrorInfo = strError;
            return(result);
        }
Пример #13
0
        void BuildAmerceRecord(XmlDocument domOperLog,
                               out string strBodyXml,
                               out string strReaderBarcode,
                               out string strReaderRefID)
        {
            strBodyXml       = "";
            strReaderBarcode = "";
            strReaderRefID   = "";

            string strError = "";

            // string strOperation = DomUtil.GetElementText(domOperLog.DocumentElement, "operation");
            string strAction      = DomUtil.GetElementText(domOperLog.DocumentElement, "action");
            string strLibraryCode = DomUtil.GetElementText(domOperLog.DocumentElement, "libraryCode");

            string      strReaderRecord = DomUtil.GetElementText(domOperLog.DocumentElement, "readerRecord");
            XmlDocument readerdom       = new XmlDocument();

            readerdom.LoadXml(strReaderRecord);

            strReaderRefID   = DomUtil.GetElementText(readerdom.DocumentElement, "refID");
            strReaderBarcode = DomUtil.GetElementText(readerdom.DocumentElement, "barcode");

            // 构造内容
            XmlDocument bodydom = new XmlDocument();

            bodydom.LoadXml("<root />");

            if (strAction == "amerce")
            {
                DomUtil.SetElementText(bodydom.DocumentElement, "type", "交费");
            }
            else if (strAction == "undo")
            {
                DomUtil.SetElementText(bodydom.DocumentElement, "type", "撤销交费");
            }
            else if (strAction == "modifyprice")
            {
                // DomUtil.SetElementText(bodydom.DocumentElement, "type", "变更交费金额");
                strBodyXml = "";
                return;
            }
            else if (strAction == "expire")
            {
                DomUtil.SetElementText(bodydom.DocumentElement, "type", "以停代金到期");
            }
            else if (strAction == "modifycomment")
            {
                // DomUtil.SetElementText(bodydom.DocumentElement, "type", "修改交费注释");
                strBodyXml = "";
                return;
            }
            else
            {
#if NO
                strError = "无法识别的 strAction '" + strAction + "'";
                throw new Exception(strError);
#endif
                strBodyXml = "";
                return;
            }

            // 复制日志记录中的一级元素
            XmlNodeList nodes = domOperLog.DocumentElement.SelectNodes("*");
            foreach (XmlNode node in nodes)
            {
                if (node.Name == "readerRecord" ||
                    node.Name == "oldReaderRecord" ||
                    node.Name == "expireOverdues" ||
                    node.Name == "amerceItems" ||
                    node.Name == "amerceRecord")
                {
                    continue;
                }

                DomUtil.SetElementText(bodydom.DocumentElement, node.Name, node.InnerText);
            }

            {
                XmlElement record = bodydom.CreateElement("patronRecord");
                bodydom.DocumentElement.AppendChild(record);
                record.InnerXml = readerdom.DocumentElement.InnerXml;

                DomUtil.DeleteElement(record, "borrowHistory");
                DomUtil.DeleteElement(record, "password");
                DomUtil.DeleteElement(record, "fingerprint");
                DomUtil.DeleteElement(record, "face");
                DomUtil.SetElementText(record, "libraryCode", strLibraryCode);
            }

            // items
            XmlElement amerce_items = bodydom.DocumentElement.SelectSingleNode("items") as XmlElement;
            if (amerce_items == null)
            {
                amerce_items = bodydom.CreateElement("items");
                bodydom.DocumentElement.AppendChild(amerce_items);
            }

            XmlNodeList amerce_records = domOperLog.DocumentElement.SelectNodes("amerceRecord");
            foreach (XmlElement amerce_record in amerce_records)
            {
                string strAmercedXml = amerce_record.InnerText;
                if (string.IsNullOrEmpty(strAmercedXml))
                {
                    continue;
                }

                string strOverdueString = "";
                string strTemp          = "";
                int    nRet             = LibraryApplication.ConvertAmerceRecordToOverdueString(strAmercedXml,
                                                                                                out strTemp,
                                                                                                out strOverdueString,
                                                                                                out strError);
                if (nRet == -1)
                {
                    throw new Exception(strError);
                }

                XmlDocumentFragment fragment = bodydom.CreateDocumentFragment();
                fragment.InnerXml = strOverdueString;

                amerce_items.AppendChild(fragment);
            }

            // expire 情况要把 expireOverdues/overdue 翻译为 items/overdue 元素
            if (strAction == "expire")
            {
                XmlElement expireOverdues = domOperLog.DocumentElement.SelectSingleNode("expiredOverdues") as XmlElement;
                if (expireOverdues != null)
                {
                    amerce_items.InnerXml = expireOverdues.InnerXml;
                }
            }
            else
            {
                // 留着 amerceItem 元素做测试对照
            }

            RmsChannel channel = this.RmsChannels.GetChannel(this.App.WsUrl);
            if (channel == null)
            {
                strError = "channel == null";
                throw new Exception(strError);
            }
            // 为 overdue 元素添加 summary 属性
            XmlNodeList overdues = bodydom.DocumentElement.SelectNodes("items/overdue");
            foreach (XmlElement overdue in overdues)
            {
                string strItemBarcode = overdue.GetAttribute("barcode");
                if (string.IsNullOrEmpty(strItemBarcode))
                {
                    continue;
                }

                // 加入书目摘要
                string strSummary          = "";
                string strBiblioRecPath    = "";
                LibraryServerResult result = this.App.GetBiblioSummary(
                    null,
                    channel,
                    strItemBarcode,
                    "", // strItemRecPath,
                    null,
                    out strBiblioRecPath,
                    out strSummary);
                if (result.Value == -1)
                {
                    // strSummary = result.ErrorInfo;
                }
                else
                {
                    overdue.SetAttribute("summary", strSummary);
                }
            }

            strBodyXml = bodydom.DocumentElement.OuterXml;
        }
Пример #14
0
        void BuildBorrowReturnRecord(XmlDocument domOperLog,
                                     out string strBodyXml,
                                     out string strReaderBarcode,
                                     out string strReaderRefID)
        {
            strBodyXml       = "";
            strReaderBarcode = "";
            strReaderRefID   = "";

            string strError = "";

            string strOperation = DomUtil.GetElementText(domOperLog.DocumentElement, "operation");

            string strLibraryCode = DomUtil.GetElementText(domOperLog.DocumentElement, "libraryCode");

            string      strReaderRecord = DomUtil.GetElementText(domOperLog.DocumentElement, "readerRecord");
            XmlDocument readerdom       = new XmlDocument();

            readerdom.LoadXml(strReaderRecord);

            string      strItemRecord = DomUtil.GetElementText(domOperLog.DocumentElement, "itemRecord");
            XmlDocument itemdom       = new XmlDocument();

            itemdom.LoadXml(strItemRecord);

            string     strItemRecPath = "";
            XmlElement item_record    = domOperLog.DocumentElement.SelectSingleNode("itemRecord") as XmlElement;

            if (item_record != null)
            {
                strItemRecPath = item_record.GetAttribute("recPath");
            }

            strReaderRefID   = DomUtil.GetElementText(readerdom.DocumentElement, "refID");
            strReaderBarcode = DomUtil.GetElementText(readerdom.DocumentElement, "barcode");

            // 构造内容
            XmlDocument bodydom = new XmlDocument();

            bodydom.LoadXml("<root />");

            if (strOperation == "borrow")
            {
                DomUtil.SetElementText(bodydom.DocumentElement, "type", "借书成功");
            }
            else if (strOperation == "return")
            {
                DomUtil.SetElementText(bodydom.DocumentElement, "type", "还书成功");
            }
            else
            {
#if NO
                strError = "无法识别的 strOperation '" + strOperation + "'";
                throw new Exception(strError);
#endif
                DomUtil.SetElementText(bodydom.DocumentElement, "type", "修改交费注释");
                strBodyXml = "";
                return;
            }

            // 复制日志记录中的一级元素
            XmlNodeList nodes = domOperLog.DocumentElement.SelectNodes("*");
            foreach (XmlNode node in nodes)
            {
                if (node.Name == "readerRecord" || node.Name == "itemRecord")
                {
                    continue;
                }
                if (node.Name == "type")
                {
                    DomUtil.SetElementText(bodydom.DocumentElement, "bookType", node.InnerText);
                }
                else
                {
                    DomUtil.SetElementText(bodydom.DocumentElement, node.Name, node.InnerText);
                }
            }

            {
                XmlElement record = bodydom.CreateElement("patronRecord");
                bodydom.DocumentElement.AppendChild(record);
                record.InnerXml = readerdom.DocumentElement.InnerXml;

                DomUtil.DeleteElement(record, "borrowHistory");
                DomUtil.DeleteElement(record, "password");
                DomUtil.DeleteElement(record, "fingerprint");
                DomUtil.DeleteElement(record, "face");
                DomUtil.SetElementText(record, "libraryCode", strLibraryCode);
            }

            {
                XmlElement record = bodydom.CreateElement("itemRecord");
                bodydom.DocumentElement.AppendChild(record);
                record.InnerXml = itemdom.DocumentElement.InnerXml;

                string strItemBarcode = DomUtil.GetElementText(itemdom.DocumentElement, "barcode");

                DomUtil.DeleteElement(record, "borrowHistory");
                // 加入书目摘要
                string     strSummary       = "";
                string     strBiblioRecPath = "";
                RmsChannel channel          = this.RmsChannels.GetChannel(this.App.WsUrl);
                if (channel == null)
                {
                    strError = "channel == null";
                    throw new Exception(strError);
                }
                LibraryServerResult result = this.App.GetBiblioSummary(
                    null,
                    channel,
                    strItemBarcode,
                    strItemRecPath,
                    null,
                    out strBiblioRecPath,
                    out strSummary);
                if (result.Value == -1)
                {
                    // strSummary = result.ErrorInfo;
                }
                else
                {
                }

                DomUtil.SetElementText(record, "summary", strSummary);
            }

            strBodyXml = bodydom.DocumentElement.OuterXml;
        }
Пример #15
0
        // 写入一条数据
        // return:
        //      -1  error
        //      0   已经写入
        //      1   没有必要写入
        int WriteOneReaderInfo(
            SessionInfo sessioninfo,
            string strReaderDbName,
            string strZhengyuanXml,
            out string strError)
        {
            strError = "";

            XmlDocument zhengyuandom = new XmlDocument();

            try
            {
                zhengyuandom.LoadXml(strZhengyuanXml);
            }
            catch (Exception ex)
            {
                strError = "从正元数据中读出的XML片段装入DOM失败: " + ex.Message;
                return(-1);
            }

            // AccType
            // 卡户类型
            // 1正式卡,2 临时卡
            string strAccType = DomUtil.GetElementText(zhengyuandom.DocumentElement,
                                                       "ACCTYPE");

            if (strAccType != "1")
            {
                return(1);
            }

            string strBarcode = DomUtil.GetElementText(zhengyuandom.DocumentElement,
                                                       "ACCNUM");

            if (String.IsNullOrEmpty(strBarcode) == true)
            {
                strError = "缺乏<ACCNUM>元素";
                return(-1);
            }

            strBarcode = strBarcode.PadLeft(10, '0');

            int    nRet          = 0;
            string strReaderXml  = "";
            string strOutputPath = "";

            byte[] baTimestamp = null;

            // 加读锁
            // 可以避免拿到读者记录处理中途的临时状态
#if DEBUG_LOCK_READER
            this.App.WriteErrorLog("WriteOneReaderInfo 开始为读者加读锁 '" + strBarcode + "'");
#endif
            this.App.ReaderLocks.LockForRead(strBarcode);

            try
            {
                RmsChannel channel = this.RmsChannels.GetChannel(this.App.WsUrl);
                if (channel == null)
                {
                    strError = "get channel error";
                    return(-1);
                }

                // 获得读者记录
                // return:
                //      -1  error
                //      0   not found
                //      1   命中1条
                //      >1  命中多于1条
                nRet = this.App.GetReaderRecXml(
                    // this.RmsChannels, // sessioninfo.Channels,
                    channel,
                    strBarcode,
                    out strReaderXml,
                    out strOutputPath,
                    out baTimestamp,
                    out strError);
            }
            finally
            {
                this.App.ReaderLocks.UnlockForRead(strBarcode);
#if DEBUG_LOCK_READER
                this.App.WriteErrorLog("WriteOneReaderInfo 结束为读者加读锁 '" + strBarcode + "'");
#endif
            }

            if (nRet == -1)
            {
                return(-1);
            }
            if (nRet > 1)
            {
                strError = "条码号 " + strBarcode + "在读者库群中检索命中 " + nRet.ToString() + " 条,请尽快更正此错误。";
                return(-1);
            }

            string strAction  = "";
            string strRecPath = "";

            string strNewXml = "";  // 修改后的记录

            if (nRet == 0)
            {
                // 没有命中,创建新记录
                strAction    = "new";
                strRecPath   = strReaderDbName + "/?";
                strReaderXml = "";  // 2009/7/17 changed // "<root />";
            }
            else
            {
                Debug.Assert(nRet == 1, "");
                // 命中,修改后覆盖原记录

                strAction  = "change";
                strRecPath = strOutputPath;
            }

            XmlDocument readerdom = new XmlDocument();
            try
            {
                readerdom.LoadXml(strReaderXml);
            }
            catch (Exception ex)
            {
                strError = "读者XML记录装入DOM发生错误: " + ex.Message;
                return(-1);
            }

            nRet = ModifyReaderRecord(ref readerdom,
                                      zhengyuandom,
                                      out strError);
            if (nRet == -1)
            {
                return(-1);
            }

            if (nRet == 1)  // 没有必要写入
            {
                Debug.Assert(strAction == "change", "");
                return(1);
            }

            if (nRet == 2) // 没有必要写入
            {
                return(1);
            }

            strNewXml = readerdom.OuterXml;

            string strExistingXml  = "";
            string strSavedXml     = "";
            string strSavedRecPath = "";
            byte[] baNewTimestamp  = null;
            DigitalPlatform.rms.Client.rmsws_localhost.ErrorCodeValue kernel_errorcode = DigitalPlatform.rms.Client.rmsws_localhost.ErrorCodeValue.NoError;

            LibraryServerResult result = this.App.SetReaderInfo(
                sessioninfo,
                strAction,
                strRecPath,
                strNewXml,
                strReaderXml,
                baTimestamp,
                out strExistingXml,
                out strSavedXml,
                out strSavedRecPath,
                out baNewTimestamp,
                out kernel_errorcode);
            if (result.Value == -1)
            {
                strError = result.ErrorInfo;
                return(-1);
            }



            return(0);   // 正常写入了
        }