1 /* 2 * Entity - Entity is an object-relational mapping tool for the D programming language. Referring to the design idea of JPA. 3 * 4 * Copyright (C) 2015-2018 Shanghai Putao Technology Co., Ltd 5 * 6 * Developer: HuntLabs.cn 7 * 8 * Licensed under the Apache-2.0 License. 9 * 10 */ 11 12 module hunt.entity.TypedQuery; 13 14 import hunt.entity; 15 import hunt.Long; 16 import hunt.logging; 17 18 import std.variant; 19 20 // version(WITH_HUNT_TRACE) 21 // { 22 // // import hunt.trace.Constrants; 23 // // import hunt.trace.Plugin; 24 // import hunt.trace.Span; 25 // } 26 27 class TypedQuery(T, F = T) if(is(T : Object) && is(F : Object)) { 28 29 private string _sqlSting; 30 private CriteriaQuery!(T, F) _query; 31 private EntityManager _manager; 32 33 // version (WITH_HUNT_TRACE) 34 // { 35 // private Span _span; 36 // private string[string] _tags; 37 // } 38 39 this(CriteriaQuery!(T, F) query, EntityManager manager) { 40 _query = query; 41 _manager = manager; 42 } 43 44 // version (WITH_HUNT_TRACE) 45 // { 46 // private void beginTrace(string name) 47 // { 48 // _tags.clear(); 49 // _span = traceSpanBefore(name); 50 // } 51 52 // private void endTrace(string error = null) 53 // { 54 // if (_span !is null) 55 // { 56 // traceSpanAfter(_span, _tags, error); 57 // } 58 // } 59 // } 60 61 R getResultAs(R)() { 62 string sql = _query.toString(); 63 Statement stmt = _manager.getSession().prepare(sql); 64 RowSet rowSet = stmt.query(); 65 version (HUNT_ENTITY_DEBUG) { 66 infof("The result columns: %s", rowSet.columnsNames()); 67 } 68 69 if (rowSet.size() == 0) { 70 warning("The result is empty"); 71 return R.init; 72 } 73 74 // First row and first column 75 76 Row firstRow = rowSet.firstRow(); 77 if (firstRow.size() == 0) { 78 warning("The column in the row is empty."); 79 return R.init; 80 } 81 82 Variant singleValue = firstRow.getValue(0); 83 version (HUNT_ENTITY_DEBUG) { 84 tracef("The first columns, type: %s, value: %s", singleValue.type, singleValue.toString()); 85 } 86 87 if (singleValue.hasValue()) 88 return singleValue.get!R(); 89 else 90 return R.init; 91 } 92 93 Object getSingleResult() { 94 Object[] ret = _getResultList(); 95 if (ret.length == 0) 96 return null; 97 return ret[0]; 98 } 99 100 T[] getResultList() { 101 Object[] ret = _getResultList(); 102 if (ret.length == 0) { 103 return null; 104 } 105 return cast(T[]) ret; 106 } 107 108 TypedQuery!(T, F) setMaxResults(int maxResult) { 109 _query.getQueryBuilder().limit(maxResult); 110 return this; 111 } 112 113 TypedQuery!(T, F) setFirstResult(int startPosition) { 114 _query.getQueryBuilder().offset(startPosition); 115 return this; 116 } 117 118 private Object[] _getResultList() { 119 string sql = _query.toString(); 120 121 // version (WITH_HUNT_TRACE) 122 // { 123 // beginTrace("TypeQuery _getResultList"); 124 // scope (exit) 125 // { 126 // _tags["sql"] = sql; 127 // endTrace(); 128 // } 129 // } 130 131 Statement stmt = _manager.getSession().prepare(sql); 132 RowSet res = stmt.query(); 133 version (HUNT_ENTITY_DEBUG) { 134 infof("The result columns: %s", res.columnsNames()); 135 } 136 137 Row[] rows; 138 foreach (value; res) { 139 rows ~= value; 140 } 141 142 long count = -1; 143 Object[] ret; 144 Root!(T, F) r = _query.getRoot(); 145 foreach (size_t k, Row v; rows) { 146 T t = r.deSerialize(rows, count, cast(int) k, null); 147 if (t is null) { 148 warningf("t is null, count=%d", count); 149 if (count != -1) { 150 ret ~= new Long(count); 151 } else { 152 throw new EntityException("getResultList has an null data"); 153 } 154 } 155 ret ~= t; 156 } 157 return ret; 158 } 159 160 }