Skip to content

Commit

Permalink
Merge pull request #13 from aymanbagabas/master
Browse files Browse the repository at this point in the history
Add aggregate functions and more test coverage
  • Loading branch information
mxcl authored Dec 15, 2020
2 parents ac3b116 + 6e012af commit ac9f378
Show file tree
Hide file tree
Showing 2 changed files with 179 additions and 7 deletions.
103 changes: 98 additions & 5 deletions Sources/SublimateQueryBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,11 @@ public extension SublimateQueryBuilder {
return self
}

@inlinable
func chunk(max: Int, closure: @escaping ([Result<Model, Error>]) -> ()) throws -> Void {
try kernel.chunk(max: max, closure: closure).wait()
}

@inlinable
func first() throws -> Model? {
try kernel.first().wait()
Expand Down Expand Up @@ -130,11 +135,6 @@ public extension SublimateQueryBuilder {
return (foo, bar)
}

@inlinable
func count() throws -> Int {
try kernel.count().wait()
}

@inlinable
func exists() throws -> Bool {
try count() > 0
Expand Down Expand Up @@ -236,3 +236,96 @@ public extension SublimateQueryBuilder {
return self
}
}

public extension SublimateQueryBuilder {
@inlinable
func count() throws -> Int {
try kernel.count().wait()
}

@inlinable
func count<Field>(_ key: KeyPath<Model, Field>) throws -> Int
where
Field: QueryableProperty,
Field.Model == Model
{
try kernel.count(key).wait()
}

@inlinable
func sum<Field>(_ key: KeyPath<Model, Field>) throws -> Field.Value?
where
Field: QueryableProperty,
Field.Model == Model
{
try kernel.sum(key).wait()
}

@inlinable
func sum<Field>(_ key: KeyPath<Model, Field>) throws -> Field.Value
where
Field: QueryableProperty,
Field.Value: OptionalType,
Field.Model == Model
{
try kernel.sum(key).wait()
}


@inlinable
func average<Field>(_ key: KeyPath<Model, Field>) throws -> Field.Value?
where
Field: QueryableProperty,
Field.Model == Model
{
try kernel.average(key).wait()
}

@inlinable
func average<Field>(_ key: KeyPath<Model, Field>) throws -> Field.Value
where
Field: QueryableProperty,
Field.Value: OptionalType,
Field.Model == Model
{
try kernel.average(key).wait()
}

@inlinable
func min<Field>(_ key: KeyPath<Model, Field>) throws -> Field.Value?
where
Field: QueryableProperty,
Field.Model == Model
{
try kernel.min(key).wait()
}

@inlinable
func min<Field>(_ key: KeyPath<Model, Field>) throws -> Field.Value
where
Field: QueryableProperty,
Field.Value: OptionalType,
Field.Model == Model
{
try kernel.min(key).wait()
}

@inlinable
func max<Field>(_ key: KeyPath<Model, Field>) throws -> Field.Value?
where
Field: QueryableProperty,
Field.Model == Model
{
try kernel.max(key).wait()
}

@inlinable
func max<Field>(_ key: KeyPath<Model, Field>) throws -> Field.Value
where
Field: QueryableProperty,
Field.Value: OptionalType,
Field.Model == Model
{
try kernel.max(key).wait()
}
}
83 changes: 81 additions & 2 deletions Tests/FluentTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ final class FluentTests: CO₂TestCase {

override func setUp() {
input = [
(Star(name: "The Sun"), [Planet(name: "Mercury"), Planet(name: "Venus"), Planet(name: "Earth")])
(Star(name: "The Sun", distance: 149_597_870), [Planet(name: "Mercury"), Planet(name: "Venus"), Planet(name: "Earth")]),
(Star(name: "Proxima Centauri", distance: 40_208_000_000_000), []),
(Star(name: "Alpha Centauri A"), []),
(Star(name: "Alpha Centauri B"), [])
]
super.setUp()
}
Expand Down Expand Up @@ -100,6 +103,50 @@ final class FluentTests: CO₂TestCase {
}.wait()
}

func testCountField() throws {
try db.sublimate { db in
XCTAssertEqual(
try Star.query(on: db).count(\.$distance),
2)
}.wait()
}

func testSum() throws {
try db.sublimate { db in
XCTAssertEqual(
try Star.query(on: db).sum(\.$distance),
self.input.compactMap { (star, _) -> Double? in
return star.distance
}.reduce(0, +))
}.wait()
}

func testAverage() throws {
try db.sublimate { db in
let starsAverageDistance = try Star.query(on: db).average(\.$distance)!
let distances = self.input.compactMap { (star, _) -> Double? in
return star.distance
}
XCTAssertEqual(starsAverageDistance, distances.reduce(0, +) / Double(distances.count))
}.wait()
}

func testMin() throws {
try db.sublimate { db in
let minStar = try Star.query(on: db).min(\.$distance)!
let min = self.input.compactMap { $0.0.distance }.min()!
XCTAssertEqual(minStar, min)
}.wait()
}

func testMax() throws {
try db.sublimate { db in
let maxStar = try Star.query(on: db).max(\.$distance)!
let max = self.input.compactMap { $0.0.distance }.max()!
XCTAssertEqual(maxStar, max)
}.wait()
}

func testFirstWith() throws {
try db.sublimate { db in
let tuple = try Planet.query(on: db)
Expand Down Expand Up @@ -190,6 +237,35 @@ final class FluentTests: CO₂TestCase {
}.wait()
}

func testLimit() throws {
try db.sublimate { db in
let stars = try Star.query(on: db)
.limit(1)
.all()
XCTAssertEqual(stars, [self.input[0].0])
}.wait()
}

func testOffset() throws {
try db.sublimate { db in
let stars = try Star.query(on: db)
.limit(2)
.offset(1)
.all()
XCTAssertEqual(stars, self.input[1...2].map { $0.0 })
}.wait()
}

func testUnique() throws {
try db.sublimate { db in
let stars = try Star.query(on: db)
.join(Planet.self, on: \Star.$id == \.$star.$id)
.filter(Star.self, \.$name == "The Sun")
.all()
XCTAssertEqual(stars.first?.name, "The Sun")
}.wait()
}

func testGroup() throws {
try db.sublimate { db in
let planets = try Planet.query(on: db)
Expand All @@ -204,13 +280,15 @@ final class FluentTests: CO₂TestCase {
private final class Star: Model {
@ID(key: .id) var id: UUID?
@Field(key: "name") var name: String
@Field(key: "distance") var distance: Double? // in km
@Children(for: \.$star) var planets: [Planet]

init()
{}

init(name: String) {
init(name: String, distance: Double? = nil) {
self.name = name
self.distance = distance
}

static let schema = "stars"
Expand Down Expand Up @@ -244,6 +322,7 @@ private struct Migration: SublimateMigration {
try db.schema(Star.schema)
.id()
.field("name", .string, .required)
.field("distance", .double)
.create()
try db.schema(Planet.schema)
.id()
Expand Down

0 comments on commit ac9f378

Please sign in to comment.