Skip to content
This repository was archived by the owner on Dec 24, 2022. It is now read-only.

Commit 3c097ce

Browse files
committed
Refactor JoinSqlBuilder to use new DialectProvider SqlExpression support
1 parent 0764e4e commit 3c097ce

File tree

1 file changed

+111
-29
lines changed

1 file changed

+111
-29
lines changed

src/ServiceStack.OrmLite/JoinSqlBuilder.cs

Lines changed: 111 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ public class JoinSqlBuilder<TNewPoco, TBasePoco> : ISqlExpression
1515
private bool isDistinct = false;
1616
private bool isAggregateUsed = false;
1717

18+
private int? Rows { get; set; }
19+
private int? Offset { get; set; }
20+
1821
private string baseSchema = "";
1922
private string baseTableName = "";
2023
private Type basePocoType;
@@ -412,12 +415,85 @@ private Type PreviousAssociatedType(Type sourceTableType, Type destinationTableT
412415

413416
private void CheckAggregateUsage(bool ignoreCurrentItem)
414417
{
415-
if ((columnList.Count > (ignoreCurrentItem ? 0 : 1)) && (isAggregateUsed == true))
418+
if ((columnList.Count > (ignoreCurrentItem ? 0 : 1)) && isAggregateUsed)
416419
{
417420
throw new Exception("Aggregate function cannot be used with non aggregate select columns");
418421
}
419422
}
420423

424+
/// <summary>
425+
/// Offset of the first row to return. The offset of the initial row is 0
426+
/// </summary>
427+
public virtual JoinSqlBuilder<TNewPoco, TBasePoco> Skip(int? skip = null)
428+
{
429+
Offset = skip;
430+
return this;
431+
}
432+
433+
/// <summary>
434+
/// Number of rows returned by a SELECT statement
435+
/// </summary>
436+
public virtual JoinSqlBuilder<TNewPoco, TBasePoco> Take(int? take = null)
437+
{
438+
Rows = take;
439+
return this;
440+
}
441+
442+
/// <summary>
443+
/// Set the specified offset and rows for SQL Limit clause.
444+
/// </summary>
445+
/// <param name='skip'>
446+
/// Offset of the first row to return. The offset of the initial row is 0
447+
/// </param>
448+
/// <param name='rows'>
449+
/// Number of rows returned by a SELECT statement
450+
/// </param>
451+
public virtual JoinSqlBuilder<TNewPoco, TBasePoco> Limit(int skip, int rows)
452+
{
453+
Offset = skip;
454+
Rows = rows;
455+
return this;
456+
}
457+
458+
/// <summary>
459+
/// Set the specified offset and rows for SQL Limit clause where they exist.
460+
/// </summary>
461+
/// <param name='skip'>
462+
/// Offset of the first row to return. The offset of the initial row is 0
463+
/// </param>
464+
/// <param name='rows'>
465+
/// Number of rows returned by a SELECT statement
466+
/// </param>
467+
public virtual JoinSqlBuilder<TNewPoco, TBasePoco> Limit(int? skip, int? rows)
468+
{
469+
Offset = skip;
470+
Rows = rows;
471+
return this;
472+
}
473+
474+
/// <summary>
475+
/// Set the specified rows for Sql Limit clause.
476+
/// </summary>
477+
/// <param name='rows'>
478+
/// Number of rows returned by a SELECT statement
479+
/// </param>
480+
public virtual JoinSqlBuilder<TNewPoco, TBasePoco> Limit(int rows)
481+
{
482+
Offset = null;
483+
Rows = rows;
484+
return this;
485+
}
486+
487+
/// <summary>
488+
/// Clear Sql Limit clause
489+
/// </summary>
490+
public virtual JoinSqlBuilder<TNewPoco, TBasePoco> Limit()
491+
{
492+
Offset = null;
493+
Rows = null;
494+
return this;
495+
}
496+
421497
public string ToSelectStatement()
422498
{
423499
return ToSql();
@@ -427,95 +503,101 @@ public string ToSql()
427503
{
428504
CheckAggregateUsage(false);
429505

430-
var sb = new StringBuilder();
431-
sb.Append("SELECT ");
506+
var modelDef = typeof(TNewPoco).GetModelDefinition();
432507

433-
var colSB = new StringBuilder();
508+
var sbSelect = new StringBuilder();
509+
sbSelect.Append("SELECT ");
510+
511+
var dbColumns = new StringBuilder();
434512

435513
if (columnList.Count > 0)
436514
{
437515
if (isDistinct)
438-
sb.Append(" DISTINCT ");
516+
sbSelect.Append(" DISTINCT ");
439517

440518
foreach (var col in columnList)
441519
{
442-
colSB.AppendFormat("{0}{1}", colSB.Length > 0 ? "," : "", col);
520+
dbColumns.AppendFormat("{0}{1}", dbColumns.Length > 0 ? "," : "", col);
443521
}
444522
}
445523
else
446524
{
447525
// improve performance avoiding multiple calls to GetModelDefinition()
448-
var modelDef = typeof(TNewPoco).GetModelDefinition();
449-
450526
if (isDistinct && modelDef.FieldDefinitions.Count > 0)
451-
sb.Append(" DISTINCT ");
527+
sbSelect.Append(" DISTINCT ");
452528

453529
foreach (var fi in modelDef.FieldDefinitions)
454530
{
455-
colSB.AppendFormat("{0}{1}", colSB.Length > 0 ? "," : "", (String.IsNullOrEmpty(fi.BelongToModelName) ? (OrmLiteConfig.DialectProvider.GetQuotedTableName(modelDef.ModelName)) : (OrmLiteConfig.DialectProvider.GetQuotedTableName(fi.BelongToModelName))) + "." + OrmLiteConfig.DialectProvider.GetQuotedColumnName(fi.FieldName));
531+
dbColumns.AppendFormat("{0}{1}", dbColumns.Length > 0 ? "," : "", (String.IsNullOrEmpty(fi.BelongToModelName) ? (OrmLiteConfig.DialectProvider.GetQuotedTableName(modelDef.ModelName)) : (OrmLiteConfig.DialectProvider.GetQuotedTableName(fi.BelongToModelName))) + "." + OrmLiteConfig.DialectProvider.GetQuotedColumnName(fi.FieldName));
456532
}
457-
if (colSB.Length == 0)
458-
colSB.AppendFormat("\"{0}{1}\".*", baseSchema, OrmLiteConfig.DialectProvider.GetQuotedTableName(baseTableName));
533+
if (dbColumns.Length == 0)
534+
dbColumns.AppendFormat("\"{0}{1}\".*", baseSchema, OrmLiteConfig.DialectProvider.GetQuotedTableName(baseTableName));
459535
}
460536

461-
sb.Append(colSB.ToString() + " \n");
537+
sbSelect.Append(dbColumns + " \n");
462538

463-
sb.AppendFormat("FROM {0}{1} \n", baseSchema, OrmLiteConfig.DialectProvider.GetQuotedTableName(baseTableName));
539+
var sbBody = new StringBuilder();
540+
sbBody.AppendFormat("FROM {0}{1} \n", baseSchema, OrmLiteConfig.DialectProvider.GetQuotedTableName(baseTableName));
464541
int i = 0;
465542
foreach (var join in joinList)
466543
{
467544
i++;
468545
if ((join.JoinType == JoinType.INNER) || (join.JoinType == JoinType.SELF))
469-
sb.Append(" INNER JOIN ");
546+
sbBody.Append(" INNER JOIN ");
470547
else if (join.JoinType == JoinType.LEFTOUTER)
471-
sb.Append(" LEFT OUTER JOIN ");
548+
sbBody.Append(" LEFT OUTER JOIN ");
472549
else if (join.JoinType == JoinType.RIGHTOUTER)
473-
sb.Append(" RIGHT OUTER JOIN ");
550+
sbBody.Append(" RIGHT OUTER JOIN ");
474551
else if (join.JoinType == JoinType.FULLOUTER)
475-
sb.Append(" FULL OUTER JOIN ");
552+
sbBody.Append(" FULL OUTER JOIN ");
476553
else if (join.JoinType == JoinType.CROSS)
477554
{
478-
sb.Append(" CROSS JOIN ");
555+
sbBody.Append(" CROSS JOIN ");
479556
}
480557

481558
if (join.JoinType == JoinType.CROSS)
482559
{
483-
sb.AppendFormat(" {0}{1} ON {2} = {3} \n", join.RefTypeSchema, OrmLiteConfig.DialectProvider.GetQuotedTableName(join.RefTypeTableName));
560+
sbBody.AppendFormat(" {0}{1} ON {2} = {3} \n", join.RefTypeSchema, OrmLiteConfig.DialectProvider.GetQuotedTableName(join.RefTypeTableName));
484561
}
485562
else
486563
{
487564
if (join.JoinType != JoinType.SELF)
488565
{
489-
sb.AppendFormat(" {0}{1} ON {2} = {3} \n", join.RefTypeSchema, OrmLiteConfig.DialectProvider.GetQuotedTableName(join.RefTypeTableName), join.Class1ColumnName, join.Class2ColumnName);
566+
sbBody.AppendFormat(" {0}{1} ON {2} = {3} \n", join.RefTypeSchema, OrmLiteConfig.DialectProvider.GetQuotedTableName(join.RefTypeTableName), join.Class1ColumnName, join.Class2ColumnName);
490567
}
491568
else
492569
{
493-
sb.AppendFormat(" {0}{1} AS {2} ON {2}.{3} = \"{1}\".{4} \n", join.RefTypeSchema, OrmLiteConfig.DialectProvider.GetQuotedTableName(join.RefTypeTableName), OrmLiteConfig.DialectProvider.GetQuotedTableName(join.RefTypeTableName) + "_" + i.ToString(), join.Class1ColumnName, join.Class2ColumnName);
570+
sbBody.AppendFormat(" {0}{1} AS {2} ON {2}.{3} = \"{1}\".{4} \n", join.RefTypeSchema, OrmLiteConfig.DialectProvider.GetQuotedTableName(join.RefTypeTableName), OrmLiteConfig.DialectProvider.GetQuotedTableName(join.RefTypeTableName) + "_" + i.ToString(), join.Class1ColumnName, join.Class2ColumnName);
494571
}
495572
}
496573
}
497574

498575
if (whereList.Count > 0)
499576
{
500-
var whereSB = new StringBuilder();
577+
var sbWhere = new StringBuilder();
501578
foreach (var where in whereList)
502579
{
503-
whereSB.AppendFormat("{0}{1}", whereSB.Length > 0 ? (where.Value == WhereType.OR ? " OR " : " AND ") : "", where.Key);
580+
sbWhere.AppendFormat("{0}{1}", sbWhere.Length > 0
581+
? (where.Value == WhereType.OR ? " OR " : " AND ") : "", where.Key);
504582
}
505-
sb.Append("WHERE " + whereSB.ToString() + " \n");
583+
sbBody.Append("WHERE " + sbWhere + " \n");
506584
}
507585

586+
var sbOrderBy = new StringBuilder();
508587
if (orderByList.Count > 0)
509588
{
510-
var orderBySB = new StringBuilder();
511589
foreach (var ob in orderByList)
512590
{
513-
orderBySB.AppendFormat("{0}{1} {2} ", orderBySB.Length > 0 ? "," : "", ob.Key, ob.Value ? "ASC" : "DESC");
591+
sbOrderBy.AppendFormat("{0}{1} {2} ", sbOrderBy.Length > 0 ? "," : "", ob.Key, ob.Value ? "ASC" : "DESC");
514592
}
515-
sb.Append("ORDER BY " + orderBySB.ToString() + " \n");
593+
sbOrderBy.Insert(0, "ORDER BY ");
594+
sbOrderBy.Append(" \n");
516595
}
517596

518-
return sb.ToString();
597+
var sql = OrmLiteConfig.DialectProvider.ToSelectStatement(
598+
modelDef, sbSelect.ToString(), sbBody.ToString(), sbOrderBy.ToString(), Offset, Rows);
599+
600+
return sql;
519601
}
520602
}
521603

0 commit comments

Comments
 (0)