001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
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.DBManagerUtil;
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    
023    import java.util.ArrayList;
024    import java.util.Collections;
025    import java.util.Iterator;
026    import java.util.List;
027    
028    /**
029     * @author Brian Wing Shun Chan
030     */
031    public class QueryUtil {
032    
033            public static final int ALL_POS = -1;
034    
035            public static Iterator<?> iterate(
036                    Query query, Dialect dialect, int start, int end) {
037    
038                    return iterate(query, dialect, start, end, true);
039            }
040    
041            public static Iterator<?> iterate(
042                    Query query, Dialect dialect, int start, int end,
043                    boolean unmodifiable) {
044    
045                    return list(query, dialect, start, end).iterator();
046            }
047    
048            public static List<?> list(
049                    Query query, Dialect dialect, int start, int end) {
050    
051                    return list(query, dialect, start, end, true);
052            }
053    
054            public static List<?> list(
055                    Query query, Dialect dialect, int start, int end,
056                    boolean unmodifiable) {
057    
058                    if ((start == ALL_POS) && (end == ALL_POS)) {
059                            return query.list(unmodifiable);
060                    }
061    
062                    if (start < 0) {
063                            start = 0;
064                    }
065    
066                    if (end < start) {
067                            end = start;
068                    }
069    
070                    if (start == end) {
071                            if (unmodifiable) {
072                                    return Collections.emptyList();
073                            }
074                            else {
075                                    return new ArrayList<>();
076                            }
077                    }
078    
079                    if (dialect.supportsLimit()) {
080                            query.setMaxResults(end - start);
081                            query.setFirstResult(start);
082    
083                            return query.list(unmodifiable);
084                    }
085    
086                    List<Object> list = new ArrayList<>();
087    
088                    DB db = DBManagerUtil.getDB();
089    
090                    if (!db.isSupportsScrollableResults()) {
091                            if (_log.isWarnEnabled()) {
092                                    _log.warn("Database does not support scrollable results");
093                            }
094    
095                            return list;
096                    }
097    
098                    ScrollableResults sr = query.scroll();
099    
100                    if (sr.first() && sr.scroll(start)) {
101                            for (int i = start; i < end; i++) {
102                                    Object[] array = sr.get();
103    
104                                    if (array.length == 1) {
105                                            list.add(array[0]);
106                                    }
107                                    else {
108                                            list.add(array);
109                                    }
110    
111                                    if (!sr.next()) {
112                                            break;
113                                    }
114                            }
115                    }
116    
117                    if (unmodifiable) {
118                            return Collections.unmodifiableList(list);
119                    }
120                    else {
121                            return list;
122                    }
123            }
124    
125            public static List<?> randomList(
126                    Query query, Dialect dialect, int total, int num) {
127    
128                    return randomList(query, dialect, total, num, true);
129            }
130    
131            public static List<?> randomList(
132                    Query query, Dialect dialect, int total, int num,
133                    boolean unmodifiable) {
134    
135                    if ((total == 0) || (num == 0)) {
136                            return new ArrayList<>();
137                    }
138    
139                    if (num >= total) {
140                            return list(query, dialect, ALL_POS, ALL_POS, true);
141                    }
142    
143                    int[] scrollIds = RandomUtil.nextInts(total, num);
144    
145                    List<Object> list = new ArrayList<>();
146    
147                    DB db = DBManagerUtil.getDB();
148    
149                    if (!db.isSupportsScrollableResults()) {
150                            if (_log.isWarnEnabled()) {
151                                    _log.warn("Database does not support scrollable results");
152                            }
153    
154                            return list;
155                    }
156    
157                    ScrollableResults sr = query.scroll();
158    
159                    for (int i = 0; i < scrollIds.length; i++) {
160                            if (sr.scroll(scrollIds[i])) {
161                                    Object[] array = sr.get();
162    
163                                    if (array.length == 1) {
164                                            list.add(array[0]);
165                                    }
166                                    else {
167                                            list.add(array);
168                                    }
169    
170                                    sr.first();
171                            }
172                    }
173    
174                    if (unmodifiable) {
175                            return Collections.unmodifiableList(list);
176                    }
177                    else {
178                            return list;
179                    }
180            }
181    
182            private static final Log _log = LogFactoryUtil.getLog(QueryUtil.class);
183    
184    }