Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/github/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 从web服务流式传输结果的最佳方法_Go - Fatal编程技术网

Go 从web服务流式传输结果的最佳方法

Go 从web服务流式传输结果的最佳方法,go,Go,我目前正在编写一个xml服务,其中返回批处理结果。我目前有以下情况: type QueryEnvelope struct { XMLName xml.Name `xml:"http://schemas.xmlsoap.org/soap/envelope/ Envelope"` Body *QueryBody `xml:"http://schemas.xmlsoap.org/soap/envelope/ Body"` } type QueryBody struct {

我目前正在编写一个xml服务,其中返回批处理结果。我目前有以下情况:

type QueryEnvelope struct {
    XMLName xml.Name   `xml:"http://schemas.xmlsoap.org/soap/envelope/ Envelope"`
    Body    *QueryBody `xml:"http://schemas.xmlsoap.org/soap/envelope/ Body"`
}

type QueryBody struct {
    QueryResult *QueryResult `xml:"queryResponse>result"`
}

type QueryResult struct {
    QueryLocator QueryLocator `xml:"queryLocator"`
    Done         bool         `xml:"done"`
    Size         int          `xml:"size"`
    Records      interface{}  `xml:"records"`
}

type QueryLocator string

func (r *Resource) Query(sql string, r interface{}) error {
     // builds xml request
     // sends xml request through Resource which contains the net client
     // decodes the result into r (type for records in QueryResult)
}

func (r *Resource) QueryMore(q QueryLocator, r interface{}) error {
     // same as above except takes queryLocator and makes call to different endpoint in order to continue retrieving results, when QueryResult.Done == true, done fetching results
}
显然,这需要重构,因为客户机需要查看Done==true,以便继续获取。我正在考虑添加以下内容,并将Query和QueryMore移动为queryer的一种方法:

类型查询器结构{ r*资源 完蛋 QueryLocator QueryLocator }

func新(r*资源)*查询器{}

然后,客户端的行为如下:

err := q.Query("sql statement", r)
if err != nil {
     // handle
}
// do stuff with r
for q.Done == false {
     q.QueryMore(r)
     // do stuff with r
}

我想知道为了最好地“流化”结果,这里的惯用方法是什么。

一个选项是使用stdlib包用于迭代行的模式。通过这种方式,您可以将初始查询与后续调用统一起来

有一个
Next()
方法,它用查询结果填充内部结构,如果有结果挂起,则返回
true
。在您的情况下,您仍然需要一个初始构造函数,如
Query
,但这只是设置数据结构。调用
Next()
完成真正的工作,而调用
Scan(r)
(或任何您想调用的读取结果)只会显示结果。迭代完成后,您就有了一个
Err()
方法来检查任何操作错误

稍微改变一下sql包中的示例:

// setup the query, but delay any action until we start iterating.
query, err := NewQuery(queryParameters)
// check err of course
defer query.Close()

for query.Next() {
    err = query.Scan(&r)
    ...
}
err = query.Err() // get any error encountered during iteration 

您也可以查看其他类似的驱动程序,以了解此模式的变化。

您到底在问什么?你说你想要一个“流”,还是只想迭代结果?你在这里提出的迭代方法有什么问题?我不喜欢我必须处理Query()的结果,然后在QueryMore()的循环中再次处理它。如果您在示例中提到SQL,我觉得可能有一种更惯用的方法来设置API,但我没有看到任何类似SQL的代码。您是否尝试过sql包或其他数据库驱动程序使用的迭代模式?很抱歉造成混淆,但我是针对soap服务编写的,而不是创建soap服务。我没有访问sql server的权限。无论如何,我指的是驱动程序使用的模式。我会在答案中加入一些东西,看看是否有帮助。谢谢你抽出时间!我将在今天晚些时候或明天对此进行研究。我能够重构所有内容,以便NewQuery()启动一个新的查询器,而Next()用于整个迭代。Query和QueryMore成为私有的。再次感谢