在函数中返回postgresql查询结果

时间:2017-07-09 16:40:34

标签: javascript postgresql kotlin

我现在正在使用expressjs,kotlin和PostgreSQL开发Web API。我以面向对象的方式组织我的项目。我还为数据库创建了一个类,它使所有经常调用的查询作为函数可用。示例:

fun addUser(firstName: String, lastName: String, password: String, classId: Int){
client.query("INSERT INTO users(first_name, last_name, password, class_id) values($1, $2, $3, $4)", arrayOf(firstName, lastName, password, classId));
}

但是当我尝试发出SELECT查询并将数据集返回给函数调用者时,这不起作用,因为查询是异步的。我已经尝试将结果分配给数据库对象的属性,并在分配值后立即使用它,但似乎在我永久检查其值时无法分配该值。有谁知道如何将值返回给函数调用者?

提前感谢您的回答。

1 个答案:

答案 0 :(得分:2)

假设您正在使用nodejs和pg模块。

正如您所说,由于查询功能是异步的,您无法直接将结果返回给调用者。传统上在nodejs中,调用者传递一个回调函数来处理结果或错误(如果有的话)。

在Kotlin中,这看起来像是:

    client.query(MY_QUERY_TEMPLATE, params) { err, result ->
        if (err != null) {
            // do something with the error
        } else {
            // do something with the result
        }
    }

为了使这个更整洁,你可以将结果处理程序放在自己的函数中

fun handleResult(err: dynamic, result: dynamic) {
    // put your code here
}

并像这样使用它:

client.query(MY_QUERY_TEMPLATE, params, ::handleResult)

如果您不喜欢这样,您还有其他选择。 pg库可以返回Promise。这种抽象允许您使用这样的方法链:

app.get("/promiseStyle") { req, res ->
    val params = arrayOf(42) // or something...

    fun handleSuccess(result: dynamic) {
        for (row in result.rows) {
            res.write(row.someField)
        }
        res.end()
    }

    fun handleError(error: dynamic) {
        res.status(500).send("Something went wrong");
    }

    client.query(MY_QUERY_TEMPLATE, params)
        .then(::handleSuccess)
        .catch(::handleError)
}

您可能会发现以下声明对于访问各种pg客户端功能非常有用:

@JsModule("pg")
external object pg {
    class Client {
        fun query(query: String, params: Array<Any>): dynamic

        fun query(
            query: String, params: Array<Any>, cb: (dynamic, dynamic) -> Unit
        )

        fun connect()
    }
}

然后可以按如下方式初始化postgres客户端:

val client = pg.Client()
client.connect()