44import org .javawebstack .orm .Repo ;
55import org .javawebstack .orm .SQLMapper ;
66import org .javawebstack .orm .exception .ORMQueryException ;
7+ import org .javawebstack .orm .wrapper .builder .SQLQueryString ;
78
89import java .sql .ResultSet ;
910import java .sql .SQLException ;
@@ -23,10 +24,9 @@ public class Query<T extends Model> {
2324 private final QueryGroup <T > where ;
2425 private Integer offset ;
2526 private Integer limit ;
26- private QueryColumn order ;
27- private boolean desc = false ;
27+ private QueryOrderBy order ;
2828 private boolean withDeleted = false ;
29- private final Map < Class <? extends Model >, QueryCondition > leftJoins = new HashMap <>();
29+ private final List < QueryWith > withs = new ArrayList <>();
3030
3131 public Query (Class <T > model ) {
3232 this (Repo .get (model ), model );
@@ -36,14 +36,47 @@ public Query(Repo<T> repo, Class<T> model) {
3636 this .repo = repo ;
3737 this .model = model ;
3838 this .where = new QueryGroup <>();
39+ this .order = new QueryOrderBy ();
40+ }
41+
42+ public boolean isWithDeleted () {
43+ return withDeleted ;
44+ }
45+
46+ public QueryGroup <T > getWhereGroup () {
47+ return where ;
48+ }
49+
50+ public List <QueryWith > getWiths () {
51+ return withs ;
52+ }
53+
54+ public Integer getLimit () {
55+ return limit ;
56+ }
57+
58+ public Integer getOffset () {
59+ return offset ;
60+ }
61+
62+ public QueryOrderBy getOrder () {
63+ return order ;
64+ }
65+
66+ public Repo <T > getRepo () {
67+ return repo ;
3968 }
4069
4170 public Class <T > getModel () {
4271 return model ;
4372 }
4473
45- public Query <T > leftJoin (Class <? extends Model > model , String self , String other ) {
46- leftJoins .put (model , new QueryCondition (new QueryColumn (repo .getInfo ().getTableName () + "." + self ), "=" , new QueryColumn (Repo .get (model ).getInfo ().getTableName () + "." + other )));
74+ public Query <T > with (String extra ) {
75+ return with (extra , null );
76+ }
77+
78+ public Query <T > with (String extra , String as ) {
79+ withs .add (new QueryWith (extra , as ));
4780 return this ;
4881 }
4982
@@ -263,18 +296,25 @@ public Query<T> search(String search) {
263296 return this ;
264297 }
265298
299+ public Query <T > order (String orderBy ) {
300+ return order (orderBy , false );
301+ }
302+
266303 public Query <T > order (String orderBy , boolean desc ) {
267304 return order (new QueryColumn (orderBy ), desc );
268305 }
269306
270307 public Query <T > order (QueryColumn orderBy , boolean desc ) {
271- this .order = orderBy ;
272- this .desc = desc ;
273- return this ;
274- }
308+ boolean success = this .order .add (orderBy , desc );
309+ if (!success ) {
310+ throw new ORMQueryException (String .format (
311+ "The column %s could not be ordered %s. This is probably caused by calling .order() on this column twice." ,
312+ orderBy .toString (),
313+ desc ? "descendingly" : "ascendingly"
314+ ));
315+ }
275316
276- public Query <T > order (String orderBy ) {
277- return order (orderBy , false );
317+ return this ;
278318 }
279319
280320 public Query <T > limit (int offset , int limit ) {
@@ -296,59 +336,10 @@ public Query<T> withDeleted() {
296336 return this ;
297337 }
298338
299- public QueryString getQueryString () {
300- return getQueryString (false );
301- }
302-
303- public QueryString getQueryString (boolean count ) {
304- List <Object > parameters = new ArrayList <>();
305- StringBuilder sb = new StringBuilder ("SELECT " )
306- .append (count ? "COUNT(*)" : "*" )
307- .append (" FROM `" )
308- .append (repo .getInfo ().getTableName ())
309- .append ('`' );
310- for (Class <? extends Model > type : leftJoins .keySet ()) {
311- sb .append (" LEFT JOIN `" )
312- .append (Repo .get (type ).getInfo ().getTableName ())
313- .append ("` ON " )
314- .append (leftJoins .get (type ).getQueryString (repo .getInfo ()).getQuery ());
315- }
316- considerSoftDelete ();
317- if (where .getQueryElements ().size () > 0 ) {
318- QueryString qs = where .getQueryString (repo .getInfo ());
319- sb .append (" WHERE " ).append (qs .getQuery ());
320- parameters .addAll (qs .getParameters ());
321- }
322- if (order != null ) {
323- sb .append (" ORDER BY " ).append (order .toString (repo .getInfo ()));
324- if (desc )
325- sb .append (" DESC" );
326- }
327- if (offset != null && limit == null )
328- limit = Integer .MAX_VALUE ;
329- if (limit != null ) {
330- sb .append (" LIMIT ?" );
331- if (offset != null ) {
332- sb .append (",?" );
333- parameters .add (offset );
334- }
335- parameters .add (limit );
336- }
337- return new QueryString (sb .toString (), SQLMapper .mapParams (repo , parameters ));
338- }
339-
340339 public void finalDelete () {
341- List <Object > parameters = new ArrayList <>();
342- StringBuilder sb = new StringBuilder ("DELETE FROM `" )
343- .append (repo .getInfo ().getTableName ())
344- .append ('`' );
345- if (where .getQueryElements ().size () > 0 ) {
346- QueryString qs = where .getQueryString (repo .getInfo ());
347- sb .append (" WHERE " ).append (qs .getQuery ());
348- parameters = qs .getParameters ();
349- }
340+ SQLQueryString qs = repo .getConnection ().builder ().buildDelete (this );
350341 try {
351- repo .getConnection ().write (sb . toString (), SQLMapper . mapParams ( repo , parameters ).toArray ());
342+ repo .getConnection ().write (qs . getQuery (), qs . getParameters ( ).toArray ());
352343 } catch (SQLException throwables ) {
353344 throw new ORMQueryException (throwables );
354345 }
@@ -374,18 +365,10 @@ public void restore() {
374365 withDeleted ().update (values );
375366 }
376367
377- private void considerSoftDelete () {
378- if (repo .getInfo ().isSoftDelete () && !withDeleted ) {
379- if (where .getQueryElements ().size () > 0 )
380- where .getQueryElements ().add (0 , QueryConjunction .AND );
381- where .getQueryElements ().add (0 , new QueryCondition (new QueryColumn (repo .getInfo ().getColumnName (repo .getInfo ().getSoftDeleteField ())), "IS NULL" , null ));
382- }
383- }
384-
385368 public T refresh (T entity ) {
386- QueryString qs = getQueryString ( false );
369+ SQLQueryString qs = repo . getConnection (). builder (). buildQuery ( this , false );
387370 try {
388- ResultSet rs = repo .getConnection ().read (qs .getQuery (), SQLMapper . mapParams ( repo , SQLMapper . mapParams ( repo , qs .getParameters ()) ).toArray ());
371+ ResultSet rs = repo .getConnection ().read (qs .getQuery (), qs .getParameters ().toArray ());
389372 SQLMapper .mapBack (repo , rs , entity );
390373 repo .getConnection ().close (rs );
391374 return entity ;
@@ -399,39 +382,19 @@ public void update(T entity) {
399382 }
400383
401384 public void update (Map <String , Object > values ) {
402- if (repo .getInfo ().hasUpdated ())
403- values .put (repo .getInfo ().getColumnName (repo .getInfo ().getUpdatedField ()), Timestamp .from (Instant .now ()));
404- List <Object > parameters = new ArrayList <>();
405- List <String > sets = new ArrayList <>();
406- values .forEach ((key , value ) -> {
407- sets .add ("`" + key + "`=?" );
408- parameters .add (value );
409- });
410- StringBuilder sb = new StringBuilder ("UPDATE `" )
411- .append (repo .getInfo ().getTableName ())
412- .append ("` SET " )
413- .append (String .join ("," , sets ));
414- considerSoftDelete ();
415- if (where .getQueryElements ().size () > 0 ) {
416- QueryString qs = where .getQueryString (repo .getInfo ());
417- sb .append (" WHERE " ).append (qs .getQuery ());
418- parameters .addAll (qs .getParameters ());
419- }
420- sb .append (';' );
385+ SQLQueryString queryString = repo .getConnection ().builder ().buildUpdate (this , values );
421386 try {
422- repo .getConnection ().write (sb . toString (), SQLMapper . mapParams ( repo , parameters ).toArray ());
387+ repo .getConnection ().write (queryString . getQuery (), queryString . getParameters ( ).toArray ());
423388 } catch (SQLException throwables ) {
424389 throw new ORMQueryException (throwables );
425390 }
426391 }
427392
428393 public List <T > all () {
429- QueryString qs = getQueryString ( false );
394+ SQLQueryString qs = repo . getConnection (). builder (). buildQuery ( this , false );
430395 try {
431- ResultSet rs = repo .getConnection ().read (qs .getQuery (), SQLMapper .mapParams (repo , qs .getParameters ()).toArray ());
432- List <Class <? extends Model >> joinedModels = new ArrayList <>();
433- joinedModels .addAll (leftJoins .keySet ());
434- List <T > list = SQLMapper .map (repo , rs , joinedModels );
396+ ResultSet rs = repo .getConnection ().read (qs .getQuery (), qs .getParameters ().toArray ());
397+ List <T > list = SQLMapper .map (repo , rs , new ArrayList <>());
435398 repo .getConnection ().close (rs );
436399 return list ;
437400 } catch (SQLException throwables ) {
@@ -455,9 +418,9 @@ public Stream<T> stream() {
455418 }
456419
457420 public int count () {
458- QueryString qs = getQueryString ( true );
421+ SQLQueryString qs = repo . getConnection (). builder (). buildQuery ( this , true );
459422 try {
460- ResultSet rs = repo .getConnection ().read (qs .getQuery (), SQLMapper . mapParams ( repo , qs .getParameters () ).toArray ());
423+ ResultSet rs = repo .getConnection ().read (qs .getQuery (), qs .getParameters ().toArray ());
461424 int c = 0 ;
462425 if (rs .next ())
463426 c = rs .getInt (1 );
0 commit comments