2009-07-11 Michael Barker <mike@middlesoft.co.uk>
[mono.git] / mcs / class / System.Data.Linq / src / DbLinq / Test / Providers / ReadTest_GroupBy.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;\r
28 using System.Collections.Generic;\r
29 using System.Text;\r
30 using System.Linq;\r
31 using System.Linq.Expressions;\r
32 using NUnit.Framework;\r
33 using Test_NUnit;\r
34 \r
35 using nwind;\r
36 \r
37 // test ns \r
38 #if MYSQL\r
39     namespace Test_NUnit_MySql\r
40 #elif ORACLE && ODP\r
41     namespace Test_NUnit_OracleODP\r
42 #elif ORACLE\r
43     namespace Test_NUnit_Oracle\r
44 #elif POSTGRES\r
45     namespace Test_NUnit_PostgreSql\r
46 #elif SQLITE\r
47     namespace Test_NUnit_Sqlite\r
48 #elif INGRES\r
49     namespace Test_NUnit_Ingres\r
50 #elif MSSQL && L2SQL\r
51     namespace Test_NUnit_MsSql_Strict\r
52 #elif MSSQL\r
53     namespace Test_NUnit_MsSql\r
54 #elif FIREBIRD\r
55     namespace Test_NUnit_Firebird\r
56 #endif\r
57 {\r
58     [TestFixture]\r
59     public class ReadTest_GroupBy : TestBase\r
60     {\r
61 \r
62 \r
63         [Test]\r
64         public void G01_SimpleGroup_Count()\r
65         {\r
66             Northwind db = base.CreateDB();\r
67 \r
68             var q2 = db.Customers.GroupBy(c => c.City)\r
69                 .Select(g => new { g.Key, Count = g.Count() });\r
70 \r
71             int rowCount = 0;\r
72             foreach (var g in q2)\r
73             {\r
74                 rowCount++;\r
75                 Assert.IsTrue(g.Count > 0, "Must have Count");\r
76                 Assert.IsTrue(g.Key != null, "Must have City");\r
77             }\r
78             Assert.IsTrue(rowCount > 0, "Must have some rows");\r
79         }\r
80 \r
81 #if !DEBUG && (MSSQL && !L2SQL)\r
82         [Explicit]\r
83 #endif\r
84         [Test]\r
85         public void G02_SimpleGroup_First()\r
86         {\r
87             try\r
88             {\r
89                 //Note: this SQL is allowed in Mysql but illegal on Postgres \r
90                 //(PostgreSql ERROR: column "c$.customerid" must appear in the GROUP BY clause or be used in an aggregate function - SQL state: 42803)\r
91                 //"SELECT City, customerid FROM customer GROUP BY City"\r
92                 //that's why DbLinq disallows it\r
93                 Northwind db = base.CreateDB();\r
94                 var q2 = db.Customers.GroupBy(c => c.City);\r
95                 var q3 = q2.First();\r
96 \r
97                 Assert.IsTrue(q3 != null && q3.Key != null, "Must have result with Key");\r
98                 foreach (var c in q3)\r
99                 {\r
100                     Assert.IsTrue(c.City != null, "City must be non-null");\r
101                 }\r
102             }\r
103             catch(InvalidOperationException)\r
104             {\r
105                 Assert.Ignore("Some vendors don't support this request (which doesn't make sense anyway)");\r
106             }\r
107         }\r
108 \r
109 #if !DEBUG && (MSSQL && !L2SQL)\r
110         [Explicit]\r
111 #endif\r
112         [Test]\r
113         public void G03_SimpleGroup_WithSelector_Invalid()\r
114         {\r
115             try\r
116             {\r
117                 //Note: this SQL is allowed in Mysql but illegal on Postgres \r
118                 //(PostgreSql ERROR: column "c$.customerid" must appear in the GROUP BY clause or be used in an aggregate function - SQL state: 42803)\r
119                 //"SELECT City, customerid FROM customer GROUP BY City"\r
120                 Northwind db = base.CreateDB();\r
121 \r
122                 var q2 = db.Customers.GroupBy(c => c.City, c => new {c.City, c.CustomerID});\r
123 \r
124                 foreach (var g in q2)\r
125                 {\r
126                     int entryCount = 0;\r
127                     foreach (var c in g)\r
128                     {\r
129                         Assert.IsTrue(c.City != null, "City must be non-null");\r
130                         entryCount++;\r
131                     }\r
132                     Assert.IsTrue(entryCount > 0, "Must have some entries in group");\r
133                 }\r
134             }\r
135             catch (InvalidOperationException)\r
136             {\r
137                 Assert.Ignore("Some vendors don't support this request (which doesn't make sense anyway)");\r
138             }\r
139         }\r
140 \r
141         [Test]\r
142         public void G03_DoubleKey()\r
143         {\r
144             //Note: this SQL is allowed in Mysql but illegal on Postgres \r
145             //(PostgreSql ERROR: column "c$.customerid" must appear in the GROUP BY clause or be used in an aggregate function - SQL state: 42803)\r
146             //"SELECT City, customerid FROM customer GROUP BY City"\r
147             Northwind db = base.CreateDB();\r
148 \r
149             var q2 = from o in db.Orders\r
150                      group o by new { o.CustomerID, o.EmployeeID } into g\r
151                      select new { g.Key.CustomerID, g.Key.EmployeeID, Count = g.Count() };\r
152 \r
153             int entryCount = 0;\r
154             foreach (var g in q2)\r
155             {\r
156                 entryCount++;\r
157                 Assert.IsTrue(g.CustomerID != null, "Must have non-null customerID");\r
158                 Assert.IsTrue(g.EmployeeID > 0, "Must have >0 employeeID");\r
159                 Assert.IsTrue(g.Count >= 0, "Must have non-neg Count");\r
160             }\r
161             Assert.IsTrue(entryCount > 0, "Must have some entries in group");\r
162         }\r
163 \r
164 \r
165 #if !DEBUG && (MSSQL && !L2SQL)\r
166         [Explicit]\r
167 #endif\r
168         [Test]\r
169         public void G04_SimpleGroup_WithSelector()\r
170         {\r
171             try\r
172             {\r
173                 //Note: this SQL is allowed in Mysql but illegal on Postgres \r
174                 //(PostgreSql ERROR: column "c$.customerid" must appear in the GROUP BY clause or be used in an aggregate function - SQL state: 42803)\r
175                 //"SELECT City, customerid FROM customer GROUP BY City"\r
176                 Northwind db = base.CreateDB();\r
177                 var q2 = db.Customers.GroupBy(c => c.City, c => c.CustomerID);\r
178 \r
179                 foreach (var g in q2)\r
180                 {\r
181                     int entryCount = 0;\r
182                     foreach (var c in g)\r
183                     {\r
184                         Assert.IsTrue(c != null, "CustomerID must be non-null");\r
185                         entryCount++;\r
186                     }\r
187                     Assert.IsTrue(entryCount > 0, "Must have some entries in group");\r
188                 }\r
189             }\r
190             catch (InvalidOperationException)\r
191             {\r
192                 Assert.Ignore("Some vendors don't support this request (which doesn't make sense anyway)");\r
193             }\r
194         }\r
195 \r
196 #if !DEBUG && (SQLITE || (MSSQL && !L2SQL))\r
197         [Explicit]\r
198 #endif\r
199         [Test]\r
200         public void G05_Group_Into()\r
201         {\r
202             Northwind db = base.CreateDB();\r
203             var q2 =\r
204                 from c in db.Customers\r
205                 //where c.Country == "France"\r
206                 group new { c.PostalCode, c.ContactName } by c.City into g\r
207                 select g;\r
208             var q3 = from g in q2 select new { FortyTwo = 42, g.Key, Count = g.Count() };\r
209             //select new {g.Key.Length, g};\r
210             //select new {42,g};\r
211 \r
212             int entryCount = 0;\r
213             foreach (var g in q3)\r
214             {\r
215                 Assert.IsTrue(g.FortyTwo == 42, "Forty42 must be there");\r
216                 Assert.IsTrue(g.Count > 0, "Positive count");\r
217                 entryCount++;\r
218             }\r
219             Assert.IsTrue(entryCount > 0, "Must have some entries in group");\r
220         }\r
221 \r
222 \r
223         [Test]\r
224         public void G06_OrderCountByCustomerID()\r
225         {\r
226             Northwind db = base.CreateDB();\r
227 \r
228             var q2 = from o in db.Orders\r
229                      group o by o.CustomerID into g\r
230                      //where g.Count()>1\r
231                      select new { g.Key, OrderCount = g.Count() };\r
232 \r
233             var lst = q2.ToList();\r
234             Assert.Greater(lst.Count, 0, "Expected some grouped order results");\r
235             var result0 = lst[0];\r
236             Assert.IsTrue(result0.Key != null, "Key must be non-null");\r
237             Assert.Greater(result0.OrderCount, 0, "Count must be > 0");\r
238             //select new { g.Key , SumPerCustomer = g.Sum(o2=>o2.OrderID) };\r
239         }\r
240 \r
241 #if !DEBUG && (SQLITE || (MSSQL && !L2SQL))\r
242         [Explicit]\r
243 #endif\r
244         [Test]\r
245         public void G07_OrderCountByCustomerID_Where()\r
246         {\r
247             Northwind db = base.CreateDB();\r
248 \r
249             var q2 = from o in db.Orders\r
250                      group o by o.CustomerID into g\r
251                      where g.Count() > 1\r
252                      select new { g.Key, OrderCount = g.Count() };\r
253 \r
254             var lst = q2.ToList();\r
255             Assert.Greater(lst.Count, 0, "Expected some grouped order results");\r
256             var result0 = lst[0];\r
257             Assert.IsTrue(result0.Key != null, "Key must be non-null");\r
258             Assert.Greater(result0.OrderCount, 0, "Count must be > 0");\r
259             //select new { g.Key , SumPerCustomer = g.Sum(o2=>o2.OrderID) };\r
260         }\r
261 \r
262 #if !DEBUG && (SQLITE || (MSSQL && !L2SQL))\r
263         [Explicit]\r
264 #endif\r
265         [Test]\r
266         public void G08_OrderSumByCustomerID()\r
267         {\r
268             Northwind db = base.CreateDB();\r
269 \r
270             var q2 = from o in db.Orders\r
271                      group o by o.CustomerID into g\r
272                      //where g.Count()>1\r
273                      select new { g.Key, OrderSum = g.Sum(o => o.OrderID) };\r
274             var lst = q2.ToList();\r
275             Assert.Greater(lst.Count, 0, "Expected some grouped order results");\r
276             foreach (var result in lst)\r
277             {\r
278                 Console.WriteLine("  Result: custID=" + result.Key + " sum=" + result.OrderSum);\r
279                 Assert.IsTrue(result.Key != null, "Key must be non-null");\r
280                 Assert.Greater(result.OrderSum, 0, "OrderSum must be > 0");\r
281             }\r
282             //select new { g.Key , SumPerCustomer = g.Sum(o2=>o2.OrderID) };\r
283         }\r
284 \r
285         /// <summary>\r
286         /// Reported by  pwy.mail in http://code.google.com/p/dblinq2007/issues/detail?id=64\r
287         /// </summary>\r
288 #if !DEBUG && (MSSQL && !L2SQL)\r
289         [Explicit]\r
290 #endif\r
291         [Test]\r
292         public void G09_UnitPriceGreaterThan10()\r
293         {\r
294             Northwind db = base.CreateDB();\r
295 \r
296             var priceQuery =\r
297                 from prod in db.Products\r
298                 group prod by new\r
299                 {\r
300                     Criterion = prod.UnitPrice > 10\r
301                 }\r
302                     into grouping\r
303                     select grouping;\r
304 \r
305             foreach (var prodObj in priceQuery)\r
306             {\r
307                 if (prodObj.Key.Criterion == false)\r
308                     Console.WriteLine("Prices 10 or less:");\r
309                 else\r
310                     Console.WriteLine("\nPrices greater than 10");\r
311                 foreach (var listing in prodObj)\r
312                 {\r
313                     Console.WriteLine("{0}, {1}", listing.ProductName,\r
314                         listing.UnitPrice);\r
315                 }\r
316             }\r
317 \r
318         }\r
319 \r
320 \r
321     }\r
322 }\r