Return 在 Vapor 中使用原始 sql 的条目总数

Return total count of enteries using raw sql in Vapor

我正在尝试将传入的 GET 路由到 return 以下字符串:

"The total number of our models is 12"

其中 12 是保存到数据库中的特定模型的实际条目数。

现在执行此操作的一种方法是使用以下内容:

func index(_ req: Request) throws -> Future<String> {
  return Model.query(on: req).all().map { models in
    return "The total number of our models is \(models.count)"
  }
}

这是记录最多但同时效率最低的方法。我找不到任何映射到 "SELECT COUNT(*) FROM Model;"

的查询

所以我求助于针对数据库编写自己的原始 SQL。我已经走到这一步了,但我不知道如何将 [PostgreSQLColumn : PostgreSQLData] 映射到 Future<String>

  func index(_ req: Request) throws -> Future<String> {
    return req.withPooledConnection(to: .psql) { (conn) in
      conn.raw("SELECT COUNT(*) FROM MODEL").all()
          ///....something something 
    }
  }

除了 all()first(),您还可以使用 all(decoding:)first(decoding:) 来解码返回的原始行

struct CountResult: Content {
    let count: Int64
}

func index(_ req: Request) throws -> Future<String> {
    req.withPooledConnection(to: .psql) { conn in
        conn.raw("SELECT COUNT(*) as count FROM MODEL").first(decoding: CountResult.self).map {
            [=10=]?.count ?? 0
        }.map {
            "The total number of our models is \([=10=])"
        }
    }
}

此外,我建议查看 SwifQL and Bridges 库以类型安全的方式处理原始 SQL。

使用纯 SwifQL

struct CountResult: Content {
    let count: Int64
}

func index(_ req: Request) throws -> Future<String> {
    req.withPooledConnection(to: .psql) { conn in
        let query = SwifQL
            .select(Fn.count(MyTable.table.*))
            .from(MyTable.table)
        return conn.raw(query)
            .first(decoding: CountResult.self)
            .map { [=11=]?.count ?? 0 }
            .map {
                "The total number of our models is \([=11=])"
            }
    }
}

使用 SwifQL + Bridges

func index(_ req: Request) throws -> Future<String> {
    MyTable.query(on: .psql, on: req).count().map {
        "The total number of our models is \([=12=])"
    }
}

到return你可以做的行数:

Model.query(on: req).count()

您也可以对该查询应用过滤器