/// <summary>
        /// Parse Inline ParameterMap
        /// </summary>
        /// <param name="dataExchangeFactory">The data exchange factory.</param>
        /// <param name="statementId">The statement id.</param>
        /// <param name="statement">The statement.</param>
        /// <param name="sqlStatement">The SQL statement.</param>
        /// <returns>A new sql command text.</returns>
        internal static SqlText ParseInlineParameterMap(DataExchangeFactory dataExchangeFactory, string statementId, IStatement statement, string sqlStatement)
        {
            string newSql = sqlStatement;
            List<ParameterProperty> mappingList = new List<ParameterProperty>();
            Type parameterClassType = null;

            if (statement != null)
            {
                parameterClassType = statement.ParameterClass;
            }

            if (sqlStatement.Contains(NEW_BEGIN_TOKEN))
            {
                // V3 parameter syntax
                //@{propertyName,column=string,type=string,dbtype=string,direction=[Input/Output/InputOutput],nullValue=string,handler=string}

                if (newSql != null)
                {
                    string toAnalyse = newSql;
                    int start = toAnalyse.IndexOf(NEW_BEGIN_TOKEN);
                    int end = toAnalyse.IndexOf(NEW_END_TOKEN);
                    StringBuilder newSqlBuffer = new StringBuilder();

                    while (start > -1 && end > start)
                    {
                        string prepend = toAnalyse.Substring(0, start);
                        string append = toAnalyse.Substring(end + NEW_END_TOKEN.Length);

                        //EmailAddress,column=string,type=string,dbType=Varchar,[email protected]
                        string parameter = toAnalyse.Substring(start + NEW_BEGIN_TOKEN.Length, end - start - NEW_BEGIN_TOKEN.Length);
                        ParameterProperty mapping = NewParseMapping(parameter, parameterClassType, dataExchangeFactory, statementId);
                        mappingList.Add(mapping);
                        newSqlBuffer.Append(prepend);
                        newSqlBuffer.Append(MARK_TOKEN);
                        toAnalyse = append;
                        start = toAnalyse.IndexOf(NEW_BEGIN_TOKEN);
                        end = toAnalyse.IndexOf(NEW_END_TOKEN);
                    }
                    newSqlBuffer.Append(toAnalyse);
                    newSql = newSqlBuffer.ToString();
                }
            }
            else
            {
                #region old syntax

                StringTokenizer parser = new StringTokenizer(sqlStatement, PARAMETER_TOKEN, true);
                StringBuilder newSqlBuffer = new StringBuilder();

                string token = null;
                string lastToken = null;

                IEnumerator enumerator = parser.GetEnumerator();

                while (enumerator.MoveNext())
                {
                    token = (string)enumerator.Current;

                    if (PARAMETER_TOKEN.Equals(lastToken))
                    {
                        // Double token ## = #
                        if (PARAMETER_TOKEN.Equals(token))
                        {
                            newSqlBuffer.Append(PARAMETER_TOKEN);
                            token = null;
                        }
                        else
                        {
                            ParameterProperty mapping = null;
                            if (token.IndexOf(PARAM_DELIM) > -1)
                            {
                                mapping = OldParseMapping(token, parameterClassType, dataExchangeFactory);
                            }
                            else
                            {
                                mapping = NewParseMapping(token, parameterClassType, dataExchangeFactory, statementId);
                            }

                            mappingList.Add(mapping);
                            newSqlBuffer.Append(MARK_TOKEN + " ");

                            enumerator.MoveNext();
                            token = (string)enumerator.Current;
                            if (!PARAMETER_TOKEN.Equals(token))
                            {
                                throw new DataMapperException("Unterminated inline parameter in mapped statement (" + statementId + ").");
                            }
                            token = null;
                        }
                    }
                    else
                    {
                        if (!PARAMETER_TOKEN.Equals(token))
                        {
                            newSqlBuffer.Append(token);
                        }
                    }

                    lastToken = token;
                }

                newSql = newSqlBuffer.ToString();

                #endregion old syntax
            }

            ParameterProperty[] mappingArray = mappingList.ToArray();

            SqlText sqlText = new SqlText();
            sqlText.Text = newSql;
            sqlText.Parameters = mappingArray;

            return sqlText;
        }
예제 #2
0
        /// <summary>
        /// Parse dynamic tags
        /// </summary>
        /// <param name="statementConfig">The statement config.</param>
        /// <param name="dynamic">The dynamic.</param>
        /// <param name="sqlBuffer">The SQL buffer.</param>
        /// <param name="isDynamic">if set to <c>true</c> [is dynamic].</param>
        /// <param name="postParseRequired">if set to <c>true</c> [post parse required].</param>
        /// <param name="statement">The statement.</param>
        /// <returns></returns>
        private bool ParseDynamicTags(
            IConfiguration statementConfig, 
            IDynamicParent dynamic,
            StringBuilder sqlBuffer, 
            bool isDynamic, 
            bool postParseRequired, 
            IStatement statement)
        {
            //具体文本的集合 可能是需要拼接成完整的SQL语句
            ConfigurationCollection children = statementConfig.Children;
            int count = children.Count;
            for (int i = 0; i < count; i++)
            {
                IConfiguration child = children[i];
                if (child.Type == ConfigConstants.ELEMENT_TEXT || child.Type == ConfigConstants.ELEMENT_CDATA)
                {
                    //第一步处理    获取当前文本的一个值 并处理"\r\n"
                    string childValueString = child.Value;
                    if (statement.PreserveWhitespace)
                    {
                        childValueString = childValueString .Replace('\n', ' ').Replace('\r', ' ').Replace('\t', ' ').Trim(); 
                    }

                    //第二部处理   将处理的当前一个部分SQL语句放入到SqlText类中
                    SqlText sqlText = null;
                    if (postParseRequired)
                    {
                        sqlText = new SqlText();
                        sqlText.Text = childValueString;
                    }
                    else
                    {
                        //分析SQL语句中的参数 例如# # ,@{}等内部参数 最后的结果是一个语句保存 和 参数列表在SqlText类中
                        sqlText = InlineParameterMapParser.ParseInlineParameterMap(modelStore.DataExchangeFactory, statementConfig.Id, null, childValueString);
                    }
                    //将此次分析的SQL语句结果保存到dynamic类对象中 可能需要添加多次 
                    dynamic.AddChild(sqlText);//按顺序放置 最后拼接即可

                    //sqlBuffer字符串拼接每一部分的sql语句 最后是当前节点的完整语句
                    sqlBuffer.Append(" " + childValueString);
                }
                else if (child.Type == ConfigConstants.ELEMENT_SELECTKEY || child.Type == ConfigConstants.ELEMENT_INCLUDE)
                {
                    //此处没有处理代码
                }
                else
                {
                    //从deSerializerFactory工厂类的字典serializerMap中获取对应的处理IDeSerializer类
                    IDeSerializer serializer = deSerializerFactory.GetDeSerializer(child.Type);//child.Type就是节点的名

                    if (serializer != null)
                    {
                        isDynamic = true;
                        SqlTag tag;

                        //当前child是一个element 进行解析
                        tag = serializer.Deserialize(child);

                        //添加到IList<ISqlChild> children中
                        dynamic.AddChild(tag);

                        if (child.Children.Count > 0)
                        {
                            //递归处理子节点 注意是子节点Tag了 递归下去 但sqlBuffer字符串一直是同一个
                            isDynamic = ParseDynamicTags(child, tag, sqlBuffer, isDynamic, tag.Handler.IsPostParseRequired, statement);
                        }
                    }
                }
            }

            return isDynamic;
        }
예제 #3
0
        internal void ApplyIteratePropertyReferenceHandling(SqlTagContext ctx, SqlText sqlText)
        {
            if (ctx == null)
                throw new ArgumentNullException("ctx");
            if (sqlText == null)
                throw new ArgumentNullException("sqlText");

            if (_propertyPlaceholder != null)
            {
                var parsedPropertyName = ReflectionMapper.GetReflectedFullName(ctx, sqlText, this._propertyPlaceholder);

                this._currentPropertyName = parsedPropertyName;
            }
        }
예제 #4
0
        /// <summary>
        /// Parse Inline ParameterMap
        /// 对statement insert update delete select 语句的参数进行分析
        /// </summary>
        /// <param name="dataExchangeFactory">The data exchange factory.</param>
        /// <param name="statementId">The statement id.</param>
        /// <param name="statement">The statement.</param>
        /// <param name="sqlStatement">The SQL statement.</param>
        /// <returns>A new sql command text.</returns>
        public static SqlText ParseInlineParameterMap(DataExchangeFactory dataExchangeFactory, string statementId, IStatement statement, string sqlStatement)
		{
			string newSql = sqlStatement;//赋值得到一条SQL部分语句
            List<ParameterProperty> mappingList = new List<ParameterProperty>();
			Type parameterClassType = null;

			if (statement != null)
			{
				parameterClassType = statement.ParameterClass;//当前节点属性中的参数类 会不会有多个参数类的情况???
			}

            if (sqlStatement.Contains(NEW_BEGIN_TOKEN))//如果SQL语句包含"@{"
            {
                // V3 parameter syntax
                //@{propertyName,column=string,type=string,dbype=string,direction=[Input/Output/InputOutput],nullValue=string,handler=string}

                /*以@{开头的例子
                    <procedure id="InsertAccountViaSPWithDynamicParameter" parameterClass="Account" >
                        ps_InsertAccountWithDefault
                        @{Id,column=Account_ID}//每一个@对应一个ParameterProperty类
                        ,@{FirstName,column=Account_FirstName}
                        ,@{LastName,column=Account_LastName}
                         ,@{EmailAddress,column=Account_Email,[email protected]}
                         <isNotNull property="NullBannerOption">
                                ,@{NullBannerOption,column=Account_Banner_Option,dbType=Varchar,type=bool}
                        </isNotNull>
                        @{CartOption,column=Account_Cart_Option,handler=HundredsBool}
                   </procedure>
                           */
                if (newSql != null)
                {
                    string toAnalyse = newSql;
                    int start = toAnalyse.IndexOf(NEW_BEGIN_TOKEN);//@{的下标
                    int end = toAnalyse.IndexOf(NEW_END_TOKEN);//"}"的下标
                    StringBuilder newSqlBuffer = new StringBuilder();

                    while (start > -1 && end > start)
                    {
                        //将语句以 @{ ******  }拆分成3份字符串
                        string prepend = toAnalyse.Substring(0, start);//@{部分
                        string append = toAnalyse.Substring(end + NEW_END_TOKEN.Length);//}.....部分
                       
                        //EmailAddress,column=string,type=string,dbType=Varchar,[email protected]
                        string parameter = toAnalyse.Substring(start + NEW_BEGIN_TOKEN.Length, end - start - NEW_BEGIN_TOKEN.Length);//第一个中间内容部分

                        ParameterProperty mapping = NewParseMapping(parameter, parameterClassType, dataExchangeFactory, statementId);
                        mappingList.Add(mapping);//将解析后得到的ParameterProperty放入列表中
                        newSqlBuffer.Append(prepend);//将”@{"加入 或者是 "},@{"部分加入
                        newSqlBuffer.Append(MARK_TOKEN);//加入 "?"标志

                        //可能有多个部分 所以循环处理准备
                        toAnalyse = append;
                        start = toAnalyse.IndexOf(NEW_BEGIN_TOKEN);
                        end = toAnalyse.IndexOf(NEW_END_TOKEN);
                    }
                    /*while 循环完成后的形势是
                     *  ps_InsertAccountWithDefault
                     *  @{?},@{?}的大概格式 保存到newSql中
                                   */
                    newSqlBuffer.Append(toAnalyse);
                    newSql = newSqlBuffer.ToString();
                }
            }
            else
            {
                #region old syntax
                /*
                   <insert id="InsertAccountViaInlineParameters"  parameterClass="Account" >
                       insert into Accounts
                      (Account_ID, Account_FirstName, Account_LastName, Account_Email)
                      values
                    (#Id#, #FirstName#, #LastName#, #EmailAddress:VarChar:[email protected]#)
                   </insert>
                */
                //每# #之间就是一个ParameterProperty类
                StringTokenizer parser = new StringTokenizer(sqlStatement, PARAMETER_TOKEN, true);//"#"区分 true表示 如果有#则返回
			    StringBuilder newSqlBuffer = new StringBuilder();

			    string token = null;
			    string lastToken = null;

			    IEnumerator enumerator = parser.GetEnumerator();

			    while (enumerator.MoveNext())//获取当前符号到下一符号之间的字符串 
			    {
                    token = (string)enumerator.Current;//Current真正保存了获取当前符号到下一符号之间的字符串 或 #

				    if (PARAMETER_TOKEN.Equals(lastToken)) //如果上一次是#
				    {
                        // Double token ## = # 
                        //先处理#
					    if (PARAMETER_TOKEN.Equals(token)) //如果当前也是#
					    {
						    newSqlBuffer.Append(PARAMETER_TOKEN);
						    token = null;
					    }
                        else //如果当前不是# 也即是两个#之间的字符串
					    {
						    ParameterProperty mapping = null; 
                            //判断# #之间的内容是否含有“:”
						    if (token.IndexOf(PARAM_DELIM) > -1) //如果字符串中含有”:"符号 则进入该函数
						    {
                                mapping = OldParseMapping(token, parameterClassType, dataExchangeFactory);
						    } 
						    else //不含有":",则再次默认","为分隔符
						    {
                                mapping = NewParseMapping(token, parameterClassType, dataExchangeFactory, statementId);
						    }															 

						    mappingList.Add(mapping);
                            newSqlBuffer.Append(MARK_TOKEN + " ");//添加"?"作为标志符号

						    enumerator.MoveNext();
						    token = (string)enumerator.Current;
						    if (!PARAMETER_TOKEN.Equals(token)) 
						    {
							    throw new DataMapperException("Unterminated inline parameter in mapped statement (" + statementId + ").");
						    }
						    token = null;
					    }
				    } 
				    else 
				    {
					    if (!PARAMETER_TOKEN.Equals(token)) 
					    {
						    newSqlBuffer.Append(token);
					    }
				    }

				    lastToken = token;
			    }
                /*处理后的sql语句格式应该为
                          insert into Accounts
                        (Account_ID, Account_FirstName, Account_LastName, Account_Email)
                        values
                       (?, ?, ?, ?)
                 *?对应的参数保存在 mappingList中  
                 *将这两部分 放到SqlText类中
                            */
                newSql = newSqlBuffer.ToString();
 
	            #endregion            
            }
            //将List内容转化为数组的形式
			ParameterProperty[] mappingArray =  mappingList.ToArray();                

            //将处理后的简化SQL语句 和 参数列表 保存到 SqlText中
			SqlText sqlText = new SqlText();
			sqlText.Text = newSql;
			sqlText.Parameters = mappingArray;

			return sqlText;
		}
예제 #5
0
        /// <summary>
        /// Processes the body children.
        /// 最终的处理的语句结果在buffer中,也即ctx中的StringBuilder,处理的参数结果在ctx中的ArrayList中
        /// </summary>
        /// <param name="request">The request.</param>
        /// <param name="ctx">The CTX.</param>
        /// <param name="parameterObject">The parameter object.</param>
        /// <param name="childEnumerator">The child enumerator.</param>
        /// <param name="buffer">The buffer.</param>
        private void ProcessBodyChildren(
            RequestScope request,
            SqlTagContext ctx,
            object parameterObject,
            IEnumerator <ISqlChild> childEnumerator,
            StringBuilder buffer)
        {
            while (childEnumerator.MoveNext())
            {
                ISqlChild child = childEnumerator.Current;

                if (child is SqlText)
                {
                    SqlText sqlText      = (SqlText)child;
                    string  sqlStatement = sqlText.Text;
                    if (sqlText.IsWhiteSpace)
                    {
                        buffer.Append(sqlStatement);
                    }
                    else
                    {
//						if (SimpleDynamicSql.IsSimpleDynamicSql(sqlStatement))
//						{
//							sqlStatement = new SimpleDynamicSql(sqlStatement, _statement).GetSql(parameterObject);
//							SqlText newSqlText = _paramParser.ParseInlineParameterMap( null, sqlStatement );
//							sqlStatement = newSqlText.Text;
//							ParameterProperty[] mappings = newSqlText.Parameters;
//							if (mappings != null)
//							{
//								for (int i = 0; i < mappings.Length; i++)
//								{
//									ctx.AddParameterMapping(mappings[i]);
//								}
//							}
//						}
                        // BODY OUT
                        buffer.Append(" ");
                        buffer.Append(sqlStatement);                        //添加当前的SQL语句

                        //处理参数列表
                        ParameterProperty[] parameters = sqlText.Parameters;
                        if (parameters != null)
                        {
                            int length = parameters.Length;
                            for (int i = 0; i < length; i++)
                            {
                                ctx.AddParameterMapping(parameters[i]);
                            }
                        }
                    }
                }
                else if (child is SqlTag)
                {
                    SqlTag         tag      = (SqlTag)child;
                    ISqlTagHandler handler  = tag.Handler;//此处是DynamicTagHandler处理类
                    int            response = BaseTagHandler.INCLUDE_BODY;

                    do
                    {
                        StringBuilder body = new StringBuilder();
                        //返回INCLUDE_BODY,即1 此处为处理开头的情况准备
                        response = handler.DoStartFragment(ctx, tag, parameterObject);
                        if (response != BaseTagHandler.SKIP_BODY)
                        {
                            if (ctx.IsOverridePrepend &&
                                ctx.FirstNonDynamicTagWithPrepend == null &&
                                tag.IsPrependAvailable &&
                                !(tag.Handler is DynamicTagHandler))
                            {
                                //此处应该是判断第一个查询条件时的开头问题
                                ctx.FirstNonDynamicTagWithPrepend = tag;
                            }
                            //递归调用,当前SqlTag中处理后的SQL语句保存到了临时的body中 后面再加入到buffer中
                            ProcessBodyChildren(request, ctx, parameterObject, tag.GetChildrenEnumerator(), body);

                            //处理结尾的片段部分 返回INCLUDE_BODY,1
                            response = handler.DoEndFragment(ctx, tag, parameterObject, body);
                            //处理prepend属性节点的问题
                            handler.DoPrepend(ctx, tag, parameterObject, body);
                            if (response != BaseTagHandler.SKIP_BODY)
                            {
                                if (body.Length > 0)
                                {
                                    // BODY OUT

                                    if (handler.IsPostParseRequired)
                                    {
                                        //将body中的SQL语句分析参数和SQL语句到SqlText中
                                        SqlText sqlText = InlineParameterMapParser.ParseInlineParameterMap(dataExchangeFactory, statement.Id, null, body.ToString());
                                        buffer.Append(sqlText.Text);
                                        ParameterProperty[] mappings = sqlText.Parameters;
                                        if (mappings != null)
                                        {
                                            int length = mappings.Length;
                                            for (int i = 0; i < length; i++)
                                            {
                                                ctx.AddParameterMapping(mappings[i]);
                                            }
                                        }
                                    }
                                    else
                                    {
                                        buffer.Append(" ");
                                        buffer.Append(body.ToString());
                                    }
                                    //此处是判断SQL语句查询条件时的关键字开头问题
                                    if (tag.IsPrependAvailable && tag == ctx.FirstNonDynamicTagWithPrepend)
                                    {
                                        ctx.IsOverridePrepend = false;
                                    }
                                }
                            }
                        }
                    }while (response == BaseTagHandler.REPEAT_BODY);
                }
            }
        }
예제 #6
0
        /// <summary>
        /// Parse dynamic tags
        /// </summary>
        /// <param name="statementConfig">The statement config.</param>
        /// <param name="dynamic">The dynamic.</param>
        /// <param name="sqlBuffer">The SQL buffer.</param>
        /// <param name="isDynamic">if set to <c>true</c> [is dynamic].</param>
        /// <param name="postParseRequired">if set to <c>true</c> [post parse required].</param>
        /// <param name="statement">The statement.</param>
        /// <returns></returns>
        private bool ParseDynamicTags(
            IConfiguration statementConfig, 
            IDynamicParent dynamic,
            StringBuilder sqlBuffer, 
            bool isDynamic, 
            bool postParseRequired, 
            IStatement statement)
        {
            ConfigurationCollection children = statementConfig.Children;
            int count = children.Count;
            for (int i = 0; i < count; i++)
            {
                IConfiguration child = children[i];
                if (child.Type == ConfigConstants.ELEMENT_TEXT || child.Type == ConfigConstants.ELEMENT_CDATA)
                {
                    string childValueString = child.Value;
                    if (statement.PreserveWhitespace)
                    {
                        childValueString = childValueString
                            .Replace('\n', ' ')
                            .Replace('\r', ' ')
                            .Replace('\t', ' ')
                            .Trim();
                    }

                    SqlText sqlText = null;
                    if (postParseRequired)
                    {
                        sqlText = new SqlText();
                        sqlText.Text = childValueString;
                    }
                    else
                    {
                        sqlText = InlineParameterMapParser.ParseInlineParameterMap(modelStore.DataExchangeFactory, statementConfig.Id, null, childValueString);
                    }

                    dynamic.AddChild(sqlText);
                    sqlBuffer.Append(" " + childValueString);
                }
                else if (child.Type == ConfigConstants.ELEMENT_SELECTKEY || child.Type == ConfigConstants.ELEMENT_INCLUDE)
                { }
                else
                {
                    IDeSerializer serializer = deSerializerFactory.GetDeSerializer(child.Type);

                    if (serializer != null)
                    {
                        isDynamic = true;
                        SqlTag tag;

                        tag = serializer.Deserialize(child);

                        dynamic.AddChild(tag);

                        if (child.Children.Count > 0)
                        {
                            isDynamic = ParseDynamicTags(child, tag, sqlBuffer, isDynamic, tag.Handler.IsPostParseRequired, statement);
                        }
                    }
                }
            }

            return isDynamic;
        }