Removed untyped contructor from ComponentRegistration and add a protected setter.
[castle.git] / ActiveRecord / Castle.ActiveRecord / Framework / Queries / Modifiers / QueryParameter.cs
blob8acdb29174e4c5b86a3607f7ec99a8eb6125eeb5
1 // Copyright 2004-2008 Castle Project - http://www.castleproject.org/
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 namespace Castle.ActiveRecord.Queries.Modifiers
17 using System;
18 using System.Collections;
20 using NHibernate;
21 using NHibernate.Type;
23 /// <summary>
24 /// Represents a query parameter.
25 /// </summary>
26 public class QueryParameter : IQueryModifier
28 private readonly String name;
29 private readonly int position = -1;
30 private readonly Object value;
31 private readonly IType type;
32 private readonly ParameterFlags flags;
34 #region Constructors for Named Parameters
35 /// <summary>
36 /// Initializes a new instance of the <see cref="QueryParameter"/> class.
37 /// </summary>
38 /// <param name="name">The name.</param>
39 /// <param name="value">The value.</param>
40 public QueryParameter(string name, object value)
42 if (name == null)
43 throw new ArgumentNullException("name");
45 flags = ParameterFlags.Named;
46 this.name = name;
47 this.value = value;
50 /// <summary>
51 /// Initializes a new instance of the <see cref="QueryParameter"/> class.
52 /// </summary>
53 /// <param name="name">The name.</param>
54 /// <param name="value">The value.</param>
55 /// <param name="type">The type.</param>
56 public QueryParameter(String name, Object value, IType type)
57 : this(name, value)
59 this.type = type;
61 #endregion
63 #region Constructors for Positional Parameters
64 /// <summary>
65 /// Initializes a new instance of the <see cref="QueryParameter"/> class.
66 /// </summary>
67 /// <param name="position">The position.</param>
68 /// <param name="value">The value.</param>
69 public QueryParameter(int position, object value)
71 if (position < 0)
72 throw new ArgumentException("Position must be equal or greater than 0", "position");
74 flags = ParameterFlags.Positional;
75 this.position = position;
76 this.value = value;
79 /// <summary>
80 /// Initializes a new instance of the <see cref="QueryParameter"/> class.
81 /// </summary>
82 /// <param name="position">The position.</param>
83 /// <param name="value">The value.</param>
84 /// <param name="type">The type.</param>
85 public QueryParameter(int position, object value, IType type)
86 : this(position, value)
88 this.type = type;
90 #endregion
92 #region Constructors for Named List Parameters
93 /// <summary>
94 /// Initializes a new instance of the <see cref="QueryParameter"/> class.
95 /// </summary>
96 /// <param name="name">The name.</param>
97 /// <param name="value">The value.</param>
98 /// <param name="type">The type.</param>
99 public QueryParameter(String name, ICollection value, IType type)
100 : this(name, (object) value, type)
102 flags |= ParameterFlags.List;
105 /// <summary>
106 /// Initializes a new instance of the <see cref="QueryParameter"/> class.
107 /// </summary>
108 /// <param name="name">The name.</param>
109 /// <param name="value">The value.</param>
110 public QueryParameter(String name, ICollection value)
111 : this(name, (object) value)
113 flags |= ParameterFlags.List;
115 #endregion
117 #region Constructors for Positional List Parameters (throws exceptions)
118 /// <remarks>
119 /// It is important to keep this constructor as is, to avoid
120 /// confusion with the <see cref="QueryParameter(int, object, IType)"/>
121 /// overload.
122 /// </remarks>
123 public QueryParameter(int position, ICollection value, IType type)
124 : this(position, (object) value, type)
126 throw new InvalidOperationException("Parameter lists can not be positional");
129 /// <remarks>
130 /// It is important to keep this constructor as is, to avoid
131 /// confusion with the <see cref="QueryParameter(int, object)"/>
132 /// overload.
133 /// </remarks>
134 public QueryParameter(int position, ICollection value)
135 : this(position, (object) value)
137 throw new InvalidOperationException("Parameter lists can not be positional");
139 #endregion
141 #region Public Read-Only Properties
142 /// <summary>
143 /// The position of the positional parameter, or <c>-1</c>
144 /// if this is a named parameter.
145 /// </summary>
146 public int Position
148 get { return position; }
151 /// <summary>
152 /// The name of the named parameter, or <c>null</c>
153 /// if this is a positional parameter.
154 /// </summary>
155 public string Name
157 get { return name; }
160 /// <summary>
161 /// The parameter value.
162 /// </summary>
163 public Object Value
165 get { return value; }
168 /// <summary>
169 /// The NHibernate type.
170 /// </summary>
171 public IType Type
173 get { return type; }
175 #endregion
177 #region "Apply" method
178 /// <summary>
179 /// Add this parameter to the <paramref name="query"/>.
180 /// </summary>
181 /// <param name="query">The query</param>
182 /// <remarks>
183 /// Is there a cleaner way to do this, without reflection or complex
184 /// hierarchies?
185 /// </remarks>
186 public void Apply(IQuery query)
188 if (IsFlagged(ParameterFlags.Named))
190 if (IsFlagged(ParameterFlags.List))
192 if (Type != null)
193 query.SetParameterList(Name, (ICollection) Value, Type);
194 else
195 query.SetParameterList(Name, (ICollection) Value);
197 else
199 if (Type != null)
200 query.SetParameter(Name, Value, Type);
201 else
202 query.SetParameter(Name, Value);
205 else if (IsFlagged(ParameterFlags.Positional))
207 if (IsFlagged(ParameterFlags.List))
209 throw new InvalidOperationException("Parameter lists can not be positional");
211 else
213 if (Type != null)
214 query.SetParameter(Position, Value, Type);
215 else
216 query.SetParameter(Position, Value);
220 #endregion
222 #region Flags
223 private bool IsFlagged(ParameterFlags flag)
225 return ((flags & flag) == flag);
228 [Flags]
229 private enum ParameterFlags
231 Positional = 0x0001,
232 Named = 0x0002,
234 List = 0x0010,
236 #endregion