diff --git a/Sources/App/Controllers/StatsAPIController.swift b/Sources/App/Controllers/StatsAPIController.swift new file mode 100644 index 0000000..8d7430f --- /dev/null +++ b/Sources/App/Controllers/StatsAPIController.swift @@ -0,0 +1,117 @@ +//// +//// StatsAPIController.swift +//// App +//// +//// Created by Michael Simard on 5/29/20. +//// +// +//import Fluent +//import Vapor +// +// +// +// +// +//protocol ContentController { +// associatedtype Model: Fluent.Model +//} +// +//protocol StatsContentRepresentable { +// associatedtype StatsItem: Content +// var statsContent : StatsItem { get } +//} +// +// +//protocol StatsContentController: ContentController where Model: StatsContentRepresentable { +// +// func stats (_:Request) throws -> EventLoopFuture> +// func setupStatsRoute( routes: RoutesBuilder) +//} +// +//extension StatsContentController { +// +// +// func stats (req:Request) throws -> EventLoopFuture> { +// return Model.query(on: req.db).paginate(for: req).map { $0.map(\.statsContent)} +// +// } +// +// func setupStatsRoute( routes: RoutesBuilder) +// { +// routes.get(use: self.stats) +// } +// +//} +// +// +// +////*********** +// +//final class StatsModel: Model, Content { +// typealias IDValue = <#type#> +// +// static var schema: String +// +// init() { +// <#code#> +// } +// +// var winLoss:String +// var totalWins:Int +// var totalLosses:Int +// init( winLoss:String, totalWins:Int, totalLosses:Int) { +// +// self.winLoss = winLoss +// self.totalWins = totalWins +// self.totalLosses = totalLosses +// } +//} +// +//extension StatsModel: StatsContentRepresentable { +// +// struct StatsItem: Content { +// +// var winLoss:String +// var totalWins:Int +// var totalLosses:Int +// +// init(model:StatsModel) { +// +// self.winLoss = model.winLoss +// self.totalWins = model.totalWins +// self.totalLosses = model.totalLosses +// } +// } +// +// var statsContent: StatsItem { .init(model:self) } +//} +// +// +////*********** +// +// +//struct StatsAPIController: StatsContentController { +// +// typealias Model = StatsModel +// +// +//} +// +//struct StatsRouter: RouteCollection { +// +// func boot(routes: RoutesBuilder) throws { +// let statsRoute = routes.grouped("api", "stats") +// +// StatsAPIController().setupStatsRoute(routes: statsRoute) +// +//// statsRoute.get("allMatches", use: index) +//// statsRoute.get("totalWins", use: totalWins) +//// statsRoute.get("totalLosses", use: totalLosses) +// //statsRoute.get("overall", use: totalLosses) +// +// //beaconsRoute.get("overallStats", use: index) +// //beaconsRoute.post("", use: create) +// // beaconsRoute.delete(":beaconID", use: delete) +// +// } +//} diff --git a/Sources/App/Controllers/StatsController.swift b/Sources/App/Controllers/StatsController.swift new file mode 100644 index 0000000..fafac56 --- /dev/null +++ b/Sources/App/Controllers/StatsController.swift @@ -0,0 +1,86 @@ +import Fluent +import Vapor + + + + + +struct StatsController: RouteCollection { + func boot(routes: RoutesBuilder) throws { + let statsRoute = routes.grouped("api", "stats") + + statsRoute.get("allMatches", use: index) + statsRoute.get("totalWins", use: totalWins) + statsRoute.get("totalLosses", use: totalLosses) + statsRoute.get("overall", use: overall) + + //beaconsRoute.get("overallStats", use: index) + //beaconsRoute.post("", use: create) + // beaconsRoute.delete(":beaconID", use: delete) + + } + + func index(req: Request) throws -> EventLoopFuture<[Match]> { + return Match.query(on: req.db).all() + } + + + func totalWins(req: Request) throws -> EventLoopFuture { + return Match.query(on: req.db) + .filter(\.$win == true) + .count() + } + + func totalLosses(req: Request) throws -> EventLoopFuture { + return Match.query(on: req.db) + .filter(\.$win == false) + .count() + } + + + func overall(req: Request) throws -> EventLoopFuture { + let lossCount = Match.query(on: req.db) + .filter(\.$win == false) + .count() + + + let winCount = Match.query(on: req.db) + .filter(\.$win == true ) + .count() + + + + let combined = winCount.and(lossCount) + + return combined.map { (winCount, lossCount) -> (Stats) in + + let ratio:Double = (Double(winCount) / Double(lossCount)).truncate(places: 2) + + return Stats.init(winLoss: String(ratio), totalWins: winCount, totalLosses: lossCount) + } + + } +// + +// func create(req: Request) throws -> EventLoopFuture { +// let newBeacon = try req.content.decode(Beacon.Create.self) +// let beacon = Beacon(id: UUID(), ownerId: nil) +// return beacon.save(on: req.db).map { beacon } +// } +// +// func delete(req: Request) throws -> EventLoopFuture { +// return Beacon.find(req.parameters.get("beaconID"), on: req.db) +// .unwrap(or: Abort(.notFound)) +// .flatMap { $0.delete(on: req.db) } +// .transform(to: .ok) +// } +} + + +extension Double +{ + func truncate(places : Int)-> Double + { + return Double(floor(pow(10.0, Double(places)) * self)/pow(10.0, Double(places))) + } +} diff --git a/Sources/App/Controllers/TodoController.swift b/Sources/App/Controllers/TodoController.swift deleted file mode 100644 index a9b57d9..0000000 --- a/Sources/App/Controllers/TodoController.swift +++ /dev/null @@ -1,29 +0,0 @@ -import Fluent -import Vapor - -struct TodoController: RouteCollection { - func boot(routes: RoutesBuilder) throws { - let todos = routes.grouped("match") - todos.get(use: index) - todos.post(use: create) - todos.group(":matchID") { todo in - todo.delete(use: delete) - } - } - - func index(req: Request) throws -> EventLoopFuture<[Todo]> { - return Todo.query(on: req.db).all() - } - - func create(req: Request) throws -> EventLoopFuture { - let todo = try req.content.decode(Todo.self) - return todo.save(on: req.db).map { todo } - } - - func delete(req: Request) throws -> EventLoopFuture { - return Todo.find(req.parameters.get("matchID"), on: req.db) - .unwrap(or: Abort(.notFound)) - .flatMap { $0.delete(on: req.db) } - .transform(to: .ok) - } -} diff --git a/Sources/App/Migrations/CreateMatch.swift b/Sources/App/Migrations/CreateMatch.swift index a426e96..27038b4 100644 --- a/Sources/App/Migrations/CreateMatch.swift +++ b/Sources/App/Migrations/CreateMatch.swift @@ -6,7 +6,7 @@ struct CreateMatch: Migration { .id() .field("map", .string) .field("win", .bool) - .field("date", .bool) + .field("date", .date) .field("roundsWon", .int) .field("roundsLost", .int) diff --git a/Sources/App/Models/Match.swift b/Sources/App/Models/Match.swift new file mode 100644 index 0000000..49bba54 --- /dev/null +++ b/Sources/App/Models/Match.swift @@ -0,0 +1,43 @@ +import Fluent +import Vapor + +final class Match: Model, Content { + static let schema = "match" + + @ID(key: .id) + var id: UUID? + + @Field(key: "map") + var map: String? + + @Field(key: "win") + var win: Bool + + @Field(key: "date") + var date: Date + + @Field(key: "roundsWon") + var roundsWon: Int? + + @Field(key: "roundsLost") + var roundsLost: Int? + + + init() { } + + init(id: UUID? = nil, map:String?, win:Bool, date:Date, roundsWon:Int?, roundsLost:Int?) { + self.id = id + self.map = map + self.win = win + self.date = date + self.roundsWon = roundsWon + self.roundsLost = roundsLost + } + +} + +extension Match { + struct Create: Content { + } +} + diff --git a/Sources/App/Models/Stats.swift b/Sources/App/Models/Stats.swift new file mode 100644 index 0000000..733b796 --- /dev/null +++ b/Sources/App/Models/Stats.swift @@ -0,0 +1,24 @@ +// +// Stats.swift +// App +// +// Created by Michael Simard on 5/29/20. +// + +import Foundation + + +import Fluent +import Vapor + +final class Stats: Content { + var winLossRatio:String + var totalWins:Int + var totalLosses:Int + + init( winLoss:String, totalWins:Int, totalLosses:Int) { + self.winLossRatio = winLoss + self.totalWins = totalWins + self.totalLosses = totalLosses + } +} diff --git a/Sources/App/Models/Todo.swift b/Sources/App/Models/Todo.swift deleted file mode 100644 index c3c9eac..0000000 --- a/Sources/App/Models/Todo.swift +++ /dev/null @@ -1,19 +0,0 @@ -import Fluent -import Vapor - -final class Todo: Model, Content { - static let schema = "todos" - - @ID(key: .id) - var id: UUID? - - @Field(key: "title") - var title: String - - init() { } - - init(id: UUID? = nil, title: String) { - self.id = id - self.title = title - } -} diff --git a/Sources/App/configure.swift b/Sources/App/configure.swift index 96e6238..3cd6e9d 100644 --- a/Sources/App/configure.swift +++ b/Sources/App/configure.swift @@ -8,10 +8,10 @@ public func configure(_ app: Application) throws { // app.middleware.use(FileMiddleware(publicDirectory: app.directory.publicDirectory)) app.databases.use(.postgres( - hostname: Environment.get("DATABASE_HOST") ?? "localhost", - username: Environment.get("DATABASE_USERNAME") ?? "fanosphere", - password: Environment.get("DATABASE_PASSWORD") ?? "pw4fanosphere", - database: Environment.get("DATABASE_NAME") ?? "codmw" + hostname: Environment.get("DATABASE_HOST") ?? "sledsoft.com", + username: Environment.get("DATABASE_USERNAME") ?? "cod", + password: Environment.get("DATABASE_PASSWORD") ?? "pw4cod", + database: Environment.get("DATABASE_NAME") ?? "cod_db" ), as: .psql) app.migrations.add(CreateMatch()) diff --git a/Sources/App/routes.swift b/Sources/App/routes.swift index 0871197..7e01529 100644 --- a/Sources/App/routes.swift +++ b/Sources/App/routes.swift @@ -10,5 +10,5 @@ func routes(_ app: Application) throws { return "Hello, world!" } - try app.register(collection: TodoController()) -} \ No newline at end of file + try app.register(collection: StatsController()) +}