Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Addd pagination to Finder/Querying APIs

  • Loading branch information...
commit fa997e101073479d679786b0733f8632cf62faa8 1 parent 5d06ad5
@seratch seratch authored
View
38 orm/src/main/scala/skinny/orm/Pagination.scala
@@ -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
+}
View
35 orm/src/main/scala/skinny/orm/SkinnyJoinTable.scala
@@ -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)
View
65 orm/src/main/scala/skinny/orm/feature/FinderFeature.scala
@@ -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]
@@ -20,6 +23,11 @@ trait FinderFeatureWithId[Id, Entity]
with IncludesFeatureWithId[Id, Entity] {
/**
+ * Default ordering condition.
+ */
+ def defaultOrdering = defaultAlias.field(primaryKeyFieldName)
+
+ /**
* Finds a single entity by primary key.
*
* @param id id
@@ -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,7 +61,7 @@ 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)
@@ -61,14 +69,17 @@ trait FinderFeatureWithId[Id, Entity]
}
/**
- * 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.
*
View
44 orm/src/main/scala/skinny/orm/feature/QueryingFeature.scala
@@ -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
@@ -46,6 +46,17 @@ trait QueryingFeature[Entity] extends SkinnyMapperBase[Entity]
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.
*
* @param n value
@@ -137,6 +148,16 @@ trait QueryingFeature[Entity] extends SkinnyMapperBase[Entity]
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.
*
* @param n value
@@ -300,6 +321,17 @@ trait QueryingFeatureWithId[Id, Entity]
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.
*
* @param n value
@@ -382,6 +414,16 @@ trait QueryingFeatureWithId[Id, Entity]
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.
*
* @param n value
View
23 orm/src/test/scala/skinny/orm/SkinnyORMSpec.scala
@@ -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") {
Please sign in to comment.
Something went wrong with that request. Please try again.