如何在 Vapor 中展平多个查询
How to flatten multiple queries in Vapor
我需要对不同的表进行大量查询,然后 return 在一个响应中得到结果。我想知道我可以将极其嵌套的函数展平吗?
final class CodeController {
internal func indexCodes(_ req: Request) throws -> EventLoopFuture<Response> {
CodeCountry.query(on: req).sort(\.name).all().flatMap { countries -> EventLoopFuture<Response> in
CodeFloor.query(on: req).sort(\.name).all().flatMap { floors -> EventLoopFuture<Response> in
CodeRegion.query(on: req).sort(\.name).all().flatMap { regions -> EventLoopFuture<Response> in
CodeObjectType.query(on: req).sort(\.name).all().flatMap { objectTypes -> EventLoopFuture<Response> in
CodePropertyType.query(on: req).sort(\.name).all().flatMap { propertyTypes -> EventLoopFuture<Response> in
CodeRooms.query(on: req).sort(\.name).all().flatMap { rooms -> EventLoopFuture<Response> in
let codes = CodesContent(
countries: countries,
floors: floors,
regions: regions,
objectTypes: objectTypes,
propertyTypes: propertyTypes,
rooms: rooms
)
return codes.encode(status: .ok, for: req)
}
}
}
}
}
}
}
}
这可能不是最好看的代码,但我认为可以解决问题。我喜欢@Nick 将新数据模型作为集合引入的方法,所以也会这样做。
您可以合并两个期货并获得一个。这来自 SwiftNIO
let futureThingOne: Future<ThingOne> = ...
let futureThingTwo: Future<ThingTwo> = ...
let futureBothThings: Future<(ThingOne, ThingTwo)> = futureThingOne.and(futureThingTwo)
因此,通过合并来自查询的未来,您可以构建一个扁平化结构。
struct Codes: Content {
let countries: [CodeCountry]
let floors: [CodeFloor]
let regions: [CodeRegion]
let objectTypes: [CodeObjectType]
let propertyTypes: [CodePropertyType]
let rooms: [CodeRooms]
static func codes(req: Request) -> Future<Codes> {
let futureCountries = CodeCountry.query(on: req).sort(\.name).all()
let futureFloors = CodeFloor.query(on: req).sort(\.name).all()
let futureRegions = CodeRegion.query(on: req).sort(\.name).all()
let futureObjectTypes = CodeObjectType.query(on: req).sort(\.name).all()
let futurePropertyTypes = CodePropertyType.query(on: req).sort(\.name).all()
let futureRooms = CodeRooms.query(on: req).sort(\.name).all()
let combined = futureCountries.and(futureFloors).and(futureRegions).and(futureObjectTypes).and(futurePropertyTypes).and(futureRooms)
return combined.map {
Codes.init(
countries: [=11=].0.0.0.0.0,
floors: [=11=].0.0.0.0.1,
regions: [=11=].0.0.0.1,
objectTypes: [=11=].0.0.1,
propertyTypes: [=11=].0.1,
rooms: [=11=].1
)
}
}
}
我需要对不同的表进行大量查询,然后 return 在一个响应中得到结果。我想知道我可以将极其嵌套的函数展平吗?
final class CodeController {
internal func indexCodes(_ req: Request) throws -> EventLoopFuture<Response> {
CodeCountry.query(on: req).sort(\.name).all().flatMap { countries -> EventLoopFuture<Response> in
CodeFloor.query(on: req).sort(\.name).all().flatMap { floors -> EventLoopFuture<Response> in
CodeRegion.query(on: req).sort(\.name).all().flatMap { regions -> EventLoopFuture<Response> in
CodeObjectType.query(on: req).sort(\.name).all().flatMap { objectTypes -> EventLoopFuture<Response> in
CodePropertyType.query(on: req).sort(\.name).all().flatMap { propertyTypes -> EventLoopFuture<Response> in
CodeRooms.query(on: req).sort(\.name).all().flatMap { rooms -> EventLoopFuture<Response> in
let codes = CodesContent(
countries: countries,
floors: floors,
regions: regions,
objectTypes: objectTypes,
propertyTypes: propertyTypes,
rooms: rooms
)
return codes.encode(status: .ok, for: req)
}
}
}
}
}
}
}
}
这可能不是最好看的代码,但我认为可以解决问题。我喜欢@Nick 将新数据模型作为集合引入的方法,所以也会这样做。 您可以合并两个期货并获得一个。这来自 SwiftNIO
let futureThingOne: Future<ThingOne> = ...
let futureThingTwo: Future<ThingTwo> = ...
let futureBothThings: Future<(ThingOne, ThingTwo)> = futureThingOne.and(futureThingTwo)
因此,通过合并来自查询的未来,您可以构建一个扁平化结构。
struct Codes: Content {
let countries: [CodeCountry]
let floors: [CodeFloor]
let regions: [CodeRegion]
let objectTypes: [CodeObjectType]
let propertyTypes: [CodePropertyType]
let rooms: [CodeRooms]
static func codes(req: Request) -> Future<Codes> {
let futureCountries = CodeCountry.query(on: req).sort(\.name).all()
let futureFloors = CodeFloor.query(on: req).sort(\.name).all()
let futureRegions = CodeRegion.query(on: req).sort(\.name).all()
let futureObjectTypes = CodeObjectType.query(on: req).sort(\.name).all()
let futurePropertyTypes = CodePropertyType.query(on: req).sort(\.name).all()
let futureRooms = CodeRooms.query(on: req).sort(\.name).all()
let combined = futureCountries.and(futureFloors).and(futureRegions).and(futureObjectTypes).and(futurePropertyTypes).and(futureRooms)
return combined.map {
Codes.init(
countries: [=11=].0.0.0.0.0,
floors: [=11=].0.0.0.0.1,
regions: [=11=].0.0.0.1,
objectTypes: [=11=].0.0.1,
propertyTypes: [=11=].0.1,
rooms: [=11=].1
)
}
}
}