-
Notifications
You must be signed in to change notification settings - Fork 1
/
gofmcon.go
111 lines (93 loc) · 2.45 KB
/
gofmcon.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
package gofmcon
import (
"encoding/xml"
"github.com/pkg/errors"
"io/ioutil"
"net/http"
"net/url"
)
const (
fmiPath = "fmi/xml/fmresultset.xml"
FMDBNames = "-dbnames"
)
type FMConnector struct {
Host string
Port string
Username string
Password string
Client *http.Client
}
func NewFMConnector(host string, port string, username string, password string) *FMConnector {
newConn := &FMConnector{
host,
port,
username,
password,
http.DefaultClient,
}
return newConn
}
func (fmc *FMConnector) Ping() error {
var newURL = &url.URL{}
newURL.Scheme = "http"
newURL.Host = fmc.Host
newURL.Path = fmiPath
newURL.RawQuery = newURL.Query().Encode() + "&" + FMDBNames
request, err := http.NewRequest("GET", newURL.String(), nil)
if err != nil {
return errors.WithMessage(err, "gofmcon.Ping: error create request")
}
request.SetBasicAuth(fmc.Username, fmc.Password)
request.Header.Set("User-Agent", "Golang FileMaker Connector")
client := &http.Client{}
res, err := client.Do(request)
if err != nil {
return err
}
defer res.Body.Close()
if res.StatusCode != 200 {
return errors.New("gofmcon.Ping: FileMaker server unreachable")
}
return nil
}
func (fmc *FMConnector) Query(q *FMQuery) (FMResultset, error) {
resultSet := FMResultset{}
queryURL := fmc.makeURL(q)
request, err := http.NewRequest("GET", queryURL, nil)
if err != nil {
return resultSet, errors.WithMessage(err, "gofmcon.Query: error create request")
}
request.Header.Set("User-Agent", "Golang FileMaker Connector")
request.SetBasicAuth(fmc.Username, fmc.Password)
if fmc.Client == nil {
fmc.Client = http.DefaultClient
}
res, err := fmc.Client.Do(request)
if err != nil {
return resultSet, errors.WithMessage(err, "gofmcon.Query: error http request")
}
defer res.Body.Close()
b, err := ioutil.ReadAll(res.Body)
if err != nil {
return resultSet, errors.WithMessage(err, "gofmcon.Query: error read response body")
}
err = xml.Unmarshal(b, &resultSet)
if err != nil {
return resultSet, errors.WithMessage(err, "gofmcon.Query: error unmarshal xml")
}
if resultSet.HasError() {
return resultSet, errors.New(resultSet.FMError.String())
}
resultSet.Resultset.prepareRecords()
return resultSet, nil
}
func (fmc *FMConnector) makeURL(q *FMQuery) string {
var newURL = &url.URL{}
newURL.Scheme = "http"
newURL.Host = fmc.Host
if fmc.Port != "" {
newURL.Host += ":" + fmc.Port
}
newURL.Path = fmiPath
return newURL.String() + "?" + q.QueryString()
}