/// <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; }
/// <summary> /// Processes the dynamic elements with old syntax $property$ /// </summary> /// <param name="parameterObject">The parameter object.</param> /// <returns></returns> private string ProcessDynamicElementsOldSyntax(object parameterObject) { // define which character is seperating fields //处理SQL语句中的$符号 StringTokenizer parser = new StringTokenizer(sqlStatement, ELEMENT_TOKEN, true); StringBuilder newSql = new StringBuilder(); string lastToken = null; IEnumerator enumerator = parser.GetEnumerator(); while (enumerator.MoveNext()) { string token = ((string)enumerator.Current); if (ELEMENT_TOKEN.Equals(lastToken)) { if (ELEMENT_TOKEN.Equals(token)) { newSql.Append(ELEMENT_TOKEN); token = null; } else//从parameterObject类中获取$$参数之间的属性值 { object value = null; if (parameterObject != null) { if (dataExchangeFactory.TypeHandlerFactory.IsSimpleType(parameterObject.GetType())) { value = parameterObject; } else { value = ObjectProbe.GetMemberValue(parameterObject, token, dataExchangeFactory.AccessorFactory); } } if (value != null) { newSql.Append(value.ToString()); } enumerator.MoveNext(); token = ((string)enumerator.Current);//一定要等于$ if (!ELEMENT_TOKEN.Equals(token)) { throw new DataMapperException("Unterminated dynamic element in sql (" + sqlStatement + ")."); } token = null; } } else { if (!ELEMENT_TOKEN.Equals(token)) { newSql.Append(token); } } lastToken = token; } return newSql.ToString(); }
/// <summary> /// Parse inline parameter with syntax as /// #propertyName,type=string,dbtype=Varchar,direction=Input,nullValue=N/A,handler=string,column=null# /// </summary> /// <param name="token">The token.</param> /// <param name="parameterClassType">Type of the parameter class.</param> /// <param name="dataExchangeFactory">The data exchange factory.</param> /// <param name="statementId">The statement id.</param> /// <returns></returns> /// <example> /// #propertyName,type=string,dbtype=Varchar,direction=Input,nullValue=N/A,handler=string# /// </example> /// <remarks> /// Updated By: Richard Beacroft /// Updated Date: 11\10\2013 /// Description: Added ability to specify "null" as value for column want to ignore, just for completeness. /// </remarks> /// <example> /// The following will convert [].Equal to the appropriate full reflection name for the Equal field/property on the current iterate element, /// taking into consideration that the iterate element may be within another iterate element, etc... /// @{[].Equal,column=null,type=string,dbtype=Decimal,direction=Input,nullValue=null,handler=null} /// </example> private static ParameterProperty NewParseMapping(string token, Type parameterClassType, DataExchangeFactory dataExchangeFactory, string statementId) { string propertyName = string.Empty; string type = string.Empty; string dbType = string.Empty; string direction = string.Empty; string callBack = string.Empty; string nullValue = null; string columnName = string.Empty; const string NULL_VALUE = "null"; StringTokenizer paramParser = new StringTokenizer(token, "=,", false); IEnumerator enumeratorParam = paramParser.GetEnumerator(); enumeratorParam.MoveNext(); propertyName = ((string)enumeratorParam.Current).Trim(); while (enumeratorParam.MoveNext()) { var field = ((string)enumeratorParam.Current).Trim().ToLower(); if (enumeratorParam.MoveNext()) { var value = ((string)enumeratorParam.Current).Trim(); if ("type".Equals(field)) { if (value == NULL_VALUE) continue; type = value; } else if ("dbtype".Equals(field)) { if (value == NULL_VALUE) continue; dbType = value; } else if ("direction".Equals(field)) { if (value == NULL_VALUE) continue; direction = value; } else if ("nullvalue".Equals(field)) { if (value == NULL_VALUE) continue; if (value.StartsWith("\"") && value.EndsWith("\"")) nullValue = value.Substring(1, value.Length - 2); else nullValue = value; } else if ("handler".Equals(field)) { if (value == NULL_VALUE) continue; callBack = value; } else if ("column".Equals(field)) { if (value == NULL_VALUE) continue; columnName = value; } else { throw new DataMapperException("When parsing inline parameter for statement '" + statementId + "', can't recognize parameter mapping field: '" + field + "' in " + token + ", check your inline parameter syntax."); } } else { throw new DataMapperException("Incorrect inline parameter map format (missmatched name=value pairs): " + token); } } return new ParameterProperty( propertyName, columnName, callBack, type, dbType, direction, nullValue, 0, 0, -1, parameterClassType, dataExchangeFactory); }
/// <summary> /// Parse inline parameter with syntax as /// </summary> /// <param name="token">The token.</param> /// <param name="parameterClassType">Type of the parameter class.</param> /// <param name="dataExchangeFactory">The data exchange factory.</param> /// <example> /// #propertyName:dbType:nullValue# /// </example> /// <returns></returns> private static ParameterProperty OldParseMapping(string token, Type parameterClassType, DataExchangeFactory dataExchangeFactory) { string propertyName = string.Empty; string dbType = string.Empty; string nullValue = null; if (token.IndexOf(PARAM_DELIM) > -1) { StringTokenizer paramParser = new StringTokenizer(token, PARAM_DELIM, true); IEnumerator enumeratorParam = paramParser.GetEnumerator(); int n1 = paramParser.TokenNumber; if (n1 == 3) { enumeratorParam.MoveNext(); propertyName = ((string)enumeratorParam.Current).Trim(); enumeratorParam.MoveNext(); enumeratorParam.MoveNext(); //ignore ":" dbType = ((string)enumeratorParam.Current).Trim(); } else if (n1 >= 5) { enumeratorParam.MoveNext(); propertyName = ((string)enumeratorParam.Current).Trim(); enumeratorParam.MoveNext(); enumeratorParam.MoveNext(); //ignore ":" dbType = ((string)enumeratorParam.Current).Trim(); enumeratorParam.MoveNext(); enumeratorParam.MoveNext(); //ignore ":" nullValue = ((string)enumeratorParam.Current).Trim(); while (enumeratorParam.MoveNext()) { nullValue = nullValue + ((string)enumeratorParam.Current).Trim(); } } else { throw new ConfigurationException("Incorrect inline parameter map format: " + token); } } else { propertyName = token; } return new ParameterProperty( propertyName, string.Empty, string.Empty, string.Empty, dbType, string.Empty, nullValue, 0, 0, -1, parameterClassType, dataExchangeFactory); }
public string Process(TextTokenHandlerBase behaviour) { if (behaviour == null) throw new ArgumentNullException("behaviour"); // define which character is separating fields var parser = new StringTokenizer(_sqlStatement, ELEMENT_TOKEN, true); var newSql = new StringBuilder(); var keepSurroundingToken = behaviour.KeepSurroundingToken; string lastToken = null; IEnumerator enumerator = parser.GetEnumerator(); while (enumerator.MoveNext()) { string token = ((string)enumerator.Current); if (ELEMENT_TOKEN.Equals(lastToken)) { if (ELEMENT_TOKEN.Equals(token)) { newSql.Append(ELEMENT_TOKEN); token = null; } else { var value = behaviour.ProcessToken(token); if (value != null) { if (keepSurroundingToken) newSql.Append(ELEMENT_TOKEN + value + ELEMENT_TOKEN); else newSql.Append(value); } enumerator.MoveNext(); token = ((string)enumerator.Current); if (!ELEMENT_TOKEN.Equals(token)) { throw new DataMapperException("Unterminated dynamic element in sql (" + _sqlStatement + ")."); } token = null; } } else { if (!ELEMENT_TOKEN.Equals(token)) { newSql.Append(token); } } lastToken = token; } return behaviour.PostProcessing(newSql.ToString()); }
public StringTokenizerEnumerator(StringTokenizer stok) { stokenizer = stok; }
/// <summary> /// Parse sql command text. /// </summary> private void EvaluateParameterMap() { string delimiter = "?"; string token = null; int index = 0; string sqlParamName = string.Empty; StringTokenizer parser = new StringTokenizer(commandText, delimiter, true); StringBuilder newCommandTextBuffer = new StringBuilder(); IEnumerator enumerator = parser.GetEnumerator(); while (enumerator.MoveNext()) { token = (string)enumerator.Current; if (delimiter.Equals(token)) // ? { ParameterProperty property = request.ParameterMap.Properties[index]; IDataParameter dataParameter = null; if (dbProvider.UsePositionalParameters) { // TODO Refactor? if (parameterPrefix.Equals(":")) { // ODP.NET uses positional parameters by default // but uses ":0" or ":1" instead of "?" sqlParamName = ":" + index; } else { // OLEDB/OBDC doesn't support named parameters !!! sqlParamName = "?"; } } else { dataParameter = (IDataParameter) propertyDbParameterMap[property]; // 5 May 2004 // Need to check UseParameterPrefixInParameter here // since CreateParametersForStatementText now does // a check for UseParameterPrefixInParameter before // creating the parameter name! if (dbProvider.UseParameterPrefixInParameter) { // Fix ByteFX.Data.MySqlClient.MySqlParameter // who strip prefix in Parameter Name ?! if (dbProvider.Id.IndexOf("ByteFx") >= 0) { sqlParamName = parameterPrefix+dataParameter.ParameterName; } else { sqlParamName = dataParameter.ParameterName; } } else { sqlParamName = parameterPrefix+dataParameter.ParameterName; } } newCommandTextBuffer.Append(" "); newCommandTextBuffer.Append(sqlParamName); sqlParamName = string.Empty; index ++; } else { newCommandTextBuffer.Append(token); } } preparedStatement.PreparedSql = newCommandTextBuffer.ToString(); }
/// <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; }
/// <summary> /// Parse inline parameter with syntax as /// #propertyName,type=string,dbype=Varchar,direction=Input,nullValue=N/A,handler=string# /// </summary> /// <param name="token">The token.</param> /// <param name="parameterClassType">Type of the parameter class.</param> /// <param name="dataExchangeFactory">The data exchange factory.</param> /// <param name="statementId">The statement id.</param> /// <returns></returns> /// <example> /// #propertyName,type=string,dbype=Varchar,direction=Input,nullValue=N/A,handler=string# /// </example> private static ParameterProperty NewParseMapping(string token, Type parameterClassType, DataExchangeFactory dataExchangeFactory, string statementId) { string propertyName = string.Empty; string type = string.Empty; string dbType = string.Empty; string direction = string.Empty; string callBack = string.Empty; string nullValue = null; string columnName = string.Empty; StringTokenizer paramParser = new StringTokenizer(token, "=,", false); //以字符propertyName,type=string,dbype=Varchar,direction=Input,nullValue=N/A,handler=string为例 IEnumerator enumeratorParam = paramParser.GetEnumerator(); enumeratorParam.MoveNext();//此处获取 propertyName保存到内部的next中 propertyName = ((string)enumeratorParam.Current).Trim();//实际上调用了next的内容 while (enumeratorParam.MoveNext()) { string field = ((string)enumeratorParam.Current).Trim().ToLower(); //每MoveNext一次 获得一次数据到Current中 if (enumeratorParam.MoveNext()) { string value = ((string)enumeratorParam.Current).Trim(); if ("type".Equals(field)) { type = value; } else if ("dbtype".Equals(field)) { dbType = value; } else if ("direction".Equals(field)) { direction = value; } else if ("nullvalue".Equals(field)) { if (value.StartsWith("\"") && value.EndsWith("\"")) { nullValue = value.Substring(1, value.Length-2); } else { nullValue = value; } } else if ("handler".Equals(field)) { callBack = value; } else if ("column".Equals(field)) { columnName = value; } else { throw new DataMapperException("When parsing inline parameter for statement '"+statementId+"', can't recognize parameter mapping field: '" + field + "' in " + token+", check your inline parameter syntax."); } } else { throw new DataMapperException("Incorrect inline parameter map format (missmatched name=value pairs): " + token); } } //将解析后的字符内容存入到ParameterProperty类中 return new ParameterProperty( propertyName, columnName, callBack, type, dbType, direction, nullValue, 0, 0, -1, parameterClassType, dataExchangeFactory); }
/// <summary> /// Parse and tokenize the sql script into multiple statements /// </summary> /// <param name="script">the script to parse</param> private ArrayList ParseScript(string script) { ArrayList statements = new ArrayList(); StringTokenizer parser = new StringTokenizer(script, ";"); IEnumerator enumerator = parser.GetEnumerator(); while (enumerator.MoveNext()) { string statement= ((string)enumerator.Current).Replace("\r\n"," "); statement = statement.Trim(); if (statement != string.Empty) { statements.Add(statement); } } return statements; }