-
Notifications
You must be signed in to change notification settings - Fork 44
/
query-marshalling-rest.go
158 lines (125 loc) · 4.17 KB
/
query-marshalling-rest.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
package main
import (
"encoding/json"
"fmt"
"net/http"
"gopkg.in/couchbase/gocb.v1"
)
// bucket reference - reuse as bucket reference in the application
var bucket *gocb.Bucket
// Create a struct for strongly typed query results
type TypedJSONAirport struct {
Inner struct {
Airport string `json:"airportname"`
City string `json:"city"`
Country string `json:"country"`
FAA string `json:"faa"`
Geo struct {
Alt int `json:"alt"`
Lat float64 `json:"lat"`
Lon float64 `json:"lon"`
} `json:"geo"`
} `json:"travel-sample"`
}
func queryOne(w http.ResponseWriter, r *http.Request) {
// Grab the parameter for the city we're looking for
search := r.URL.Query().Get("search")
// New query, a really generic one with high selectivity
myQuery := gocb.NewN1qlQuery("SELECT * FROM `travel-sample` " +
"WHERE name like '" + search + "%' OR airportname like '" + search + "%' ")
rows, err := bucket.ExecuteN1qlQuery(myQuery, nil)
if err != nil {
fmt.Println("ERROR EXECUTING N1QL QUERY:", err)
}
// Interface for handling streaming return values
var row interface{}
// Stream the first result only into the interface
err = rows.One(&row)
if err != nil {
fmt.Println("ERROR ITERATING QUERY RESULTS:", err)
}
// Marshal single result in interface
jsonOut, err := json.Marshal(row)
if err != nil {
fmt.Println("ERROR PROCESSING STREAMING OUTPUT:", err)
}
// Return the JSON
w.Write(jsonOut)
}
func queryUntyped(w http.ResponseWriter, r *http.Request) {
// Grab the parameter for the city we're looking for
search := r.URL.Query().Get("search")
// New query, a really generic one with high selectivity
myQuery := gocb.NewN1qlQuery("SELECT * FROM `travel-sample` " +
"WHERE name like '" + search + "%' OR airportname like '" + search + "%' ")
rows, err := bucket.ExecuteN1qlQuery(myQuery, nil)
if err != nil {
fmt.Println("ERROR EXECUTING N1QL QUERY:", err)
}
// Interfaces for handling streaming return values
var retValues []interface{}
var row interface{}
// Stream the values returned from the query into an untyped and unstructred
// array of interfaces
for rows.Next(&row) {
retValues = append(retValues, row)
}
// Marshal array of interfaces to JSON
jsonOut, err := json.Marshal(retValues)
if err != nil {
fmt.Println("ERROR PROCESSING STREAMING OUTPUT:", err)
}
// Return the JSON
w.Write(jsonOut)
}
func queryTyped(w http.ResponseWriter, r *http.Request) {
// Grab the parameter for the city we're looking for
search := r.URL.Query().Get("search")
// New query, a really generic one with high selectivity
myQuery := gocb.NewN1qlQuery("SELECT * FROM `travel-sample` " +
"WHERE name like '" + search + "%' OR airportname like '" + search + "%' ")
rows, err := bucket.ExecuteN1qlQuery(myQuery, nil)
if err != nil {
fmt.Println("ERROR EXECUTING N1QL QUERY:", err)
}
// Interfaces for handling streaming return values
var row TypedJSONAirport
var retValues []TypedJSONAirport
// Stream the values returned from the query into a typed array of structs
for rows.Next(&row) {
// Check if the current row has a value for FAA, if it does it's an airport
// and should be added to the return values
if row.Inner.FAA != "" {
retValues = append(retValues, row)
}
// Set the row to an empty struct, to prevent current values being added
// to the next row in the results collection returned by the query
row = TypedJSONAirport{}
}
// Marshal array of structs to JSON
bytes, err := json.Marshal(retValues)
if err != nil {
fmt.Println("ERROR PROCESSING STREAMING OUTPUT:", err)
}
// Return the JSON
w.Write(bytes)
}
func main() {
// Connect to Cluster
cluster, err := gocb.Connect("couchbase://127.0.0.1")
if err != nil {
fmt.Println("ERROR CONNECTING TO CLUSTER:", err)
}
// Open Bucket
bucket, err = cluster.OpenBucket("travel-sample", "")
if err != nil {
fmt.Println("ERROR OPENING BUCKET:", err)
}
// Inbound http handlers
http.Handle("/", http.FileServer(http.Dir("./public")))
http.HandleFunc("/api/query/untyped", queryUntyped)
http.HandleFunc("/api/query/typed", queryTyped)
http.HandleFunc("/api/query/one", queryOne)
fmt.Printf("Starting server on :3000\n")
http.ListenAndServe(":3000", nil)
}