瀏覽代碼

Implement plaintext, json, db, queries for Vapor + Postgres (#4033)

Gopal Sharma 7 年之前
父節點
當前提交
d49cc662c9

+ 42 - 24
frameworks/Swift/vapor/Package.resolved

@@ -15,8 +15,8 @@
         "repositoryURL": "https://github.com/vapor/core.git",
         "state": {
           "branch": null,
-          "revision": "efe79e4f59445b661ba7e6511c2a0b80645c2e72",
-          "version": "3.1.6"
+          "revision": "eb876a758733166a4fb20f3f0a17b480c5ea563e",
+          "version": "3.4.3"
         }
       },
       {
@@ -24,8 +24,8 @@
         "repositoryURL": "https://github.com/vapor/crypto.git",
         "state": {
           "branch": null,
-          "revision": "1b8c2ba5a42f1adf2aa812204678d8b16466fa59",
-          "version": "3.1.2"
+          "revision": "4b85405430df1892ee3aa1554bdb477e96cf46ad",
+          "version": "3.2.0"
         }
       },
       {
@@ -33,8 +33,8 @@
         "repositoryURL": "https://github.com/vapor/database-kit.git",
         "state": {
           "branch": null,
-          "revision": "0db303439e5ef8b6df50a2b6c4029edddee90cb0",
-          "version": "1.0.1"
+          "revision": "3a17dbbe9be5f8c37703e4b7982c1332ad6b00c4",
+          "version": "1.3.1"
         }
       },
       {
@@ -42,8 +42,8 @@
         "repositoryURL": "https://github.com/vapor/http.git",
         "state": {
           "branch": null,
-          "revision": "9246340ae4c5310627099349fc74785267b55607",
-          "version": "3.0.5"
+          "revision": "9e3eff9dfa4df7fc282bf27f801c72b3ffbfd984",
+          "version": "3.1.4"
         }
       },
       {
@@ -51,8 +51,17 @@
         "repositoryURL": "https://github.com/vapor/multipart.git",
         "state": {
           "branch": null,
-          "revision": "7778dcb62f3efa845e8e2808937bb347575ba7ce",
-          "version": "3.0.1"
+          "revision": "e57007c23a52b68e44ebdfc70cbe882a7c4f1ec3",
+          "version": "3.0.2"
+        }
+      },
+      {
+        "package": "PostgreSQL",
+        "repositoryURL": "https://github.com/vapor/postgresql.git",
+        "state": {
+          "branch": null,
+          "revision": "c8b01a35efae6737e8d896440f5eec9b219571d9",
+          "version": "1.1.0"
         }
       },
       {
@@ -73,13 +82,22 @@
           "version": "1.0.0"
         }
       },
+      {
+        "package": "SQL",
+        "repositoryURL": "https://github.com/vapor/sql.git",
+        "state": {
+          "branch": null,
+          "revision": "a35cf1dced4ddd32bb2dc8b6e765aea7bcf8d6e0",
+          "version": "2.1.0"
+        }
+      },
       {
         "package": "swift-nio",
         "repositoryURL": "https://github.com/apple/swift-nio.git",
         "state": {
           "branch": null,
-          "revision": "a5db2a67515ad2b490ac5646db204a5edf939f47",
-          "version": "1.6.1"
+          "revision": "5d8148c8b45dfb449276557f22120694567dd1d2",
+          "version": "1.9.5"
         }
       },
       {
@@ -87,8 +105,8 @@
         "repositoryURL": "https://github.com/apple/swift-nio-ssl.git",
         "state": {
           "branch": null,
-          "revision": "38955a5f806a952daf2b16fbfe9aa529749cf1dd",
-          "version": "1.1.0"
+          "revision": "8380fa29a2af784b067d8ee01c956626ca29f172",
+          "version": "1.3.1"
         }
       },
       {
@@ -114,8 +132,8 @@
         "repositoryURL": "https://github.com/vapor/template-kit.git",
         "state": {
           "branch": null,
-          "revision": "43b57b5861d5181b906ac6411d28645e980bb638",
-          "version": "1.0.1"
+          "revision": "db35b1c35aabd0f5db3abca0cfda7becfe9c43e2",
+          "version": "1.1.0"
         }
       },
       {
@@ -123,8 +141,8 @@
         "repositoryURL": "https://github.com/vapor/url-encoded-form.git",
         "state": {
           "branch": null,
-          "revision": "8448fa943057c01220f6a940d3b1b8e9fd92a96e",
-          "version": "1.0.2"
+          "revision": "932024f363ee5ff59059cf7d67194a1c271d3d0c",
+          "version": "1.0.5"
         }
       },
       {
@@ -132,8 +150,8 @@
         "repositoryURL": "https://github.com/vapor/validation.git",
         "state": {
           "branch": null,
-          "revision": "ab6c5a352d97c8687b91ed4963aef8e7cfe0795b",
-          "version": "2.0.0"
+          "revision": "156f8adeac3440e868da3757777884efbc6ec0cc",
+          "version": "2.1.0"
         }
       },
       {
@@ -141,8 +159,8 @@
         "repositoryURL": "https://github.com/vapor/vapor.git",
         "state": {
           "branch": null,
-          "revision": "821184be792dfa144a82fe379784e04eb9dad1eb",
-          "version": "3.0.1"
+          "revision": "157d3b15336caa882662cc75024dd04b2e225246",
+          "version": "3.1.0"
         }
       },
       {
@@ -150,8 +168,8 @@
         "repositoryURL": "https://github.com/vapor/websocket.git",
         "state": {
           "branch": null,
-          "revision": "23acd21aa37a200faa2f5d5525c974efa6b5676c",
-          "version": "1.0.0"
+          "revision": "149af03348f60ac8b84defdf277112d62fd8c704",
+          "version": "1.0.2"
         }
       }
     ]

+ 11 - 8
frameworks/Swift/vapor/Package.swift

@@ -1,12 +1,15 @@
-// swift-tools-version:4.0
+// swift-tools-version:4.2
 import PackageDescription
 
 let package = Package(
-  name: "tfb",
-  dependencies: [
-    .package(url: "https://github.com/vapor/vapor.git", from: "3.0.0"),
-  ],
-  targets: [
-    .target(name: "vapor-tfb", dependencies: ["Vapor"], exclude: ["Resources"]),
-  ]
+    name: "tefb",
+    dependencies: [
+        .package(url: "https://github.com/vapor/vapor.git", from: "3.1.0"),
+        .package(url: "https://github.com/vapor/postgresql.git", from: "1.0.2"),
+    ],
+    targets: [
+        .target(name: "App", dependencies: ["PostgreSQL", "Vapor"]),
+        .target(name: "Run", dependencies: ["App"])
+    ]
 )
+

+ 5 - 19
frameworks/Swift/vapor/README.md

@@ -4,23 +4,17 @@ This is the Vapor portion of a [benchmarking tests suite](../../) comparing a va
 
 ### Targets
 
-Two executable targets. Each listens on port 8080.
-`vapor-tfb` is for a bare server, (neither Fluent nor Leaf are dependencies)
-`vapor-tfb-mysql` is for MySQL
-
-### Dependencies
-
-Linked MySQL client libraries are required to build the app, please consult Vapor's documentation [for MySQL](https://github.com/vapor/mysql).
+One executable target. Listens on port 8080.
 
 ### Database
 
-MySQL
+PostgreSQL
 
 ## Versions
-[Swift 4.1.0](https://swift.org/)
-[Vapor 3.0.0 gm](https://vapor.codes/)
+[Swift 4.2](https://swift.org/)
+[Vapor 3.1.0](https://vapor.codes/)
 
-## Test URLs: `vapor-tfb`
+## Test URLs: `vapor`
 
 ### Plaintext test
 http://localhost:8080/plaintext
@@ -28,16 +22,8 @@ http://localhost:8080/plaintext
 #### JSON serialization test
 http://localhost:8080/json
 
-## Test URLs: `vapor-tfb-mysql`
-
 ### Single database query test
 http://localhost:8080/db
 
 ### Multiple database queries test
 http://localhost:8080/queries/[1...500]
-
-### Fortunes test
-http://localhost:8080/fortunes
-
-### Database updates test
-http://localhost:8080/updates/[1...500]

+ 16 - 0
frameworks/Swift/vapor/Sources/App/Controllers/JSONController.swift

@@ -0,0 +1,16 @@
+//
+//  JSONController.swift
+//  App
+//
+//  Created by Gopal Sharma on 7/29/18.
+//
+
+import Vapor
+
+final class JSONController {
+
+    func get(_ req: Request) throws -> Message {
+        return Message(message: "Hello, world!")
+    }
+
+}

+ 16 - 0
frameworks/Swift/vapor/Sources/App/Controllers/PlainTextController.swift

@@ -0,0 +1,16 @@
+//
+//  PlainTextController.swift
+//  App
+//
+//  Created by Gopal Sharma on 7/29/18.
+//
+
+import Vapor
+
+final class PlainTextController {
+
+    func get(_ req: Request) throws -> String {
+        return "Hello, world!"
+    }
+
+}

+ 65 - 0
frameworks/Swift/vapor/Sources/App/Controllers/WorldController.swift

@@ -0,0 +1,65 @@
+import Logging
+import PostgreSQL
+import Vapor
+
+struct BadRequestError : AbortError {
+    var status: HTTPResponseStatus {
+        return .badRequest
+    }
+
+    var reason: String {
+        return "Bad request"
+    }
+
+    var identifier: String {
+        return "badRequest"
+    }
+
+}
+
+final class WorldController {
+
+    func get(_ req: Request) throws -> Future<World> {
+        return req.withPooledConnection(to: .psql) { (conn: PostgreSQLDatabase.Connection) in
+            return conn.select().all().from(World.self).where(\World.id == Int.random(in: 1...10_000)).all(decoding: World.self)
+        }.map { (rows: [World]) in
+            if let first = rows.first {
+                return first
+            }
+            throw NotFound(rootCause: nil)
+        }
+    }
+
+    func queries(_ req: Request) throws -> Future<[World]> {
+        let numQueries: Int
+        do {
+            let queries = try req.query.get(Int.self, at: "queries")
+            if queries < 1 {
+                numQueries = 1
+            } else if queries > 500 {
+                numQueries = 500
+            } else {
+                numQueries = queries
+            }
+        } catch {
+            numQueries = 1
+        }
+        var futures: [Future<World>] = []
+        for _ in 0..<numQueries {
+            futures.append(
+                req.withPooledConnection(to: .psql) { (conn: PostgreSQLDatabase.Connection) in
+                    return conn.select().all().from(World.self).where(\World.id == Int.random(in: 1...10_000)).all(decoding: World.self)
+                }.map { (rows: [World]) in
+                    if let first = rows.first {
+                        return first
+                    }
+                    throw NotFound(rootCause: nil)
+                }
+            )
+        }
+        return Future<[World]>.reduce(into: [], futures, eventLoop: req.eventLoop) { (worlds, world) in
+            return worlds.append(world)
+        }
+    }
+
+}

+ 1 - 1
frameworks/Swift/vapor/Sources/vapor-tfb/Message.swift → frameworks/Swift/vapor/Sources/App/Models/Message.swift

@@ -1,5 +1,5 @@
 import Vapor
 
-struct Message: Content {
+struct Message : Content {
     let message: String
 }

+ 13 - 0
frameworks/Swift/vapor/Sources/App/Models/World.swift

@@ -0,0 +1,13 @@
+import PostgreSQL
+import Vapor
+
+struct World: Codable, Content, SQLTable {
+    static let sqlTableIdentifierString = "World"
+    var id: Int?
+    var randomnumber: Int
+
+    init(id: Int? = nil, randomNumber: Int) {
+        self.id = id
+        self.randomnumber = randomNumber
+    }
+}

+ 12 - 0
frameworks/Swift/vapor/Sources/App/app.swift

@@ -0,0 +1,12 @@
+import Vapor
+
+/// Creates an instance of Application. This is called from main.swift in the run target.
+public func app(_ env: Environment) throws -> Application {
+    var config = Config.default()
+    var env = env
+    var services = Services.default()
+    try configure(&config, &env, &services)
+    let app = try Application(config: config, environment: env, services: services)
+    try boot(app)
+    return app
+}

+ 6 - 0
frameworks/Swift/vapor/Sources/App/boot.swift

@@ -0,0 +1,6 @@
+import Vapor
+
+/// Called after your application has initialized.
+public func boot(_ app: Application) throws {
+    // your code here
+}

+ 39 - 0
frameworks/Swift/vapor/Sources/App/configure.swift

@@ -0,0 +1,39 @@
+import PostgreSQL
+import Vapor
+
+class ServerHeaderMiddleWare : Middleware, Service {
+    func respond(to request: Request, chainingTo next: Responder) throws -> EventLoopFuture<Response> {
+        return try next.respond(to: request).map { response in
+            response.http.headers.add(name: HTTPHeaderName.server, value: "Vapor")
+            return response
+        }
+    }
+}
+
+public func configure(_ config: inout Config, _ env: inout Environment, _ services: inout Services) throws {
+    let router = EngineRouter.default()
+    try routes(router)
+    services.register(router, as: Router.self)
+    services.register(ServerHeaderMiddleWare.self) { _ in
+        return ServerHeaderMiddleWare()
+    }
+
+    var middlewares = MiddlewareConfig()
+    middlewares.use(ErrorMiddleware.self)
+    middlewares.use(ServerHeaderMiddleWare.self)
+    services.register(middlewares)
+
+    try services.register(PostgreSQLProvider())
+
+    let postgresql = PostgreSQLDatabase(
+        config: PostgreSQLDatabaseConfig(
+            hostname: "tfb-database",
+            username: "benchmarkdbuser",
+            database: "hello_world",
+            password: "benchmarkdbpass"
+    ))
+
+    var databases = DatabasesConfig()
+    databases.add(database: postgresql, as: .psql)
+    services.register(databases)
+}

+ 15 - 0
frameworks/Swift/vapor/Sources/App/routes.swift

@@ -0,0 +1,15 @@
+import Vapor
+
+/// Register your application's routes here.
+public func routes(_ router: Router) throws {
+
+    let jsonController = JSONController()
+    router.get("json", use: jsonController.get)
+
+    let plainTextController = PlainTextController()
+    router.get("plaintext", use: plainTextController.get)
+
+    let worldController = WorldController()
+    router.get("db", use: worldController.get)
+    router.get("queries", use: worldController.queries)
+}

+ 3 - 0
frameworks/Swift/vapor/Sources/Run/main.swift

@@ -0,0 +1,3 @@
+import App
+
+try app(.detect()).run()

+ 0 - 35
frameworks/Swift/vapor/Sources/vapor-tfb/main.swift

@@ -1,35 +0,0 @@
-import Vapor
-
-// Services
-var services = Services.default()
-
-// Router
-let router = EngineRouter.default()
-
-// Routes
-
-// JSON test
-var jsonRes = HTTPResponse(status: .ok, headers: ["Server": "Vapor"])
-let jsonEncoder = JSONEncoder()
-
-router.get("json") { req -> Response in
-    let res = Response(http: jsonRes, using: req.sharedContainer)
-    try res.content.encode(json: Message(message: "Hello, world!"), using: jsonEncoder)
-    return res
-}
-
-// Plaintext test
-let plaintextRes = HTTPResponse(status: .ok, headers: ["Server": "Vapor", "Content-Type": "text/plain"], body: "Hello, world!")
-
-router.get("plaintext") { req in
-    return plaintextRes
-}
-
-services.register(router, as: Router.self)
-
-// Middlewares (remove unused ErrorMiddleware)
-var middlewares = MiddlewareConfig()
-services.register(middlewares)
-
-let app = try Application(config: .default(), environment: .detect(), services: services)
-try app.run()

+ 24 - 20
frameworks/Swift/vapor/benchmark_config.json

@@ -1,24 +1,28 @@
 {
   "framework": "vapor",
-  "tests": [{
-    "default": {
-      "json_url": "/json",
-      "plaintext_url": "/plaintext",
-      "port": 8080,
-      "approach": "Realistic",
-      "classification": "Fullstack",
-      "database": "None",
-      "framework": "Vapor",
-      "language": "Swift",
-      "flavor": "None",
-      "orm": "None",
-      "platform": "None",
-      "webserver": "None",
-      "os": "Linux",
-      "database_os": "Linux",
-      "display_name": "Vapor",
-      "notes": "",
-      "versus": ""
+  "tests": [
+    {
+      "default": {
+        "plaintext_url": "/plaintext",
+        "json_url": "/json",
+        "db_url": "/db",
+        "query_url": "/queries?queries=",
+        "port": 8080,
+        "approach": "Realistic",
+        "classification": "Fullstack",
+        "database": "Postgres",
+        "framework": "Vapor",
+        "language": "Swift",
+        "flavor": "None",
+        "orm": "Micro",
+        "platform": "None",
+        "webserver": "None",
+        "os": "Linux",
+        "database_os": "Linux",
+        "display_name": "Vapor",
+        "notes": "",
+        "versus": "None"
+      }
     }
-  }]
+  ]
 }

+ 2 - 2
frameworks/Swift/vapor/vapor.dockerfile

@@ -1,7 +1,7 @@
-FROM swift:4.1
+FROM swift:4.2
 
 ADD ./ /vapor
 WORKDIR /vapor
 RUN swift build -c release
 
-CMD .build/release/vapor-tfb -e production -b 0.0.0.0:8080
+CMD .build/release/Run -e production -b 0.0.0.0:8080