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