001
014
015 package com.liferay.portal.kernel.dao.orm;
016
017 import com.liferay.portal.kernel.dao.db.DB;
018 import com.liferay.portal.kernel.dao.db.DBFactoryUtil;
019 import com.liferay.portal.kernel.log.Log;
020 import com.liferay.portal.kernel.log.LogFactoryUtil;
021 import com.liferay.portal.kernel.security.RandomUtil;
022 import com.liferay.portal.kernel.util.OrderByComparator;
023 import com.liferay.portal.kernel.util.UnmodifiableList;
024
025 import java.util.ArrayList;
026 import java.util.Collections;
027 import java.util.Iterator;
028 import java.util.List;
029
030
033 public class QueryUtil {
034
035 public static final int ALL_POS = -1;
036
037 public static Comparable<?>[] getPrevAndNext(
038 Query query, int count, OrderByComparator obc,
039 Comparable<?> comparable) {
040
041 int pos = count;
042 int boundary = 0;
043
044 Comparable<?>[] array = new Comparable[3];
045
046 DB db = DBFactoryUtil.getDB();
047
048 if (!db.isSupportsScrollableResults()) {
049 if (_log.isWarnEnabled()) {
050 _log.warn("Database does not support scrollable results");
051 }
052
053 return array;
054 }
055
056 ScrollableResults sr = query.scroll();
057
058 if (sr.first()) {
059 while (true) {
060 Object obj = sr.get(0);
061
062 if (obj == null) {
063 if (_log.isWarnEnabled()) {
064 _log.warn("Object is null");
065 }
066
067 break;
068 }
069
070 Comparable<?> curComparable = (Comparable<?>)obj;
071
072 int value = obc.compare(comparable, curComparable);
073
074 if (_log.isDebugEnabled()) {
075 _log.debug("Comparison result is " + value);
076 }
077
078 if (value == 0) {
079 if (!comparable.equals(curComparable)) {
080 break;
081 }
082
083 array[1] = curComparable;
084
085 if (sr.previous()) {
086 array[0] = (Comparable<?>)sr.get(0);
087 }
088
089 sr.next();
090
091 if (sr.next()) {
092 array[2] = (Comparable<?>)sr.get(0);
093 }
094
095 break;
096 }
097
098 if (pos == 1) {
099 break;
100 }
101
102 pos = (int)Math.ceil(pos / 2.0);
103
104 int scrollPos = pos;
105
106 if (value < 0) {
107 scrollPos = scrollPos * -1;
108 }
109
110 boundary += scrollPos;
111
112 if (boundary < 0) {
113 scrollPos = scrollPos + (boundary * -1) + 1;
114
115 boundary = 0;
116 }
117
118 if (boundary > count) {
119 scrollPos = scrollPos - (boundary - count);
120
121 boundary = scrollPos;
122 }
123
124 if (_log.isDebugEnabled()) {
125 _log.debug("Scroll " + scrollPos);
126 }
127
128 if (!sr.scroll(scrollPos)) {
129 if (value < 0) {
130 if (!sr.next()) {
131 break;
132 }
133 }
134 else {
135 if (!sr.previous()) {
136 break;
137 }
138 }
139 }
140 }
141 }
142
143 return array;
144 }
145
146 public static Iterator<?> iterate(
147 Query query, Dialect dialect, int start, int end) {
148
149 return iterate(query, dialect, start, end, true);
150 }
151
152 public static Iterator<?> iterate(
153 Query query, Dialect dialect, int start, int end,
154 boolean unmodifiable) {
155
156 return list(query, dialect, start, end).iterator();
157 }
158
159 public static List<?> list(
160 Query query, Dialect dialect, int start, int end) {
161
162 return list(query, dialect, start, end, true);
163 }
164
165 public static List<?> list(
166 Query query, Dialect dialect, int start, int end,
167 boolean unmodifiable) {
168
169 if ((start == ALL_POS) && (end == ALL_POS)) {
170 return query.list(unmodifiable);
171 }
172
173 if (start < 0) {
174 start = 0;
175 }
176
177 if (end < start) {
178 end = start;
179 }
180
181 if (start == end) {
182 if (unmodifiable) {
183 return Collections.emptyList();
184 }
185 else {
186 return new ArrayList<Object>();
187 }
188 }
189
190 if (dialect.supportsLimit()) {
191 query.setMaxResults(end - start);
192 query.setFirstResult(start);
193
194 return query.list(unmodifiable);
195 }
196
197 List<Object> list = new ArrayList<Object>();
198
199 DB db = DBFactoryUtil.getDB();
200
201 if (!db.isSupportsScrollableResults()) {
202 if (_log.isWarnEnabled()) {
203 _log.warn("Database does not support scrollable results");
204 }
205
206 return list;
207 }
208
209 ScrollableResults sr = query.scroll();
210
211 if (sr.first() && sr.scroll(start)) {
212 for (int i = start; i < end; i++) {
213 Object[] array = sr.get();
214
215 if (array.length == 1) {
216 list.add(array[0]);
217 }
218 else {
219 list.add(array);
220 }
221
222 if (!sr.next()) {
223 break;
224 }
225 }
226 }
227
228 if (unmodifiable) {
229 return new UnmodifiableList<Object>(list);
230 }
231 else {
232 return list;
233 }
234 }
235
236 public static List<?> randomList(
237 Query query, Dialect dialect, int total, int num) {
238
239 return randomList(query, dialect, total, num, true);
240 }
241
242 public static List<?> randomList(
243 Query query, Dialect dialect, int total, int num,
244 boolean unmodifiable) {
245
246 if ((total == 0) || (num == 0)) {
247 return new ArrayList<Object>();
248 }
249
250 if (num >= total) {
251 return list(query, dialect, ALL_POS, ALL_POS, true);
252 }
253
254 int[] scrollIds = RandomUtil.nextInts(total, num);
255
256 List<Object> list = new ArrayList<Object>();
257
258 DB db = DBFactoryUtil.getDB();
259
260 if (!db.isSupportsScrollableResults()) {
261 if (_log.isWarnEnabled()) {
262 _log.warn("Database does not support scrollable results");
263 }
264
265 return list;
266 }
267
268 ScrollableResults sr = query.scroll();
269
270 for (int i = 0; i < scrollIds.length; i++) {
271 if (sr.scroll(scrollIds[i])) {
272 Object[] array = sr.get();
273
274 if (array.length == 1) {
275 list.add(array[0]);
276 }
277 else {
278 list.add(array);
279 }
280
281 sr.first();
282 }
283 }
284
285 if (unmodifiable) {
286 return new UnmodifiableList<Object>(list);
287 }
288 else {
289 return list;
290 }
291 }
292
293 private static Log _log = LogFactoryUtil.getLog(QueryUtil.class);
294
295 }