1
14
15 package com.liferay.portal.kernel.dao.orm;
16
17 import com.liferay.portal.kernel.dao.db.DB;
18 import com.liferay.portal.kernel.dao.db.DBFactoryUtil;
19 import com.liferay.portal.kernel.log.Log;
20 import com.liferay.portal.kernel.log.LogFactoryUtil;
21 import com.liferay.portal.kernel.util.OrderByComparator;
22 import com.liferay.portal.kernel.util.Randomizer;
23 import com.liferay.portal.kernel.util.UnmodifiableList;
24
25 import java.util.ArrayList;
26 import java.util.Iterator;
27 import java.util.List;
28
29
34 public class QueryUtil {
35
36 public static final int ALL_POS = -1;
37
38 public static Iterator<?> iterate(
39 Query query, Dialect dialect, int start, int end) {
40
41 return iterate(query, dialect, start, end, true);
42 }
43
44 public static Iterator<?> iterate(
45 Query query, Dialect dialect, int start, int end,
46 boolean unmodifiable) {
47
48 return list(query, dialect, start, end).iterator();
49 }
50
51 public static List<?> list(
52 Query query, Dialect dialect, int start, int end) {
53
54 return list(query, dialect, start, end, true);
55 }
56
57 public static List<?> list(
58 Query query, Dialect dialect, int start, int end,
59 boolean unmodifiable) {
60
61 if ((start == ALL_POS) && (end == ALL_POS)) {
62 return query.list(unmodifiable);
63 }
64 else {
65 if (dialect.supportsLimit()) {
66 query.setMaxResults(end - start);
67 query.setFirstResult(start);
68
69 return query.list(unmodifiable);
70 }
71 else {
72 List<Object> list = new ArrayList<Object>();
73
74 DB db = DBFactoryUtil.getDB();
75
76 if (!db.isSupportsScrollableResults()) {
77 if (_log.isWarnEnabled()) {
78 _log.warn(
79 "Database does not support scrollable results");
80 }
81
82 return list;
83 }
84
85 ScrollableResults sr = query.scroll();
86
87 if (sr.first() && sr.scroll(start)) {
88 for (int i = start; i < end; i++) {
89 Object[] array = sr.get();
90
91 if (array.length == 1) {
92 list.add(array[0]);
93 }
94 else {
95 list.add(array);
96 }
97
98 if (!sr.next()) {
99 break;
100 }
101 }
102 }
103
104 if (unmodifiable) {
105 return new UnmodifiableList<Object>(list);
106 }
107 else {
108 return list;
109 }
110 }
111 }
112 }
113
114 public static List<?> randomList(
115 Query query, Dialect dialect, int total, int num) {
116
117 return randomList(query, dialect, total, num, true);
118 }
119
120 public static List<?> randomList(
121 Query query, Dialect dialect, int total, int num,
122 boolean unmodifiable) {
123
124 if ((total == 0) || (num == 0)) {
125 return new ArrayList<Object>();
126 }
127
128 if (num >= total) {
129 return list(query, dialect, ALL_POS, ALL_POS, true);
130 }
131
132 int[] scrollIds = Randomizer.getInstance().nextInt(total, num);
133
134 List<Object> list = new ArrayList<Object>();
135
136 DB db = DBFactoryUtil.getDB();
137
138 if (!db.isSupportsScrollableResults()) {
139 if (_log.isWarnEnabled()) {
140 _log.warn("Database does not support scrollable results");
141 }
142
143 return list;
144 }
145
146 ScrollableResults sr = query.scroll();
147
148 for (int i = 0; i < scrollIds.length; i++) {
149 if (sr.scroll(scrollIds[i])) {
150 Object[] array = sr.get();
151
152 if (array.length == 1) {
153 list.add(array[0]);
154 }
155 else {
156 list.add(array);
157 }
158
159 sr.first();
160 }
161 }
162
163 if (unmodifiable) {
164 return new UnmodifiableList<Object>(list);
165 }
166 else {
167 return list;
168 }
169 }
170
171 public static Comparable<?>[] getPrevAndNext(
172 Query query, int count, OrderByComparator obc,
173 Comparable<?> comparable) {
174
175 int pos = count;
176 int boundary = 0;
177
178 Comparable<?>[] array = new Comparable[3];
179
180 DB db = DBFactoryUtil.getDB();
181
182 if (!db.isSupportsScrollableResults()) {
183 if (_log.isWarnEnabled()) {
184 _log.warn("Database does not support scrollable results");
185 }
186
187 return array;
188 }
189
190 ScrollableResults sr = query.scroll();
191
192 if (sr.first()) {
193 while (true) {
194 Object obj = sr.get(0);
195
196 if (obj == null) {
197 if (_log.isWarnEnabled()) {
198 _log.warn("Object is null");
199 }
200
201 break;
202 }
203
204 Comparable<?> curComparable = (Comparable<?>)obj;
205
206 int value = obc.compare(comparable, curComparable);
207
208 if (_log.isDebugEnabled()) {
209 _log.debug("Comparison result is " + value);
210 }
211
212 if (value == 0) {
213 if (!comparable.equals(curComparable)) {
214 break;
215 }
216
217 array[1] = curComparable;
218
219 if (sr.previous()) {
220 array[0] = (Comparable<?>)sr.get(0);
221 }
222
223 sr.next();
224
225 if (sr.next()) {
226 array[2] = (Comparable<?>)sr.get(0);
227 }
228
229 break;
230 }
231
232 if (pos == 1) {
233 break;
234 }
235
236 pos = (int)Math.ceil(pos / 2.0);
237
238 int scrollPos = pos;
239
240 if (value < 0) {
241 scrollPos = scrollPos * -1;
242 }
243
244 boundary += scrollPos;
245
246 if (boundary < 0) {
247 scrollPos = scrollPos + (boundary * -1) + 1;
248
249 boundary = 0;
250 }
251
252 if (boundary > count) {
253 scrollPos = scrollPos - (boundary - count);
254
255 boundary = scrollPos;
256 }
257
258 if (_log.isDebugEnabled()) {
259 _log.debug("Scroll " + scrollPos);
260 }
261
262 if (!sr.scroll(scrollPos)) {
263 if (value < 0) {
264 if (!sr.next()) {
265 break;
266 }
267 }
268 else {
269 if (!sr.previous()) {
270 break;
271 }
272 }
273 }
274 }
275 }
276
277 return array;
278 }
279
280 private static Log _log = LogFactoryUtil.getLog(QueryUtil.class);
281
282 }