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