Revision 5966d0a36a44fc465b6e29781c62bfa5b9c93ef1 authored by Denys Smirnov on 11 December 2019, 22:11:52 UTC, committed by Denys Smirnov on 15 December 2019, 13:03:38 UTC
1 parent 20cf98c
client.go
package client
import (
"fmt"
"io"
"net/http"
"net/url"
"github.com/cayleygraph/quad"
"github.com/cayleygraph/quad/pquads"
)
func New(addr string) *Client {
return &Client{addr: addr, cli: http.DefaultClient}
}
type Client struct {
addr string
cli *http.Client
}
func (c *Client) SetHTTPClient(cli *http.Client) {
c.cli = cli
}
func (c *Client) url(s string, q map[string]string) string {
addr := c.addr + s
if len(q) != 0 {
p := make(url.Values, len(q))
for k, v := range q {
p.Set(k, v)
}
addr += "?" + p.Encode()
}
return addr
}
type errRequestFailed struct {
Status string
StatusCode int
}
func (e errRequestFailed) Error() string {
return fmt.Sprintf("request failed: %d %v", e.StatusCode, e.Status)
}
func (c *Client) QuadReader() (quad.ReadCloser, error) {
resp, err := http.Get(c.url("/api/v2/read", map[string]string{
"format": "pquads",
}))
if err != nil {
return nil, err
}
if resp.StatusCode != http.StatusOK {
resp.Body.Close()
return nil, errRequestFailed{StatusCode: resp.StatusCode, Status: resp.Status}
}
r := pquads.NewReader(resp.Body, 10*1024*1024)
r.SetCloser(resp.Body)
return r, nil
}
type funcCloser struct {
f func() error
closed bool
}
func (c funcCloser) Close() error {
if c.closed {
return nil
}
c.closed = true
return c.f()
}
func (c *Client) QuadWriter() (quad.WriteCloser, error) {
pr, pw := io.Pipe()
req, err := http.NewRequest("POST", c.url("/api/v2/write", nil), pr)
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", pquads.ContentType)
errc := make(chan error, 1)
go func() {
defer func() {
close(errc)
pr.Close()
}()
resp, err := c.cli.Do(req)
if resp != nil && resp.Body != nil {
defer resp.Body.Close()
}
if err == nil && resp.StatusCode != http.StatusOK {
err = errRequestFailed{StatusCode: resp.StatusCode, Status: resp.Status}
}
errc <- err
}()
qw := pquads.NewWriter(pw, &pquads.Options{
Full: false,
Strict: false,
})
qw.SetCloser(funcCloser{f: func() error {
pw.Close()
return <-errc
}})
return qw, nil
}
![swh spinner](/static/img/swh-spinner.gif)
Computing file changes ...