This repository has been archived by the owner on Apr 27, 2021. It is now read-only.
forked from snormore/gosky
-
Notifications
You must be signed in to change notification settings - Fork 2
/
client.go
161 lines (138 loc) · 3.75 KB
/
client.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
package sky
import (
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"strings"
)
//------------------------------------------------------------------------------
//
// Constants
//
//------------------------------------------------------------------------------
const (
DefaultPort = 8585
)
//------------------------------------------------------------------------------
//
// Typedefs
//
//------------------------------------------------------------------------------
// A Client is what communicates command to the server.
type Client struct {
Host string
Port int
httpClient *http.Client
}
//------------------------------------------------------------------------------
//
// Constructor
//
//------------------------------------------------------------------------------
func NewClient(host string) *Client {
return &Client{
Host: host,
Port: DefaultPort,
httpClient: &http.Client{},
}
}
//------------------------------------------------------------------------------
//
// Methods
//
//------------------------------------------------------------------------------
//--------------------------------------
// HTTP
//--------------------------------------
// Creates a table on the server.
func (c *Client) send(method string, path string, data interface{}, ret interface{}) error {
// Create the URL.
url := fmt.Sprintf("http://%s:%d%s", c.Host, c.Port, path)
// Convert the data to JSON.
var err error
var body []byte
if data != nil {
body, err = json.Marshal(data)
if err != nil {
return err
}
}
// Create the request object.
req, err := http.NewRequest(method, url, strings.NewReader(string(body)))
if err != nil {
return err
}
req.Header.Add("Content-Type", "application/json")
// Send the request to the server.
resp, err := c.httpClient.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
// If we have a return object then deserialize to it.
if resp.StatusCode != http.StatusOK {
h := make(map[string]interface{})
err := json.NewDecoder(resp.Body).Decode(h)
if message, ok := h["message"].(string); (err == nil || err == io.EOF) && ok {
return NewError(message)
} else {
return NewError(fmt.Sprintf("sky.Error: \"%s %s\" [%d]", method, url, resp.StatusCode))
}
}
// Deserialize data into return object if we have one.
if ret != nil {
err := json.NewDecoder(resp.Body).Decode(ret)
if err != nil && err != io.EOF {
return err
}
}
return nil
}
//--------------------------------------
// Table API
//--------------------------------------
// Retrieves a single table from the server.
func (c *Client) GetTable(name string) (*Table, error) {
if name == "" {
return nil, errors.New("Table name required")
}
table := NewTable("", c)
if err := c.send("GET", fmt.Sprintf("/tables/%s", name), nil, table); err != nil {
return nil, err
}
return table, nil
}
// Retrieves a list of all tables on the server.
func (c *Client) GetTables() ([]*Table, error) {
tables := []*Table{}
if err := c.send("GET", "/tables", nil, &tables); err != nil {
return nil, err
}
return tables, nil
}
// Creates a table on the server.
func (c *Client) CreateTable(table *Table) error {
if table == nil {
return errors.New("Table required")
}
table.client = c
return c.send("POST", "/tables", table, table)
}
// Deletes a table on the server.
func (c *Client) DeleteTable(table *Table) error {
if table == nil {
return errors.New("Table required")
}
table.client = c
return c.send("DELETE", fmt.Sprintf("/tables/%s", table.Name), nil, nil)
}
//--------------------------------------
// Utility API
//--------------------------------------
// Checks if the server is currently running and available.
func (c *Client) Ping() (bool) {
err := c.send("GET", "/ping", nil, nil)
return err == nil
}