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