Permalink
Browse files

Addd pagination to Finder/Querying APIs

  • Loading branch information...
1 parent 5d06ad5 commit fa997e101073479d679786b0733f8632cf62faa8 @seratch seratch committed Mar 8, 2014
@@ -0,0 +1,38 @@
+package skinny.orm
+
+/**
+ * Pagination builder.
+ */
+object Pagination {
+
+ def page(pageNo: Int): PaginationPageNoBuilder = {
+ PaginationPageNoBuilder(pageNo = Option(pageNo))
+ }
+
+ def per(pageSize: Int): PaginationPageSizeBuilder = {
+ PaginationPageSizeBuilder(pageSize = Option(pageSize))
+ }
+
+}
+
+/**
+ * Pagination builder.
+ */
+case class PaginationPageNoBuilder(pageNo: Option[Int] = None) {
+ def per(pageSize: Int): Pagination = Pagination(pageNo = pageNo.get, pageSize = pageSize)
+}
+/**
+ * Pagination builder.
+ */
+case class PaginationPageSizeBuilder(pageSize: Option[Int] = None) {
+ def page(pageNo: Int): Pagination = Pagination(pageNo = pageNo, pageSize = pageSize.get)
+}
+
+/**
+ * Pagination parameters.
+ */
+case class Pagination(pageSize: Int, pageNo: Int) {
+
+ def offset: Int = (pageNo - 1) * pageSize
+ def limit: Int = pageSize
+}
@@ -22,22 +22,35 @@ trait SkinnyJoinTableWithId[Id, Entity]
override def extract(rs: WrappedResultSet, s: ResultName[Entity]): Entity = ???
- def findAll(ordering: SQLSyntax = syntax.id)(implicit s: DBSession = autoSession): List[Entity] = {
+ def defaultOrdering = defaultAlias.field(primaryKeyFieldName)
+
+ def findAll(ordering: SQLSyntax = defaultOrdering)(implicit s: DBSession = autoSession): List[Entity] = {
implicit val repository = IncludesQueryRepository[Entity]()
appendIncludedAttributes(extract(withSQL {
selectQueryWithAssociations.orderBy(ordering)
}).list.apply())
}
- def findAllPaging(limit: Int = 100, offset: Int = 0, ordering: SQLSyntax = syntax.id)(
+ def findAllWithPagination(pagination: Pagination, ordering: SQLSyntax = defaultOrdering)(
+ implicit s: DBSession = autoSession): List[Entity] = {
+ findAllWithLimitOffset(pagination.limit, pagination.offset, ordering)
+ }
+
+ def findAllWithLimitOffset(limit: Int = 100, offset: Int = 0, ordering: SQLSyntax = defaultOrdering)(
implicit s: DBSession = autoSession): List[Entity] = {
implicit val repository = IncludesQueryRepository[Entity]()
appendIncludedAttributes(extract(withSQL {
- selectQueryWithAssociations.orderBy(ordering).limit(limit).offset(offset)
+ selectQueryWithAssociations.where(defaultScopeWithDefaultAlias).orderBy(ordering).limit(limit).offset(offset)
}).list.apply())
}
+ @deprecated("Use #findAllWithLimitOffset or #findAllWithPagination instead. This method will be removed since version 1.1.0.", since = "1.0.0")
+ def findAllPaging(limit: Int = 100, offset: Int = 0, ordering: SQLSyntax = defaultOrdering)(
+ implicit s: DBSession = autoSession): List[Entity] = {
+ findAllWithLimitOffset(limit, offset, ordering)
+ }
+
def countAll()(implicit s: DBSession = autoSession): Long = {
withSQL {
select(sqls.count).from(as(syntax))
@@ -58,15 +71,27 @@ trait SkinnyJoinTableWithId[Id, Entity]
}).list.apply())
}
- def findAllByPaging(where: SQLSyntax, limit: Int = 100, offset: Int = 0, ordering: SQLSyntax = syntax.id)(
+ def findAllByWithPagination(where: SQLSyntax, pagination: Pagination, ordering: SQLSyntax = defaultAlias.field(primaryKeyFieldName))(
+ implicit s: DBSession = autoSession): List[Entity] = {
+ findAllByWithLimitOffset(where, pagination.limit, pagination.offset, ordering)
+ }
+
+ def findAllByWithLimitOffset(where: SQLSyntax, limit: Int = 100, offset: Int = 0, ordering: SQLSyntax = defaultAlias.field(primaryKeyFieldName))(
implicit s: DBSession = autoSession): List[Entity] = {
implicit val repository = IncludesQueryRepository[Entity]()
appendIncludedAttributes(extract(withSQL {
- selectQueryWithAssociations.where.append(where).orderBy(ordering).limit(limit).offset(offset)
+ selectQueryWithAssociations.where(where).and(defaultScopeWithDefaultAlias)
+ .orderBy(ordering).limit(limit).offset(offset)
}).list.apply())
}
+ @deprecated("Use #findAllWithLimitOffset or #findAllWithPagination instead. This method will be removed since version 1.1.0.", since = "1.0.0")
+ def findAllByPaging(where: SQLSyntax, limit: Int = 100, offset: Int = 0, ordering: SQLSyntax = defaultAlias.field(primaryKeyFieldName))(
+ implicit s: DBSession = autoSession): List[Entity] = {
+ findAllByWithLimitOffset(where, limit, offset, ordering)
+ }
+
def countAllBy(where: SQLSyntax)(implicit s: DBSession = autoSession): Long = {
withSQL {
select(sqls.count).from(as(syntax)).where.append(where)
@@ -1,11 +1,14 @@
package skinny.orm.feature
-import skinny.orm.SkinnyMapperBase
+import skinny.orm.{ Pagination, SkinnyMapperBase }
import scalikejdbc._, SQLInterpolation._
import skinny.orm.feature.includes.IncludesQueryRepository
/**
* Provides #find something APIs.
+ *
+ * NOTE: For some reasons, skinny.orm.SkinnyJoinTable has copy implementation of this trait (subset).
+ * Be aware that you should fix SkinnyJoinTable too.
*/
trait FinderFeature[Entity]
extends FinderFeatureWithId[Long, Entity]
@@ -19,6 +22,11 @@ trait FinderFeatureWithId[Id, Entity]
with IdFeature[Id]
with IncludesFeatureWithId[Id, Entity] {
+ /**
+ * Default ordering condition.
+ */
+ def defaultOrdering = defaultAlias.field(primaryKeyFieldName)
+
/**
* Finds a single entity by primary key.
*
@@ -29,7 +37,7 @@ trait FinderFeatureWithId[Id, Entity]
def findById(id: Id)(implicit s: DBSession = autoSession): Option[Entity] = {
implicit val repository = IncludesQueryRepository[Entity]()
appendIncludedAttributes(extract(withSQL {
- selectQueryWithAssociations.where.eq(defaultAlias.field(primaryKeyFieldName), idToRawValue(id)).and(defaultScopeWithDefaultAlias)
+ selectQueryWithAssociations.where.eq(defaultOrdering, idToRawValue(id)).and(defaultScopeWithDefaultAlias)
}).single.apply())
}
@@ -43,7 +51,7 @@ trait FinderFeatureWithId[Id, Entity]
def findAllByIds(ids: Id*)(implicit s: DBSession = autoSession): List[Entity] = {
implicit val repository = IncludesQueryRepository[Entity]()
appendIncludedAttributes(extract(withSQL {
- selectQueryWithAssociations.where.in(defaultAlias.field(primaryKeyFieldName), ids.map(idToRawValue)).and(defaultScopeWithDefaultAlias)
+ selectQueryWithAssociations.where.in(defaultOrdering, ids.map(idToRawValue)).and(defaultScopeWithDefaultAlias)
}).list.apply())
}
@@ -53,22 +61,25 @@ trait FinderFeatureWithId[Id, Entity]
* @param s db session
* @return entities
*/
- def findAll(ordering: SQLSyntax = defaultAlias.field(primaryKeyFieldName))(implicit s: DBSession = autoSession): List[Entity] = {
+ def findAll(ordering: SQLSyntax = defaultOrdering)(implicit s: DBSession = autoSession): List[Entity] = {
implicit val repository = IncludesQueryRepository[Entity]()
appendIncludedAttributes(extract(withSQL {
selectQueryWithAssociations.where(defaultScopeWithDefaultAlias).orderBy(ordering)
}).list.apply())
}
/**
- * Finds all entities by paging.
- *
- * @param limit limit
- * @param offset offset
- * @param s db session
- * @return entities
+ * Finds all entities with pagination.
*/
- def findAllPaging(limit: Int = 100, offset: Int = 0, ordering: SQLSyntax = defaultAlias.field(primaryKeyFieldName))(
+ def findAllWithPagination(pagination: Pagination, ordering: SQLSyntax = defaultOrdering)(
+ implicit s: DBSession = autoSession): List[Entity] = {
+ findAllWithLimitOffset(pagination.limit, pagination.offset, ordering)
+ }
+
+ /**
+ * Finds all entities with pagination.
+ */
+ def findAllWithLimitOffset(limit: Int = 100, offset: Int = 0, ordering: SQLSyntax = defaultOrdering)(
implicit s: DBSession = autoSession): List[Entity] = {
implicit val repository = IncludesQueryRepository[Entity]()
@@ -77,6 +88,12 @@ trait FinderFeatureWithId[Id, Entity]
}).list.apply())
}
+ @deprecated("Use #findAllWithLimitOffset or #findAllWithPagination instead. This method will be removed since version 1.1.0.", since = "1.0.0")
+ def findAllPaging(limit: Int = 100, offset: Int = 0, ordering: SQLSyntax = defaultOrdering)(
+ implicit s: DBSession = autoSession): List[Entity] = {
+ findAllWithLimitOffset(limit, offset, ordering)
+ }
+
/**
* Calculates rows.
*/
@@ -164,7 +181,7 @@ trait FinderFeatureWithId[Id, Entity]
* @param s db session
* @return entities
*/
- def findAllBy(where: SQLSyntax, ordering: SQLSyntax = defaultAlias.field(primaryKeyFieldName))(
+ def findAllBy(where: SQLSyntax, ordering: SQLSyntax = defaultOrdering)(
implicit s: DBSession = autoSession): List[Entity] = {
implicit val repository = IncludesQueryRepository[Entity]()
@@ -174,15 +191,17 @@ trait FinderFeatureWithId[Id, Entity]
}
/**
- * Finds all entities by condition and paging.
- *
- * @param where where condition
- * @param limit limit
- * @param offset offset
- * @param s db session
- * @return entities
+ * Finds all entities by condition and with pagination.
*/
- def findAllByPaging(where: SQLSyntax, limit: Int = 100, offset: Int = 0, ordering: SQLSyntax = defaultAlias.field(primaryKeyFieldName))(
+ def findAllByWithPagination(where: SQLSyntax, pagination: Pagination, ordering: SQLSyntax = defaultOrdering)(
+ implicit s: DBSession = autoSession): List[Entity] = {
+ findAllByWithLimitOffset(where, pagination.limit, pagination.offset, ordering)
+ }
+
+ /**
+ * Finds all entities by condition and with pagination.
+ */
+ def findAllByWithLimitOffset(where: SQLSyntax, limit: Int = 100, offset: Int = 0, ordering: SQLSyntax = defaultOrdering)(
implicit s: DBSession = autoSession): List[Entity] = {
implicit val repository = IncludesQueryRepository[Entity]()
@@ -192,6 +211,12 @@ trait FinderFeatureWithId[Id, Entity]
}).list.apply())
}
+ @deprecated("Use #findAllWithLimitOffset or #findAllWithPagination instead. This method will be removed since version 1.1.0.", since = "1.0.0")
+ def findAllByPaging(where: SQLSyntax, limit: Int = 100, offset: Int = 0, ordering: SQLSyntax = defaultOrdering)(
+ implicit s: DBSession = autoSession): List[Entity] = {
+ findAllByWithLimitOffset(where, limit, offset, ordering)
+ }
+
/**
* Counts all rows by condition.
*
@@ -1,6 +1,6 @@
package skinny.orm.feature
-import skinny.orm.SkinnyMapperBase
+import skinny.orm.{ Pagination, SkinnyMapperBase }
import scalikejdbc._, SQLInterpolation._
import skinny.orm.feature.includes.IncludesQueryRepository
@@ -45,6 +45,17 @@ trait QueryingFeature[Entity] extends SkinnyMapperBase[Entity]
def where(condition: SQLSyntax): EntitiesSelectOperationBuilder = new EntitiesSelectOperationBuilder(
mapper = this, conditions = Seq(condition))
+ /**
+ * Appends pagination settings as limit/offset.
+ *
+ * @param pagination pagination
+ * @return query buildder
+ */
+ def paginate(pagination: Pagination): EntitiesSelectOperationBuilder = {
+ new EntitiesSelectOperationBuilder(
+ mapper = this, limit = Some(pagination.limit), offset = Some(pagination.offset))
+ }
+
/**
* Appends limit part.
*
@@ -136,6 +147,16 @@ trait QueryingFeature[Entity] extends SkinnyMapperBase[Entity]
limit: Option[Int] = None,
offset: Option[Int] = None) extends SelectOperationBuilder(mapper, conditions, orderings, limit, offset, false) {
+ /**
+ * Appends pagination settings as limit/offset.
+ *
+ * @param pagination pagination
+ * @return query buildder
+ */
+ def paginate(pagination: Pagination): EntitiesSelectOperationBuilder = {
+ this.copy(limit = Some(pagination.limit), offset = Some(pagination.offset))
+ }
+
/**
* Appends limit part.
*
@@ -299,6 +320,17 @@ trait QueryingFeatureWithId[Id, Entity]
def where(condition: SQLSyntax): EntitiesSelectOperationBuilder = new EntitiesSelectOperationBuilder(
mapper = this, conditions = Seq(condition))
+ /**
+ * Appends pagination settings as limit/offset.
+ *
+ * @param pagination pagination
+ * @return query buildder
+ */
+ def paginate(pagination: Pagination): EntitiesSelectOperationBuilder = {
+ new EntitiesSelectOperationBuilder(
+ mapper = this, limit = Some(pagination.limit), offset = Some(pagination.offset))
+ }
+
/**
* Appends limit part.
*
@@ -381,6 +413,16 @@ trait QueryingFeatureWithId[Id, Entity]
limit: Option[Int] = None,
offset: Option[Int] = None) extends SelectOperationBuilder(mapper, conditions, orderings, limit, offset, false) {
+ /**
+ * Appends pagination settings as limit/offset.
+ *
+ * @param pagination pagination
+ * @return query buildder
+ */
+ def paginate(pagination: Pagination): EntitiesSelectOperationBuilder = {
+ this.copy(limit = Some(pagination.limit), offset = Some(pagination.offset))
+ }
+
/**
* Appends limit part.
*
@@ -86,10 +86,13 @@ class SkinnyORMSpec extends fixture.FunSpec with ShouldMatchers
it("returns nested belongsTo relations") { implicit session =>
val m = Member.defaultAlias
- val member = Member.findAllByPaging(sqls.isNotNull(m.companyId), 1, 0).head
+ val member = Member.findAllByWithLimitOffset(sqls.isNotNull(m.companyId), 1, 0).head
member.company.get.country.isDefined should be(false)
- val memberWithCountry = Member.includes(Member.companyOpt).findAllByPaging(sqls.isNotNull(m.companyId), 1, 0).head
+ val member2 = Member.findAllByWithPagination(sqls.isNotNull(m.companyId), Pagination.page(1).per(1)).head
+ member2.company.get.country.isDefined should be(false)
+
+ val memberWithCountry = Member.includes(Member.companyOpt).findAllByWithLimitOffset(sqls.isNotNull(m.companyId), 1, 0).head
memberWithCountry.company.get.country.isDefined should be(true)
}
@@ -161,10 +164,15 @@ class SkinnyORMSpec extends fixture.FunSpec with ShouldMatchers
val countryId = Country.findAll().map(_.id).head
Member.withAlias { m =>
Member.findAllBy(sqls.eq(m.countryId, countryId)).size should be > (0)
- Member.findAllByPaging(sqls.eq(m.countryId, countryId), 1, 0).size should equal(1)
+ Member.findAllByWithLimitOffset(sqls.eq(m.countryId, countryId), 1, 0).size should equal(1)
+ Member.findAllByWithPagination(sqls.eq(m.countryId, countryId), Pagination.page(1).per(1)).size should equal(1)
val ordering = sqls"${m.id}, ${m.createdAt} desc"
Member.findAllBy(sqls.eq(m.countryId, countryId), ordering).size should be > (0)
+ Member.findAllByWithLimitOffset(sqls.eq(m.countryId, countryId), 1, 0, ordering).size should equal(1)
+ Member.findAllByWithPagination(sqls.eq(m.countryId, countryId), Pagination.page(1).per(1), ordering).size should equal(1)
+ // TODO remove this in 1.1.0
+ Member.findAllByPaging(sqls.eq(m.countryId, countryId), 1, 0).size should equal(1)
Member.findAllByPaging(sqls.eq(m.countryId, countryId), 1, 0, ordering).size should equal(1)
}
}
@@ -253,6 +261,15 @@ class SkinnyORMSpec extends fixture.FunSpec with ShouldMatchers
ids should equal(Seq(id2, id3, id1))
}
+ it("should have #paginate in Querying APIs") { implicit session =>
+ Seq("America", "Russia", "Korea", "India", "Brazil").foreach { name =>
+ Country.createWithAttributes('name -> name)
+ }
+ val res1 = Country.limit(3).offset(3).apply().map(_.id)
+ val res2 = Country.paginate(Pagination.page(2).per(3)).apply().map(_.id)
+ res1 should equal(res2)
+ }
+
}
describe("Relationship") {

0 comments on commit fa997e1

Please sign in to comment.