2009-06-12 Bill Holmes <billholmes54@gmail.com>
[mono.git] / mcs / class / System.Data.Linq / src / DbLinq / Data / Linq / Sql / SqlStatement.cs
1 #region MIT license\r
2 // \r
3 // MIT license\r
4 //\r
5 // Copyright (c) 2007-2008 Jiri Moudry, Pascal Craponne\r
6 // \r
7 // Permission is hereby granted, free of charge, to any person obtaining a copy\r
8 // of this software and associated documentation files (the "Software"), to deal\r
9 // in the Software without restriction, including without limitation the rights\r
10 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
11 // copies of the Software, and to permit persons to whom the Software is\r
12 // furnished to do so, subject to the following conditions:\r
13 // \r
14 // The above copyright notice and this permission notice shall be included in\r
15 // all copies or substantial portions of the Software.\r
16 // \r
17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
20 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
22 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
23 // THE SOFTWARE.\r
24 // \r
25 #endregion\r
26 \r
27 using System.Collections;\r
28 using System.Collections.Generic;\r
29 using System.Diagnostics;\r
30 using System.Linq;\r
31 \r
32 #if MONO_STRICT\r
33 namespace System.Data.Linq.Sql\r
34 #else\r
35 namespace DbLinq.Data.Linq.Sql\r
36 #endif\r
37 {\r
38     /// <summary>\r
39     /// An SqlStatement is a literal SQL request, composed of different parts (SqlPart)\r
40     /// each part being either a parameter or a literal string\r
41     /// </summary>\r
42     [DebuggerDisplay("SqlStatement {ToString()}")]\r
43 #if MONO_STRICT\r
44     internal\r
45 #else\r
46     public\r
47 #endif\r
48     class SqlStatement : IEnumerable<SqlPart>\r
49     {\r
50         private readonly List<SqlPart> parts = new List<SqlPart>();\r
51 \r
52         /// <summary>\r
53         /// Empty SqlStatement, used to build new statements\r
54         /// </summary>\r
55         public static readonly SqlStatement Empty = new SqlStatement();\r
56 \r
57         /// <summary>\r
58         /// Returns the number of parts present\r
59         /// </summary>\r
60         public int Count { get { return parts.Count; } }\r
61 \r
62         /// <summary>\r
63         /// Enumerates all parts\r
64         /// </summary>\r
65         /// <returns></returns>\r
66         public IEnumerator<SqlPart> GetEnumerator()\r
67         {\r
68             return parts.GetEnumerator();\r
69         }\r
70 \r
71         /// <summary>\r
72         /// Enumerates all parts\r
73         /// </summary>\r
74         /// <returns></returns>\r
75         IEnumerator IEnumerable.GetEnumerator()\r
76         {\r
77             return GetEnumerator();\r
78         }\r
79 \r
80         /// <summary>\r
81         /// Returns part at given index\r
82         /// </summary>\r
83         /// <param name="index"></param>\r
84         /// <returns></returns>\r
85         public SqlPart this[int index]\r
86         {\r
87             get { return parts[index]; }\r
88         }\r
89 \r
90         /// <summary>\r
91         /// Combines all parts, in correct order\r
92         /// </summary>\r
93         /// <returns></returns>\r
94         public override string ToString()\r
95         {\r
96             return string.Join(string.Empty, (from part in parts select part.Sql).ToArray());\r
97         }\r
98 \r
99         /// <summary>\r
100         /// Joins SqlStatements into a new SqlStatement\r
101         /// </summary>\r
102         /// <param name="sqlStatement"></param>\r
103         /// <param name="sqlStatements"></param>\r
104         /// <returns></returns>\r
105         public static SqlStatement Join(SqlStatement sqlStatement, IList<SqlStatement> sqlStatements)\r
106         {\r
107             // optimization: if we have only one statement to join, we return the statement itself\r
108             if (sqlStatements.Count == 1)\r
109                 return sqlStatements[0];\r
110             var builder = new SqlStatementBuilder();\r
111             builder.AppendJoin(sqlStatement, sqlStatements);\r
112             return builder.ToSqlStatement();\r
113         }\r
114 \r
115         /// <summary>\r
116         /// Joins SqlStatements into a new SqlStatement\r
117         /// </summary>\r
118         /// <param name="sqlStatement"></param>\r
119         /// <param name="sqlStatements"></param>\r
120         /// <returns></returns>\r
121         public static SqlStatement Join(SqlStatement sqlStatement, params SqlStatement[] sqlStatements)\r
122         {\r
123             return Join(sqlStatement, (IList<SqlStatement>)sqlStatements);\r
124         }\r
125 \r
126         /// <summary>\r
127         /// Formats an SqlStatement\r
128         /// </summary>\r
129         /// <param name="format"></param>\r
130         /// <param name="sqlStatements"></param>\r
131         /// <returns></returns>\r
132         public static SqlStatement Format(string format, IList<SqlStatement> sqlStatements)\r
133         {\r
134             var builder = new SqlStatementBuilder();\r
135             builder.AppendFormat(format, sqlStatements);\r
136             return builder.ToSqlStatement();\r
137         }\r
138 \r
139         /// <summary>\r
140         /// Formats the specified text.\r
141         /// </summary>\r
142         /// <param name="format">The format.</param>\r
143         /// <param name="sqlStatements">The SQL statements.</param>\r
144         /// <returns></returns>\r
145         public static SqlStatement Format(string format, params SqlStatement[] sqlStatements)\r
146         {\r
147             return Format(format, (IList<SqlStatement>)sqlStatements);\r
148         }\r
149 \r
150         /// <summary>\r
151         /// Replaces all text occurrences in the SqlStatement\r
152         /// </summary>\r
153         /// <param name="find"></param>\r
154         /// <param name="replace"></param>\r
155         /// <param name="ignoreCase"></param>\r
156         /// <returns></returns>\r
157         public SqlStatement Replace(string find, string replace, bool ignoreCase)\r
158         {\r
159             var builder = new SqlStatementBuilder(this);\r
160             builder.Replace(find, replace, ignoreCase);\r
161             return builder.ToSqlStatement();\r
162         }\r
163 \r
164         /// <summary>\r
165         /// Initializes a new instance of the <see cref="SqlStatement"/> class.\r
166         /// </summary>\r
167         public SqlStatement()\r
168         {\r
169         }\r
170 \r
171         /// <summary>\r
172         /// Builds an SqlStatement by concatenating several statements\r
173         /// </summary>\r
174         /// <param name="sqlStatements"></param>\r
175         public SqlStatement(IEnumerable<SqlStatement> sqlStatements)\r
176         {\r
177             foreach (var sqlStatement in sqlStatements)\r
178             {\r
179                 parts.AddRange(sqlStatement.parts);\r
180             }\r
181         }\r
182 \r
183         /// <summary>\r
184         /// Builds SqlStatement\r
185         /// </summary>\r
186         /// <param name="sqlStatements"></param>\r
187         public SqlStatement(params SqlStatement[] sqlStatements)\r
188             : this((IEnumerable<SqlStatement>)sqlStatements)\r
189         {\r
190         }\r
191 \r
192         /// <summary>\r
193         /// Initializes a new instance of the <see cref="SqlStatement"/> class.\r
194         /// </summary>\r
195         /// <param name="sqlParts">The SQL parts.</param>\r
196         public SqlStatement(params SqlPart[] sqlParts)\r
197             : this((IList<SqlPart>)sqlParts)\r
198         {\r
199         }\r
200 \r
201         /// <summary>\r
202         /// Initializes a new instance of the <see cref="SqlStatement"/> class.\r
203         /// </summary>\r
204         /// <param name="sqlParts">The SQL parts.</param>\r
205         public SqlStatement(IEnumerable<SqlPart> sqlParts)\r
206         {\r
207             foreach (var sqlPart in sqlParts)\r
208                 SqlStatementBuilder.AddPart(parts, sqlPart);\r
209         }\r
210 \r
211         /// <summary>\r
212         /// Initializes a new instance of the <see cref="SqlStatement"/> class.\r
213         /// </summary>\r
214         /// <param name="sql">The SQL.</param>\r
215         public SqlStatement(string sql)\r
216         {\r
217             parts.Add(new SqlLiteralPart(sql));\r
218         }\r
219 \r
220         /// <summary>\r
221         /// Converts a string to an SqlStatement\r
222         /// </summary>\r
223         /// <param name="sql"></param>\r
224         /// <returns></returns>\r
225         public static implicit operator SqlStatement(string sql)\r
226         {\r
227             return new SqlStatement(sql);\r
228         }\r
229     }\r
230 }\r