Skip to content

Commit 06d0c5d

Browse files
committed
Merge pull request #214 from markuspfeiffer/dev-where
Add support for count/exists queries.
2 parents 7b2ed13 + 1c8e7d3 commit 06d0c5d

File tree

6 files changed

+606
-75
lines changed

6 files changed

+606
-75
lines changed

src/com/activeandroid/query/From.java

+170-75
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public final class From implements Sqlable {
3434
private Class<? extends Model> mType;
3535
private String mAlias;
3636
private List<Join> mJoins;
37-
private String mWhere;
37+
private final StringBuilder mWhere = new StringBuilder();
3838
private String mGroupBy;
3939
private String mHaving;
4040
private String mOrderBy;
@@ -87,29 +87,41 @@ public Join crossJoin(Class<? extends Model> table) {
8787
return join;
8888
}
8989

90-
public From where(String where) {
91-
if (mWhere != null) { // Chain conditions if a previous
92-
mWhere = mWhere + " AND " + where; // condition exists.
93-
} else {
94-
mWhere = where;
90+
public From where(String clause) {
91+
// Chain conditions if a previous condition exists.
92+
if (mWhere.length() > 0) {
93+
mWhere.append(" AND ");
9594
}
95+
mWhere.append(clause);
96+
return this;
97+
}
9698

99+
public From where(String clause, Object... args) {
100+
where(clause).addArguments(args);
97101
return this;
98102
}
99103

100-
public From where(String where, Object... args) {
101-
if (mWhere != null) { // Chain conditions if a previous
102-
mWhere = mWhere + " AND " + where; // condition exists.
103-
}
104-
else {
105-
mWhere = where;
106-
}
104+
public From and(String clause) {
105+
return where(clause);
106+
}
107107

108-
addArguments(args);
108+
public From and(String clause, Object... args) {
109+
return where(clause, args);
110+
}
109111

112+
public From or(String clause) {
113+
if (mWhere.length() > 0) {
114+
mWhere.append(" OR ");
115+
}
116+
mWhere.append(clause);
110117
return this;
111118
}
112119

120+
public From or(String clause, Object... args) {
121+
or(clause).addArguments(args);
122+
return this;
123+
}
124+
113125
public From groupBy(String groupBy) {
114126
mGroupBy = groupBy;
115127
return this;
@@ -144,99 +156,182 @@ public From offset(String offset) {
144156
}
145157

146158
void addArguments(Object[] args) {
147-
for( Object arg : args ) {
148-
if (arg.getClass() == boolean.class || arg.getClass() == Boolean.class)
149-
arg = ( arg.equals(true) ? 1 : 0 );
150-
159+
for(Object arg : args) {
160+
if (arg.getClass() == boolean.class || arg.getClass() == Boolean.class) {
161+
arg = (arg.equals(true) ? 1 : 0);
162+
}
151163
mArguments.add(arg);
152164
}
153165
}
154166

155-
@Override
156-
public String toSql() {
157-
StringBuilder sql = new StringBuilder();
158-
sql.append(mQueryBase.toSql());
159-
sql.append("FROM ");
160-
sql.append(Cache.getTableName(mType)).append(" ");
167+
private void addFrom(final StringBuilder sql) {
168+
sql.append("FROM ");
169+
sql.append(Cache.getTableName(mType)).append(" ");
161170

162-
if (mAlias != null) {
163-
sql.append("AS ");
164-
sql.append(mAlias);
165-
sql.append(" ");
166-
}
171+
if (mAlias != null) {
172+
sql.append("AS ");
173+
sql.append(mAlias);
174+
sql.append(" ");
175+
}
176+
}
167177

168-
for (Join join : mJoins) {
169-
sql.append(join.toSql());
170-
}
178+
private void addJoins(final StringBuilder sql) {
179+
for (final Join join : mJoins) {
180+
sql.append(join.toSql());
181+
}
182+
}
171183

172-
if (mWhere != null) {
173-
sql.append("WHERE ");
174-
sql.append(mWhere);
175-
sql.append(" ");
176-
}
184+
private void addWhere(final StringBuilder sql) {
185+
if (mWhere.length() > 0) {
186+
sql.append("WHERE ");
187+
sql.append(mWhere);
188+
sql.append(" ");
189+
}
190+
}
177191

178-
if (mGroupBy != null) {
179-
sql.append("GROUP BY ");
180-
sql.append(mGroupBy);
181-
sql.append(" ");
182-
}
192+
private void addGroupBy(final StringBuilder sql) {
193+
if (mGroupBy != null) {
194+
sql.append("GROUP BY ");
195+
sql.append(mGroupBy);
196+
sql.append(" ");
197+
}
198+
}
183199

184-
if (mHaving != null) {
185-
sql.append("HAVING ");
186-
sql.append(mHaving);
187-
sql.append(" ");
188-
}
200+
private void addHaving(final StringBuilder sql) {
201+
if (mHaving != null) {
202+
sql.append("HAVING ");
203+
sql.append(mHaving);
204+
sql.append(" ");
205+
}
206+
}
189207

190-
if (mOrderBy != null) {
191-
sql.append("ORDER BY ");
192-
sql.append(mOrderBy);
193-
sql.append(" ");
194-
}
208+
private void addOrderBy(final StringBuilder sql) {
209+
if (mOrderBy != null) {
210+
sql.append("ORDER BY ");
211+
sql.append(mOrderBy);
212+
sql.append(" ");
213+
}
214+
}
195215

196-
if (mLimit != null) {
197-
sql.append("LIMIT ");
198-
sql.append(mLimit);
199-
sql.append(" ");
200-
}
216+
private void addLimit(final StringBuilder sql) {
217+
if (mLimit != null) {
218+
sql.append("LIMIT ");
219+
sql.append(mLimit);
220+
sql.append(" ");
221+
}
222+
}
201223

202-
if (mOffset != null) {
203-
sql.append("OFFSET ");
204-
sql.append(mOffset);
205-
sql.append(" ");
206-
}
224+
private void addOffset(final StringBuilder sql) {
225+
if (mOffset != null) {
226+
sql.append("OFFSET ");
227+
sql.append(mOffset);
228+
sql.append(" ");
229+
}
230+
}
207231

208-
// Don't wast time building the string
209-
// unless we're going to log it.
210-
if (Log.isEnabled()) {
211-
Log.v(sql.toString() + " " + TextUtils.join(",", getArguments()));
212-
}
232+
private String sqlString(final StringBuilder sql) {
213233

214-
return sql.toString().trim();
215-
}
234+
final String sqlString = sql.toString().trim();
235+
236+
// Don't waste time building the string
237+
// unless we're going to log it.
238+
if (Log.isEnabled()) {
239+
Log.v(sqlString + " " + TextUtils.join(",", getArguments()));
240+
}
241+
242+
return sqlString;
243+
}
244+
245+
@Override
246+
public String toSql() {
247+
final StringBuilder sql = new StringBuilder();
248+
sql.append(mQueryBase.toSql());
249+
250+
addFrom(sql);
251+
addJoins(sql);
252+
addWhere(sql);
253+
addGroupBy(sql);
254+
addHaving(sql);
255+
addOrderBy(sql);
256+
addLimit(sql);
257+
addOffset(sql);
258+
259+
return sqlString(sql);
260+
}
261+
262+
public String toExistsSql() {
263+
264+
final StringBuilder sql = new StringBuilder();
265+
sql.append("SELECT EXISTS(SELECT 1 ");
266+
267+
addFrom(sql);
268+
addJoins(sql);
269+
addWhere(sql);
270+
addGroupBy(sql);
271+
addHaving(sql);
272+
addLimit(sql);
273+
addOffset(sql);
274+
275+
sql.append(")");
276+
277+
return sqlString(sql);
278+
}
279+
280+
public String toCountSql() {
281+
282+
final StringBuilder sql = new StringBuilder();
283+
sql.append("SELECT COUNT(*) ");
284+
285+
addFrom(sql);
286+
addJoins(sql);
287+
addWhere(sql);
288+
addGroupBy(sql);
289+
addHaving(sql);
290+
addLimit(sql);
291+
addOffset(sql);
292+
293+
return sqlString(sql);
294+
}
216295

217296
public <T extends Model> List<T> execute() {
218297
if (mQueryBase instanceof Select) {
219298
return SQLiteUtils.rawQuery(mType, toSql(), getArguments());
220-
}
221-
else {
299+
300+
} else {
222301
SQLiteUtils.execSql(toSql(), getArguments());
223-
Cache.getContext().getContentResolver().notifyChange(ContentProvider
224-
.createUri(mType, null), null);
302+
Cache.getContext().getContentResolver().notifyChange(ContentProvider.createUri(mType, null), null);
225303
return null;
304+
226305
}
227306
}
228307

229308
public <T extends Model> T executeSingle() {
230309
if (mQueryBase instanceof Select) {
231310
limit(1);
232311
return (T) SQLiteUtils.rawQuerySingle(mType, toSql(), getArguments());
233-
}
234-
else {
312+
313+
} else {
235314
limit(1);
236315
SQLiteUtils.rawQuerySingle(mType, toSql(), getArguments()).delete();
237316
return null;
317+
238318
}
239319
}
320+
321+
/**
322+
* Gets a value indicating whether the query returns any rows.
323+
* @return <code>true</code> if the query returns at least one row; otherwise, <code>false</code>.
324+
*/
325+
public boolean exists() {
326+
return SQLiteUtils.intQuery(toExistsSql(), getArguments()) != 0;
327+
}
328+
329+
/**
330+
* Gets the number of rows returned by the query.
331+
*/
332+
public int count() {
333+
return SQLiteUtils.intQuery(toCountSql(), getArguments());
334+
}
240335

241336
public String[] getArguments() {
242337
final int size = mArguments.size();

src/com/activeandroid/util/SQLiteUtils.java

+15
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,14 @@ public static <T extends Model> List<T> rawQuery(Class<? extends Model> type, St
106106

107107
return entities;
108108
}
109+
110+
public static int intQuery(final String sql, final String[] selectionArgs) {
111+
final Cursor cursor = Cache.openDatabase().rawQuery(sql, selectionArgs);
112+
final int number = processIntCursor(cursor);
113+
cursor.close();
114+
115+
return number;
116+
}
109117

110118
public static <T extends Model> T rawQuerySingle(Class<? extends Model> type, String sql, String[] selectionArgs) {
111119
List<T> entities = rawQuery(type, sql, selectionArgs);
@@ -349,6 +357,13 @@ public static <T extends Model> List<T> processCursor(Class<? extends Model> typ
349357
return entities;
350358
}
351359

360+
private static int processIntCursor(final Cursor cursor) {
361+
if (cursor.moveToFirst()) {
362+
return cursor.getInt(0);
363+
}
364+
return 0;
365+
}
366+
352367
public static List<String> lexSqlScript(String sqlScript) {
353368
ArrayList<String> sl = new ArrayList<String>();
354369
boolean inString = false, quoteNext = false;

0 commit comments

Comments
 (0)