如何在SQLite.swift中创建一个类型安全的自定义函数



我想创建一个简单的距离函数来排序对象,同时从Swift2中的SQLite数据库获取。我使用的是很棒的SQLite.swift框架。

使用下面的代码,我可以获取最近的对象:

db.createFunction("distance") { (args) -> Binding? in
    assert(args.count == 4)
    if let lat1 = args[0] as? Double, let lon1 = args[1] as? Double, let lat2 = args[2] as? Double, let lon2 = args[3] as? Double {
        let deltaLat = lat1 - lat2
        let deltaLon = lon1 - lon2
        return deltaLat * deltaLat + deltaLon * deltaLon * 0.46512281898705
    }
    return nil
}
let queryString = "SELECT * FROM objects where lat != "" and lng != "" ORDER BY distance(lat, lng, (lat), (lng)) ASC LIMIT (fetchLimit)"
let stmt = db.prepare(queryString)
for row in stmt {
    print(row)
}

但是我想使用类型安全的SQL表达式而不使用查询字符串。我怎么能添加一个函数,能够使它像这样工作(这里的lat和lon值是表达式值,表示表中行和centerLat的位置,centerLon值表示从我计算对象的距离的中心点):

for row in db.order(distance(lat, lon, centerLat, centerLon).limit(fetchLimit) {
    print(row)
}

目前还没有很好的方法来做到这一点(目前许多表达式构建助手都在SQLite.swift内部)。我鼓励你打开一个问题作为一个功能请求。

同时,由于这些值不需要加引号,因此可以执行以下操作:

func distance(
    lat1: Expression<Double>, lng1: Expression<Double>,
    lat2: Double, lng2: Double
) -> Expression<Double> {
    return Expression(
        literal: "distance((lat1.asSQL()), (lng1.asSQL()), ?, ?)",
        lat2, lng2
    )
}

当前的文档为这个问题带来了希望。然而,我不能得到示例代码编译与多个参数(上下文闭包类型'([Binding?]) -> Binding?'期望有1个参数,但在闭包体中使用了2个参数),应该可以:

import MobileCoreServices
let typeConformsTo: (Expression<String>, String) -> Expression<Bool> = (
    try db.createFunction("typeConformsTo", deterministic: true) { UTI, conformsToUTI in
        return UTTypeConformsTo(UTI, conformsToUTI)
    }
)

https://github.com/stephencelis/SQLite.swift/blob/master/Documentation/Index.md custom-sql-functions

相关内容

  • 没有找到相关文章

最新更新