#region Apache Notice /***************************************************************************** * $Header: $ * $Revision: $ * $Date: $ * * iBATIS.NET Data Mapper * Copyright (C) 2004 - Gilles Bayon * * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ********************************************************************************/ #endregion #region Imports using System; using System.Collections; using System.Text; using IBatisNet.Common; using IBatisNet.DataMapper.Configuration.Sql; using IBatisNet.DataMapper.Configuration.Sql.SimpleDynamic; using IBatisNet.DataMapper.Configuration.Statements; using IBatisNet.DataMapper.Configuration.ParameterMapping; using IBatisNet.DataMapper.Configuration.Sql.Dynamic.Elements; using IBatisNet.DataMapper.Configuration.Sql.Dynamic.Handlers; using IBatisNet.DataMapper.Scope; using IBatisNet.DataMapper.TypeHandlers; #endregion namespace IBatisNet.DataMapper.Configuration.Sql.Dynamic { /// /// DynamicSql represent the root element of a dynamic sql statement /// /// /// ... /// internal class DynamicSql : ISql, IDynamicParent { #region Fields private IList _children = new ArrayList(); private IStatement _statement = null ; private InlineParameterMapParser _paramParser = null; private TypeHandlerFactory _typeHandlerFactory = null; private bool _usePositionalParameters = false; #endregion #region Constructor (s) / Destructor /// /// Constructor /// /// The mapped statement. /// internal DynamicSql(ConfigurationScope configScope, IStatement statement) { _statement = statement; _typeHandlerFactory = configScope.TypeHandlerFactory; _usePositionalParameters = configScope.DataSource.Provider.UsePositionalParameters; } #endregion #region Methods #region ISql IDynamicParent /// /// /// /// public void AddChild(ISqlChild child) { _children.Add(child); } #endregion #region ISql Members /// /// /// /// /// /// public RequestScope GetRequestScope(object parameterObject, IDalSession session) { RequestScope request = new RequestScope(); _paramParser = new InlineParameterMapParser(request.ErrorContext); request.ResultMap = _statement.ResultMap; string sqlStatement = Process(request, parameterObject); request.PreparedStatement = BuildPreparedStatement(session, request, sqlStatement); return request; } #endregion /// /// /// /// /// /// private string Process(RequestScope request, object parameterObject) { SqlTagContext ctx = new SqlTagContext(); IList localChildren = _children; ProcessBodyChildren(request, ctx, parameterObject, localChildren); // Builds a 'dynamic' ParameterMap ParameterMap map = new ParameterMap(_usePositionalParameters); map.Id = _statement.Id + "-InlineParameterMap"; // Adds 'dynamic' ParameterProperty IList parameters = ctx.GetParameterMappings(); for(int i=0;i /// /// /// /// /// /// private void ProcessBodyChildren(RequestScope request, SqlTagContext ctx, object parameterObject, IList localChildren) { StringBuilder buffer = ctx.GetWriter(); ProcessBodyChildren(request, ctx, parameterObject, localChildren.GetEnumerator(), buffer); } /// /// /// /// /// /// /// /// private void ProcessBodyChildren(RequestScope request, SqlTagContext ctx, object parameterObject, IEnumerator localChildren, StringBuilder buffer) { while (localChildren.MoveNext()) { ISqlChild child = (ISqlChild) localChildren.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); ParameterProperty[] parameters = sqlText.Parameters; if (parameters != null) { for (int i = 0; i< parameters.Length; i++) { ctx.AddParameterMapping(parameters[i]); } } } } else if (child is SqlTag) { SqlTag tag = (SqlTag) child; ISqlTagHandler handler = tag.Handler; int response = BaseTagHandler.INCLUDE_BODY; do { StringBuilder body = new StringBuilder(); 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; } ProcessBodyChildren(request, ctx, parameterObject, tag.GetChildrenEnumerator(), body); response = handler.DoEndFragment(ctx, tag, parameterObject, body); handler.DoPrepend(ctx, tag, parameterObject, body); if (response != BaseTagHandler.SKIP_BODY) { if (body.Length > 0) { // BODY OUT if (handler.IsPostParseRequired) { SqlText sqlText = _paramParser.ParseInlineParameterMap(_typeHandlerFactory, null, body.ToString() ); buffer.Append(sqlText.Text); ParameterProperty[] mappings = sqlText.Parameters; if (mappings != null) { for (int i = 0; i< mappings.Length; i++) { ctx.AddParameterMapping(mappings[i]); } } } else { buffer.Append(" "); buffer.Append(body.ToString()); } if (tag.IsPrependAvailable && tag == ctx.FirstNonDynamicTagWithPrepend) { ctx.IsOverridePrepend = false; } } } } } while (response == BaseTagHandler.REPEAT_BODY); } } } /// /// /// /// /// /// /// private PreparedStatement BuildPreparedStatement(IDalSession session, RequestScope request, string sqlStatement) { PreparedStatementFactory factory = new PreparedStatementFactory( session, request, _statement, sqlStatement); return factory.Prepare(); } #endregion } }