@@ -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 ();
0 commit comments