Beispiel #1
0
        // 构造函数
        // paramter:
        //		dbColl  数据库集合指针
        //		user    帐户对象指针
        //		dom     检索式DOM
        public Query(DatabaseCollection dbColl,
            User user,
            XmlDocument dom)
        {
            m_dbColl = dbColl;
            m_oUser = user;
            m_dom = dom;

            // 从dom里找到warnging的处理级别信息
            string strWarningLevel = "";
            XmlNode nodeWarningLevel = dom.SelectSingleNode("//option");
            if (nodeWarningLevel != null)
                strWarningLevel = DomUtil.GetAttr(nodeWarningLevel, "warning");

            if (StringUtil.RegexCompare(@"\d", strWarningLevel) == true)
                m_nWarningLevel = Convert.ToInt32(strWarningLevel);
        }
Beispiel #2
0
        // 新建数据库
        // parameter:
        //		user	            帐户对象
        //		logicNames	        LogicNameItem数组
        //		strType	            数据库类型,以逗号分隔,可以是file,accout
        //		strSqlDbName    	指定的Sql数据库名称,可以为null,系统自动生成一个,,如果数据库为文为文件型数据库,则认作数据源目录的名称
        //		strKeysDefault  	keys配置信息
        //		strBrowseDefault	browse配置信息
        // return:
        //      -3	在新建库中,发现已经存在同名数据库, 本次不能创建
        //      -2	没有足够的权限
        //      -1	一般性错误,例如输入参数不合法等
        //      0	操作成功
        public int CreateDb(User user,
            LogicNameItem[] logicNames,
            string strType,
            string strSqlDbName,
            string strKeysDefault,
            string strBrowseDefault,
            out string strError)
        {
            strError = "";

            if (strKeysDefault == null)
                strKeysDefault = "";
            if (strBrowseDefault == null)
                strBrowseDefault = "";

            if (strKeysDefault != "")
            {
                XmlDocument dom = new XmlDocument();
                try
                {
                    dom.LoadXml(strKeysDefault);
                }
                catch (Exception ex)
                {
                    strError = "加载keys配置文件内容到dom出错,原因:" + ex.Message;
                    return -1;
                }
            }
            if (strBrowseDefault != "")
            {
                XmlDocument dom = new XmlDocument();
                try
                {
                    dom.LoadXml(strBrowseDefault);
                }
                catch (Exception ex)
                {
                    strError = "加载browse配置文件内容到dom出错,原因:" + ex.Message;
                    return -1;
                }
            }

            string strEnLoginName = "";

            // 可以一个逻辑库名也没有,不出错
            string strLogicNames = "";
            for (int i = 0; i < logicNames.Length; i++)
            {
                string strLang = logicNames[i].Lang;
                string strLogicName = logicNames[i].Value;

                if (strLang.Length != 2
                    && strLang.Length != 5)
                {
                    strError = "语言版本字符串长度只能是2位或者5位,'" + strLang + "'语言版本不合法";
                    return -1;
                }

                if (this.IsExistLogicName(strLogicName, null) == true)
                {
                    strError = "数据库中已存在'" + strLogicName + "'逻辑库名";
                    return -3;  // 已存在相同数据库名
                }
                strLogicNames += "<caption lang='" + strLang + "'>" + strLogicName + "</caption>";
                if (String.Compare(logicNames[i].Lang.Substring(0, 2), "en", true) == 0)
                    strEnLoginName = strLogicName;
            }
            strLogicNames = "<logicname>" + strLogicNames + "</logicname>";

            // 检查当前帐户是否有创建数据库的权限
            string strTempDbName = "test";
            if (logicNames.Length > 0)
                strTempDbName = logicNames[0].Value;
            string strExistRights = "";
            bool bHasRight = user.HasRights(strTempDbName,
                ResType.Database,
                "create",
                out strExistRights);
            if (bHasRight == false)
            {
                strError = "您的帐户名为'" + user.Name + "',对数据库没有'创建(create)'权限,目前的权限值为'" + strExistRights + "'。";
                return -2;  // 权限不够
            }

            //**********对库集合加写锁****************
            m_lock.AcquireWriterLock(m_nTimeOut);
#if DEBUG_LOCK
			this.WriteDebugInfo("CreateDb(),对库集合加写锁。");
#endif
            try
            {
                if (strType == null)
                    strType = "";

                // 得到库的ID
                string strDbID = Convert.ToString(this.GetNewDbID());

                string strPureCfgsDir = "";
                string strTempSqlDbName = "";
                if (strEnLoginName != "")
                {
                    strTempSqlDbName = strEnLoginName + "_db";
                    strPureCfgsDir = strEnLoginName + "_cfgs";
                }
                else
                {
                    strTempSqlDbName = "dprms_" + strDbID + "_db";
                    strPureCfgsDir = "dprms_" + strDbID + "_cfgs";
                }

                if (strSqlDbName == null || strSqlDbName == "")
                    strSqlDbName = strTempSqlDbName;

                if (StringUtil.IsInList("file", strType, true) == false)
                {
                    strSqlDbName = this.GetFinalSqlDbName(strSqlDbName);

                    if (this.IsExistSqlName(strSqlDbName) == true)
                    {
                        strError = "不可能的情况,数据库中已存在'" + strSqlDbName + "'Sql库名";
                        return -1;
                    }

                    if (this.InstanceName != "")
                        strSqlDbName = this.InstanceName + "_" + strSqlDbName;
                }

                string strDataSource = "";
                if (StringUtil.IsInList("file", strType, true) == true)
                {
                    strDataSource = strSqlDbName;

                    strDataSource = this.GetFinalDataSource(strDataSource);

                    if (this.IsExistFileDbSource(strDataSource) == true)
                    {
                        strError = "不可能的情况,数据库中已存在''文件数据目录";
                        return -1;
                    }

                    string strDataDir = this.DataDir + "\\" + strDataSource;
                    if (Directory.Exists(strDataDir) == true)
                    {
                        strError = "不可能的情况,本地不会有重名的目录。";
                        return -1;
                    }

                    Directory.CreateDirectory(strDataDir);
                }

                strPureCfgsDir = this.GetFinalCfgsDir(strPureCfgsDir);
                // 把配置文件目录自动创建好
                string strCfgsDir = this.DataDir + "\\" + strPureCfgsDir + "\\cfgs";
                if (Directory.Exists(strCfgsDir) == true)
                {
                    strError = "服务器已存在'" + strPureCfgsDir + "'配置文件目录,请指定其它的英文逻辑库名。";
                    return -1;
                }

                Directory.CreateDirectory(strCfgsDir);

                string strPureKeysLocalName = "keys.xml";
                string strPureBrowseLocalName = "browse.xml";

                int nRet = 0;

                // 写keys配置文件
                nRet = DatabaseUtil.CreateXmlFile(strCfgsDir + "\\" + strPureKeysLocalName,
                    strKeysDefault,
                    out strError);
                if (nRet == -1)
                    return -1;


                // 写browse配置文件
                nRet = DatabaseUtil.CreateXmlFile(strCfgsDir + "\\" + strPureBrowseLocalName,
                    strBrowseDefault,
                    out strError);
                if (nRet == -1)
                    return -1;

                if (StringUtil.IsInList("file", strType) == true)
                    strSqlDbName = "";

                // 这里发生xml片断可能会有小问题,应当用XmlTextWriter来发生?
                string strDbXml = "<database type='" + strType + "' id='" + strDbID + "' localdir='" + strPureCfgsDir
                    + "' dbo='"+user.Name+"'>"  // dbo参数为2006/7/4增加
                    + "<property>"
                    + strLogicNames
                    + "<datasource>" + strDataSource + "</datasource>"
                    + "<seed>0</seed>"
                    + "<sqlserverdb name='" + strSqlDbName + "'/>"
                    + "</property>"
                    + "<dir name='cfgs' localdir='cfgs'>"
                    + "<file name='keys' localname='" + strPureKeysLocalName + "'/>"
                    + "<file name='browse' localname='" + strPureBrowseLocalName + "'/>"
                    + "</dir>"
                    + "</database>";

                this.NodeDbs.InnerXml = this.NodeDbs.InnerXml + strDbXml;

                XmlNodeList nodeListDb = this.NodeDbs.SelectNodes("database");
                if (nodeListDb.Count == 0)
                {
                    strError = "刚新建数据库,不可能一个数据库都不存在。";
                    return -1;
                }

                // 最后一个库为新建的数据库,加到集合里
                XmlNode nodeDb = nodeListDb[nodeListDb.Count - 1];
                // return:
                //      -1  出错
                //      0   成功
                nRet = this.AddDatabase(nodeDb,
                    out strError);
                if (nRet == -1)
                    return -1;

                // 及时加入dbo特性
                user.AddOwnerDbName(strTempDbName);

                // 及时保存到database.xml
                this.Changed = true;
                this.SaveXml();
            }
            finally
            {
                m_lock.ReleaseWriterLock();
                //***********对库集合解写锁****************
#if DEBUG_LOCK
				this.WriteDebugInfo("CreateDb(),对库集合解写锁。");
#endif
            }
            return 0;
        }
Beispiel #3
0
        // 写入一批 XML 记录
        // 这里利用 WriteXml 实现了基本功能,但速度没有得到优化。派生类可以重写此函数,以求得最快的速度
        // return:
        //      -1  出错
        //      >=0 如果是 rebuildkeys,则返回总共处理的 keys 行数
        public virtual int WriteRecords(
            // SessionInfo sessininfo,
            User oUser,
            List<RecordBody> records,
            string strStyle,
            out List<RecordBody> outputs,
            out string strError)
        {
            strError = "";
            outputs = new List<RecordBody>();

            if (StringUtil.IsInList("rebuildkeys", strStyle) == true)
            {
                strError = "目前 Database::WriteRecords() 尚未实现重建检索点的功能";
                return -1;
            }

            foreach (RecordBody record in records)
            {
                string strPath = record.Path;   // 包括数据库名的路径

                string strDbName = StringUtil.GetFirstPartPath(ref strPath);

                bool bObject = false;
                string strRecordID = "";
                string strObjectID = "";
                string strXPath = "";

                string strFirstPart = StringUtil.GetFirstPartPath(ref strPath);
                //***********吃掉第2层*************
                // 到此为止,strPath不含记录号层了,下级分情况判断
                strRecordID = strFirstPart;
                // 只到记录号层的路径
                if (strPath == "")
                {
                    bObject = false;
                }
                else
                {
                    strFirstPart = StringUtil.GetFirstPartPath(ref strPath);
                    //***********吃掉第2层*************
                    // 到此为止,strPath不含object或xpath层 strFirstPart可能是object 或 xpath

                    if (strFirstPart != "object"
        && strFirstPart != "xpath")
                    {
                        record.Result.Value = -1;
                        record.Result.ErrorString = "资源路径 '" + record.Path + "' 不合法, 第3级必须是 'object' 或 'xpath' ";
                        record.Result.ErrorCode = ErrorCodeValue.PathError; // -7;
                        continue;
                    }
                    if (string.IsNullOrEmpty(strPath) == true)  //object或xpath下级必须有值
                    {
                        record.Result.Value = -1;
                        record.Result.ErrorString = "资源路径 '" + record.Path + "' 不合法,当第3级是 'object' 或 'xpath' 时,第4级必须有内容";
                        record.Result.ErrorCode = ErrorCodeValue.PathError; // -7;
                        continue;
                    }

                    if (strFirstPart == "object")
                    {
                        strObjectID = strPath;
                        bObject = true;
                    }
                    else
                    {
                        strXPath = strPath;
                        bObject = false;
                    }
                }

                if (bObject == true)
                {
                    record.Result.Value = -1;
                    record.Result.ErrorString = "目前不允许用 WriteRecords 写入对象资源";
                    record.Result.ErrorCode = ErrorCodeValue.CommonError;
                    continue;
                }

                byte[] baContent = Encoding.UTF8.GetBytes(record.Xml);
                string strRanges = "0-" + (baContent.Length - 1).ToString();

                byte[] outputTimestamp = null;
                string strOutputID = "";
                string strOutputValue = "";

                int nRet = WriteXml(oUser,
                strRecordID,
                strXPath,
                strRanges,
                baContent.Length,
                baContent,
                record.Metadata,
                strStyle,
                record.Timestamp,
            out outputTimestamp,
            out strOutputID,
            out strOutputValue,
            false,
            out strError);
                if (nRet <= -1)
                {
                    record.Result.Value = -1;
                    record.Result.ErrorCode = KernelApplication.Ret2ErrorCode(nRet);
                    record.Result.ErrorString = strError;
                }
                else
                {
                    if (string.IsNullOrEmpty(strXPath) == true)
                        record.Path = strDbName + "/" + strOutputID;
                    else
                        record.Path = strDbName + "/" + strOutputID + "/xpath/" + strXPath;
                    record.Result.Value = nRet;
                    record.Result.ErrorCode = ErrorCodeValue.NoError;
                    record.Result.ErrorString = strOutputValue;
                }

                record.Timestamp = outputTimestamp;
                record.Metadata = null;
                record.Xml = null;

                outputs.Add(record);
            }

            return 0;
        }
Beispiel #4
0
        // 写xml数据
        // parameter:
        //		strID           记录ID -1:表示追加一条记录
        //		strRanges       目标的位置,多个range用逗号分隔
        //		nTotalLength    总长度
        //		inputTimestamp  输入的时间戳
        //		outputTimestamp 返回的时间戳
        //		strOutputID     返回的记录ID,当strID == -1时,得到实际的ID
        //		strError        
        // return:
        //		-1  出错
        //		-2  时间戳不匹配
        //      -4  记录不存在
        //      -6  权限不够
        //		0   成功
        public override int WriteXml(User oUser,  //null,则不检索权限
            string strID,
            string strXPath,
            string strRanges,
            long lTotalLength,
            byte[] baSource,
            Stream streamSource,
            string strMetadata,
            string strStyle,
            byte[] inputTimestamp,
            out byte[] outputTimestamp,
            out string strOutputID,
            out string strOutputValue,   //当AddInteger 或 AppendString时 返回值最后的值
            bool bCheckAccount,
            out string strError)
        {
            strOutputValue = "";
            outputTimestamp = null;
            strOutputID = "";
            strError = "";

            if (strID == "?")
                strID = "-1";

            bool bPushTailNo = false;
            strID = this.EnsureID(strID,
                out bPushTailNo);  //加好写锁
            if (oUser != null)
            {
                string strTempRecordPath = this.GetCaption("zh-cn") + "/" + strID;
                if (bPushTailNo == true)
                {
                    string strExistRights = "";
                    bool bHasRight = oUser.HasRights(strTempRecordPath,
                        ResType.Record,
                        "create",//"append",
                        out strExistRights);
                    if (bHasRight == false)
                    {
                        strError = "您的帐户名为'" + oUser.Name + "',对'" + strTempRecordPath + "'记录没有'创建(create)'权限,目前的权限值为'" + strExistRights + "'。";
                        return -6;
                    }
                }
                else
                {
                    string strExistRights = "";
                    bool bHasRight = oUser.HasRights(strTempRecordPath,
                        ResType.Record,
                        "overwrite",
                        out strExistRights);
                    if (bHasRight == false)
                    {
                        strError = "您的帐户名为'" + oUser.Name + "',对'" + strTempRecordPath + "'记录没有'覆盖(overwrite)'权限,目前的权限值为'" + strExistRights + "'。";
                        return -6;
                    }
                }
            }

            strOutputID = DbPath.GetCompressedID(strID);
            int nRet = 0;

            bool bFull = false;
            //*********对数据库加读锁*************
            m_lock.AcquireReaderLock(m_nTimeOut);

#if DEBUG_LOCK_SQLDATABASE
			this.container.WriteDebugInfo("WriteXml(),对'" + this.GetCaption("zh-cn") + "'数据库加读锁。");
#endif
            try
            {
                strID = DbPath.GetID10(strID);
                //**********对记录加写锁***************
                this.m_recordLockColl.LockForWrite(strID, m_nTimeOut);
#if DEBUG_LOCK_SQLDATABASE
				this.container.WriteDebugInfo("WriteXml(),对'" + this.GetCaption("zh-cn") + "/" + strID + "'记录加写锁。");
#endif
                try // 记录锁
                {

                    SqlConnection connection = new SqlConnection(this.m_strConnString);
                    connection.Open();
                    try // 连接
                    {
                        // 1.如果记录不存在,插入一条字节的记录,以确保得到textPtr
                        // return:
                        //		-1  出错
                        //      0   不存在
                        //      1   存在
                        nRet = this.RecordIsExist(connection,
                            strID,
                            out strError);
                        if (nRet == -1)
                            return -1;

                        bool bExist = false;
                        if (nRet == 1)
                            bExist = true;

                        // 新记录时,插入一个字节,并生成新时间戳
                        if (bExist == false)
                        {
                            byte[] tempInputTimestamp = inputTimestamp;
                            // 注意新记录的时间戳,用inputTimestamp变量
                            nRet = this.InsertRecord(connection,
                                strID,
                                out inputTimestamp,//tempTimestamp,//
                                out strError);

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


                        // 写数据
                        // return:
                        //		-1	一般性错误
                        //		-2	时间戳不匹配
                        //		0	成功
                        nRet = this.WriteSqlRecord(connection,
                            strID,
                            strRanges,
                            (int)lTotalLength,
                            baSource,
                            streamSource,
                            strMetadata,
                            strStyle,
                            inputTimestamp,
                            out outputTimestamp,
                            out bFull,
                            out strError);
                        if (nRet <= -1)
                            return nRet;

                        // 检查范围
                        //string strCurrentRange = this.GetRange(connection,
                        //	strID);
                        if (bFull == true)  //覆盖完了
                        {
                            byte[] baOldPreamble = new byte[0];
                            byte[] baNewPreamble = new byte[0];

                            // 1.得到新旧检索点
                            string strOldXml = "";
                            if (bExist == true)
                            {
                                // return:
                                //      -1  出错
                                //      -4  记录不存在
                                //      0   正确
                                nRet = this.GetXmlData(
                                    connection,
                                    strID,
                                    "data",
                                    out strOldXml,
                                    out baOldPreamble,
                                    out strError);
                                if (nRet <= -1 && nRet != -3)
                                    return nRet;
                            }

                            string strNewXml = "";
                            // return:
                            //      -1  出错
                            //      -4  记录不存在
                            //      0   正确
                            nRet = this.GetXmlData(
                                connection,
                                strID,
                                "newdata",
                                out strNewXml,
                                out baNewPreamble,
                                out strError);
                            if (nRet == -1)
                                return -1;

                            // 修改部分
                            if (strXPath != null
                                && strXPath != "")
                            {
                                string strLocateXPath = "";
                                string strCreatePath = "";
                                string strNewRecordTemplate = "";
                                string strAction = "";
                                nRet = DatabaseUtil.PaseXPathParameter(strXPath,
                                    out strLocateXPath,
                                    out strCreatePath,
                                    out strNewRecordTemplate,
                                    out strAction,
                                    out strError);
                                if (nRet == -1)
                                    return -1;

                                XmlDocument tempDom = new XmlDocument();
                                tempDom.PreserveWhitespace = true; //设PreserveWhitespace为true

                                try
                                {
                                    if (strOldXml == "")
                                    {
                                        if (strNewRecordTemplate == "")
                                            tempDom.LoadXml("<root/>");
                                        else
                                            tempDom.LoadXml(strNewRecordTemplate);
                                    }
                                    else
                                        tempDom.LoadXml(strOldXml);
                                }
                                catch (Exception ex)
                                {
                                    strError = "WriteXml() 在给'" + this.GetCaption("zh-cn") + "'库写入记录'" + strID + "'时,装载旧记录到dom出错,原因:" + ex.Message;
                                    return -1;
                                }


                                if (strLocateXPath == "")
                                {
                                    strError = "xpath表达式中的locate参数不能为空值";
                                    return -1;
                                }

                                // 通过strLocateXPath定位到指定的节点
                                XmlNode node = null;
                                try
                                {
                                    node = tempDom.DocumentElement.SelectSingleNode(strLocateXPath);
                                }
                                catch (Exception ex)
                                {
                                    strError = "WriteXml() 在给'" + this.GetCaption("zh-cn") + "'库写入记录'" + strID + "'时,XPath式子'" + strXPath + "'选择元素时出错,原因:" + ex.Message;
                                    return -1;
                                }



                                if (node == null)
                                {
                                    if (strCreatePath == "")
                                    {
                                        strError = "给'" + this.GetCaption("zh-cn") + "'库写入记录'" + strID + "'时,XPath式子'" + strXPath + "'指定的节点未找到。此时xpath表达式中的create参数不能为空值";
                                        return -1;
                                    }

                                    node = DomUtil.CreateNodeByPath(tempDom.DocumentElement,
                                        strCreatePath);
                                    if (node == null)
                                    {
                                        strError = "内部错误!";
                                        return -1;
                                    }

                                }

                                if (node.NodeType == XmlNodeType.Attribute)
                                {

                                    if (strAction == "AddInteger"
                                        || strAction == "+AddInteger"
                                        || strAction == "AddInteger+")
                                    {
                                        int nNumber = 0;
                                        try
                                        {
                                            nNumber = Convert.ToInt32(strNewXml);
                                        }
                                        catch (Exception ex)
                                        {
                                            strError = "传入的内容'" + strNewXml + "'不是数字格式。" + ex.Message;
                                            return -1;
                                        }

                                        string strOldValue = node.Value;
                                        string strLastValue;
                                        nRet = StringUtil.IncreaseNumber(strOldValue,
                                            nNumber,
                                            out strLastValue,
                                            out strError);
                                        if (nRet == -1)
                                            return -1;

                                        if (strAction == "AddInteger+")
                                        {
                                            strOutputValue = node.Value;
                                        }
                                        else
                                        {
                                            strOutputValue = strLastValue;
                                        }

                                        node.Value = strLastValue;
                                        //strOutputValue = node.Value;
                                    }
                                    else if (strAction == "AppendString")
                                    {

                                        node.Value = node.Value + strNewXml;
                                        strOutputValue = node.Value;
                                    }
                                    else if (strAction == "Push")
                                    {
                                        string strLastValue;
                                        nRet = StringUtil.GetBiggerLedNumber(node.Value,
                                            strNewXml,
                                            out strLastValue,
                                            out strError);
                                        if (nRet == -1)
                                            return -1;

                                        node.Value = strLastValue;
                                        strOutputValue = node.Value;
                                    }
                                    else
                                    {
                                        node.Value = strNewXml;
                                        strOutputValue = node.Value;
                                    }
                                }
                                else if (node.NodeType == XmlNodeType.Element)
                                {

                                    //Create a document fragment.
                                    XmlDocumentFragment docFrag = tempDom.CreateDocumentFragment();

                                    //Set the contents of the document fragment.
                                    docFrag.InnerXml = strNewXml;

                                    //Add the children of the document fragment to the
                                    //original document.
                                    node.ParentNode.InsertBefore(docFrag, node);

                                    if (strAction == "AddInteger"
                                        || strAction == "AppendString")
                                    {
                                        XmlNode newNode = node.PreviousSibling;
                                        if (newNode == null)
                                        {
                                            strError = "newNode不可能为null";
                                            return -1;
                                        }

                                        string strNewValue = newNode.InnerText;
                                        string strOldValue = DomUtil.GetNodeText(node);
                                        if (strAction == "AddInteger")
                                        {


                                            int nNumber = 0;
                                            try
                                            {
                                                nNumber = Convert.ToInt32(strNewValue);
                                            }
                                            catch (Exception ex)
                                            {
                                                strError = "传入的内容'" + strNewValue + "'不是数字格式。" + ex.Message;
                                                return -1;
                                            }


                                            string strLastValue;
                                            nRet = StringUtil.IncreaseNumber(strOldValue,
                                                nNumber,
                                                out strLastValue,
                                                out strError);
                                            if (nRet == -1)
                                                return -1;
                                            /*
                                                                                    string strLastValue;
                                                                                    nRet = Database.AddInteger(strNewValue,
                                                                                        strOldValue,
                                                                                        out strLastValue,
                                                                                        out strError);
                                                                                    if (nRet == -1)
                                                                                        return -1;
                                            */
                                            newNode.InnerText = strLastValue;
                                            strOutputValue = newNode.OuterXml;
                                        }
                                        else if (strAction == "AppendString")
                                        {
                                            newNode.InnerText = strOldValue + strNewValue;
                                            strOutputValue = newNode.OuterXml;
                                        }
                                        else if (strAction == "Push")
                                        {
                                            string strLastValue;
                                            nRet = StringUtil.GetBiggerLedNumber(strOldValue,
                                                strNewValue,
                                                out strLastValue,
                                                out strError);
                                            if (nRet == -1)
                                                return -1;

                                            newNode.InnerText = strLastValue;
                                            strOutputValue = newNode.OuterXml;
                                        }
                                    }

                                    node.ParentNode.RemoveChild(node);

                                }

                                strNewXml = tempDom.OuterXml;

                                byte[] baRealXml =
                                    DatabaseUtil.StringToByteArray(
                                    strNewXml,
                                    baNewPreamble);

                                string strMyRange = "";
                                strMyRange = "0-" + Convert.ToString(baRealXml.Length - 1);
                                lTotalLength = baRealXml.Length;

                                // return:
                                //		-1	一般性错误
                                //		-2	时间戳不匹配
                                //		0	成功
                                nRet = this.WriteSqlRecord(connection,
                                    strID,
                                    strMyRange,
                                    (int)lTotalLength,
                                    baRealXml,
                                    null,
                                    strMetadata,
                                    strStyle,
                                    outputTimestamp,   //注意这儿
                                    out outputTimestamp,
                                    out bFull,
                                    out strError);
                                if (nRet <= -1)
                                    return nRet;
                            }




                            KeyCollection newKeys = null;
                            KeyCollection oldKeys = null;
                            XmlDocument newDom = null;
                            XmlDocument oldDom = null;

                            // return:
                            //      -1  出错
                            //      0   成功
                            nRet = this.MergeKeys(strID,
                                strNewXml,
                                strOldXml,
                                true,
                                out newKeys,
                                out oldKeys,
                                out newDom,
                                out oldDom,
                                out strError);
                            if (nRet == -1)
                                return -1;

                            // 处理检索点
                            // return:
                            //      -1  出错
                            //      0   成功
                            nRet = this.ModifyKeys(connection,
                                newKeys,
                                oldKeys,
                                out strError);
                            if (nRet == -1)
                                return -1;

                            // 处理子文件
                            // return:
                            //      -1  出错
                            //      0   成功
                            nRet = this.ModifyFiles(connection,
                                strID,
                                newDom,
                                oldDom,
                                out strError);
                            if (nRet == -1)
                                return -1;

                            // 4.用new更新data
                            // return:
                            //      -1  出错
                            //      >=0   成功 返回影响的记录数
                            nRet = this.UpdateDataField(connection,
                                strID,
                                out strError);
                            if (nRet == -1)
                                return -1;

                            // 5.删除newdata字段
                            // return:
                            //		-1  出错
                            //		0   成功
                            nRet = this.DeleteDuoYuImage(connection,
                                strID,
                                "newdata",
                                0,
                                out strError);
                            if (nRet == -1)
                                return -1;
                        }
                    }
                    catch (SqlException sqlEx)
                    {
                        if (sqlEx.Errors is SqlErrorCollection)
                            strError = "数据库'" + this.GetCaption("zh") + "'尚未初始化。";
                        else
                            strError = "WriteXml() 在给'" + this.GetCaption("zh-cn") + "'库写入记录'" + strID + "'时出错,原因:" + sqlEx.Message;
                        return -1;
                    }
                    catch (Exception ex)
                    {
                        strError = "WriteXml() 在给'" + this.GetCaption("zh-cn") + "'库写入记录'" + strID + "'时出错,原因:" + ex.Message;
                        return -1;
                    }
                    finally // 连接
                    {
                        connection.Close();
                    }
                }
                finally  // 记录锁
                {
                    //******对记录解写锁****************************
                    m_recordLockColl.UnlockForWrite(strID);
#if DEBUG_LOCK_SQLDATABASE
					this.container.WriteDebugInfo("WriteXml(),对'" + this.GetCaption("zh-cn") + "/" + strID + "'记录解写锁。");
#endif
                }
            }
            finally
            {
                //********对数据库解读锁****************
                m_lock.ReleaseReaderLock();
#if DEBUG_LOCK_SQLDATABASE
				this.container.WriteDebugInfo("WriteXml(),对'" + this.GetCaption("zh-cn") + "'数据库解读锁。");
#endif
            }


            // 当本函数被明知为账户库的写操作调用时, 一定要用bCheckAccount==false
            // 来调用,否则容易引起不必要的递归
            if (bFull == true
                && bCheckAccount == true
                && StringUtil.IsInList("account", this.TypeSafety) == true)
            {
                string strResPath = this.FullID + "/" + strID;

                this.container.UserColl.RefreshUserSafety(strResPath);
            }

            return 0;
        }
Beispiel #5
0
        // 写对象
        //		strRecordID	记录ID
        //		strObjectID	资源ID
        //		strRanges	范围
        //		nTotalLength	总长度
        //		sourceBuffer	源数据
        //		strMetadata	元数据
        //		strStyle	样式
        //		inputTimestamp	输入的时间戳
        //		outputTimestamp	out参数,返回的时间戳
        // return:
        //		-1  出错
        //		-2  时间戳不匹配
        //      -4  记录或对象资源不存在
        //      -6  权限不够
        //		0   成功
        public override int WriteObject(User user,
            string strRecordID,
            string strObjectID,
            string strRanges,
            long lTotalLength,
            byte[] baSource,
            // Stream streamSource,
            string strMetadata,
            string strStyle,
            byte[] inputTimestamp,
            out byte[] outputTimestamp,
            out string strError)
        {
            outputTimestamp = null;
            strError = "";
            int nRet = 0;

            if (user != null)
            {
                string strTempRecordPath = this.GetCaption("zh-CN") + "/" + strRecordID;
                string strExistRights = "";
                bool bHasRight = user.HasRights(strTempRecordPath,
                    ResType.Record,
                    "overwrite",
                    out strExistRights);
                if (bHasRight == false)
                {
                    strError = "您的帐户名为'" + user.Name + "',对'" + strTempRecordPath + "'记录没有'覆盖(overwrite)'权限,目前的权限值为'" + strExistRights + "'。";
                    return -6;
                }
            }

            //**********对数据库加读锁************
            m_db_lock.AcquireReaderLock(m_nTimeOut);
#if DEBUG_LOCK
			this.container.WriteDebugInfo("WriteObject(),对'" + this.GetCaption("zh-CN") + "'数据库加读锁。");
#endif
            try
            {
                string strOutputRecordID = "";
                // return:
                //      -1  出错
                //      0   成功
                nRet = this.CanonicalizeRecordID(strRecordID,
                    out strOutputRecordID,
                    out strError);
                if (nRet == -1)
                    return -1;
                if (strOutputRecordID == "-1")
                {
                    strError = "保存对象资源不支持记录号参数值为'" + strRecordID + "'。";
                    return -1;
                }
                strRecordID = strOutputRecordID;

                //**********对记录加写锁***************
                m_recordLockColl.LockForWrite(strRecordID, m_nTimeOut);
#if DEBUG_LOCK
				this.container.WriteDebugInfo("WriteObject(),对'" + this.GetCaption("zh-CN") + "/" + strRecordID + "'记录加写锁。");
#endif
                try
                {
                    //////////////////////////////////////////////
                    // 1.在对应的xml数据,用对象路径找到对象ID
                    ///////////////////////////////////////////////
                    string strXmlFilePath = this.GetXmlFilePath(strRecordID);

                    XmlDocument xmlDom = new XmlDocument();
                    xmlDom.PreserveWhitespace = true; //设PreserveWhitespace为true

                    xmlDom.Load(strXmlFilePath);

                    XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDom.NameTable);
                    nsmgr.AddNamespace("dprms", DpNs.dprms);
                    XmlNode fileNode = xmlDom.DocumentElement.SelectSingleNode("//dprms:file[@id='" + strObjectID + "']", nsmgr);
                    if (fileNode == null)
                    {
                        strError = "在数据xml里没有找到该ID对应的dprms:file节点";
                        return -1;
                    }

                    string strObjectFilePath = this.GetObjectFileName(strRecordID,
                        strObjectID);
                    if (File.Exists(strObjectFilePath) == false)
                    {
                        strError = "服务器错误:资源记录'" + strObjectFilePath + "'不存在,不可能的情况";
                        return -1;
                    }
                    string strNewObjectFileName = DatabaseUtil.GetNewFileName(strObjectFilePath);
                    if (File.Exists(strNewObjectFileName) == false)
                    {
                        this.UpdateObject(strObjectFilePath,
                            strStyle,
                            inputTimestamp,
                            out inputTimestamp);
                        // Updata后,记录临时文件有一个字节,所有信息都存在了.
                    }

                    int nFull;
                    nRet = this.WriteFileDbTempRecord(strObjectFilePath,
                        strRanges,
                        lTotalLength,
                        baSource,
                        // streamSource,
                        strMetadata,
                        strStyle,
                        inputTimestamp,
                        out outputTimestamp,
                        out nFull,
                        out strError);
                    if (nRet <= -1)
                        return nRet;

                    if (nFull == 1)  //覆盖完了
                    {
                        // 1. 替换data字段
                        File.Copy(strNewObjectFileName,
                            strObjectFilePath,
                            true);

                        // 2. 删除newdata字段
                        File.Delete(strNewObjectFileName);

                    }
                }
                catch (Exception ex)
                {
                    strError = "WriteXml() 在给'" + this.GetCaption("zh-CN") + "'库写入资源'" + strRecordID + "_" + strObjectID + "'时出错,原因:" + ex.Message;
                    return -1;
                }
                finally
                {
                    //********对记录解写锁****************************
                    m_recordLockColl.UnlockForWrite(strRecordID);
#if DEBUG_LOCK
					this.container.WriteDebugInfo("WriteObject(),对'" + this.GetCaption("zh-CN") + "/" + strRecordID + "'记录解写锁。");
#endif
                }
            }
            finally
            {
                //*******对数据库解读锁****************
                m_db_lock.ReleaseReaderLock();
#if DEBUG_LOCK

				this.container.WriteDebugInfo("WriteObject(),对'" + this.GetCaption("zh-CN") + "'数据库解读锁。");
#endif
            }

            return 0;
        }
Beispiel #6
0
        // 删除数据库
        // parameters:
        //		strDbName	数据库名称,可以是各种语言版本的逻辑名,也可以是id号
        //		strError	out参数,返回出错信息
        // return:
        //		-1	出错
        //		-6	无足够的权限
        //		0	成功
        public int DeleteDb(User user,
            string strDbName,
            out string strError)
        {
            strError = "";

            if (user == null)
            {
                strError = "DeleteDb()调用错误,user参数不能为null。";
                return -1;
            }
            if (String.IsNullOrEmpty(strDbName) == true)
            {
                strError = "DeleteDb()调用错误,strDbName参数值不能为null或空字符串。";
                return -1;
            }

            //**********对库集合加写锁****************
            m_lock.AcquireWriterLock(m_nTimeOut);
#if DEBUG_LOCK
			this.WriteDebugInfo("DeleteDb(),对库集合加写锁。");
#endif
            try
            {
                Database db = this.GetDatabase(strDbName);
                if (db == null)
                {
                    strError = "未找到名为'" + strDbName + "'的数据库";
                    return -1;
                }

                // 检查当前帐户是否有写权限
                string strExistRights = "";
                bool bHasRight = user.HasRights(db.GetCaption("zh-cn"),
                    ResType.Database,
                    "delete",
                    out strExistRights);
                if (bHasRight == false)
                {
                    strError = "您的帐户名为'" + user.Name + "',对'" + strDbName + "'数据库没有'删除(delete)'权限,目前的权限值为'" + strExistRights + "'。";
                    return -6;
                }

                // 调database的Delete()函数,删除该库使用的配置文件,与物理数据库
                // return:
                //      -1  出错
                //      0   成功
                int nRet = db.Delete(out strError);
                if (nRet == -1)
                    return -1;

                //this.m_nodeDbs.RemoveChild(db.m_selfNode);
                List<XmlNode> nodes = DatabaseUtil.GetNodes(this.NodeDbs,
                    strDbName);
                if (nodes.Count != 1)
                {
                    strError = "未找到名为'" + db.GetCaption("zh") + "'的数据库。";
                    return -1;
                }
                this.NodeDbs.RemoveChild(nodes[0]);

                // 删除内存对象
                this.Remove(db);


                // 及时除去dbo特性
                user.RemoveOwerDbName(strDbName);


                // 及时保存到database.xml
                this.Changed = true;
                this.SaveXml();

                return 0;
            }
            finally
            {
                m_lock.ReleaseWriterLock();
                //***********对库集合解写锁****************
#if DEBUG_LOCK
				this.WriteDebugInfo("DeleteDb(),对库集合解写锁。");
#endif
            }
        }
Beispiel #7
0
        // 列出服务器下当前帐户有显示权限的数据库
        // 线:不安全的
        // parameters:
        //      strStyle    是否要列出所有语言的名字? "alllang"表示要列出所有语言的名字
        public int GetDirableChildren(User user,
            string strLang,
            string strStyle,
            out ArrayList aItem,
            out string strError)
        {
            aItem = new ArrayList();
            strError = "";

            if (this.NodeDbs == null)
            {
                strError = "服装器配置文件不合法,未定义<dbs>元素";
                return -1;
            }

            foreach (XmlNode child in this.NodeDbs.ChildNodes)
            {
                string strChildName = DomUtil.GetAttr(child, "name");
                if (String.Compare(child.Name, "database", true) != 0
                    && strChildName == "")
                    continue;

                if (String.Compare(child.Name, "database", true) != 0
                    && String.Compare(child.Name, "dir", true) != 0
                    && String.Compare(child.Name, "file", true) != 0)
                {
                    continue;
                }

                string strExistRights;
                bool bHasRight = false;

                ResInfoItem resInfoItem = new ResInfoItem();
                if (String.Compare(child.Name, "database", true) == 0)
                {
                    string strID = DomUtil.GetAttr(child, "id");
                    Database db = this.GetDatabaseByID("@" + strID);
                    if (db == null)
                    {
                        strError = "未找到id为'" + strID + "'的数据库";
                        return -1;
                    }

                    bHasRight = user.HasRights(db.GetCaption("zh"),
                        ResType.Database,
                        "list",
                        out strExistRights);
                    if (bHasRight == false)
                        continue;

                    if (StringUtil.IsInList("account", db.GetDbType(), true) == true)
                        resInfoItem.Style = 1;
                    else
                        resInfoItem.Style = 0;

                    resInfoItem.TypeString = db.GetDbType();

                    resInfoItem.Name = db.GetCaptionSafety(strLang);
                    resInfoItem.Type = 0;   // 数据库
                    resInfoItem.HasChildren = true;

                    // 如果要获得全部语言的名字
                    if (StringUtil.IsInList("alllang", strStyle) == true)
                    {
                        List<string> results = db.GetAllLangCaptionSafety();
                        string [] names = new string[results.Count];
                        results.CopyTo(names);
                        resInfoItem.Names = names;
                    }
                }
                else if (String.Compare(child.Name, "dir", true) == 0)
                {
                    bHasRight = user.HasRights(strChildName,
                        ResType.Directory,
                        "list",
                        out strExistRights);
                    if (bHasRight == false)
                        continue;
                    resInfoItem.HasChildren = true;
                    resInfoItem.Type = 4;   // 目录
                    resInfoItem.Name = strChildName;

                    resInfoItem.TypeString = DomUtil.GetAttr(child, "type");   // xietao 2006/6/5 add
                }
                else
                {
                    bHasRight = user.HasRights(strChildName,
                        ResType.File,
                        "list",
                        out strExistRights);
                    if (bHasRight == false)
                        continue;
                    resInfoItem.HasChildren = false;
                    resInfoItem.Name = strChildName;
                    resInfoItem.Type = 5;   // 文件?

                    resInfoItem.TypeString = DomUtil.GetAttr(child, "type");   // xietao 2006/6/5 add
                }
                aItem.Add(resInfoItem);
            }
            return 0;
        }
Beispiel #8
0
        // 根据服务器上的指定路径列出其下级的事项
        // parameters:
        //		strPath	路径,不带服务器部分,
        //				格式为: "数据库名/下级名/下级名",
        //				当为null或者为""时,表示列出该服务器下所有的数据库
        //		lStart	起始位置,从0开始 ,不能小于0
        //		lLength	长度 -1表示从lStart到最后
        //		strLang	语言版本 用标准字母表示法,如zh-cn
        //      strStyle    是否要列出所有语言的名字? "alllang"表示要列出全部语言
        //		items	 out参数,返回下级事项数组
        // return:
        //		-1  出错
        //      -6  权限不够
        //		0   正常
        // 说明	只有当前帐户对事项有"list"权限时,才能列出来。
        //		如果列本服务器的数据库时,对所有的数据库都没有list权限,都按错误处理,与没有数据库事项区分开。
        public int Dir(string strResPath,
            long lStart,
            long lLength,
            long lMaxLength,
            string strLang,
            string strStyle,
            User user,
            out ResInfoItem[] items,
            out int nTotalLength,
            out string strError)
        {
            items = new ResInfoItem[0];
            nTotalLength = 0;

            ArrayList aItem = new ArrayList();
            strError = "";
            int nRet = 0;
            //******************加库集合加读锁******
            this.m_lock.AcquireReaderLock(m_nTimeOut);

#if DEBUG_LOCK
			this.WriteDebugInfo("Dir(),对库集合加读锁。");
#endif
            try
            {

                if (strResPath == "" || strResPath == null)
                {
                    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                    // 1.取服务器下的数据库

                    nRet = this.GetDirableChildren(user,
                        strLang,
                        strStyle,
                        out aItem,
                        out strError);
                    if (this.Count > 0 && aItem.Count == 0)
                    {
                        strError = "您的帐户名为'" + user.Name + "',对所有的数据库都没有'显示(list)'权限。";
                        return -6;
                    }
                }
                else
                {
                    string strPath = strResPath;
                    string strDbName = StringUtil.GetFirstPartPath(ref strPath);

                    // 可以是数据库也可以是配置事项
                    if (strPath == "")
                    {
                        Database db = this.GetDatabase(strDbName);
                        if (db != null)
                        {
                            // return:
                            //		-1	出错
                            //		0	成功
                            nRet = db.GetDirableChildren(user,
                                strLang,
                                strStyle,
                                out aItem,
                                out strError);
                            if (nRet == -1)
                                return -1;
                            goto END1;
                        }
                    }

                    // return:
                    //		-1	出错
                    //		0	成功
                    nRet = this.DirCfgItem(user,
                        strResPath,
                        out aItem,
                        out strError);
                    if (nRet == -1)
                        return -1;
                }

            }
            finally
            {
                m_lock.ReleaseReaderLock();
                //*************对库集合解读锁***********
#if DEBUG_LOCK
				this.WriteDebugInfo("Dir(),对库集合解读锁。");
#endif
            }


        END1:
            // 列出实际需要的项
            nTotalLength = aItem.Count;
            int nOutputLength;
            // return:
            //		-1  出错
            //		0   成功
            nRet = DatabaseUtil.GetRealLength((int)lStart,
                (int)lLength,
                nTotalLength,
                (int)lMaxLength,
                out nOutputLength,
                out strError);
            if (nRet == -1)
                return -1;

            items = new ResInfoItem[(int)nOutputLength];
            for (int i = 0; i < items.Length; i++)
            {
                items[i] = (ResInfoItem)(aItem[i + (int)lStart]);
            }

            return 0;
        }
Beispiel #9
0
        // 检索
        // parameter:
        //		strQuery	检索式XML字符串
        //		resultSet	结果集,用于存放检索结果
        //		oUser	    帐户对象,用于检索该帐户对某库是否有读权限
        //  				为null,则不进行权限的检查,即按有权限算
        //		isConnected	delegate对象,用于通讯是否连接正常
        //					为null,则不调delegate函数
        //		strError	out参数,返回出错信息
        // return:
        //		-1	出错
        //      -6  权限不够
        //		0	成功
        // 线: 安全的
        public int Search(string strQuery,
            DpResultSet resultSet,
            User oUser,
            Delegate_isConnected isConnected,
            out string strError)
        {
            strError = "";

            //对库集合加读锁*********************************
            m_lock.AcquireReaderLock(m_nTimeOut);
#if DEBUG_LOCK
			this.WriteDebugInfo("Search(),对库集合加读锁。");
#endif
            try
            {
                if (String.IsNullOrEmpty(strQuery) == true)
                {
                    strError = "Search()调用错误,strQuery不能为null或空字符串";
                    return -1;
                }

                // 一进来先给结果集的m_strQuery成员赋值,
                // 不管是否是合法的XML,在用结果集的时候再判断
                resultSet.m_strQuery = strQuery;
                XmlDocument dom = new XmlDocument();
                dom.PreserveWhitespace = true; //设PreserveWhitespace为true
                try
                {
                    dom.LoadXml(strQuery);
                }
                catch (Exception ex)
                {
                    strError += "检索式字符串加载到dom出错,原因:" + ex.Message + "\r\n"
                        + "检索式字符串如下:\r\n"
                        + strQuery;
                    return -1;
                }

                //创建Query对象
                Query query = new Query(this,
                    oUser,
                    dom);

                //进行检索
                // return:
                //		-1	出错
                //		-6	无权限
                //		0	成功
                int nRet = query.DoQuery(dom.DocumentElement,
                    resultSet,
                    isConnected,
                    out strError);
                if (nRet <= -1)
                    return nRet;
            }
            finally
            {
                //****************对库集合解读锁**************
                m_lock.ReleaseReaderLock();
#if DEBUG_LOCK
				this.WriteDebugInfo("Search(),对库集合解读锁。");
#endif
            }
            return 0;
        }
Beispiel #10
0
        // ???对库集合加读锁
        // 初始化数据库
        // parameters:
        //      user    帐户对象
        //      strDbName   数据库名称
        //      strError    out参数,返回出错信息
        // return:
        //      -1  出错
        //      -5  数据库不存在
        //      -6  权限不够
        //      0   成功
        // 线:安全 代码没跟上
        public int InitializePhysicalDatabase(User user,
            string strDbName,
            out string strError)
        {
            strError = "";
            Debug.Assert(user != null, "InitializeDb()调用错误,user参数值不能为null。");

            if (String.IsNullOrEmpty(strDbName) == true)
            {
                strError = "InitializeDb()调用错误,strDbName参数值不能为null或空字符串。";
                return -1;
            }

            // 1.得到数据库
            Database db = this.GetDatabaseSafety(strDbName);
            if (db == null)
            {
                strError = "没有找到名为'" + strDbName + "'的数据库";
                return -5;
            }

            string strExistRights = "";
            bool bHasRight = user.HasRights(db.GetCaption("zh-cn"),
                ResType.Database,
                "clear",
                out strExistRights);
            if (bHasRight == false)
            {
                strError = "您的帐户名为'" + user.Name + "',对'" + strDbName + "'数据库没有'初始化(clear)'权限,目前的权限值为'" + strExistRights + "'。";
                return -6;
            }

            // 3.初始化
            // return:
            //		-1  出错
            //		0   成功
            return db.InitialPhysicalDatabase(out strError);
        }
Beispiel #11
0
        // 设置数据库基本信息
        // parameter:
        //		strDbName	        数据库名称
        //		strLang	            对应的语言版本,如果语言版本为null或者为空字符串,则从所有的语言版本中找
        //		logicNames	        LogicNameItem数组
        //		strType	            数据库类型,以逗号分隔,可以是file,accout,目前无效,因为涉及到是文件库,还是sql库的问题
        //		strSqlDbName	    指定的新Sql数据库名称,,目前无效
        //		strKeysDefault	    keys配置信息
        //		strBrowseDefault	browse配置信息
        // return:
        //      -1  一般性错误
        //      -2  已存在同名的数据库
        //      -5  未找到数据库对象
        //      -6  没有足够的权限
        //      0   成功
        public int SetDbInfo(User user,
            string strDbName,
            LogicNameItem[] logicNames,
            string strType,
            string strSqlDbName,
            string strKeysText,
            string strBrowseText,
            out string strError)
        {
            strError = "";

            Debug.Assert(user != null, "SetDbInfo()调用错误,user参数不能为null。");

            if (String.IsNullOrEmpty(strDbName) == true)
            {
                strError = "SetDbInfo()调用错误,strDbName参数值不能为null或空字符串。";
                return -1;
            }

            // 为避免死锁的问题,将查看权限的函数放在外面了
            // 检查当前帐户是否有覆盖数据库结构的权限
            string strExistRights = "";
            bool bHasRight = user.HasRights(strDbName,
                ResType.Database,
                "overwrite",
                out strExistRights);

            //******************对库集合加读锁******
            this.m_lock.AcquireReaderLock(m_nTimeOut);
#if DEBUG_LOCK
			this.WriteDebugInfo("SetDbInfo(),对库集合加读锁。");
#endif
            try
            {
                Database db = this.GetDatabase(strDbName);
                if (db == null)
                {
                    strError = "未找到名为'" + strDbName + "'的数据库。";
                    return -5;
                }

                if (bHasRight == false)
                {
                    strError = "您的帐户名为'" + user.Name + "',对'" + strDbName + "'数据库没有'覆盖(overwrite)'权限,目前的权限值为'" + strExistRights + "'。";
                    return -6;
                }

                // return:
                //		-1	出错
                //      -2  已存在同名的数据库
                //		0	成功
                int nRet = db.SetInfo(logicNames,
                    strType,
                    strSqlDbName,
                    strKeysText,
                    strBrowseText,
                    out strError);
                if (nRet <= -1)
                    return nRet;

                // 及时保存databases.xml
                this.Changed = true;
                this.SaveXml();

                return 0;
            }
            finally
            {
                this.m_lock.ReleaseReaderLock();
                //*****************对库集合解读锁*************
#if DEBUG_LOCK
				this.WriteDebugInfo("SetDbInfo(),对库集合解读锁。");
#endif
            }

        }
Beispiel #12
0
        // 得到数据库可以显示的下级
        // parameters:
        //		oUser	帐户对象
        //		db	数据库对象
        //		strLang	语言版本
        //		aItem	out参数,返回数据库可以显示的下级
        //		strError	out参数,返回出错信息
        // return:
        //		-1	出错
        //		0	成功
        public int GetDirableChildren(User user,
            string strLang,
            string strStyle,
            out ArrayList aItem,
            out string strError)
        {
            aItem = new ArrayList();
            strError = "";

            //**********对数据库加读锁**************
            this.m_db_lock.AcquireReaderLock(m_nTimeOut);
#if DEBUG_LOCK
			this.container.WriteDebugInfo("Dir(),对'" + this.GetCaption("zh-CN") + "'数据库加读锁。");
#endif
            try
            {
                // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                // 1.配置事项

                foreach (XmlNode child in this.m_selfNode.ChildNodes)
                {
                    string strElementName = child.Name;
                    if (String.Compare(strElementName, "dir", true) != 0
                        && String.Compare(strElementName, "file", true) != 0)
                    {
                        continue;
                    }


                    string strChildName = DomUtil.GetAttr(child, "name");
                    if (strChildName == "")
                        continue;
                    string strCfgPath = this.GetCaption("zh-CN") + "/" + strChildName;
                    string strExistRights;
                    bool bHasRight = false;

                    ResInfoItem resInfoItem = new ResInfoItem();
                    resInfoItem.Name = strChildName;
                    if (child.Name == "dir")
                    {
                        bHasRight = user.HasRights(strCfgPath,
                            ResType.Directory,
                            "list",
                            out strExistRights);
                        if (bHasRight == false)
                            continue;

                        resInfoItem.HasChildren = true;
                        resInfoItem.Type = 4;   // 目录

                        resInfoItem.TypeString = DomUtil.GetAttr(child, "type");    // xietao 2006/6/5
                    }
                    else
                    {
                        bHasRight = user.HasRights(strCfgPath,
                            ResType.File,
                            "list",
                            out strExistRights);
                        if (bHasRight == false)
                            continue;
                        resInfoItem.HasChildren = false;
                        resInfoItem.Type = 5;   // 文件

                        resInfoItem.TypeString = DomUtil.GetAttr(child, "type"); // xietao 2006/6/5 add

                    }
                    aItem.Add(resInfoItem);
                }


                // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                // 2.检索途径

                KeysCfg keysCfg = null;
                int nRet = this.GetKeysCfg(out keysCfg,
                    out strError);
                if (nRet == -1)
                    return -1;

                if (keysCfg != null)
                {
                    List<TableInfo> aTableInfo = null;
                    nRet = keysCfg.GetTableInfosRemoveDup(
                        out aTableInfo,
                        out strError);
                    if (nRet == -1)
                        return -1;

                    // 对于检索途径,全部都有权限
                    for (int i = 0; i < aTableInfo.Count; i++)
                    {
                        TableInfo tableInfo = aTableInfo[i];
                        Debug.Assert(tableInfo.Dup == false, "不可能再有重复的了。");

                        ResInfoItem resInfoItem = new ResInfoItem();
                        resInfoItem.Type = 1;
                        resInfoItem.Name = tableInfo.GetCaption(strLang);
                        resInfoItem.HasChildren = false;

                        resInfoItem.TypeString = tableInfo.TypeString;  // xietao 2006/6/5 add

                        // 2012/5/16
                        if (string.IsNullOrEmpty(tableInfo.ExtTypeString) == false)
                        {
                            if (string.IsNullOrEmpty(resInfoItem.TypeString) == false)
                                resInfoItem.TypeString += ",";

                            resInfoItem.TypeString += tableInfo.ExtTypeString;
                        }

                        // 如果需要, 列出所有语言下的名字
                        if (StringUtil.IsInList("alllang", strStyle) == true)
                        {
                            List<string> results = tableInfo.GetAllLangCaption();
                            string[] names = new string[results.Count];
                            results.CopyTo(names);
                            resInfoItem.Names = names;
                        }

                        aItem.Add(resInfoItem);
                    }
                }

                // 加__id
                ResInfoItem resInfoItemID = new ResInfoItem();
                resInfoItemID.Type = 1;
                resInfoItemID.Name = "__id";
                resInfoItemID.HasChildren = false;
                resInfoItemID.TypeString = "recid";

                aItem.Add(resInfoItemID);

                return 0;
            }
            finally
            {
                //***************对数据库解读锁************
                this.m_db_lock.ReleaseReaderLock();
#if DEBUG_LOCK
				this.container.WriteDebugInfo("Dir(),对'" + this.GetCaption("zh-CN") + "'数据库解读锁。");
#endif
            }

        }
Beispiel #13
0
 // parameters:
 //      strRecordID  记录ID
 //      strObjectID  对象ID
 //      其它同WriteXml,无strOutputID参数
 // return:
 //		-1  出错
 //		-2  时间戳不匹配
 //      -4  记录或对象资源不存在
 //      -6  权限不够
 //		0   成功
 // 线: 安全的
 public virtual int WriteObject(User user,
     string strRecordID,
     string strObjectID,
     string strRanges,
     long lTotalLength,
     byte[] baSource,
     // Stream streamSource,
     string strMetadata,
     string strStyle,
     byte[] intputTimestamp,
     out byte[] outputTimestamp,
     out string strError)
 {
     outputTimestamp = intputTimestamp;
     strError = "";
     return 0;
 }
Beispiel #14
0
        // 写xml数据
        // parameter:
        //		strRecordID     记录ID
        //		strRanges       写入的片断范围
        //		nTotalLength    数据总长度
        //		sourceBuffer    写入的数据字节数组
        //		strMetadata     元数据
        //		intputTimestamp 输入的时间戳
        //		outputTimestamp out参数,返回的时间戳,出错时,也返回时间戳
        //		strOutputID     out参数,返回的记录ID,追加记录时,有用
        //		strError        out参数,返回出错信息
        // return:
        // return:
        //		-1  出错
        //		-2  时间戳不匹配
        //      -4  记录不存在
        //      -6  权限不够
        //		0   成功
        // 说明,总长度与源流如果 != null,就写到库里,片断合并后会把新片断记到库里,如果已满,则新片断为空字符串
        // 线: 安全的
        public virtual int WriteXml(User oUser,
            string strID,
            string strXPath,
            string strRanges,
            long lTotalLength,
            byte[] baSource,
            // Stream streamSource,
            string strMetadata,
            string strStyle,
            byte[] inputTimestamp,
            out byte[] outputTimestamp,
            out string strOutputID,
            out string strOutputValue,
            bool bCheckAccount,
            out string strError)
        {
            outputTimestamp = null;
            strOutputID = "";
            strOutputValue = "";
            strError = "";

            return 0;
        }
Beispiel #15
0
        // 删除资源,可以是记录 或 配置事项,不支持对象资源或部分记录体
        // parameter:
        //		strResPath		资源路径,不能为null或空字符串
        //						资源类型可以是数据库配置事项(目录或文件),记录
        //						配置事项: 库名/配置事项路径
        //						记录: 库名/记录号
        //		user	当前帐户对象,不能为null
        //		baInputTimestamp	输入的时间戳
        //		baOutputTimestamp	out参数,返回时间戳
        //		strError	out参数,返回出错信息
        // return:
        //      -1	一般性错误,例如输入参数不合法等
        //      -2	时间戳不匹配
        //      -4	未找到路径对应的资源
        //      -5	未找到数据库
        //      -6	没有足够的权限
        //      -7	路径不合法
        //      0	操作成功
        // 说明: 
        // 1)删除需要当前帐户对将被删除的记录的有delete权限		
        // 2)删除记录的明确含义是删除记录体,并且删除该记录包含的所有对象资源
        // 3)删除配置目录不要求时间戳,同时baOutputTimestamp也是null
        public int DeleteRes(string strResPath,
            User user,
            byte[] baInputTimestamp,
            out byte[] baOutputTimestamp,
            out string strError)
        {
            baOutputTimestamp = null;
            strError = "";

            //-----------------------------------------
            //对输入参数做例行检查
            //---------------------------------------
            if (strResPath == null || strResPath == "")
            {
                strError = "DeleteRes()调用错误,strResPath参数不能为null或空字符串。";
                return -1;
            }
            if (user == null)
            {
                strError = "DeleteRes()调用错误,user参数不能为null。";
                return -1;
            }


            //-----------------------------------------
            //开始做事情 
            //---------------------------------------

            //******************加库集合加读锁******
            this.m_lock.AcquireReaderLock(m_nTimeOut);

#if DEBUG_LOCK
			this.WriteDebugInfo("CheckDbsTailNoSafety(),对库集合加读锁。");
#endif
            try
            {
                int nRet = 0;

                bool bRecordPath = this.IsRecordPath(strResPath);
                if (bRecordPath == false)
                {
                    // 也可能是数据库对象


                    // 删除实际的物理文件
                    //      -1  一般性错误
                    //      -2  时间戳不匹配
                    //      -4  未找到路径对应的资源
                    //      -6  没有足够的权限
                    //      0   成功
                    nRet = this.DeleteCfgItem(user,
                        strResPath,
                        baInputTimestamp,
                        out baOutputTimestamp,
                        out strError);
                    if (nRet <= -1)
                        return nRet;
                }
                else
                {

                    string strPath = strResPath;
                    string strDbName = StringUtil.GetFirstPartPath(ref strPath);
                    if (strPath == "")
                    {
                        strError = "资源路径'" + strResPath + "'不合法,未指定库的下级。";
                        return -7;
                    }

                    // 根据资源类型,写资源
                    Database db = this.GetDatabase(strDbName);
                    if (db == null)
                    {
                        strError = "没找到名为'" + strDbName + "'的数据库。";
                        return -5;
                    }

                    string strFirstPart = StringUtil.GetFirstPartPath(ref strPath);
                    //***********吃掉第2层*************
                    // 到此为止,strPath不含cfgs或记录号层了,下级分情况判断
                    // strFirstPart可能是为cfg或记录号

                    string strRecordID = strFirstPart;

                    // 检查当前帐户是否有删除记录
                    string strExistRights = "";
                    bool bHasRight = user.HasRights(strResPath,//db.GetCaption("zh-cn"),
                        ResType.Record,
                        "delete",
                        out strExistRights);
                    if (bHasRight == false)
                    {
                        strError = "您的帐户名为'" + user.Name + "',对'" + strDbName + "'数据库没有'删除记录(delete)'权限,目前的权限值为'" + strExistRights + "'。";
                        return -6;
                    }

                    // return:
                    //		-1  一般性错误
                    //		-2  时间戳不匹配
                    //      -4  未找到记录
                    //		0   成功
                    nRet = db.DeleteRecord(strRecordID,
                        baInputTimestamp,
                        out baOutputTimestamp,
                        out strError);
                    if (nRet <= -1)
                        return nRet;
                }
            }
            finally
            {
                m_lock.ReleaseReaderLock();
                //*************对库集合解读锁***********
#if DEBUG_LOCK
				this.WriteDebugInfo("CheckDbsTailNoSafety(),对库集合解读锁。");
#endif
            }

            //及时保存database.xml // 是用加锁的函数吗?
            if (this.Changed == true)
                this.SaveXmlSafety();

            return 0;

        }
Beispiel #16
0
        // 删除一个配置事项,可以是目录,也可以是文件
        // return:
        //      -1  一般性错误
        //      -2  时间戳不匹配
        //      -4  未找到路径对应的资源
        //      -6  没有足够的权限
        //      0   成功
        public int DeleteCfgItem(User user,
            string strCfgItemPath,
            byte[] intputTimestamp,
            out byte[] outputTimestamp,
            out string strError)
        {
            outputTimestamp = null;
            strError = "";

            if (strCfgItemPath == null
                || strCfgItemPath == "")
            {
                strError = "DeleteCfgItem()调用错误,strCfgItemPath参数值不能为null或空字符串。";
                return -1;
            }

            List<XmlNode> nodes = DatabaseUtil.GetNodes(this.NodeDbs,
                strCfgItemPath);
            if (nodes.Count == 0)
            {
                strError = "服务器不存在路径为'" + strCfgItemPath + "'的配置事项。";
                return -4;
            }
            if (nodes.Count != 1)
            {
                strError = "服务器上路径为'" + strCfgItemPath + "'的配置事项个数为'" + Convert.ToString(nodes.Count) + "',database.xml配置文件异常。";
                return -1;
            }


            string strExistRights = "";
            bool bHasRight = false;

            XmlNode node = nodes[0];

            if (node.Name == "dir")
            {
                // 检查当前帐户是否有删除记录'
                bHasRight = user.HasRights(strCfgItemPath,
                    ResType.Directory,
                    "delete",
                    out strExistRights);
                if (bHasRight == false)
                {
                    strError = "您的帐户名为'" + user.Name + "',对'" + strCfgItemPath + "'配置事项没有'删除(delete)'权限,目前的权限值为'" + strExistRights + "'。";
                    return -6;
                }
                string strDir = DatabaseUtil.GetLocalDir(this.NodeDbs, node).Trim();
                Directory.Delete(this.DataDir + "\\" + strDir, true);
                node.ParentNode.RemoveChild(node);
                return 0;
            }
            else if (String.Compare(node.Name, "database", true) == 0)
            {

            }


            // 检查当前帐户是否有删除记录'
            bHasRight = user.HasRights(strCfgItemPath,
                ResType.File,
                "delete",
                out strExistRights);
            if (bHasRight == false)
            {
                strError = "您的帐户名为'" + user.Name + "',对'" + strCfgItemPath + "'配置事项没有'删除(delete)'权限,目前的权限值为'" + strExistRights + "'。";
                return -6;
            }

            string strFilePath = "";//GetCfgItemLacalPath(strCfgItemPath);
            // return:
            //		-1	一般性错误,比如调用错误,参数不合法等
            //		-2	没找到节点
            //		-3	localname属性未定义或为值空
            //		-4	localname在本地不存在
            //		-5	存在多个节点
            //		0	成功
            int nRet = this.GetFileCfgItemLacalPath(strCfgItemPath,
                out strFilePath,
                out strError);
            if (nRet != 0)
            {
                if (nRet == -1 || nRet == -5)
                    return -1;

            }
            if (strFilePath != "")
            {
                string strNewFileName = DatabaseUtil.GetNewFileName(strFilePath);

                if (File.Exists(strFilePath) == true)
                {

                    byte[] oldTimestamp = null;
                    if (File.Exists(strNewFileName) == true)
                        oldTimestamp = DatabaseUtil.CreateTimestampForCfg(strNewFileName);
                    else
                        oldTimestamp = DatabaseUtil.CreateTimestampForCfg(strFilePath);

                    outputTimestamp = oldTimestamp;
                    if (ByteArray.Compare(oldTimestamp, intputTimestamp) != 0)
                    {
                        strError = "时间戳不匹配";
                        return -2;
                    }
                }

                File.Delete(strNewFileName);
                File.Delete(strFilePath);

                string strRangeFileName = DatabaseUtil.GetRangeFileName(strFilePath);
                if (File.Exists(strRangeFileName) == false)
                    File.Delete(strRangeFileName);

                string strMetadataFileName = DatabaseUtil.GetMetadataFileName(strFilePath);
                if (File.Exists(strMetadataFileName) == false)
                    File.Delete(strMetadataFileName);
            }
            node.ParentNode.RemoveChild(node);

            this.Changed = true;
            this.SaveXml();

            return 0;
        }
Beispiel #17
0
        // 拷贝一条源记录到目标记录,要求对源记录有读权限,对目标记录有写权限
        // 关键点是锁的问题
        // Parameter:
        //      user                    用户对象
        //		strOriginRecordPath	    源记录路径
        //		strTargetRecordPath	    目标记录路径
        //		bDeleteOriginRecord	    是否删除源记录
        //      strOutputRecordPath     返回目标记录的路径,用于目标记录是新建一条记录
        //      baOutputRecordTimestamp 返回目标记录的时间戳
        //		strError	出错信息
        // return:
        //		-1	一般性错误
        //      -4  未找到记录
        //      -5  未找到数据库
        //      -6  没有足够的权限
        //      -7  路径不合法
        //		0	成功
        public int CopyRecord(User user,
            string strOriginRecordPath,
            string strTargetRecordPath,
            bool bDeleteOriginRecord,
            out string strTargetRecordOutputPath,
            out byte[] baOutputRecordTimestamp,
            out string strError)
        {
            Debug.Assert(user != null, "CopyRecord()调用错误,user对象不能为null。");

            this.WriteErrorLog("走到CopyRecord(),strOriginRecordPath='" + strOriginRecordPath + "' strTargetRecordPath='" + strTargetRecordPath + "'");

            strTargetRecordOutputPath = "";
            baOutputRecordTimestamp = null;
            strError = "";

            if (String.IsNullOrEmpty(strOriginRecordPath) == true)
            {
                strError = "CopyRecord()调用错误,strOriginRecordPath参数值不能为nul或空字符串";
                return -1;
            }
            if (String.IsNullOrEmpty(strTargetRecordPath) == true)
            {
                strError = "CopyRecord()调用错误,strTargetRecordPath参数值不能为null或空字符串";
                return -1;
            }

            long nRet = 0;

            // 得到源记录的xml
            string strOriginRecordStyle = "data,metadata,timestamp";
            byte[] baOriginRecordData = null;
            string strOriginRecordMetadata = "";
            string strOriginRecordOutputPath = "";
            byte[] baOriginRecordOutputTimestamp = null;

            int nAdditionError = 0;
            // return:
            //		-1	一般性错误
            //		-4	未找到路径指定的资源
            //		-5	未找到数据库
            //		-6	没有足够的权限
            //		-7	路径不合法
            //		-10	未找到记录xpath对应的节点  // 此次调用不可能出现这种情况
            //		>= 0	成功,返回最大长度
            nRet = this.GetRes(strOriginRecordPath,
                0,
                -1,
                strOriginRecordStyle,
                user,
                -1,
                out baOriginRecordData,
                out strOriginRecordMetadata,
                out strOriginRecordOutputPath,
                out baOriginRecordOutputTimestamp,
                out nAdditionError,
                out strError);
            if (nRet <= -1)
                return (int)nRet;


            // 写目标记录xml
            string strTargetRecordRanges = "";
            long lTargetRecordTotalLength = baOriginRecordData.Length;
            byte[] baTargetRecordData = baOriginRecordData;
            string strTargetRecordMetadata = strOriginRecordMetadata;
            string strTargetRecordStyle = "ignorechecktimestamp";
            byte[] baTargetRecordOutputTimestamp = null;
            string strTargetRecordOutputValue = "";
            // return:
            //		-1	一般性错误
            //		-2	时间戳不匹配    // 此处调用不可能出现这种情况
            //		-4	未找到路径指定的资源
            //		-5	未找到数据库
            //		-6	没有足够的权限
            //		-7	路径不合法
            //		-8	已经存在同名同类型的项  // 此处调用不可能出现这种情况
            //		-9	已经存在同名但不同类型的项  // 此处调用不可能出现这种情况
            //		0	成功
            nRet = this.WriteRes(strTargetRecordPath,
                strTargetRecordRanges,
                lTargetRecordTotalLength,
                baTargetRecordData,
                null, //streamSource
                strTargetRecordMetadata,
                strTargetRecordStyle,
                null, //baInputTimestamp
                user,
                out strTargetRecordOutputPath,
                out baTargetRecordOutputTimestamp,
                out strTargetRecordOutputValue,
                out strError);
            if (nRet <= -1)
                return (int)nRet;

            // 处理资源
            byte[] baPreamble;
            string strXml = DatabaseUtil.ByteArrayToString(baOriginRecordData,
                out baPreamble);
            XmlDocument dom = new XmlDocument();
            dom.PreserveWhitespace = true; //设PreserveWhitespace为true
            try
            {
                dom.LoadXml(strXml);
            }
            catch (Exception ex)
            {
                strError = "加载'" + strOriginRecordPath + "'的记录体到dom出错,原因:" + ex.Message;
                return -1;
            }

            XmlNamespaceManager nsmgr = new XmlNamespaceManager(dom.NameTable);
            nsmgr.AddNamespace("dprms", DpNs.dprms);
            XmlNodeList fileList = dom.DocumentElement.SelectNodes("//dprms:file", nsmgr);
            foreach (XmlNode fileNode in fileList)
            {

                // 获取源资源对象
                string strObjectID = DomUtil.GetAttr(fileNode, "id");
                string strOriginObjectPath = strOriginRecordPath + "/object/" + strObjectID;
                byte[] baOriginObjectData = null;
                string strOriginObjectMetadata = "";
                string strOriginObjectOutputPath = "";
                byte[] baOriginObjectOutputTimestamp = null;

                this.WriteErrorLog("走到CopyRecord(),获取资源,源路径='" + strOriginObjectPath + "'");

                // int nAdditionError = 0;
                // return:
                //		-1	一般性错误
                //		-4	未找到路径指定的资源
                //		-5	未找到数据库
                //		-6	没有足够的权限
                //		-7	路径不合法
                //		-10	未找到记录xpath对应的节点
                //		>= 0	成功,返回最大长度
                nRet = this.GetRes(strOriginObjectPath,
                    0,
                    -1,
                    "data,metadata",
                    user,
                    -1,
                    out baOriginObjectData,
                    out strOriginObjectMetadata,
                    out strOriginObjectOutputPath,
                    out baOriginObjectOutputTimestamp,
                    out nAdditionError,
                    out strError);
                if (nRet <= -1)
                    return (int)nRet;

                // 写目标资源对象
                string strTargetObjectPath = strTargetRecordOutputPath + "/object/" + strObjectID;
                long lTargetObjectTotalLength = baOriginObjectData.Length;
                string strTargetObjectMetadata = strOriginObjectMetadata;
                string strTargetObjectStyle = "ignorechecktimestamp";
                string strTargetObjectOutputPath = "";
                byte[] baTargetObjectOutputTimestamp = null;
                string strTargetObjectOutputValue = "";

                //this.WriteErrorLog("走到CopyRecord(),写资源,目标路径='" + strTargetObjectPath + "'");

                // return:
                //		-1	一般性错误
                //		-2	时间戳不匹配
                //		-4	未找到路径指定的资源
                //		-5	未找到数据库
                //		-6	没有足够的权限
                //		-7	路径不合法
                //		-8	已经存在同名同类型的项
                //		-9	已经存在同名但不同类型的项
                //		0	成功
                nRet = this.WriteRes(strTargetObjectPath,
                    "",
                    lTargetObjectTotalLength,
                    baOriginObjectData,
                    null,
                    strTargetObjectMetadata,
                    strTargetObjectStyle,
                    null,
                    user,
                    out strTargetObjectOutputPath,
                    out baTargetObjectOutputTimestamp,
                    out strTargetObjectOutputValue,
                    out strError);
                if (nRet <= -1)
                    return (int)nRet;
            }

            // 判断是否删除源记录
            if (bDeleteOriginRecord == true)
            {
                // return:
                //      -1	一般性错误,例如输入参数不合法等
                //      -2	时间戳不匹配    // 建议忽略时间戳,不应出现这种情况
                //      -4	未找到路径对应的资源
                //      -5	未找到数据库
                //      -6	没有足够的权限
                //      -7	路径不合法
                //      0	操作成功
                nRet = this.DeleteRes(strOriginRecordPath,
                    user,
                    baOriginRecordOutputTimestamp,
                    out baOriginRecordOutputTimestamp,
                    out strError);
                if (nRet <= -1)
                    return (int)nRet;
            }

            // 取出目标记录的最终时间戳
            // return:
            //		-1  出错
            //		-4  未找到记录
            //      0   成功
            nRet = this.GetTimestampFromDb(
                strTargetRecordOutputPath,
                out baOutputRecordTimestamp,
                out strError);
            if (nRet <= -1)
            {
                strError = "拷贝记录完成,但获取目标记录的时间戳时出错:" + strError;
                return -1;
            }

            return 0;
        }
Beispiel #18
0
        // 得到某一指定路径strPath的可以显示的下级
        // parameters:
        //		oUser	当前帐户
        //		db	当前数据库
        //		strPath	配置事项的路径
        //		strLang	语言版本
        //		aItem	out参数,返回可以显示的下级
        //		strError	out参数,出错信息
        // return:
        //		-1	出错
        //		0	成功
        private int DirCfgItem(User user,
            string strCfgItemPath,
            out ArrayList aItem,
            out string strError)
        {
            strError = "";
            aItem = new ArrayList();

            if (this.NodeDbs == null)
            {
                strError = "服务器配置文件未定义<dbs>元素";
                return -1;
            }
            List<XmlNode> list = DatabaseUtil.GetNodes(this.NodeDbs,
                strCfgItemPath);
            if (list.Count == 0)
            {
                strError = "未找到路径为'" + strCfgItemPath + "'对应的事项。";
                return -1;
            }

            if (list.Count > 1)
            {
                strError = "服务器端总配置文件不合法,检查到路径为'" + strCfgItemPath + "'对应的节点有'" + Convert.ToString(list.Count) + "'个,有且只能有一个。";
                return -1;
            }
            XmlNode node = list[0];

            for (int i = 0; i < node.ChildNodes.Count; i++)
            {
                XmlNode child = node.ChildNodes[i];
                string strChildName = DomUtil.GetAttr(child, "name");
                if (strChildName == "")
                    continue;

                string strTempPath = strCfgItemPath + "/" + strChildName;
                string strExistRights;
                bool bHasRight = false;


                ResInfoItem resInfoItem = new ResInfoItem();
                resInfoItem.Name = strChildName;
                if (child.Name == "dir")
                {
                    bHasRight = user.HasRights(strTempPath,
                     ResType.Directory,
                     "list",
                     out strExistRights);
                    if (bHasRight == false)
                        continue;

                    resInfoItem.HasChildren = true;
                    resInfoItem.Type = 4;

                    resInfoItem.TypeString = DomUtil.GetAttr(child, "type");    // xietao 2006/6/5 add
                }
                else
                {
                    bHasRight = user.HasRights(strTempPath,
                        ResType.File,
                        "list",
                        out strExistRights);
                    if (bHasRight == false)
                        continue;
                    resInfoItem.HasChildren = false;
                    resInfoItem.Type = 5;

                    resInfoItem.TypeString = DomUtil.GetAttr(child, "type");    // xietao 2006/6/5 add

                }
                aItem.Add(resInfoItem);
            }
            return 0;
        }
Beispiel #19
0
        // 写资源
        // parameter:
        //		strResPath		资源路径,不能为null或空字符串
        //						资源类型可以是数据库配置事项(目录或文件),记录体,对象资源,部分记录体
        //						配置事项: 库名/配置事项路径
        //						记录体: 库名/记录号
        //						对象资源: 库名/记录号/object/资源ID
        //						部分记录体: 库名/记录/xpath/<locate>hitcount</locate><action>AddInteger</action> 或者 库名/记录/xpath/@hitcount
        //		strRanges		目标的位置,多个range用逗号分隔,null认为是空字符串,空字符串认为是0-(lTotalLength-1)
        //		lTotalLength	资源总长度,可以为0
        //		baContent		用byte[]数据传送的资源内容,如果为null则表示是0字节的数组
        //		streamContent	内容流
        //		strMetadata		元数据内容,null认为是空字符串,注:有些元数据虽然传过来,但服务器不认,比如长度
        //		strStyle		风格,null认为是空字符串
        //						ignorechecktimestamp 忽略时间戳;
        //						createdir,创建目录,路径表示待创建的目录路径
        //						autocreatedir	自动创建中间层的目录
        //						content	数据放在baContent参数里
        //						attachment	数据放在附件里
        //		baInputTimestamp	输入的时间戳,对于创建目录,不检查时间戳
        //		user	帐户对象,不能为null
        //		strOutputResPath	返回的资源路径
        //							比如追加记录时,返回实际的路径
        //							其它资源返回的路径与输入的路径相同
        //		baOutputTimestamp	返回时间戳
        //							当为目录时,返回的时间戳为null
        //		strOutputValue	返回的值,比如做累加计算时
        //		strError	出错信息
        // 说明:
        //		本函数实际代表了两种情况,新建资源,覆盖资源
        //		baContent,strAttachmentID只能使用一个,与strStyle配置使用
        // return:
        //		-1	一般性错误
        //		-2	时间戳不匹配
        //		-4	未找到路径指定的资源
        //		-5	未找到数据库
        //		-6	没有足够的权限
        //		-7	路径不合法
        //		-8	已经存在同名同类型的项
        //		-9	已经存在同名但不同类型的项
        //		0	成功
        // 线:安全
        public int WriteRes(string strResPath,
            string strRanges,
            long lTotalLength,
            byte[] baSource,
            Stream streamSource,
            string strMetadata,
            string strStyle,
            byte[] baInputTimestamp,
            User user,
            out string strOutputResPath,
            out byte[] baOutputTimestamp,
            out string strOutputValue,
            out string strError)
        {
            baOutputTimestamp = null;
            strOutputResPath = strResPath;
            strOutputValue = "";
            strError = "";

            //**********对库集合加写锁****************
            m_lock.AcquireWriterLock(m_nTimeOut);
#if DEBUG_LOCK
			this.WriteDebugInfo("WriteRes(),对库集合加写锁。");
#endif
            try
            {

                //------------------------------------------------
                //检查输入参数是否合法,并规范输入参数
                //---------------------------------------------------
                if (user == null)
                {
                    strError = "WriteRes()调用错误,user对象不能为null";
                    return -1;
                }
                if (String.IsNullOrEmpty(strResPath) == true)
                {
                    strError = "资源路径'" + strResPath + "'不合法,不能为null或空字符串。";
                    return -7;
                }
                if (lTotalLength < 0)
                {
                    strError = "WriteRes(),lTotalLength不能为'" + Convert.ToString(lTotalLength) + "',必须>=0。";
                    return -1;
                }
                if (strRanges == null) //里面的函数,会处理成代表的范围
                    strRanges = "";
                if (strMetadata == null)
                    strMetadata = "";
                if (strStyle == null)
                    strStyle = "";

                if (baSource == null && streamSource == null)
                {
                    strError = "WriteRes()调用错误,baSource参数与streamSource参数不能同时为null。";
                    return -1;
                }
                if (baSource != null && streamSource != null)
                {
                    strError = "WriteRes()调用错误,baSource参数与streamSource参数只能有一个被赋值。";
                    return -1;
                }


                //------------------------------------------------
                //分析出资源的类型
                //---------------------------------------------------

                int nRet = 0;

                bool bRecordPath = this.IsRecordPath(strResPath);
                if (bRecordPath == false)
                {
                    // 关于配置目录
                    if (StringUtil.IsInList("createdir", strStyle, true) == true)
                    {
                        // return:
                        //      -1  一般性错误
                        //		-4	未指定路径对应的对象
                        //		-6	权限不够
                        //		-8	目录已存在
                        //		-9	存在其它类型的事项
                        //		0	成功
                        nRet = this.WriteDirCfgItem(strResPath,
                            strStyle,
                            user,
                            out strError);
                    }
                    else
                    {
                        // return:
                        //      -1  一般性错误
                        //      -2  时间戳不匹配
                        //      -4  自动创建目录时,未找到上级
                        //		-6	权限不够
                        //		-9	存在其它类型的事项
                        //		0	成功
                        nRet = this.WriteFileCfgItem(strResPath,
                            strRanges,
                            lTotalLength,
                            baSource,
                            streamSource,
                            strMetadata,
                            strStyle,
                            baInputTimestamp,
                            user,
                            out baOutputTimestamp,
                            out strError);
                    }

                    strOutputResPath = strResPath;

                    // 保存database.xml文件
                    if (this.Changed == true)
                        this.SaveXmlSafety();
                }
                else
                {
                    bool bObject = false;
                    string strRecordID = "";
                    string strObjectID = "";
                    string strXPath = "";

                    string strPath = strResPath;
                    string strDbName = StringUtil.GetFirstPartPath(ref strPath);
                    //***********吃掉第1层*************
                    // 到此为止,strPath不含数据库名了,下面的路径有两种情况:cfgs;其余都被当作记录id
                    if (strPath == "")
                    {
                        strError = "资源路径'" + strResPath + "'路径不合法,未指定库的下级。";
                        return -7;
                    }
                    // 找到数据库对象
                    Database db = this.GetDatabaseSafety(strDbName);
                    if (db == null)
                    {
                        strError = "名'" + strDbName + "'的数据库不存在。";
                        return -5;
                    }

                    string strFirstPart = StringUtil.GetFirstPartPath(ref strPath);
                    //***********吃掉第2层*************
                    // 到此为止,strPath不含记录号层了,下级分情况判断


                    strRecordID = strFirstPart;
                    // 只到记录号层的路径
                    if (strPath == "")
                    {
                        bObject = false;
                        goto DOWRITE;
                    }

                    strFirstPart = StringUtil.GetFirstPartPath(ref strPath);
                    //***********吃掉第2层*************
                    // 到此为止,strPath不含object或xpath层 strFirstPart可能是object 或 xpath

                    if (strFirstPart != "object"
                        && strFirstPart != "xpath")
                    {
                        strError = "资源路径 '" + strResPath + "' 不合法,第3级必须是'object'或'xpath'";
                        return -7;
                    }
                    if (strPath == "")  //object或xpath下级必须有值
                    {
                        strError = "资源路径 '" + strResPath + "' 不合法,当第3级是'object'或'xpath',第4级必须有内容。";
                        return -7;
                    }

                    if (strFirstPart == "object")
                    {
                        strObjectID = strPath;
                        bObject = true;
                    }
                    else
                    {
                        strXPath = strPath;
                        bObject = false;
                    }


                    //------------------------------------------------
                //开始处理资源
                //---------------------------------------------------

                DOWRITE:

                    // ****************************************


                    string strOutputRecordID = "";
                    nRet = db.CanonicalizeRecordID(strRecordID,
                        out strOutputRecordID,
                        out strError);
                    if (nRet == -1)
                    {
                        strError = "资源路径 '" + strResPath + "' 不合法,原因:记录号不能为'" + strRecordID + "'";
                        return -1;
                    }


                    // ************************************
                    // 处理记录和记录里的对象
                    if (bObject == true)  //对像
                    {
                        if (strOutputRecordID == "-1")
                        {
                            strError = "资源路径 '" + strResPath + "' 不合法,原因:保存对象资源时,记录号不能为'" + strRecordID + "'。";
                            return -1;
                        }
                        strRecordID = strOutputRecordID;

                        // return:
                        //		-1  出错
                        //		-2  时间戳不匹配
                        //      -4  记录或对象资源不存在
                        //      -6  权限不够
                        //		0   成功
                        nRet = db.WriteObject(user,
                            strRecordID,
                            strObjectID,
                            strRanges,
                            lTotalLength,
                            baSource,
                            streamSource,
                            strMetadata,
                            strStyle,
                            baInputTimestamp,
                            out baOutputTimestamp,
                            out strError);

                        strOutputResPath = strDbName + "/" + strRecordID + "/object/" + strObjectID;

                    }
                    else  // 记录体
                    {
                        strRecordID = strOutputRecordID;

                        string strOutputID = "";
                        // return:
                        //		-1  出错
                        //		-2  时间戳不匹配
                        //      -4  记录不存在
                        //      -6  权限不够
                        //		0   成功
                        nRet = db.WriteXml(user,
                            strRecordID,
                            strXPath,
                            strRanges,
                            lTotalLength,
                            baSource,
                            streamSource,
                            strMetadata,
                            strStyle,
                            baInputTimestamp,
                            out baOutputTimestamp,
                            out strOutputID,
                            out strOutputValue,
                            true,
                            out strError);

                        strRecordID = strOutputID;

                        if (strXPath == "")
                            strOutputResPath = strDbName + "/" + strRecordID;
                        else
                            strOutputResPath = strDbName + "/" + strRecordID + "/xpath/" + strXPath;

                    }
                }

                return nRet;
            }
            finally
            {
                //**********对库集合解写锁****************
                m_lock.ReleaseWriterLock();
#if DEBUG_LOCK
			this.WriteDebugInfo("WriteRes(),对库集合写写锁。");
#endif
            }
        }
Beispiel #20
0
        // 根据用户名从库中查找用户记录,得到用户对象
        // 对象尚未进入集合, 因此无需为对象加锁
        // parameters:
        //		strBelongDb	用户从属的数据库,中文名称
        //      user        out参数,返回帐户对象
        //      strError    out参数,返回出错信息
        // return:
        //		-1	出错
        //		0	未找到帐户
        //		1	找到了
        // 线:安全
        internal int ShearchUser(string strUserName,
            out User user,
            out string strError)
        {
            user = null;
            strError = "";

            int nRet = 0;

            DpResultSet resultSet = new DpResultSet();


            //*********对帐户库集合加读锁***********
            m_lock.AcquireReaderLock(m_nTimeOut);
#if DEBUG_LOCK
			this.WriteDebugInfo("ShearchUser(),对帐户库集合加读锁。");
#endif
            try
            {
                // return:
                //		-1	出错
                //		0	成功
                nRet = this.SearchUserInternal(strUserName,
                    resultSet,
                    out strError);
                if (nRet == -1)
                    return -1;
            }
            finally
            {
                //*********对帐户库集合解读锁*************
                m_lock.ReleaseReaderLock();
#if DEBUG_LOCK
				this.m_dbColl.WriteDebugInfo("ShearchUser(),对帐户库集合解读锁。");
#endif
            }

            // 根据用户名没找到对应的帐户记录
            long lCount = resultSet.Count;
            if (lCount == 0)
                return 0;

            if (lCount > 1)
            {
                strError = "用户名'" + strUserName + "'对应多条记录";
                return -1;
            }

            // 按第一个帐户算
            DpRecord record = (DpRecord)resultSet[0];

            // 创建一个DpPsth实例
            DbPath path = new DbPath(record.ID);

            // 找到指定帐户数据库
            Database db = this.GetDatabaseSafety(path.Name);
            if (db == null)
            {
                strError = "未找到'" + strUserName + "'帐户对应的名为'" + path.Name + "'的数据库对象";
                return -1;
            }

            // 从帐户库中找到记录
            string strXml = "";
            // return:
            //      -1  出错
            //      -4  记录不存在
            //      0   正确
            nRet = db.GetXmlDataSafety(path.ID,
                out strXml,
                out strError);
            if (nRet <= -1)  // 将-4与-1都作为-1返回
                return -1;

            //加载到dom
            XmlDocument dom = new XmlDocument();
            //dom.PreserveWhitespace = true; //设PreserveWhitespace为true
            try
            {
                dom.LoadXml(strXml);
            }
            catch (Exception ex)
            {
                strError = "加载用户 '" + strUserName + "' 的帐户记录到dom时出错,原因:" + ex.Message;
                return -1;
            }

            user = new User();
            // return:
            //      -1  出错
            //      0   成功
            nRet = user.Initial(
                record.ID,
                dom,
                db,
                this,
                out strError);
            if (nRet == -1)
                return -1;

            return 1;
        }
Beispiel #21
0
        // 写目录配置事项
        // parameters:
        //		strResPath	资源路径带库名
        //					原来是没有这个参数,为什么加上呢?
        //					是为报错时忠于原路径。如果为null或空字符串,则改为:库名路径/strCfgItemPath
        //		strStyle	风格 null认为是空字符串
        //					clear	表示清除下级
        //					autocreatedir	表示自动创建缺省的目录
        //		user	User对象,用来判断是否有权限,不能为null
        //		strCfgItemPath	配置事项路径,不带库名,不能为null或空字符串。???可以与strResPath一起用,但易乱
        //		strError	out参数,返回出错信息
        // return:
        //      -1  一般性错误
        //		-4	未指定路径对应的对象
        //		-6	权限不够
        //		-8	目录已存在
        //		-9	存在其它类型的事项
        //		0	成功
        // 线:不安全
        public int WriteDirCfgItem(string strCfgItemPath,
            string strStyle,
            User user,
            out string strError)
        {
            strError = "";
            int nRet = 0;

            if (String.IsNullOrEmpty(strCfgItemPath) == true)
            {
                strError = "WriteDirCfgItem()调入错误,strCfgItemPath不能为null或空字符串。";
                return -1;
            }

            List<XmlNode> list = DatabaseUtil.GetNodes(this.NodeDbs,
                strCfgItemPath);
            if (list.Count > 1)
            {
                strError = "服务器总配置文件不合法,路径为'" + strCfgItemPath + "'的配置事项对应的节点有'" + Convert.ToString(list.Count) + "'个。";
                return -1;
            }

            string strExistRights = "";
            bool bHasRight = false;

            // 已存在同名配置事项的情况
            if (list.Count == 1)
            {
                XmlNode node = list[0];
                if (node.Name == "file")
                {
                    strError = "服务器已存在路径为'" + strCfgItemPath + "'的配置文件,不能用目录覆盖文件。";
                    return -9;
                }
                if (node.Name == "database")
                {
                    strError = "服务器已存在名为'" + strCfgItemPath + "'的数据库,不能用目录覆盖数据库。";
                    return -9;
                }

                if (StringUtil.IsInList("clear", strStyle) == true)
                {
                    // 如果配置事项已存在,则检索是否有clear权限
                    string strPathForRights = strCfgItemPath;
                    bHasRight = user.HasRights(strPathForRights,
                        ResType.Directory,
                        "clear",
                        out strExistRights);
                    if (bHasRight == false)
                    {
                        strError = "您的帐户名为'" + user.Name + "',对路径为'" + strCfgItemPath + "'的配置事项没有'清空下级(clear)'权限,目前的权限值为'" + strExistRights + "'。";
                        return -6;
                    }

                    // 清空目录
                    // return:
                    //		-1	出错
                    //      -4  未指定路径对应的对象
                    //		0	成功
                    return this.ClearDirCfgItem(strCfgItemPath,
                        node,
                        out strError);
                }
                else
                {
                    strError = "服务器已存在路径为'" + strCfgItemPath + "'的配置目录。";
                    return -8;
                }
            }


            //***************************************

            bHasRight = user.HasRights(strCfgItemPath,
                ResType.Directory,
                "create",
                out strExistRights);
            if (bHasRight == false)
            {
                strError = "您的帐户名为'" + user.Name + "',对路径为'" + strCfgItemPath + "'的配置事项没有'清空下级(clear)'权限,目前的权限值为'" + strExistRights + "'。";
                return -6;
            }

            // return:
            //		-1	出错
            //		0	成功
            nRet = this.AutoCreateDirCfgItem(strCfgItemPath,
                out strError);
            if (nRet == -1)
                return -1;

            return 0;
        }
Beispiel #22
0
        // 获得数据定义方面的信息
        // parameters:
        //      strStyle            获得那些输出参数? all表示全部 分别指定则是logicnames/type/sqldbname/keystext/browsetext
        // return:
        //      -1  一般性错误
        //      -5  未找到数据库对象
        //      -6  没有足够的权限
        //      0   成功
        public int GetDbInfo(User user,
            string strDbName,
            string strStyle,
            out LogicNameItem[] logicNames,
            out string strType,
            out string strSqlDbName,
            out string strKeysText,
            out string strBrowseText,
            out string strError)
        {
            strError = "";

            logicNames = null;
            strType = "";
            strSqlDbName = "";
            strKeysText = "";
            strBrowseText = "";

            Debug.Assert(user != null, "GetDbInfo()调用错误,user参数不能为null。");

            if (String.IsNullOrEmpty(strDbName) == true)
            {
                strError = "GetDbInfo()调用不合法,strDbName参数值不能为null或空字符串。";
                return -1;
            }

            // 检查当前帐户是否有显示权限
            string strExistRights = "";
            bool bHasRight = user.HasRights(strDbName,
                ResType.Database,
                "read",
                out strExistRights);

            //******************对库集合加读锁******
            this.m_lock.AcquireReaderLock(m_nTimeOut);
#if DEBUG_LOCK
			this.WriteDebugInfo("GetDbInfo(),对库集合加读锁。");
#endif
            try
            {
                Database db = this.GetDatabase(strDbName);
                if (db == null)
                {
                    strError = "未找到名为'" + strDbName + "'的数据库。";
                    return -5;
                }

                if (bHasRight == false)
                {
                    strError = "您的帐户名为'" + user.Name + "',对'" + strDbName + "'数据库没有'读(read)'权限,目前的权限值为'" + strExistRights + "'。";
                    return -6;
                }

                // return:
                //		-1	出错
                //		0	正常
                return db.GetInfo(
                    strStyle,
                    out logicNames,
                    out strType,
                    out strSqlDbName,
                    out strKeysText,
                    out strBrowseText,
                    out strError);
            }
            finally
            {
                this.m_lock.ReleaseReaderLock();
                //*****************对库集合解读锁*************
#if DEBUG_LOCK
				this.WriteDebugInfo("GetDbInfo(),对库集合解读锁。");
#endif
            }
        }
Beispiel #23
0
        // 写文件配置事项
        // return:
        //      -1  一般性错误
        //      -2  时间戳不匹配
        //      -4  自动创建目录时,未找到上级
        //		-6	权限不够
        //		-9	存在其它类型的事项
        //		0	成功
        // 线程,不安全的
        internal int WriteFileCfgItem(string strCfgItemPath,
            string strRanges,
            long lTotalLength,
            byte[] baSource,
            Stream streamSource,
            string strMetadata,
            string strStyle,
            byte[] baInputTimestamp,
            User user,
            out byte[] baOutputTimestamp,
            out string strError)
        {
            baOutputTimestamp = null;
            strError = "";
            int nRet = 0;

            Debug.Assert(user != null, "WriteFileCfgItem()调用错误,user对象不能为null");

            //------------------------------------------------
            // 检查输入参数,并规范化输入参数
            //--------------------------------------------------
            if (lTotalLength <= -1)
            {
                strError = "WriteFileCfgItem()调用错误,lTotalLength值为'" + Convert.ToString(lTotalLength) + "'不合法,必须大于等于0。";
                return -1;
            }
            if (strStyle == null)
                strStyle = "";
            if (strRanges == null)
                strRanges = null;
            if (strMetadata == null)
                strMetadata = "";

            if (baSource == null && streamSource == null)
            {
                strError = "WriteFileCfgItem()调用错误,baSource参数与streamSource参数不能同时为null。";
                return -1;
            }
            if (baSource != null && streamSource != null)
            {
                strError = "WriteFileCfgItem()调用错误,baSource参数与streamSource参数只能有一个被赋值。";
                return -1;
            }

            if (strCfgItemPath == null || strCfgItemPath == "")
            {
                strError = "WriteFileCfgItem()调用错误,strResPath不能为null或空字符串。";
                return -1;
            }

            //------------------------------------------------
            // 开始做事情
            //--------------------------------------------------

            List<XmlNode> list = DatabaseUtil.GetNodes(this.NodeDbs,
                strCfgItemPath);
            if (list.Count > 1)
            {
                strError = "服务器总配置文件不合法,路径为'" + strCfgItemPath + "'的配置事项对应的节点有'" + Convert.ToString(list.Count) + "'个。";
                return -1;
            }

            string strExistRights = "";
            bool bHasRight = false;


            //------------------------------------------------
            // 已存在同名配置事项的情况
            //--------------------------------------------------

            if (list.Count == 1)
            {
                XmlNode node = list[0];
                if (node.Name == "dir")
                {
                    strError = "服务器已存在路径为'" + strCfgItemPath + "'的配置目录,不能用文件覆盖目录。";
                    return -9;
                }
                if (node.Name == "database")
                {
                    strError = "服务器已存在名为'" + strCfgItemPath + "'的数据库,不能用文件覆盖数据库。";
                    return -9;
                }

                // 如果配置事项已存在,则检索是否有overwrite权限
                string strPathForRights = strCfgItemPath;
                bHasRight = user.HasRights(strPathForRights,
                    ResType.File,
                    "overwrite",
                    out strExistRights);
                if (bHasRight == false)
                {
                    strError = "您的帐户名为'" + user.Name + "',对路径为'" + strCfgItemPath + "'的配置事项没有'覆盖(overwrite)'权限,目前的权限值为'" + strExistRights + "'。";
                    return -6;
                }

                // 如果按正规的渠道创建配置文件,
                // 则内存对象中已存在,那么物理文件名一定存在,则物理文件一定存在
                string strLocalPath = "";
                // return:
                //		-1	一般性错误,比如调用错误,参数不合法等
                //		-2	没找到节点
                //		-3	localname属性未定义或为值空
                //		-4	localname在本地不存在
                //		-5	存在多个节点
                //		0	成功
                nRet = this.GetFileCfgItemLacalPath(strCfgItemPath,
                    out strLocalPath,
                    out strError);
                if (nRet != 0)
                {
                    if (nRet != -4)
                        return -1;
                }

                goto DOWRITE;
            }


            //------------------------------------------------
            // 不存在配置事项的情况
            //--------------------------------------------------


            string strParentCfgItemPath = ""; //父亲的路径
            string strThisCfgItemName = ""; //本配置事项的名称
            int nIndex = strCfgItemPath.LastIndexOf('/');
            if (nIndex != -1)
            {
                strParentCfgItemPath = strCfgItemPath.Substring(0, nIndex);
                strThisCfgItemName = strCfgItemPath.Substring(nIndex + 1);
            }
            else
            {
                strThisCfgItemName = strCfgItemPath;
            }

            XmlNode nodeParent = null;
            // 对上级路径进行检查
            if (strParentCfgItemPath != "")
            {
                List<XmlNode> parentNodes = DatabaseUtil.GetNodes(this.NodeDbs,
                    strParentCfgItemPath);
                if (parentNodes.Count > 1)
                {
                    nIndex = strCfgItemPath.LastIndexOf("/");
                    string strTempParentPath = strCfgItemPath.Substring(0, nIndex);
                    strError = "服务器端路径为'" + strTempParentPath + "'的配置事项有'" + Convert.ToString(parentNodes.Count) + "'个,配置文件不合法。";
                    return -1;
                }

                if (parentNodes.Count == 1)
                {
                    nodeParent = parentNodes[0];
                }
                else
                {

                    if (StringUtil.IsInList("autocreatedir", strStyle, true) == false)
                    {
                        nIndex = strCfgItemPath.LastIndexOf("/");
                        string strTempParentPath = strCfgItemPath.Substring(0, nIndex);
                        strError = "未找到路径为'" + strTempParentPath + "'配置事项,无法创建下级文件。";
                        return -4;
                    }

                    // return:
                    //		-1	出错
                    //		0	成功
                    nRet = this.AutoCreateDirCfgItem(strParentCfgItemPath,
                        out strError);
                    if (nRet == -1)
                        return -1;

                    parentNodes = DatabaseUtil.GetNodes(this.NodeDbs,
                        strParentCfgItemPath);
                    if (parentNodes.Count != 1)
                    {
                        strError = "WriteFileCfgItem(),自动创建好上级目录了,此时不可能找不到路径为'" + strParentCfgItemPath + "'的配置事项了。";
                        return -1;
                    }

                    nodeParent = parentNodes[0];
                }
            }
            else
            {
                nodeParent = this.NodeDbs;
            }


            // 检查上级是否有指定权限
            bHasRight = user.HasRights(strCfgItemPath,
                ResType.File,
                "create",
                out strExistRights);
            if (bHasRight == false)
            {
                strError = "您的帐户名为'" + user.Name + "',对'" + strCfgItemPath + "',没有'创建(create)'权限,目前的权限值为'" + strExistRights + "'。";
                return -6;
            }


            // return:
            //		-1	出错
            //		0	成功
            nRet = this.SetFileCfgItem(strParentCfgItemPath,
                nodeParent,
                strThisCfgItemName,
                out strError);
            if (nRet == -1)
                return -1;


        DOWRITE:

            string strFilePath = "";//GetCfgItemLacalPath(strCfgItemPath);
            // return:
            //		-1	一般性错误,比如调用错误,参数不合法等
            //		-2	没找到节点
            //		-3	localname属性未定义或为值空
            //		-4	localname在本地不存在
            //		-5	存在多个节点
            //		0	成功
            nRet = this.GetFileCfgItemLacalPath(strCfgItemPath,
                out strFilePath,
                out strError);
            if (nRet != 0)
            {
                if (nRet != -4)
                    return -1;
            }

            string strTempPath = strCfgItemPath;
            string strFirstPart = StringUtil.GetFirstPartPath(ref strTempPath);
            Database db = this.GetDatabase(strFirstPart);
            if (db != null)
            {

                // return:
                //		-1  一般性错误
                //      -2  时间戳不匹配
                //		0	成功
                return db.WriteFileForCfgItem(strCfgItemPath,
                    strFilePath,
                     strRanges,
                     lTotalLength,
                     baSource,
                     streamSource,
                     strMetadata,
                     strStyle,
                     baInputTimestamp,
                     out baOutputTimestamp,
                     out strError);
            }
            else
            {
                // 不从属于某一个数据库的配置文件
                // return:
                //		-1	一般性错误
                //		-2	时间戳不匹配
                //		0	成功
                return this.WriteFileForCfgItem(strFilePath,
                    strRanges,
                    lTotalLength,
                    baSource,
                    streamSource,
                    strMetadata,
                    strStyle,
                    baInputTimestamp,
                    out baOutputTimestamp,
                    out strError);
            }
        }
Beispiel #24
0
        // 写xml数据
        // parameter:
        //		strID	        记录ID -1:表示追加一条记录
        //		strRanges	    目标的位置,多个range用逗号分隔
        //		nTotalLength	总长度
        //		inputTimestamp	输入的时间戳
        //		outputTimestamp	out参数,返回的时间戳
        //		strOutputID	    out参数,返回的记录ID,当strID == -1时,得到实际的ID
        //		strError	    out参数,返回出错信息
        // return:
        // return:
        //		-1  出错
        //		-2  时间戳不匹配
        //      -4  记录不存在
        //      -6  权限不够
        //		0   成功
        // ??? AddInteger+,+AddInteger,Push好像没有实现
        public override int WriteXml(User oUser,
            string strID,
            string strXPath,
            string strRanges,
            long lTotalLength,
            byte[] baSource,
            // Stream streamSource,
            string strMetadata,
            string strStyle,
            byte[] inputTimestamp,
            out byte[] outputTimestamp,
            out string strOutputID,
            out string strOutputValue,
            bool bCheckAccount,
            out string strError)
        {
            outputTimestamp = null;
            strOutputID = "";
            strOutputValue = "";
            strError = "";

            if (strID == "?")
                strID = "-1";

            // 确保ID,并且给返回值赋值
            bool bPushTailNo = false;
            bPushTailNo = this.EnsureID(ref strID);
            if (oUser != null)
            {
                string strTempRecordPath = this.GetCaption("zh-CN") + "/" + strID;
                if (bPushTailNo == true)
                {
                    string strExistRights = "";
                    bool bHasRight = oUser.HasRights(strTempRecordPath,
                        ResType.Record,
                        "create",
                        out strExistRights);
                    if (bHasRight == false)
                    {
                        strError = "您的帐户名为'" + oUser.Name + "',对'" + strTempRecordPath + "'记录没有'创建(create)'权限,目前的权限值为'" + strExistRights + "'。";
                        return -6;
                    }
                }
                else
                {
                    string strExistRights = "";
                    bool bHasRight = oUser.HasRights(strTempRecordPath,
                        ResType.Record,
                        "overwrite",
                        out strExistRights);
                    if (bHasRight == false)
                    {
                        strError = "您的帐户名为'" + oUser.Name + "',对'" + strTempRecordPath + "'记录没有'覆盖(overwrite)'权限,目前的权限值为'" + strExistRights + "'。";
                        return -6;
                    }
                }
            }

            strOutputID = DbPath.GetCompressedID(strID);
            int nRet;
            int nFull = -1;

            //***********对数据库加读锁***********
            m_db_lock.AcquireReaderLock(m_nTimeOut);
#if DEBUG_LOCK
			this.container.WriteDebugInfo("WriteXml(),对'" + this.GetCaption("zh-CN") + "'数据库加读锁。");
#endif
            try
            {
                strID = DbPath.GetID10(strID);
                //**********对记录加写锁***************
                m_recordLockColl.LockForWrite(strID, m_nTimeOut);
#if DEBUG_LOCK
				this.container.WriteDebugInfo("WriteXml(),对'" + this.GetCaption("zh-CN") + "/" + strID + "'记录加写锁。");
#endif
                try
                {
                    string strXmlFilePath = this.GetXmlFilePath(strID);
                    bool bExist = File.Exists(strXmlFilePath);
                    if (bExist == false)
                    {
                        //创建新文件,并把辅助信息创建好
                        this.InsertRecord(strID,
                            strStyle,
                            inputTimestamp,
                            out inputTimestamp);
                        // 创建后存在一个字节,所有信息都有了
                    }

                    nRet = this.WriteFileDbTempRecord(strXmlFilePath,
                        strRanges,
                        lTotalLength,
                        baSource,
                        // streamSource,
                        strMetadata,
                        strStyle,
                        inputTimestamp,
                        out outputTimestamp,
                        out nFull,
                        out strError);
                    if (nRet <= -1)
                        return nRet;

                    if (nFull == 1)  // 文件已满
                    {
                        // 1.得到新旧检索点
                        string strNewFileName = DatabaseUtil.GetNewFileName(strXmlFilePath);
                        string strNewXml = FileUtil.File2StringE(strNewFileName);
                        string strOldXml = FileUtil.File2StringE(strXmlFilePath);

                        if (strXPath != null
                            && strXPath != "")
                        {
                            string strLocateXPath = "";
                            string strCreatePath = "";
                            string strNewRecordTemplate = "";
                            string strAction = "";
                            nRet = DatabaseUtil.ParseXPathParameter(strXPath,
                                out strLocateXPath,
                                out strCreatePath,
                                out strNewRecordTemplate,
                                out strAction,
                                out strError);
                            if (nRet == -1)
                                return -1;

                            XmlDocument tempDom = new XmlDocument();
                            tempDom.PreserveWhitespace = true; //设PreserveWhitespace为true
                            try
                            {
                                if (strOldXml == "")
                                {
                                    if (strNewRecordTemplate == "")
                                        tempDom.LoadXml("<root/>");
                                    else
                                        tempDom.LoadXml(strNewRecordTemplate);
                                }
                                else
                                    tempDom.LoadXml(strOldXml);
                            }
                            catch (Exception ex)
                            {
                                strError = "WriteXml() 在给'" + this.GetCaption("zh-CN") + "'库写入记录'" + strID + "'时,装载旧记录到dom出错,原因:" + ex.Message;
                                return -1;
                            }

                            if (strLocateXPath == "")
                            {
                                strError = "xpath表达式中的locate参数不能为空值";
                                return -1;
                            }

                            // 通过strLocateXPath定位到指定的节点
                            XmlNode node = null;
                            try
                            {
                                node = tempDom.DocumentElement.SelectSingleNode(strLocateXPath);
                            }
                            catch (Exception ex)
                            {
                                strError = "WriteXml() 在给'" + this.GetCaption("zh-CN") + "'库写入记录'" + strID + "'时,XPath式子'" + strXPath + "'选择元素时出错,原因:" + ex.Message;
                                return -1;
                            }

                            if (node == null)
                            {
                                if (strLocateXPath == "")
                                {
                                    strError = "xpath表达式中的create参数不能为空值";
                                    return -1;
                                }
                                node = DomUtil.CreateNodeByPath(tempDom.DocumentElement,
                                    strCreatePath);
                                if (node == null)
                                {
                                    strError = "内部错误!";
                                    return -1;
                                }
                            }

                            //Create a document fragment.
                            XmlDocumentFragment docFrag = tempDom.CreateDocumentFragment();

                            //Set the contents of the document fragment.
                            docFrag.InnerXml = strNewXml;

                            //Add the children of the document fragment to the
                            //original document.
                            node.ParentNode.InsertBefore(docFrag, node);


                            if (strAction == "AddInteger"
                                || strAction == "AppendString")
                            {
                                XmlNode newNode = node.PreviousSibling;
                                if (newNode == null)
                                {
                                    strError = "newNode不可能为null";
                                    return -1;
                                }

                                string strNewValue = newNode.InnerText;
                                string strOldValue = node.InnerText.Trim(); // 2012/2/16
                                if (strAction == "AddInteger")
                                {

                                    int nNumber = 0;
                                    try
                                    {
                                        nNumber = Convert.ToInt32(strNewValue);
                                    }
                                    catch (Exception ex)
                                    {
                                        strError = "传入的内容'" + strNewXml + "'不是数字格式。" + ex.Message;
                                        return -1;
                                    }

                                    string strLastValue;
                                    nRet = StringUtil.IncreaseNumber(strOldValue,
                                        nNumber,
                                        out strLastValue,
                                        out strError);
                                    if (nRet == -1)
                                        return -1;

                                    newNode.InnerText = strLastValue;
                                    strOutputValue = newNode.OuterXml;
                                }
                                else if (strAction == "AppendString")
                                {
                                    newNode.InnerText = strOldValue + strNewValue;
                                    strOutputValue = newNode.OuterXml;
                                }
                            }

                            node.ParentNode.RemoveChild(node);

                            strNewXml = tempDom.OuterXml;
                        }


                        KeyCollection newKeys = null;
                        KeyCollection oldKeys = null;
                        XmlDocument newDom = null;
                        XmlDocument oldDom = null;

                        // return:
                        //      -1  出错
                        //      0   成功
                        nRet = this.MergeKeys(strID,
                            strNewXml,
                            strOldXml,
                            true,
                            out newKeys,
                            out oldKeys,
                            out newDom,
                            out oldDom,
                            out strError);
                        if (nRet == -1)
                            return -1;

                        this.AddKeys(newKeys);
                        this.DeleteKeys(oldKeys);

                        // 3.处理子文件
                        nRet = this.ProcessFiles(strID,
                            newDom,
                            oldDom,
                            out strError);
                        if (nRet <= -1)
                            return nRet;

                        // 4.用newdata替换data
                        // 先把xml数据更新了,再更新检索点
                        if (strXPath != null
                            && strXPath != "")
                        {
                            FileUtil.String2File(strNewXml,
                                strXmlFilePath);
                        }
                        else
                        {
                            File.Copy(strNewFileName,
                                strXmlFilePath,
                                true);
                        }

                        // 5.删除newdata字段
                        File.Delete(strNewFileName);

                    }
                }
                catch (Exception ex)
                {
                    strError = "WriteXml() 在给'" + this.GetCaption("zh-CN") + "'库写入记录'" + strID + "'时出错,原因:" + ex.Message;
                    return -1;
                }
                finally
                {
                    //*********对记录解写锁****************************
                    m_recordLockColl.UnlockForWrite(strID);
#if DEBUG_LOCK
					this.container.WriteDebugInfo("WriteXml(),对'" + this.GetCaption("zh-CN") + "/" + strID + "'记录解写锁。");
#endif
                }
            }
            finally
            {
                //**********对数据库解读锁**************
                m_db_lock.ReleaseReaderLock();
#if DEBUG_LOCK
				this.container.WriteDebugInfo("WriteXml(),对'" + this.GetCaption("zh-CN") + "'数据库解读锁。");
#endif
            }

            // 当本函数被明知为账户库的写操作调用时, 一定要用bCheckAccount==false
            // 来调用,否则容易引起不必要的递归
            if (nFull == 1
                && bCheckAccount == true
                && StringUtil.IsInList("account", this.TypeSafety) == true)
            {
                string strResPath = this.FullID + "/" + strID;
                this.container.UserColl.RefreshUserSafety(
                    strResPath);
            }
            return 0;
        }
Beispiel #25
0
        // GetRes()用range不太好实现,因为原来当请求的长度超过允许的长度时,长度会自动为截取
        // 而如果用range来表示,则不知该截短哪部分好。
        // parameter:
        //		strResPath		资源路径,不能为null或空字符串
        //						资源类型可以是数据库配置事项(目录或文件),记录体,对象资源,部分记录体
        //						配置事项: 库名/配置事项路径
        //						记录体: 库名/记录号
        //						对象资源: 库名/记录号/object/资源ID
        //						部分记录体: 库名/记录/xpath/<locate>hitcount</locate><action>AddInteger</action> 或者 库名/记录/xpath/@hitcount
        //		lStart	起始长度
        //		lLength	总长度,-1:从start到最后
        //		strStyle	取资源的风格,以逗豆间隔的字符串
        /*
        strStyle用法

        1.控制数据存放的位置
        content		把返回的数据放到字节数组参数里
        attachment	把返回的数据放到附件中,并返回附件的id

        2.控制返回的数据
        metadata	返回metadata信息
        timestamp	返回timestamp
        length		数据总长度,始终都有值
        data		返回数据体
        respath		返回记录路径,目前始终都有值
        all			返回所有值

        3.控制记录号
        prev		前一条
        prev,self	自己或前一条
        next		下一条
        next,self	自己或下一条
        放到strOutputResPath参数里

        */
        //		baContent	用content字节数组返回资源内容
        //		strAttachmentID	用附件返回资源内容
        //		strMetadata	返回的metadata内容
        //		strOutputResPath	返回的资源路径
        //		baTimestamp	返回的资源时间戳
        // return:
        //		-1	一般性错误
        //		-4	未找到路径指定的资源
        //		-5	未找到数据库
        //		-6	没有足够的权限
        //		-7	路径不合法
        //		-10	未找到记录xpath对应的节点
        //		>= 0	成功,返回最大长度
        //      nAdditionError -50 有一个以上下级资源记录不存在
        // 线:安全
        public long GetRes(string strResPath,
            int nStart,
            int nLength,
            string strStyle,
            User user,
            int nMaxLength,
            out byte[] baData,
            out string strMetadata,
            out string strOutputResPath,
            out byte[] baOutputTimestamp,
            out int nAdditionError, // 附加的错误码
            out string strError)
        {
            baData = null;
            strMetadata = "";
            strOutputResPath = "";
            baOutputTimestamp = null;
            strError = "";
            nAdditionError = 0;

            //------------------------------------------------
            //检查输入参数是否合法,并规范输入参数
            //---------------------------------------------------

            Debug.Assert(user != null, "GetRes()调用错误,user对象不能为null。");

            if (user == null)
            {
                strError = "GetRes()调用错误,user对象不能为null。";
                return -1;
            }
            if (String.IsNullOrEmpty(strResPath) == true)
            {
                strError = "资源路径'" + strResPath + "'不合法,不能为null或空字符串。";
                return -7;
            }
            if (nStart < 0)
            {
                strError = "GetRes()调用错误,nStart不能小于0。";
                return -1;
            }
            if (strStyle == null)
                strStyle = "";


            //------------------------------------------------
            // 开始做事情
            //---------------------------------------------------

            //******************加库集合加读锁******
            this.m_lock.AcquireReaderLock(m_nTimeOut);

#if DEBUG_LOCK
			this.WriteDebugInfo("GetRes(),对库集合加读锁。");
#endif
            try
            {
                long nRet = 0;

                bool bRecordPath = this.IsRecordPath(strResPath);
                if (bRecordPath == false)
                {
                    //当配置事项处理
                    // return:
                    //		-1  一般性错误
                    //		-4	未找到路径对应的对象
                    //		-6	没有足够的权限
                    //		>= 0    成功 返回最大长度
                    nRet = this.GetFileCfgItem(strResPath,
                        nStart,
                        nLength,
                        nMaxLength,
                        strStyle,
                        user,
                        out baData,
                        out strMetadata,
                        out baOutputTimestamp,
                        out strError);


                    if (StringUtil.IsInList("outputpath", strStyle) == true)
                    {
                        strOutputResPath = strResPath;
                    }
                }
                else
                {

                    // 判断资源类型
                    string strPath = strResPath;
                    string strDbName = StringUtil.GetFirstPartPath(ref strPath);
                    //***********吃掉第1层*************
                    // 到此为止,strPath不含数据库名了,下面的路径有两种情况:cfgs;其余都被当作记录id
                    if (strPath == "")
                    {
                        strError = "资源路径'" + strResPath + "'路径不合法,未指定库的下级。";
                        return -7;
                    }

                    // 从这里区别是数据库还是服务器端配置文件

                    // 根据资源类型,写资源
                    Database db = this.GetDatabase(strDbName);
                    if (db == null)
                    {
                        strError = "未找到'" + strDbName + "'库";
                        return -5;
                    }

                    bool bObject = false;
                    string strRecordID = "";
                    string strObjectID = "";
                    string strXPath = "";

                    string strFirstPart = StringUtil.GetFirstPartPath(ref strPath);
                    //***********吃掉第2层*************
                    // 到此为止,strPath记录号层了,下级分情况判断

                    strRecordID = strFirstPart;
                    // 只到记录号层的路径
                    if (strPath == "")
                    {
                        bObject = false;
                        goto DOGET;
                    }

                    strFirstPart = StringUtil.GetFirstPartPath(ref strPath);
                    //***********吃掉第2层*************
                    // 到此为止,strPath不含object或xpath层 strFirstPart可能是object 或 xpath
                    if (strFirstPart != "object"
                        && strFirstPart != "xpath")
                    {
                        strError = "资源路径 '" + strResPath + "' 不合法,第3级必须是'object'或'xpath'";
                        return -7;
                    }
                    if (strPath == "")  //object或xpath下级必须有值
                    {
                        strError = "资源路径 '" + strResPath + "' 不合法,当第3级是'object'或'xpath',第4级必须有内容。";
                        return -7;
                    }

                    if (strFirstPart == "object")
                    {
                        strObjectID = strPath;
                        bObject = true;
                    }
                    else
                    {
                        strXPath = strPath;
                        bObject = false;
                    }

                    ///////////////////////////////////
                ///开始做事情
                //////////////////////////////////////////

                DOGET:


                    // 检查对数据库中记录的权限
                    string strExistRights = "";
                    bool bHasRight = user.HasRights(strDbName + "/" + strRecordID,
                        ResType.Record,
                        "read",
                        out strExistRights);
                    if (bHasRight == false)
                    {
                        strError = "您的帐户名为'" + user.Name + "',对'" + strDbName + "'库没有'读记录(read)'权限,目前的权限值为'" + strExistRights + "'。";
                        return -6;
                    }

                    if (bObject == true)  //对像
                    {
                        //		-1  出错
                        //		-4  记录不存在
                        //		>=0 资源总长度
                        nRet = db.GetObject(strRecordID,
                            strObjectID,
                            nStart,
                            nLength,
                            nMaxLength,
                            strStyle,
                            out baData,
                            out strMetadata,
                            out baOutputTimestamp,
                            out strError);

                        if (StringUtil.IsInList("outputpath", strStyle) == true)
                        {
                            strOutputResPath = strDbName + "/" + strRecordID + "/object/" + strObjectID;

                        }
                    }
                    else
                    {
                        string strOutputID;
                        // return:
                        //		-1  出错
                        //		-4  未找到记录
                        //      -10 记录局部未找到
                        //		>=0 资源总长度
                        //      nAdditionError -50 有一个以上下级资源记录不存在
                        nRet = db.GetXml(strRecordID,
                            strXPath,
                            nStart,
                            nLength,
                            nMaxLength,
                            strStyle,
                            out baData,
                            out strMetadata,
                            out strOutputID,
                            out baOutputTimestamp,
                            true,
                            out nAdditionError,
                            out strError);
                        if (StringUtil.IsInList("outputpath", strStyle) == true)
                        {
                            strRecordID = strOutputID;
                        }

                        if (StringUtil.IsInList("outputpath", strStyle) == true)
                        {
                            if (strXPath == "")
                                strOutputResPath = strDbName + "/" + strRecordID;
                            else
                                strOutputResPath = strDbName + "/" + strRecordID + "/xpath/" + strXPath;

                        }
                    }
                }

                return nRet;

            }
            finally
            {
                //******************对库集合解读锁******
                this.m_lock.ReleaseReaderLock();
#if DEBUG_LOCK
			this.WriteDebugInfo("GetRes(),对库集合解读锁。");
#endif
            }
        }
Beispiel #26
0
        // parameters:
        //      strRecorID   记录ID
        //      strObjectID  对象ID
        //      其它参数同WriteXml,无strOutputID参数
        // return:
        //		-1  出错
        //		-2  时间戳不匹配
        //      -4  记录或对象资源不存在
        //      -6  权限不够
        //		0   成功
        public override int WriteObject(User user,
            string strRecordID,
            string strObjectID,
            string strRanges,
            long lTotalLength,
            byte[] baSource,
            Stream streamSource,
            string strMetadata,
            string strStyle,
            byte[] inputTimestamp,
            out byte[] outputTimestamp,
            out string strError)
        {
            outputTimestamp = null;
            strError = "";
            int nRet = 0;



            if (user != null)
            {
                string strTempRecordPath = this.GetCaption("zh-cn") + "/" + strRecordID;
                string strExistRights = "";
                bool bHasRight = user.HasRights(strTempRecordPath,
                    ResType.Record,
                    "overwrite",
                    out strExistRights);
                if (bHasRight == false)
                {
                    strError = "您的帐户名为'" + user.Name + "',对'" + strTempRecordPath + "'记录没有'覆盖(overwrite)'权限,目前的权限值为'" + strExistRights + "'。";
                    return -6;
                }
            }

            //**********对数据库加读锁************
            m_lock.AcquireReaderLock(m_nTimeOut);
#if DEBUG_LOCK_SQLDATABASE
			this.container.WriteDebugInfo("WriteObject(),对'" + this.GetCaption("zh-cn") + "'数据库加读锁。");
#endif
            try
            {
                string strOutputRecordID = "";
                // return:
                //      -1  出错
                //      0   成功
                nRet = this.CanonicalizeRecordID(strRecordID,
                    out strOutputRecordID,
                    out strError);
                if (nRet == -1)
                    return -1;
                if (strOutputRecordID == "-1")
                {
                    strError = "保存对象资源不支持记录号参数值为'" + strRecordID + "'。";
                    return -1;
                }
                strRecordID = strOutputRecordID;


                //**********对记录加写锁***************
                m_recordLockColl.LockForWrite(strRecordID, m_nTimeOut);
#if DEBUG_LOCK_SQLDATABASE
				this.container.WriteDebugInfo("WriteObject(),对'" + this.GetCaption("zh-cn") + "/" + strRecordID + "'记录加写锁。");
#endif
                try // 记录锁
                {
                    // 打开连接对象
                    SqlConnection connection = new SqlConnection(this.m_strConnString);
                    connection.Open();
                    try // 连接
                    {
                        // 1.在对应的xml数据,用对象路径找到对象ID
                        string strXml;
                        // return:
                        //      -1  出错
                        //      -4  记录不存在
                        //      0   正确
                        nRet = this.GetXmlString(connection,
                            strRecordID,
                            out strXml,
                            out strError);
                        if (nRet <= -1)
                        {
                            strError = "保存'" + strRecordID + "/" + strObjectID + "'资源失败,原因:" + strError;
                            return nRet;
                        }
                        XmlDocument xmlDom = new XmlDocument();
                        xmlDom.PreserveWhitespace = true; //设PreserveWhitespace为true

                        xmlDom.LoadXml(strXml);

                        XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDom.NameTable);
                        nsmgr.AddNamespace("dprms", DpNs.dprms);
                        XmlNode fileNode = xmlDom.DocumentElement.SelectSingleNode("//dprms:file[@id='" + strObjectID + "']", nsmgr);
                        if (fileNode == null)
                        {
                            strError = "在数据xml里没有找到该ID对应的dprms:file节点";
                            return -1;
                        }

                        strObjectID = strRecordID + "_" + strObjectID;

                        // 2. 当记录为空记录时,用updata更改文本指针
                        if (this.IsEmptyObject(connection, strObjectID) == true)
                        {
                            // return
                            //		-1  出错
                            //		0   成功
                            nRet = this.UpdateObject(connection,
                                strObjectID,
                                out inputTimestamp,
                                out strError);
                            if (nRet == -1)
                                return -1;
                        }

                        // 3.把数据写到range指定的范围
                        bool bFull = false;
                        // return:
                        //		-1	一般性错误
                        //		-2	时间戳不匹配
                        //		0	成功
                        nRet = this.WriteSqlRecord(connection,
                            strObjectID,
                            strRanges,
                            (int)lTotalLength,
                            baSource,
                            streamSource,
                            strMetadata,
                            strStyle,
                            inputTimestamp,
                            out outputTimestamp,
                            out bFull,
                            out strError);
                        if (nRet <= -1)
                            return nRet;



                        //string strCurrentRange = this.GetRange(connection,strObjectID);
                        if (bFull == true)  //覆盖完了
                        {
                            // 1. 用newdata替换data字段
                            // return:
                            //      -1  出错
                            //      >=0   成功 返回影响的记录数
                            nRet = this.UpdateDataField(connection,
                                strObjectID,
                                out strError);
                            if (nRet == -1)
                                return -1;

                            // 2. 删除newdata字段
                            // return:
                            //		-1  出错
                            //		0   成功
                            nRet = this.DeleteDuoYuImage(connection,
                                strObjectID,
                                "newdata",
                                0,
                                out strError);
                            if (nRet == -1)
                                return -1;
                        }

                        // 负责修改一下记录的时间戳
                        string strNewTimestamp = this.CreateTimestampForDb();
                        // return:
                        //      -1  出错
                        //      >=0   成功 返回被影响的记录数
                        nRet = this.SetTimestampForDb(connection,
                            strRecordID,
                            strNewTimestamp,
                            out strError);
                        if (nRet == -1)
                            return -1;
                    }
                    catch (SqlException sqlEx)
                    {
                        if (sqlEx.Errors is SqlErrorCollection)
                            strError = "数据库'" + this.GetCaption("zh") + "'尚未初始化。";
                        else
                            strError = sqlEx.Message;
                        return -1;
                    }
                    catch (Exception ex)
                    {
                        strError = "WriteXml() 在给'" + this.GetCaption("zh-cn") + "'库写入资源'" + strObjectID + "'时出错,原因:" + ex.Message;
                        return -1;
                    }
                    finally // 连接
                    {
                        connection.Close();
                    }
                }
                finally // 记录锁
                {
                    //*********对记录解写锁****************************
                    m_recordLockColl.UnlockForWrite(strRecordID);
#if DEBUG_LOCK_SQLDATABASE
					this.container.WriteDebugInfo("WriteObject(),对'" + this.GetCaption("zh-cn") + "/" + strRecordID + "'记录解写锁。");
#endif

                }
            }
            finally
            {
                //************对数据库解读锁************
                m_lock.ReleaseReaderLock();
#if DEBUG_LOCK_SQLDATABASE
				this.container.WriteDebugInfo("WriteObject(),对'" + this.GetCaption("zh-cn") + "'数据库解读锁。");
#endif

            }

            return 0;
        }
Beispiel #27
0
        // 按指定范围读配置文件
        // strRoleName:  角色名,大小写均可
        // 其它参数同GetXml(),无strOutputResPath参数
        // 线: 安全的
        // return:
        //		-1  一般性错误
        //		-4	未找到路径对应的对象
        //		-6	没有足够的权限
        //		>= 0    成功 返回最大长度
        // 线:安全
        public int GetFileCfgItem(string strCfgItemPath,
            int nStart,
            int nLength,
            int nMaxLength,
            string strStyle,
            User user,
            out byte[] destBuffer,
            out string strMetadata,
            out byte[] outputTimestamp,
            out string strError)
        {
            strMetadata = "";
            destBuffer = null;
            outputTimestamp = null;
            strError = "";

            // 检查当前帐户对配置事项的权限,暂时不报权限的错,检查完对象是否存在,再报错
            string strExistRights = "";
            bool bHasRight = user.HasRights(strCfgItemPath,
                ResType.File,
                "read",
                out strExistRights);


            //**********对数据库集合加读锁**************
            this.m_lock.AcquireReaderLock(m_nTimeOut);
#if DEBUG_LOCK
			this.container.WriteDebugInfo("GetCfgFile(),对'" + this.GetCaption("zh-cn") + "'数据库集合加读锁。");
#endif
            try
            {

                string strFilePath = "";//this.GetCfgItemLacalPath(strCfgItemPath);
                // return:
                //		-1	一般性错误,比如调用错误,参数不合法等
                //		-2	没找到节点
                //		-3	localname属性未定义或为值空
                //		-4	localname在本地不存在
                //		-5	存在多个节点
                //		0	成功
                int nRet = this.GetFileCfgItemLacalPath(strCfgItemPath,
                    out strFilePath,
                    out strError);
                if (nRet != 0)
                {
                    if (nRet == -2)
                        return -4;
                    return -1;
                }

                // 此时再报权限的错
                if (bHasRight == false)
                {
                    strError = "您的帐户名为'" + user.Name + "',对路径为'" + strCfgItemPath + "'的配置事项没有'读(read)'权限,目前的权限值为'" + strExistRights + "'。";
                    return -6;
                }

                // return:
                //		-1      出错
                //		>= 0	成功,返回最大长度
                return DatabaseCollection.GetFileForCfgItem(strFilePath,
                    nStart,
                    nLength,
                    nMaxLength,
                    strStyle,
                    out destBuffer,
                    out strMetadata,
                    out outputTimestamp,
                    out strError);
            }
            finally
            {
                //****************对数据库集合解读锁**************
                this.m_lock.ReleaseReaderLock();
#if DEBUG_LOCK	
				this.container.WriteDebugInfo("GetCfgFile(),对'" + this.GetCaption("zh-cn") + "'数据库集合解读锁。");
#endif
            }
        }