You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

SamplesTest.java 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. /*
  2. * Copyright 2004-2011 H2 Group.
  3. * Copyright 2011 James Moger.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. package com.iciql.test;
  18. import static com.iciql.Function.count;
  19. import static com.iciql.Function.isNull;
  20. import static com.iciql.Function.length;
  21. import static com.iciql.Function.max;
  22. import static com.iciql.Function.min;
  23. import static com.iciql.Function.not;
  24. import static com.iciql.Function.sum;
  25. import static org.junit.Assert.assertEquals;
  26. import static org.junit.Assert.assertTrue;
  27. import java.math.BigDecimal;
  28. import java.util.HashSet;
  29. import java.util.List;
  30. import java.util.Set;
  31. import org.junit.After;
  32. import org.junit.Before;
  33. import org.junit.Test;
  34. import com.iciql.Db;
  35. import com.iciql.Filter;
  36. import com.iciql.test.models.ComplexObject;
  37. import com.iciql.test.models.Customer;
  38. import com.iciql.test.models.Order;
  39. import com.iciql.test.models.Product;
  40. import com.iciql.test.models.SupportedTypes;
  41. /**
  42. * This is the implementation of the 101 LINQ Samples as described in
  43. * http://msdn2.microsoft.com/en-us/vcsharp/aa336760.aspx
  44. */
  45. public class SamplesTest {
  46. /**
  47. * This object represents a database (actually a connection to the
  48. * database).
  49. */
  50. Db db;
  51. @Before
  52. public void setUp() {
  53. db = Db.open("jdbc:h2:mem:", "sa", "sa");
  54. db.insertAll(Product.getList());
  55. db.insertAll(Customer.getList());
  56. db.insertAll(Order.getList());
  57. db.insertAll(ComplexObject.getList());
  58. }
  59. @After
  60. public void tearDown() {
  61. db.close();
  62. }
  63. /**
  64. * A simple test table. The columns are in a different order than in the
  65. * database.
  66. */
  67. public static class TestReverse {
  68. public String name;
  69. public Integer id;
  70. }
  71. @Test
  72. public void testReverseColumns() {
  73. db.executeUpdate("create table TestReverse(id int, name varchar, additional varchar)");
  74. TestReverse t = new TestReverse();
  75. t.id = 10;
  76. t.name = "Hello";
  77. db.insert(t);
  78. TestReverse check = db.from(new TestReverse()).selectFirst();
  79. assertEquals(t.name, check.name);
  80. assertEquals(t.id, check.id);
  81. }
  82. @Test
  83. public void testWhereSimple2() {
  84. // var soldOutProducts =
  85. // from p in products
  86. // where p.UnitsInStock == 0
  87. // select p;
  88. Product p = new Product();
  89. List<Product> soldOutProducts = db.from(p).where(p.unitsInStock).is(0).orderBy(p.productId).select();
  90. assertEquals("[Chef Anton's Gumbo Mix: 0]", soldOutProducts.toString());
  91. }
  92. @Test
  93. public void testWhereSimple3() {
  94. // var expensiveInStockProducts =
  95. // from p in products
  96. // where p.UnitsInStock > 0
  97. // && p.UnitPrice > 3.00M
  98. // select p;
  99. Product p = new Product();
  100. List<Product> expensiveInStockProducts = db.from(p).where(p.unitsInStock).exceeds(0).and(p.unitPrice)
  101. .exceeds(30.0).orderBy(p.productId).select();
  102. assertEquals("[Northwoods Cranberry Sauce: 6, Mishi Kobe Niku: 29, Ikura: 31]",
  103. expensiveInStockProducts.toString());
  104. }
  105. @Test
  106. public void testWhereSimple4() {
  107. // var waCustomers =
  108. // from c in customers
  109. // where c.Region == "WA"
  110. // select c;
  111. Customer c = new Customer();
  112. List<Customer> waCustomers = db.from(c).where(c.region).is("WA").select();
  113. assertEquals("[ALFKI, ANATR]", waCustomers.toString());
  114. }
  115. @Test
  116. public void testSelectSimple2() {
  117. // var productNames =
  118. // from p in products
  119. // select p.ProductName;
  120. Product p = new Product();
  121. List<String> productNames = db.from(p).orderBy(p.productId).select(p.productName);
  122. List<Product> products = Product.getList();
  123. for (int i = 0; i < products.size(); i++) {
  124. assertEquals(products.get(i).productName, productNames.get(i));
  125. }
  126. }
  127. /**
  128. * A result set class containing the product name and price.
  129. */
  130. public static class ProductPrice {
  131. public String productName;
  132. public String category;
  133. public Double price;
  134. }
  135. @Test
  136. public void testAnonymousTypes3() {
  137. // var productInfos =
  138. // from p in products
  139. // select new {
  140. // p.ProductName,
  141. // p.Category,
  142. // Price = p.UnitPrice
  143. // };
  144. final Product p = new Product();
  145. List<ProductPrice> productInfos = db.from(p).orderBy(p.productId).select(new ProductPrice() {
  146. {
  147. productName = p.productName;
  148. category = p.category;
  149. price = p.unitPrice;
  150. }
  151. });
  152. List<Product> products = Product.getList();
  153. assertEquals(products.size(), productInfos.size());
  154. for (int i = 0; i < products.size(); i++) {
  155. ProductPrice pr = productInfos.get(i);
  156. Product p2 = products.get(i);
  157. assertEquals(p2.productName, pr.productName);
  158. assertEquals(p2.category, pr.category);
  159. assertEquals(p2.unitPrice, pr.price);
  160. }
  161. }
  162. /**
  163. * A result set class containing customer data and the order total.
  164. */
  165. public static class CustOrder {
  166. public String customerId;
  167. public Integer orderId;
  168. public BigDecimal total;
  169. public String toString() {
  170. return customerId + ":" + orderId + ":" + total;
  171. }
  172. }
  173. @Test
  174. public void testSelectManyCompoundFrom2() {
  175. // var orders =
  176. // from c in customers,
  177. // o in c.Orders
  178. // where o.Total < 500.00M
  179. // select new {
  180. // c.CustomerID,
  181. // o.OrderID,
  182. // o.Total
  183. // };
  184. final Customer c = new Customer();
  185. final Order o = new Order();
  186. List<CustOrder> orders = db.from(c).innerJoin(o).on(c.customerId).is(o.customerId).where(o.total)
  187. .lessThan(new BigDecimal("100.00")).orderBy(1).select(new CustOrder() {
  188. {
  189. customerId = c.customerId;
  190. orderId = o.orderId;
  191. total = o.total;
  192. }
  193. });
  194. assertEquals("[ANATR:10308:88.80]", orders.toString());
  195. }
  196. @Test
  197. public void testIsNull() {
  198. Product p = new Product();
  199. String sql = db.from(p).whereTrue(isNull(p.productName)).getSQL();
  200. assertEquals("SELECT * FROM Product WHERE (productName IS NULL)", sql);
  201. }
  202. @Test
  203. public void testDelete() {
  204. Product p = new Product();
  205. int deleted = db.from(p).where(p.productName).like("A%").delete();
  206. assertEquals(1, deleted);
  207. deleted = db.from(p).delete();
  208. assertEquals(9, deleted);
  209. db.insertAll(Product.getList());
  210. db.deleteAll(Product.getList());
  211. assertEquals(0, db.from(p).selectCount());
  212. db.insertAll(Product.getList());
  213. }
  214. @Test
  215. public void testOrAndNot() {
  216. Product p = new Product();
  217. String sql = db.from(p).whereTrue(not(isNull(p.productName))).getSQL();
  218. assertEquals("SELECT * FROM Product WHERE (NOT productName IS NULL)", sql);
  219. sql = db.from(p).whereTrue(not(isNull(p.productName))).getSQL();
  220. assertEquals("SELECT * FROM Product WHERE (NOT productName IS NULL)", sql);
  221. sql = db.from(p).whereTrue(db.test(p.productId).is(1)).getSQL();
  222. assertEquals("SELECT * FROM Product WHERE ((productId = ?))", sql);
  223. }
  224. @Test
  225. public void testLength() {
  226. Product p = new Product();
  227. List<Integer> lengths = db.from(p).where(length(p.productName)).lessThan(10).orderBy(1)
  228. .selectDistinct(length(p.productName));
  229. assertEquals("[4, 5]", lengths.toString());
  230. }
  231. @Test
  232. public void testSum() {
  233. Product p = new Product();
  234. Long sum = db.from(p).selectFirst(sum(p.unitsInStock));
  235. assertEquals(323, sum.intValue());
  236. Double sumPrice = db.from(p).selectFirst(sum(p.unitPrice));
  237. assertEquals(313.35, sumPrice.doubleValue(), 0.001);
  238. }
  239. @Test
  240. public void testMinMax() {
  241. Product p = new Product();
  242. Integer min = db.from(p).selectFirst(min(p.unitsInStock));
  243. assertEquals(0, min.intValue());
  244. String minName = db.from(p).selectFirst(min(p.productName));
  245. assertEquals("Aniseed Syrup", minName);
  246. Double max = db.from(p).selectFirst(max(p.unitPrice));
  247. assertEquals(97.0, max.doubleValue(), 0.001);
  248. }
  249. @Test
  250. public void testLike() {
  251. Product p = new Product();
  252. List<Product> aList = db.from(p).where(p.productName).like("Cha%").orderBy(p.productName).select();
  253. assertEquals("[Chai: 39, Chang: 17]", aList.toString());
  254. }
  255. @Test
  256. public void testCount() {
  257. long count = db.from(new Product()).selectCount();
  258. assertEquals(10, count);
  259. }
  260. @Test
  261. public void testComplexObject() {
  262. ComplexObject co = new ComplexObject();
  263. String sql = db.from(co).where(co.id).is(1).and(co.amount).is(1L).and(co.birthday)
  264. .lessThan(new java.util.Date()).and(co.created)
  265. .lessThan(java.sql.Timestamp.valueOf("2005-05-05 05:05:05")).and(co.name).is("hello").and(co.time)
  266. .lessThan(java.sql.Time.valueOf("23:23:23")).and(co.value).is(new BigDecimal("1")).getSQL();
  267. assertEquals("SELECT * FROM ComplexObject " + "WHERE id = ? " + "AND amount = ? " + "AND birthday < ? "
  268. + "AND created < ? " + "AND name = ? " + "AND time < ? " + "AND value = ?", sql);
  269. long count = db.from(co).where(co.id).is(1).and(co.amount).is(1L).and(co.birthday)
  270. .lessThan(new java.util.Date()).and(co.created)
  271. .lessThan(java.sql.Timestamp.valueOf("2005-05-05 05:05:05")).and(co.name).is("hello").and(co.time)
  272. .lessThan(java.sql.Time.valueOf("23:23:23")).and(co.value).is(new BigDecimal("1")).selectCount();
  273. assertEquals(1, count);
  274. }
  275. @Test
  276. public void testComplexObject2() {
  277. testComplexObject2(1, "hello");
  278. }
  279. private void testComplexObject2(final int x, final String name) {
  280. final ComplexObject co = new ComplexObject();
  281. String sql = db.from(co).where(new Filter() {
  282. public boolean where() {
  283. return co.id == x && co.name.equals(name) && co.name.equals("hello");
  284. }
  285. }).getSQL();
  286. assertEquals("SELECT * FROM ComplexObject " + "WHERE id=? " + "AND ?=name " + "AND 'hello'=name", sql);
  287. long count = db.from(co).where(new Filter() {
  288. public boolean where() {
  289. return co.id == x && co.name.equals(name) && co.name.equals("hello");
  290. }
  291. }).selectCount();
  292. assertEquals(1, count);
  293. }
  294. @Test
  295. public void testLimitOffset() {
  296. Set<Integer> ids = new HashSet<Integer>();
  297. Product p = new Product();
  298. for (int i = 0; i < 5; i++) {
  299. List<Product> products = db.from(p).limit(2).offset(2 * i).select();
  300. assertTrue(products.size() == 2);
  301. for (Product prod : products) {
  302. assertTrue("Failed to add product id. Duplicate?", ids.add(prod.productId));
  303. }
  304. }
  305. }
  306. @Test
  307. public void testKeyRetrieval() {
  308. List<SupportedTypes> list = SupportedTypes.createList();
  309. List<Long> keys = db.insertAllAndGetKeys(list);
  310. Set<Long> uniqueKeys = new HashSet<Long>();
  311. for (Long l : keys) {
  312. assertTrue("Failed to add key. Duplicate?", uniqueKeys.add(l));
  313. }
  314. }
  315. /**
  316. * A result set class containing product groups.
  317. */
  318. public static class ProductGroup {
  319. public String category;
  320. public Long productCount;
  321. public String toString() {
  322. return category + ":" + productCount;
  323. }
  324. }
  325. @Test
  326. public void testGroup() {
  327. // var orderGroups =
  328. // from p in products
  329. // group p by p.Category into g
  330. // select new {
  331. // Category = g.Key,
  332. // Products = g
  333. // };
  334. final Product p = new Product();
  335. List<ProductGroup> list = db.from(p).groupBy(p.category).orderBy(1).select(new ProductGroup() {
  336. {
  337. category = p.category;
  338. productCount = count();
  339. }
  340. });
  341. assertEquals("[Beverages:2, Condiments:5, " + "Meat/Poultry:1, Produce:1, Seafood:1]", list.toString());
  342. }
  343. }