Example #1
0
		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="statement">The statement.</param>
		/// <param name="sqlStatement"></param>
		/// <param name="scope"></param>
		public ProcedureSql(IScope scope, string sqlStatement, IStatement statement)
		{
			_sqlStatement = sqlStatement;
			_statement = statement;

			_dataExchangeFactory = scope.DataExchangeFactory;
		}
Example #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="DynamicSql"/> class.
        /// </summary>
        /// <param name="configScope">The config scope.</param>
        /// <param name="statement">The statement.</param>
		internal DynamicSql(ConfigurationScope configScope, IStatement statement)
		{
			_statement = statement;

			_usePositionalParameters = configScope.DataSource.DbProvider.UsePositionalParameters;
			_dataExchangeFactory = configScope.DataExchangeFactory;
		}
Example #3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="SimpleDynamicSql"/> class.
        /// </summary>
        /// <param name="scope">The scope.</param>
        /// <param name="sqlStatement">The SQL statement.</param>
        /// <param name="statement">The statement.</param>
		internal SimpleDynamicSql(IScope scope,
			string sqlStatement, 
			IStatement statement)
		{
			_simpleSqlStatement = sqlStatement;
			_statement = statement;

			_dataExchangeFactory = scope.DataExchangeFactory;
		}
Example #4
0
		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="statement">The statement.</param>
		/// <param name="scope"></param>
		public StaticSql(IScope scope, IStatement statement)
		{
			_statement = statement;

			_dataExchangeFactory = scope.DataExchangeFactory;
		}
Example #5
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ResultMap"/> class.
        /// </summary>
        /// <param name="configScope">The config scope.</param>
        /// <param name="className">The output class name of the resultMap.</param>
        /// <param name="extendMap">The extend result map bame.</param>
        /// <param name="id">Identifier used to identify the resultMap amongst the others.</param>
        /// <param name="groupBy">The groupBy properties</param>
        public ResultMap(ConfigurationScope configScope, string id, string className, string extendMap, string groupBy)
		{
            _nullResultMap = new NullResultMap();

            _dataExchangeFactory = configScope.DataExchangeFactory;
            _sqlMapNameSpace = configScope.SqlMapNamespace;
            if ((id == null) || (id.Length < 1))
            {
                 throw new ArgumentNullException("The id attribute is mandatory in a ResultMap tag.");
            }
            _id = configScope.ApplyNamespace(id);
            if ((className == null) || (className.Length < 1))
            {
                throw new ArgumentNullException("The class attribute is mandatory in the ResultMap tag id:"+_id);
            }
            _className = className;
            _extendMap = extendMap;
             if (groupBy != null && groupBy.Length>0)
             {
                 string[] groupByProperties = groupBy.Split(',');
                 for (int i = 0; i < groupByProperties.Length; i++)
                 {
                     string memberName = groupByProperties[i].Trim();
                     _groupByPropertyNames.Add(memberName);
                 }
             }
            
		}
Example #6
0
 /// <summary>
 /// Do not use direclty, only for serialization.
 /// </summary>
 /// <param name="dataExchangeFactory"></param>
 public ParameterMap(DataExchangeFactory dataExchangeFactory)
 {
     _dataExchangeFactory = dataExchangeFactory;
 }
        /// <summary>
        /// Initializes a new instance of the <see cref="ParameterProperty"/> class.
        /// </summary>
        /// <param name="propertyName">Name of the property.</param>
        /// <param name="columnName">Name of the column.</param>
        /// <param name="callBackName">Name of the call back.</param>
        /// <param name="clrType">Type of the CLR.</param>
        /// <param name="dbType">Type of the db.</param>
        /// <param name="directionAttribute">The direction attribute.</param>
        /// <param name="nullValue">The null value.</param>
        /// <param name="precision">The precision.</param>
        /// <param name="scale">The scale.</param>
        /// <param name="size">The size.</param>
        /// <param name="parameterClass">The parameter class.</param>
        /// <param name="dataExchangeFactory">The data exchange factory.</param>
        public ParameterProperty(
            string propertyName,
            string columnName,
            string callBackName,
            string clrType,
            string dbType,
            string directionAttribute,
            string nullValue,
            Byte precision,
            Byte scale,
            int size,
            Type parameterClass,
            DataExchangeFactory dataExchangeFactory 
            )   
        {
            Contract.Require.That(propertyName, Is.Not.Null & Is.Not.Empty).When("retrieving argument propertyName");

            this.scale = scale;
            this.size = size;
            this.precision = precision;
            this.clrType = clrType;
            this.dbType = dbType;
            this.callBackName = callBackName;
            this.columnName = columnName;

            #region Direction
            if (directionAttribute.Length > 0)
            {
                direction = (ParameterDirection)Enum.Parse(typeof(ParameterDirection), directionAttribute, true);
                this.directionAttribute = direction.ToString();
            } 
            #endregion
                
            #region Property Name
            this.propertyName = propertyName;
            if (propertyName.IndexOf('.') < 0)
            {
                isComplexMemberName = false;
            }
            else // complex member name FavouriteLineItem.Id
            {
                isComplexMemberName = true;
            }  
            #endregion     
                
            #region GetAccessor
            if (!typeof(IDictionary).IsAssignableFrom(parameterClass) // Hashtable parameter map
                && parameterClass != null // value property
                && !dataExchangeFactory.TypeHandlerFactory.IsSimpleType(parameterClass)) // value property
            {
                if (!isComplexMemberName)
                {
                    IGetAccessorFactory getAccessorFactory = dataExchangeFactory.AccessorFactory.GetAccessorFactory;
                    getAccessor = getAccessorFactory.CreateGetAccessor(parameterClass, propertyName);
                }
                else // complex member name FavouriteLineItem.Id
                {
                    string memberName = propertyName.Substring(propertyName.LastIndexOf('.') + 1);
                    string parentName = propertyName.Substring(0, propertyName.LastIndexOf('.'));
                    Type parentType = ObjectProbe.GetMemberTypeForGetter(parameterClass, parentName);

                    IGetAccessorFactory getAccessorFactory = dataExchangeFactory.AccessorFactory.GetAccessorFactory;
                    getAccessor = getAccessorFactory.CreateGetAccessor(parentType, memberName);
                }
            } 
            #endregion 

            #region TypeHandler
            if (this.CallBackName.Length > 0)
            {
                try
                {
                    Type type = dataExchangeFactory.TypeHandlerFactory.GetType(this.CallBackName);
                    ITypeHandlerCallback typeHandlerCallback = (ITypeHandlerCallback)Activator.CreateInstance(type);
                    typeHandler = new CustomTypeHandler(typeHandlerCallback);
                }
                catch (Exception e)
                {
                    throw new ConfigurationException("Error occurred during custom type handler configuration.  Cause: " + e.Message, e);
                }
            }
            else
            {
                if (this.CLRType.Length == 0)  // Unknown
                {
                    if (getAccessor != null &&
                        dataExchangeFactory.TypeHandlerFactory.IsSimpleType(getAccessor.MemberType))
                    {
                        // Primitive
                        typeHandler = dataExchangeFactory.TypeHandlerFactory.GetTypeHandler(getAccessor.MemberType, dbType);
                    }
                    else
                    {
                        typeHandler = dataExchangeFactory.TypeHandlerFactory.GetUnkownTypeHandler();
                    }
                }
                else // If we specify a CLR type, use it
                {
                    Type type = TypeUtils.ResolveType(this.CLRType);

                    if (dataExchangeFactory.TypeHandlerFactory.IsSimpleType(type))
                    {
                        // Primitive
                        typeHandler = dataExchangeFactory.TypeHandlerFactory.GetTypeHandler(type, dbType);
                    }
                    else
                    {
                        // .NET object
                        type = ObjectProbe.GetMemberTypeForGetter(type, this.PropertyName);
                        typeHandler = dataExchangeFactory.TypeHandlerFactory.GetTypeHandler(type, dbType);
                    }
                }
            }
            
            #endregion

        }
        /// <summary>
        /// Builds a <see cref="ResultPropertyCollection"/> for an <see cref="AutoResultMap"/>.
        /// </summary>
        /// <param name="dataExchangeFactory">The data exchange factory.</param>
        /// <param name="reader">The reader.</param>
        /// <param name="resultObject">The result object.</param>
        public static ResultPropertyCollection Build(DataExchangeFactory dataExchangeFactory,
                                                     IDataReader reader,
                                                     ref object resultObject)
        {
            Type targetType = resultObject.GetType();
            ResultPropertyCollection properties = new ResultPropertyCollection();

            try
            {
                // Get all PropertyInfo from the resultObject properties
                ReflectionInfo reflectionInfo = ReflectionInfo.GetInstance(targetType);
                string[]       membersName    = reflectionInfo.GetWriteableMemberNames();

                Hashtable propertyMap = new Hashtable();
                int       length      = membersName.Length;
                for (int i = 0; i < length; i++)
                {
                    ISetAccessorFactory setAccessorFactory = dataExchangeFactory.AccessorFactory.SetAccessorFactory;
                    ISetAccessor        setAccessor        = setAccessorFactory.CreateSetAccessor(targetType, membersName[i]);
                    propertyMap.Add(membersName[i], setAccessor);
                }

                // Get all column Name from the reader
                // and build a resultMap from with the help of the PropertyInfo[].
                DataTable dataColumn = reader.GetSchemaTable();
                int       count      = dataColumn.Rows.Count;
                for (int i = 0; i < count; i++)
                {
                    string       columnName         = dataColumn.Rows[i][0].ToString();
                    ISetAccessor matchedSetAccessor = propertyMap[columnName] as ISetAccessor;

                    ResultProperty property = new ResultProperty();
                    property.ColumnName  = columnName;
                    property.ColumnIndex = i;

                    if (resultObject is Hashtable)
                    {
                        property.PropertyName = columnName;
                        properties.Add(property);
                    }

                    Type propertyType = null;

                    if (matchedSetAccessor == null)
                    {
                        try
                        {
                            propertyType = ObjectProbe.GetMemberTypeForSetter(resultObject, columnName);
                        }
                        catch
                        {
                            _logger.Error("The column [" + columnName + "] could not be auto mapped to a property on [" + resultObject.ToString() + "]");
                        }
                    }
                    else
                    {
                        propertyType = matchedSetAccessor.MemberType;
                    }

                    if (propertyType != null || matchedSetAccessor != null)
                    {
                        property.PropertyName = (matchedSetAccessor != null ? matchedSetAccessor.Name : columnName);
                        if (matchedSetAccessor != null)
                        {
                            property.Initialize(dataExchangeFactory.TypeHandlerFactory, matchedSetAccessor);
                        }
                        else
                        {
                            property.TypeHandler = dataExchangeFactory.TypeHandlerFactory.GetTypeHandler(propertyType);
                        }

                        property.PropertyStrategy = PropertyStrategyFactory.Get(property);
                        properties.Add(property);
                    }
                }
            }
            catch (Exception e)
            {
                throw new DataMapperException("Error automapping columns. Cause: " + e.Message, e);
            }

            return(properties);
        }
Example #9
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="statement">The statement.</param>
        /// <param name="scope"></param>
        public StaticSql(IScope scope, IStatement statement)
        {
            _statement = statement;

            _dataExchangeFactory = scope.DataExchangeFactory;
        }
Example #10
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ResultProperty"/> class.
        /// </summary>
        /// <param name="propertyName">Name of the property.</param>
        /// <param name="columnName">Name of the column.</param>
        /// <param name="columnIndex">Index of the column.</param>
        /// <param name="clrType">Type of the CLR.</param>
        /// <param name="callBackName">Name of the call back.</param>
        /// <param name="dbType">Type of the db.</param>
        /// <param name="isLazyLoad">if set to <c>true</c> [is lazy load].</param>
        /// <param name="nestedResultMapName">Name of the nested result map.</param>
        /// <param name="nullValue">The null value.</param>
        /// <param name="select">The select.</param>
        /// <param name="resultClass">The result class.</param>
        /// <param name="dataExchangeFactory">The data exchange factory.</param>
        /// <param name="typeHandler">The type handler.</param>
        public ResultProperty(
            string propertyName,
            string columnName,
            int columnIndex,
            string clrType,
            string callBackName,
            string dbType,
            bool isLazyLoad,
            string nestedResultMapName,
            string nullValue,
            string select,
            Type resultClass,
            DataExchangeFactory dataExchangeFactory,
            ITypeHandler typeHandler
            )
        {
            Contract.Require.That(propertyName, Is.Not.Null & Is.Not.Empty).When("retrieving argument propertyName in ResultProperty constructor");

            this.propertyName = propertyName;

            this.columnName          = columnName;
            this.callBackName        = callBackName;
            this.dbType              = dbType;
            this.clrType             = clrType;
            this.select              = select;
            this.nestedResultMapName = nestedResultMapName;
            this.isLazyLoad          = isLazyLoad;
            this.nullValue           = nullValue;
            this.columnIndex         = columnIndex;
            this.typeHandler         = typeHandler;

            #region isComplexMemberName
            if (propertyName.IndexOf('.') < 0)
            {
                isComplexMemberName = false;
            }
            else // complex member name FavouriteLineItem.Id
            {
                isComplexMemberName = true;
            }
            #endregion

            if (propertyName.Length > 0 &&
                propertyName != "value" &&
                !typeof(IDictionary).IsAssignableFrom(resultClass) &&
                !typeof(DataRow).IsAssignableFrom(resultClass))
            {
                #region SetAccessor
                if (!isComplexMemberName)
                {
                    setAccessor = dataExchangeFactory.AccessorFactory.SetAccessorFactory.CreateSetAccessor(resultClass, propertyName);
                }
                else // complex member name FavouriteLineItem.Id
                {
                    MemberInfo propertyInfo = ObjectProbe.GetMemberInfoForSetter(resultClass, propertyName);
                    string     memberName   = propertyName.Substring(propertyName.LastIndexOf('.') + 1);
                    setAccessor = dataExchangeFactory.AccessorFactory.SetAccessorFactory.CreateSetAccessor(propertyInfo.ReflectedType, memberName);
                }
                #endregion

                isGenericIList = TypeUtils.IsImplementGenericIListInterface(MemberType);
                isIList        = typeof(IList).IsAssignableFrom(MemberType);

                #region Set the list factory
                if (isGenericIList)
                {
                    if (MemberType.IsArray)
                    {
                        listFactory = arrayListFactory;
                    }
                    else
                    {
                        Type[] typeArgs = MemberType.GetGenericArguments();

                        if (typeArgs.Length == 0)// Custom collection which derive from List<T>
                        {
                            listFactory = dataExchangeFactory.ObjectFactory.CreateFactory(MemberType, Type.EmptyTypes);
                        }
                        else
                        {
                            Type genericIList      = typeof(IList <>);
                            Type interfaceListType = genericIList.MakeGenericType(typeArgs);

                            Type genericList = typeof(List <>);
                            Type listType    = genericList.MakeGenericType(typeArgs);

                            if ((interfaceListType == MemberType) || (listType == MemberType))
                            {
                                Type constructedType = genericList.MakeGenericType(typeArgs);
                                listFactory = dataExchangeFactory.ObjectFactory.CreateFactory(
                                    constructedType,
                                    Type.EmptyTypes);
                            }
                            else // Custom collection which derive from List<T>
                            {
                                listFactory = dataExchangeFactory.ObjectFactory.CreateFactory(MemberType, Type.EmptyTypes);
                            }
                        }
                    }
                }
                else if (isIList)
                {
                    if (MemberType.IsArray)
                    {
                        listFactory = arrayListFactory;
                    }
                    else
                    {
                        if (MemberType == typeof(IList))
                        {
                            listFactory = arrayListFactory;
                        }
                        else // custom collection
                        {
                            listFactory = dataExchangeFactory.ObjectFactory.CreateFactory(MemberType, Type.EmptyTypes);
                        }
                    }
                }
                #endregion
            }

            #region TypeHandler
            if (!string.IsNullOrEmpty(CallBackName))
            {
                try
                {
                    Type type = dataExchangeFactory.TypeHandlerFactory.GetType(CallBackName);
                    ITypeHandlerCallback typeHandlerCallback = (ITypeHandlerCallback)Activator.CreateInstance(type);
                    this.typeHandler = new CustomTypeHandler(typeHandlerCallback);
                }
                catch (Exception e)
                {
                    throw new ConfigurationException("Error occurred during custom type handler configuration.  Cause: " + e.Message, e);
                }
            }
            else
            {
                if (typeHandler == null)
                {
                    //configScope.ErrorContext.MoreInfo = "Result property '" + propertyName + "' set the typeHandler attribute.";
                    this.typeHandler = dataExchangeFactory.TypeHandlerFactory.ResolveTypeHandler(resultClass, propertyName, clrType, dbType, true);
                }
            }
            #endregion

            #region LazyLoad
            if (IsLazyLoad)
            {
                lazyFactory = new LazyFactoryBuilder().GetLazyFactory(setAccessor.MemberType);
            }
            #endregion

            if (!GetType().IsSubclassOf(typeof(ResultProperty)))
            {
                propertyStrategy = PropertyStrategyFactory.Get(this);
            }
        }
Example #11
0
        /// <summary>
        /// Deserializes the specified config.
        /// </summary>
        /// <param name="config">The config.</param>
        /// <param name="dataExchangeFactory">The data exchange factory.</param>
        /// <param name="waitResultPropertyResolution">The wait result property resolution delegate.</param>
        /// <param name="waitDiscriminatorResolution">The wait discriminator resolution.</param>
        /// <returns></returns>
        public static ResultMap Deserialize(
            IConfiguration config,
            DataExchangeFactory dataExchangeFactory,
            WaitResultPropertyResolution waitResultPropertyResolution,
            WaitDiscriminatorResolution waitDiscriminatorResolution
            )
        {
            /*resultMaps子节点信息格式
             *   <resultMap id="account-result-constructor"  class="Account" >
             *      <constructor>
             *          <argument argumentName="identifiant"	column="Account_ID"/>
             *          <argument argumentName="firstName"    column="Account_FirstName"/>
             *          <argument argumentName="lastName"     column="Account_LastName"/>
             *   </constructor>
             *   <result property="EmailAddress" column="Account_Email" nullValue="*****@*****.**"/>
             *   <result property="BannerOption" column="Account_Banner_Option" dbType="Varchar" type="bool"/>
             *   <result property="CartOption"	  column="Account_Cart_Option" typeHandler="HundredsBool"/>
             * </resultMap>
             */
            //从config中对应的resultMap节点获取其属性
            string id         = config.Id;
            string className  = ConfigurationUtils.GetMandatoryStringAttribute(config, ConfigConstants.ATTRIBUTE_CLASS);
            string extends    = config.GetAttributeValue(ConfigConstants.ATTRIBUTE_EXTENDS);
            string groupBy    = config.GetAttributeValue(ConfigConstants.ATTRIBUTE_GROUPBY);
            string keyColumns = config.GetAttributeValue(ConfigConstants.ATTRIBUTE_KEYS_PROPERTIES);
            string suffix     = ConfigurationUtils.GetStringAttribute(config.Attributes, ConfigConstants.ATTRIBUTE_SUFFIX, string.Empty);
            string prefix     = ConfigurationUtils.GetStringAttribute(config.Attributes, ConfigConstants.ATTRIBUTE_PREFIX, string.Empty);

            //从工厂类的别名字典中获取
            Type type = dataExchangeFactory.TypeHandlerFactory.GetType(className);
            //根据type类型获取IDataExchange类对象
            IDataExchange dataExchange = dataExchangeFactory.GetDataExchangeForClass(type);
            IFactory      factory      = null;
            //准备存储构造函数参数argument节点信息
            ArgumentPropertyCollection arguments = new ArgumentPropertyCollection();

            #region Get the constructor & associated parameters

            //获取config下节点构造函数constructor的集合
            ConfigurationCollection constructors = config.Children.Find(ConfigConstants.ELEMENT_CONSTRUCTOR);

            if (constructors.Count > 0)
            {
                //默认获取第一个构造函数constructor节点  因为是初始化一个类  一个构造函数就足够了
                IConfiguration constructor = constructors[0];

                Type[]   argumentsType = new Type[constructor.Children.Count];
                string[] argumentsName = new string[constructor.Children.Count];

                // Builds param name list
                //argument节点的个数
                for (int i = 0; i < constructor.Children.Count; i++)
                {
                    //argumentName属性的取值
                    argumentsName[i] = ConfigurationUtils.GetStringAttribute(constructor.Children[i].Attributes, ConfigConstants.ATTRIBUTE_ARGUMENTNAME);
                }

                // Find the constructor  匹配构造函数
                ConstructorInfo constructorInfo = GetConstructor(id, type, argumentsName);

                // Build ArgumentProperty and parameter type list
                //处理构造函数的参数 每一个参数添加到arguments参数列表中
                for (int i = 0; i < constructor.Children.Count; i++)
                {
                    ArgumentProperty argumentMapping = ArgumentPropertyDeSerializer.Deserialize(
                        constructor.Children[i], //第i个Argument节点配置类
                        type,                    //当前构造函数的类
                        constructorInfo,         //当前构造函数的信息
                        dataExchangeFactory);

                    arguments.Add(argumentMapping);

                    //此处NestedResultMapName字符串应该为空
                    if (argumentMapping.NestedResultMapName.Length > 0)
                    {
                        waitResultPropertyResolution(argumentMapping);
                    }
                    //保存当前参数的类型
                    argumentsType[i] = argumentMapping.MemberType;
                }
                // Init the object factory
                //构造函数参数信息分析完成   动态初始化这个构造函数
                factory = dataExchangeFactory.ObjectFactory.CreateFactory(type, argumentsType);
            }
            else
            {
                if (!dataExchangeFactory.TypeHandlerFactory.IsSimpleType(type) && type != typeof(DataRow))
                {
                    factory = dataExchangeFactory.ObjectFactory.CreateFactory(type, Type.EmptyTypes);
                }
            }

            #endregion

            //处理result所有节点
            ResultPropertyCollection properties = BuildResultProperties(
                id,
                config,
                type,
                prefix,
                suffix,
                dataExchangeFactory,
                waitResultPropertyResolution);
            //对discriminator鉴别器的分析
            Discriminator discriminator = BuildDiscriminator(config, type, dataExchangeFactory, waitDiscriminatorResolution);

            //子节点分析完毕 将这些信息加入到resultMap父节点中
            ResultMap resultMap = new ResultMap(
                id,
                className,
                extends,
                groupBy,
                keyColumns,
                type,
                dataExchange,
                factory,
                dataExchangeFactory.TypeHandlerFactory,
                properties,
                arguments,
                discriminator
                );

            return(resultMap);
        }
Example #12
0
 public ProcedureSql(IScope scope, string sqlStatement, IStatement statement)
 {
     this._sqlStatement        = sqlStatement;
     this._statement           = statement;
     this._dataExchangeFactory = scope.DataExchangeFactory;
 }
Example #13
0
 internal DynamicSql(ConfigurationScope configScope, IStatement statement)
 {
     this._statement = statement;
     this._usePositionalParameters = configScope.DataSource.DbProvider.UsePositionalParameters;
     this._dataExchangeFactory     = configScope.DataExchangeFactory;
 }
        /// <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>
        public 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,dbype=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
            }

            ParameterProperty[] mappingArray = mappingList.ToArray();

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

            return(sqlText);
        }
        /// <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));
        }
        /// <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);
            IEnumerator     enumeratorParam = paramParser.GetEnumerator();

            enumeratorParam.MoveNext();

            propertyName = ((string)enumeratorParam.Current).Trim();

            while (enumeratorParam.MoveNext())
            {
                string field = ((string)enumeratorParam.Current).Trim().ToLower();
                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);
                }
            }

            return(new ParameterProperty(
                       propertyName,
                       columnName,
                       callBack,
                       type,
                       dbType,
                       direction,
                       nullValue,
                       0,
                       0,
                       -1,
                       parameterClassType,
                       dataExchangeFactory));
        }