adjust tests and client to comply with the new HTTP endpoints

This commit is contained in:
Travis 2017-04-18 14:12:12 -05:00
parent 63df926968
commit 95a546e138
8 changed files with 234 additions and 378 deletions

View file

@ -125,7 +125,6 @@ func (c *Client) Schema(ctx context.Context) ([]*DBInfo, error) {
func (c *Client) CreateDB(ctx context.Context, db string, opt DBOptions) error {
// Encode query request.
buf, err := json.Marshal(&postDBRequest{
DB: db,
Options: opt,
})
if err != nil {
@ -133,7 +132,7 @@ func (c *Client) CreateDB(ctx context.Context, db string, opt DBOptions) error {
}
// Create URL & HTTP request.
u := url.URL{Scheme: "http", Host: c.host, Path: "/db"}
u := url.URL{Scheme: "http", Host: c.host, Path: fmt.Sprintf("/db/%s", db)}
req, err := http.NewRequest("POST", u.String(), bytes.NewReader(buf))
if err != nil {
return err
@ -209,7 +208,6 @@ func (c *Client) ExecuteQuery(ctx context.Context, db, query string, allowRedire
// Encode query request.
buf, err := proto.Marshal(&internal.QueryRequest{
DB: db,
Query: query,
Remote: !allowRedirect,
})
@ -218,7 +216,11 @@ func (c *Client) ExecuteQuery(ctx context.Context, db, query string, allowRedire
}
// Create URL & HTTP request.
u := url.URL{Scheme: "http", Host: c.host, Path: "/query"}
u := url.URL{
Scheme: "http",
Host: c.host,
Path: fmt.Sprintf("/db/%s/query", db),
}
req, err := http.NewRequest("POST", u.String(), bytes.NewReader(buf))
if err != nil {
return nil, err
@ -664,8 +666,6 @@ func (c *Client) CreateFrame(ctx context.Context, db, frame string, opt FrameOpt
// Encode query request.
buf, err := json.Marshal(&postFrameRequest{
DB: db,
Frame: frame,
Options: opt,
})
if err != nil {
@ -673,7 +673,7 @@ func (c *Client) CreateFrame(ctx context.Context, db, frame string, opt FrameOpt
}
// Create URL & HTTP request.
u := url.URL{Scheme: "http", Host: c.host, Path: "/frame"}
u := url.URL{Scheme: "http", Host: c.host, Path: fmt.Sprintf("/db/%s/frame/%s", db, frame)}
req, err := http.NewRequest("POST", u.String(), bytes.NewReader(buf))
if err != nil {
return err
@ -711,11 +711,9 @@ func (c *Client) RestoreFrame(ctx context.Context, host, db, frame string) error
u := url.URL{
Scheme: "http",
Host: c.Host(),
Path: "/frame/restore",
Path: fmt.Sprintf("/db/%s/frame/%s/restore", db, frame),
RawQuery: url.Values{
"host": {host},
"db": {db},
"frame": {frame},
"host": {host},
}.Encode(),
}
@ -747,11 +745,7 @@ func (c *Client) FrameViews(ctx context.Context, db, frame string) ([]string, er
u := url.URL{
Scheme: "http",
Host: c.host,
Path: "/frame/views",
RawQuery: (&url.Values{
"db": {db},
"frame": {frame},
}).Encode(),
Path: fmt.Sprintf("/db/%s/frame/%s/views", db, frame),
}
req, err := http.NewRequest("GET", u.String(), nil)
if err != nil {
@ -879,14 +873,13 @@ func (c *Client) BlockData(ctx context.Context, db, frame, view string, slice ui
// ProfileAttrDiff returns data from differing blocks on a remote host.
func (c *Client) ProfileAttrDiff(ctx context.Context, db string, blks []AttrBlock) (map[uint64]map[string]interface{}, error) {
u := url.URL{
Scheme: "http",
Host: c.host,
Path: "/db/attr/diff",
RawQuery: url.Values{"db": {db}}.Encode(),
Scheme: "http",
Host: c.host,
Path: fmt.Sprintf("/db/%s/attr/diff", db),
}
// Encode request.
buf, err := json.Marshal(postDBAttrDiffRequest{DB: db, Blocks: blks})
buf, err := json.Marshal(postDBAttrDiffRequest{Blocks: blks})
if err != nil {
return nil, err
}
@ -923,14 +916,13 @@ func (c *Client) ProfileAttrDiff(ctx context.Context, db string, blks []AttrBloc
// BitmapAttrDiff returns data from differing blocks on a remote host.
func (c *Client) BitmapAttrDiff(ctx context.Context, db, frame string, blks []AttrBlock) (map[uint64]map[string]interface{}, error) {
u := url.URL{
Scheme: "http",
Host: c.host,
Path: "/frame/attr/diff",
RawQuery: url.Values{"db": {db}, "frame": {frame}}.Encode(),
Scheme: "http",
Host: c.host,
Path: fmt.Sprintf("/db/%s/frame/%s/attr/diff", db, frame),
}
// Encode request.
buf, err := json.Marshal(postFrameAttrDiffRequest{DB: db, Frame: frame, Blocks: blks})
buf, err := json.Marshal(postFrameAttrDiffRequest{Blocks: blks})
if err != nil {
return nil, err
}

View file

@ -944,7 +944,6 @@ func (e *Executor) executeSetProfileAttrs(ctx context.Context, db string, c *pql
func (e *Executor) exec(ctx context.Context, node *Node, db string, q *pql.Query, slices []uint64, opt *ExecOptions) (results []interface{}, err error) {
// Encode request object.
pbreq := &internal.QueryRequest{
DB: db,
Query: q.String(),
Slices: slices,
Remote: true,
@ -958,7 +957,7 @@ func (e *Executor) exec(ctx context.Context, node *Node, db string, q *pql.Query
req, err := http.NewRequest("POST", (&url.URL{
Scheme: "http",
Host: node.Host,
Path: "/query",
Path: fmt.Sprintf("/db/%s/query", db),
}).String(), bytes.NewReader(buf))
if err != nil {
return nil, err

View file

@ -56,24 +56,23 @@ func NewHandler() *Handler {
func NewRouter(handler *Handler) *mux.Router {
router := mux.NewRouter()
router.HandleFunc("/db", handler.handleGetDB).Methods("GET")
router.HandleFunc("/db", handler.handlePostDB).Methods("POST")
router.HandleFunc("/db", handler.handleDeleteDB).Methods("DELETE")
router.HandleFunc("/db/{db}", handler.handleGetSingleDB).Methods("GET")
router.HandleFunc("/db", handler.handleGetDBs).Methods("GET")
router.HandleFunc("/db/{db}", handler.handleGetDB).Methods("GET")
router.HandleFunc("/db/{db}", handler.handlePostDB).Methods("POST")
router.HandleFunc("/db/{db}", handler.handleDeleteDB).Methods("DELETE")
router.HandleFunc("/db/{db}/attr/diff", handler.handlePostDBAttrDiff).Methods("POST")
//router.HandleFunc("/db/{db}/frame", handler.handleGetFrames).Methods("GET") // Not implemented.
router.HandleFunc("/db/{db}/frame/{frame}", handler.handlePostFrame).Methods("POST")
router.HandleFunc("/db/{db}/frame/{frame}", handler.handleDeleteFrame).Methods("DELETE")
router.HandleFunc("/db/{db}/query", handler.handlePostQuery).Methods("POST")
router.HandleFunc("/db/time_quantum", handler.handlePatchDBTimeQuantum).Methods("PATCH")
router.HandleFunc("/db/{db}/frame/{frame}/attr/diff", handler.handlePostFrameAttrDiff).Methods("POST")
router.HandleFunc("/db/{db}/frame/{frame}/restore", handler.handlePostFrameRestore).Methods("POST")
router.HandleFunc("/db/{db}/frame/{frame}/time-quantum", handler.handlePatchFrameTimeQuantum).Methods("PATCH")
router.HandleFunc("/db/{db}/frame/{frame}/views", handler.handleGetFrameViews).Methods("GET")
router.HandleFunc("/db/{db}/time-quantum", handler.handlePatchDBTimeQuantum).Methods("PATCH")
router.HandleFunc("/db/attr/diff", handler.handlePostDBAttrDiff).Methods("POST")
router.PathPrefix("/debug/pprof/").Handler(http.DefaultServeMux).Methods("GET")
router.HandleFunc("/debug/vars", handler.handleExpvar).Methods("GET")
router.HandleFunc("/export", handler.handleGetExport).Methods("GET")
router.HandleFunc("/frame", handler.handlePostFrame).Methods("POST")
router.HandleFunc("/frame", handler.handleDeleteFrame).Methods("DELETE")
router.HandleFunc("/frame/attr/diff", handler.handlePostFrameAttrDiff).Methods("POST")
router.HandleFunc("/frame/restore", handler.handlePostFrameRestore).Methods("POST")
router.HandleFunc("/frame/time_quantum", handler.handlePatchFrameTimeQuantum).Methods("PATCH")
router.HandleFunc("/frame/views", handler.handleGetFrameViews).Methods("GET")
router.HandleFunc("/fragment/block/data", handler.handleGetFragmentBlockData).Methods("GET")
router.HandleFunc("/fragment/blocks", handler.handleGetFragmentBlocks).Methods("GET")
router.HandleFunc("/fragment/data", handler.handleGetFragmentData).Methods("GET")
@ -81,7 +80,6 @@ func NewRouter(handler *Handler) *mux.Router {
router.HandleFunc("/fragment/nodes", handler.handleGetFragmentNodes).Methods("GET")
router.HandleFunc("/import", handler.handlePostImport).Methods("POST")
router.HandleFunc("/nodes", handler.handleGetNodes).Methods("GET")
router.HandleFunc("/query", handler.handlePostQuery).Methods("POST")
router.HandleFunc("/schema", handler.handleGetSchema).Methods("GET")
router.HandleFunc("/slices/max", handler.handleGetSliceMax).Methods("GET")
router.HandleFunc("/version", handler.handleGetVersion).Methods("GET")
@ -90,7 +88,7 @@ func NewRouter(handler *Handler) *mux.Router {
// Ideally this would be automatic, as described in this (wontfix) ticket:
// https://github.com/gorilla/mux/issues/6
// For now we just do it for the most commonly used handler, /query
router.HandleFunc("/query", handler.methodNotAllowedHandler).Methods("GET")
router.HandleFunc("/db/{db}/query", handler.methodNotAllowedHandler).Methods("GET")
return router
}
@ -119,6 +117,8 @@ type getSchemaResponse struct {
// handlePostQuery handles /query requests.
func (h *Handler) handlePostQuery(w http.ResponseWriter, r *http.Request) {
dbName := mux.Vars(r)["db"]
// Parse incoming request.
req, err := h.readQueryRequest(r)
if err != nil {
@ -141,7 +141,7 @@ func (h *Handler) handlePostQuery(w http.ResponseWriter, r *http.Request) {
}
// Execute the query.
results, err := h.Executor.Execute(r.Context(), req.DB, q, req.Slices, opt)
results, err := h.Executor.Execute(r.Context(), dbName, q, req.Slices, opt)
resp := &QueryResponse{Results: results, Err: err}
// Fill profile attributes if requested.
@ -157,7 +157,7 @@ func (h *Handler) handlePostQuery(w http.ResponseWriter, r *http.Request) {
}
// Retrieve profile attributes across all calls.
profiles, err := h.readProfiles(h.Index.DB(req.DB), profileIDs)
profiles, err := h.readProfiles(h.Index.DB(dbName), profileIDs)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
h.writeQueryResponse(w, r, &QueryResponse{Err: err})
@ -203,71 +203,33 @@ type sliceMaxResponse struct {
MaxSlices map[string]uint64 `json:"MaxSlices"`
}
// handleGetDB handles GET /db request.
// handleGetDBs handles GET /db request.
func (h *Handler) handleGetDBs(w http.ResponseWriter, r *http.Request) {
h.handleGetSchema(w, r)
}
// handleGetDB handles GET /db/<dbname> requests.
func (h *Handler) handleGetDB(w http.ResponseWriter, r *http.Request) {
if r.URL.Query().Get("schema") != "" {
h.handleGetSchema(w, r)
return
}
var dbs []map[string]string
for _, db := range h.Index.DBs() {
dbs = append(dbs, map[string]string{"name": db.Name()})
}
if err := json.NewEncoder(w).Encode(getDBResponse{
DBs: dbs,
}); err != nil {
h.logger().Printf("write schema response error: %s", err)
}
}
type getDBResponse struct {
DBs []map[string]string `json:"dbs"`
}
// handleGetSingleDB handles GET /db/<dbname> requests.
func (h *Handler) handleGetSingleDB(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
dbName := vars["db"]
dbName := mux.Vars(r)["db"]
db := h.Index.DB(dbName)
if db == nil {
http.Error(w, ErrDatabaseNotFound.Error(), http.StatusNotFound)
return
}
if err := json.NewEncoder(w).Encode(getSingleDBResponse{
if err := json.NewEncoder(w).Encode(getDBResponse{
map[string]string{"name": db.Name()},
}); err != nil {
h.logger().Printf("write response error: %s", err)
}
}
type getSingleDBResponse struct {
Db map[string]string `json:"db"`
type getDBResponse struct {
DB map[string]string `json:"db"`
}
// handlePostDB handles POST /db request.
func (h *Handler) handlePostDB(w http.ResponseWriter, r *http.Request) {
// Decode request.
var req postDBRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
// Create database.
_, err := h.Index.CreateDB(req.DB, req.Options)
if err == ErrDatabaseExists {
http.Error(w, err.Error(), http.StatusConflict)
return
} else if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// Encode response.
if err := json.NewEncoder(w).Encode(postDBResponse{}); err != nil {
h.logger().Printf("response encoding error: %s", err)
}
type postDBRequest struct {
Options DBOptions `json:"options"`
}
// Custom Unmarshal JSON to validate request body when creating a new database
@ -278,12 +240,6 @@ func (p *postDBRequest) UnmarshalJSON(b []byte) error {
}
for key, value := range data {
switch key {
case "db":
val, ok := data["db"].(string)
if !ok {
return errors.New("db required and must be a string")
}
p.DB = val
case "options":
value, err := validateOptions(data, "columnLabel")
if err != nil {
@ -327,29 +283,14 @@ func validateOptions(data map[string]interface{}, field string) (string, error)
return optionValue, nil
}
type postDBRequest struct {
DB string `json:"db"`
Options DBOptions `json:"options"`
}
type postDBResponse struct{}
// handleDeleteDB handles DELETE /db request.
func (h *Handler) handleDeleteDB(w http.ResponseWriter, r *http.Request) {
// Get db name from URL or Querystring if does not exist
var db string
if db = mux.Vars(r)["db"]; db == "" {
// Decode request.
var req deleteDBRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
db = req.DB
}
dbName := mux.Vars(r)["db"]
// Delete database from the index.
if err := h.Index.DeleteDB(db); err != nil {
if err := h.Index.DeleteDB(dbName); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
@ -360,48 +301,55 @@ func (h *Handler) handleDeleteDB(w http.ResponseWriter, r *http.Request) {
}
}
type deleteDBRequest struct {
DB string `json:"db"`
}
type deleteDBResponse struct{}
// handlePostDB handles POST /db request.
func (h *Handler) handlePostDB(w http.ResponseWriter, r *http.Request) {
dbName := mux.Vars(r)["db"]
// Decode request.
var req postDBRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
// Create database.
_, err := h.Index.CreateDB(dbName, req.Options)
if err == ErrDatabaseExists {
http.Error(w, err.Error(), http.StatusConflict)
return
} else if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// Encode response.
if err := json.NewEncoder(w).Encode(postDBResponse{}); err != nil {
h.logger().Printf("response encoding error: %s", err)
}
}
// handlePatchDBTimeQuantum handles PATCH /db/time_quantum request.
func (h *Handler) handlePatchDBTimeQuantum(w http.ResponseWriter, r *http.Request) {
// Get db name from URL or Querystring if does not exist
var db string
var timeQuantum string
if db = mux.Vars(r)["db"]; db == "" {
// Decode request.
var req deprecatedPatchDBTimeQuantumRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
db = req.DB
timeQuantum = req.TimeQuantum
} else {
// Decode request.
var req patchDBTimeQuantumRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
timeQuantum = req.TimeQuantum
dbName := mux.Vars(r)["db"]
// Decode request.
var req patchDBTimeQuantumRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
log.Println(db)
log.Println(timeQuantum)
// Validate quantum.
tq, err := ParseTimeQuantum(timeQuantum)
tq, err := ParseTimeQuantum(req.TimeQuantum)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
// Retrieve database by name.
database := h.Index.DB(db)
database := h.Index.DB(dbName)
if database == nil {
http.Error(w, ErrDatabaseNotFound.Error(), http.StatusNotFound)
return
@ -419,19 +367,16 @@ func (h *Handler) handlePatchDBTimeQuantum(w http.ResponseWriter, r *http.Reques
}
}
type deprecatedPatchDBTimeQuantumRequest struct {
DB string `json:"db"`
TimeQuantum string `json:"time_quantum"`
}
type patchDBTimeQuantumRequest struct {
TimeQuantum string `json:"time-quantum"`
TimeQuantum string `json:"time_quantum"`
}
type patchDBTimeQuantumResponse struct{}
// handlePostDBAttrDiff handles POST /db/attr/diff requests.
func (h *Handler) handlePostDBAttrDiff(w http.ResponseWriter, r *http.Request) {
dbName := mux.Vars(r)["db"]
// Decode request.
var req postDBAttrDiffRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
@ -440,7 +385,7 @@ func (h *Handler) handlePostDBAttrDiff(w http.ResponseWriter, r *http.Request) {
}
// Retrieve database from index.
db := h.Index.DB(req.DB)
db := h.Index.DB(dbName)
if db == nil {
http.Error(w, ErrDatabaseNotFound.Error(), http.StatusNotFound)
return
@ -478,7 +423,6 @@ func (h *Handler) handlePostDBAttrDiff(w http.ResponseWriter, r *http.Request) {
}
type postDBAttrDiffRequest struct {
DB string `json:"db"`
Blocks []AttrBlock `json:"blocks"`
}
@ -488,6 +432,8 @@ type postDBAttrDiffResponse struct {
// handlePostFrame handles POST /frame request.
func (h *Handler) handlePostFrame(w http.ResponseWriter, r *http.Request) {
dbName := mux.Vars(r)["db"]
frameName := mux.Vars(r)["frame"]
// Decode request.
var req postFrameRequest
@ -497,14 +443,14 @@ func (h *Handler) handlePostFrame(w http.ResponseWriter, r *http.Request) {
}
// Find database.
db := h.Index.DB(req.DB)
db := h.Index.DB(dbName)
if db == nil {
http.Error(w, ErrDatabaseNotFound.Error(), http.StatusNotFound)
return
}
// Create frame.
_, err := db.CreateFrame(req.Frame, req.Options)
_, err := db.CreateFrame(frameName, req.Options)
if err == ErrFrameExists {
http.Error(w, err.Error(), http.StatusConflict)
return
@ -527,19 +473,6 @@ func (p *postFrameRequest) UnmarshalJSON(b []byte) error {
}
for key, value := range data {
switch key {
case "db":
val, ok := data["db"].(string)
if !ok {
return errors.New("db required and must be a string")
}
p.DB = val
case "frame":
val, ok := data["frame"].(string)
if !ok {
return errors.New("frame required and must be a string")
}
p.Frame = val
case "options":
value, err := validateOptions(data, "rowLabel")
if err != nil {
@ -550,7 +483,6 @@ func (p *postFrameRequest) UnmarshalJSON(b []byte) error {
} else {
p.Options = FrameOptions{RowLabel: value}
}
default:
return fmt.Errorf("Unknown key: {%v:%v}", key, value)
}
@ -560,8 +492,6 @@ func (p *postFrameRequest) UnmarshalJSON(b []byte) error {
}
type postFrameRequest struct {
DB string `json:"db"`
Frame string `json:"frame"`
Options FrameOptions `json:"options"`
}
@ -569,15 +499,11 @@ type postFrameResponse struct{}
// handleDeleteFrame handles DELETE /frame request.
func (h *Handler) handleDeleteFrame(w http.ResponseWriter, r *http.Request) {
// Decode request.
var req deleteFrameRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
dbName := mux.Vars(r)["db"]
frameName := mux.Vars(r)["frame"]
// Find database.
db := h.Index.DB(req.DB)
db := h.Index.DB(dbName)
if db == nil {
if err := json.NewEncoder(w).Encode(deleteDBResponse{}); err != nil {
h.logger().Printf("response encoding error: %s", err)
@ -586,7 +512,7 @@ func (h *Handler) handleDeleteFrame(w http.ResponseWriter, r *http.Request) {
}
// Delete frame from the database.
if err := db.DeleteFrame(req.Frame); err != nil {
if err := db.DeleteFrame(frameName); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
@ -597,15 +523,13 @@ func (h *Handler) handleDeleteFrame(w http.ResponseWriter, r *http.Request) {
}
}
type deleteFrameRequest struct {
DB string `json:"db"`
Frame string `json:"frame"`
}
type deleteFrameResponse struct{}
// handlePatchFrameTimeQuantum handles PATCH /frame/time_quantum request.
func (h *Handler) handlePatchFrameTimeQuantum(w http.ResponseWriter, r *http.Request) {
dbName := mux.Vars(r)["db"]
frameName := mux.Vars(r)["frame"]
// Decode request.
var req patchFrameTimeQuantumRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
@ -621,7 +545,7 @@ func (h *Handler) handlePatchFrameTimeQuantum(w http.ResponseWriter, r *http.Req
}
// Retrieve database by name.
f := h.Index.Frame(req.DB, req.Frame)
f := h.Index.Frame(dbName, frameName)
if f == nil {
http.Error(w, ErrFrameNotFound.Error(), http.StatusNotFound)
return
@ -640,8 +564,6 @@ func (h *Handler) handlePatchFrameTimeQuantum(w http.ResponseWriter, r *http.Req
}
type patchFrameTimeQuantumRequest struct {
DB string `json:"db"`
Frame string `json:"frame"`
TimeQuantum string `json:"time_quantum"`
}
@ -649,11 +571,11 @@ type patchFrameTimeQuantumResponse struct{}
// handleGetFrameViews handles GET /frame/views request.
func (h *Handler) handleGetFrameViews(w http.ResponseWriter, r *http.Request) {
q := r.URL.Query()
db, frame := q.Get("db"), q.Get("frame")
dbName := mux.Vars(r)["db"]
frameName := mux.Vars(r)["frame"]
// Retrieve views.
f := h.Index.Frame(db, frame)
f := h.Index.Frame(dbName, frameName)
if f == nil {
http.Error(w, ErrFrameNotFound.Error(), http.StatusNotFound)
return
@ -678,6 +600,9 @@ type getFrameViewsResponse struct {
// handlePostFrameAttrDiff handles POST /frame/attr/diff requests.
func (h *Handler) handlePostFrameAttrDiff(w http.ResponseWriter, r *http.Request) {
dbName := mux.Vars(r)["db"]
frameName := mux.Vars(r)["frame"]
// Decode request.
var req postFrameAttrDiffRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
@ -686,7 +611,7 @@ func (h *Handler) handlePostFrameAttrDiff(w http.ResponseWriter, r *http.Request
}
// Retrieve database from index.
f := h.Index.Frame(req.DB, req.Frame)
f := h.Index.Frame(dbName, frameName)
if f == nil {
http.Error(w, ErrFrameNotFound.Error(), http.StatusNotFound)
return
@ -724,8 +649,6 @@ func (h *Handler) handlePostFrameAttrDiff(w http.ResponseWriter, r *http.Request
}
type postFrameAttrDiffRequest struct {
DB string `json:"db"`
Frame string `json:"frame"`
Blocks []AttrBlock `json:"blocks"`
}
@ -810,14 +733,7 @@ func (h *Handler) readURLQueryRequest(r *http.Request) (*QueryRequest, error) {
quantum = v
}
// Get db name from URL or Querystring if does not exist
var db string
if db = mux.Vars(r)["db"]; db == "" {
db = q.Get("db")
}
return &QueryRequest{
DB: db,
Query: query,
Slices: slices,
Profiles: q.Get("profiles") == "true",
@ -1134,20 +1050,16 @@ type getFragmentBlocksResponse struct {
// handlePostFrameRestore handles POST /frame/restore requests.
func (h *Handler) handlePostFrameRestore(w http.ResponseWriter, r *http.Request) {
dbName := mux.Vars(r)["db"]
frameName := mux.Vars(r)["frame"]
q := r.URL.Query()
host := q.Get("host")
db, frame := q.Get("db"), q.Get("frame")
// Validate query parameters.
if host == "" {
http.Error(w, "host required", http.StatusBadRequest)
return
} else if db == "" {
http.Error(w, "db required", http.StatusBadRequest)
return
} else if frame == "" {
http.Error(w, "frame required", http.StatusBadRequest)
return
}
// Create a client for the remote cluster.
@ -1165,24 +1077,23 @@ func (h *Handler) handlePostFrameRestore(w http.ResponseWriter, r *http.Request)
}
// Retrieve frame.
f := h.Index.Frame(db, frame)
f := h.Index.Frame(dbName, frameName)
if f == nil {
http.Error(w, ErrFrameNotFound.Error(), http.StatusNotFound)
return
}
// Retrieve list of all views.
views, err := client.FrameViews(r.Context(), db, frame)
views, err := client.FrameViews(r.Context(), dbName, frameName)
if err != nil {
http.Error(w, "cannot retrieve frame views: "+err.Error(), http.StatusInternalServerError)
return
}
// Loop over each slice and import it if this node owns it.
//travis
for slice := uint64(0); slice <= maxSlices[db]; slice++ {
for slice := uint64(0); slice <= maxSlices[dbName]; slice++ {
// Ignore this slice if we don't own it.
if !h.Cluster.OwnsFragment(h.Host, db, slice) {
if !h.Cluster.OwnsFragment(h.Host, dbName, slice) {
continue
}
@ -1203,7 +1114,7 @@ func (h *Handler) handlePostFrameRestore(w http.ResponseWriter, r *http.Request)
}
// Stream backup from remote node.
rd, err := client.BackupSlice(r.Context(), db, frame, view, slice)
rd, err := client.BackupSlice(r.Context(), dbName, frameName, view, slice)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@ -1290,7 +1201,6 @@ type QueryRequest struct {
func decodeQueryRequest(pb *internal.QueryRequest) *QueryRequest {
req := &QueryRequest{
DB: pb.DB,
Query: pb.Query,
Slices: pb.Slices,
Profiles: pb.Profiles,

View file

@ -13,12 +13,11 @@ func TestPostDBRequestUnmarshalJSON(t *testing.T) {
expected postDBRequest
err string
}{
{json: `{"db": "d", "options": {}}`, expected: postDBRequest{DB: "d", Options: DBOptions{}}},
{json: `{"db": 1, "options": {}}`, err: "db required and must be a string"},
{json: `{"db": "d", "options": 4}`, err: "options is not map[string]interface{}"},
{json: `{"db": "d", "option": {}}`, err: "Unknown key: option:map[]"},
{json: `{"db": "d", "options": {"columnLabel": "test"}}`, expected: postDBRequest{DB: "d", Options: DBOptions{ColumnLabel: "test"}}},
{json: `{"db": "d", "options": {"columnLabl": "test"}}`, err: "invalid key for options {columnLabl:test}"},
{json: `{"options": {}}`, expected: postDBRequest{Options: DBOptions{}}},
{json: `{"options": 4}`, err: "options is not map[string]interface{}"},
{json: `{"option": {}}`, err: "Unknown key: option:map[]"},
{json: `{"options": {"columnLabel": "test"}}`, expected: postDBRequest{Options: DBOptions{ColumnLabel: "test"}}},
{json: `{"options": {"columnLabl": "test"}}`, err: "invalid key for options {columnLabl:test}"},
}
for _, test := range tests {
actual := &postDBRequest{}
@ -50,12 +49,11 @@ func TestPostFrameRequestUnmarshalJSON(t *testing.T) {
expected postFrameRequest
err string
}{
{json: `{"db": "d", "frame":"f", "options": {}}`, expected: postFrameRequest{DB: "d", Frame: "f", Options: FrameOptions{}}},
{json: `{"db": "d", "options": {}}`, err: "frame required and must be a string"},
{json: `{"db": "d", "frame":"f", "options": 4}`, err: "options is not map[string]interface{}"},
{json: `{"db": "d", "frame":"f", "option": {}}`, err: "Unknown key: {option:map[]}"},
{json: `{"db": "d", "frame":"f", "options": {"rowLabel": "test"}}`, expected: postFrameRequest{DB: "d", Frame: "f", Options: FrameOptions{RowLabel: "test"}}},
{json: `{"db": "d", "frame":"f", "options": {"rowLabl": "test"}}`, err: "invalid key for options {rowLabl:test}"},
{json: `{"options": {}}`, expected: postFrameRequest{Options: FrameOptions{}}},
{json: `{"options": 4}`, err: "options is not map[string]interface{}"},
{json: `{"option": {}}`, err: "Unknown key: {option:map[]}"},
{json: `{"options": {"rowLabel": "test"}}`, expected: postFrameRequest{Options: FrameOptions{RowLabel: "test"}}},
{json: `{"options": {"rowLabl": "test"}}`, err: "invalid key for options {rowLabl:test}"},
}
for _, test := range tests {
actual := &postFrameRequest{}

View file

@ -143,7 +143,7 @@ func TestHandler_Query_Args_URL(t *testing.T) {
}
w := httptest.NewRecorder()
h.ServeHTTP(w, MustNewHTTPRequest("POST", "/query?db=db0&slices=0,1", strings.NewReader("Count( Bitmap( id=100))")))
h.ServeHTTP(w, MustNewHTTPRequest("POST", "/db/db0/query?slices=0,1", strings.NewReader("Count( Bitmap( id=100))")))
if w.Code != http.StatusOK {
t.Fatalf("unexpected status code: %d", w.Code, w.Body.String())
} else if body := w.Body.String(); body != `{"results":[100]}`+"\n" {
@ -167,7 +167,6 @@ func TestHandler_Query_Args_Protobuf(t *testing.T) {
// Generate request body.
reqBody, err := proto.Marshal(&internal.QueryRequest{
DB: "db0",
Query: "Count(Bitmap(id=100))",
Slices: []uint64{0, 1},
})
@ -176,7 +175,7 @@ func TestHandler_Query_Args_Protobuf(t *testing.T) {
}
// Generate protobuf request.
req := MustNewHTTPRequest("POST", "/query", bytes.NewReader(reqBody))
req := MustNewHTTPRequest("POST", "/db/db0/query", bytes.NewReader(reqBody))
req.Header.Set("Content-Type", "application/x-protobuf")
w := httptest.NewRecorder()
@ -189,7 +188,7 @@ func TestHandler_Query_Args_Protobuf(t *testing.T) {
// Ensure the handler returns an error when parsing bad arguments.
func TestHandler_Query_Args_Err(t *testing.T) {
w := httptest.NewRecorder()
NewHandler().ServeHTTP(w, MustNewHTTPRequest("POST", "/query?db=db0&slices=a,b", strings.NewReader("Bitmap(id=100)")))
NewHandler().ServeHTTP(w, MustNewHTTPRequest("POST", "/db/db0/query?slices=a,b", strings.NewReader("Bitmap(id=100)")))
if w.Code != http.StatusBadRequest {
t.Fatalf("unexpected status code: %d", w.Code)
} else if body := w.Body.String(); body != `{"error":"invalid slice argument"}`+"\n" {
@ -205,7 +204,7 @@ func TestHandler_Query_Uint64_JSON(t *testing.T) {
}
w := httptest.NewRecorder()
h.ServeHTTP(w, MustNewHTTPRequest("POST", "/query?db=db0&slices=0,1", strings.NewReader("Count( Bitmap( id=100))")))
h.ServeHTTP(w, MustNewHTTPRequest("POST", "/db/db0/query?slices=0,1", strings.NewReader("Count( Bitmap( id=100))")))
if w.Code != http.StatusOK {
t.Fatalf("unexpected status code: %d", w.Code)
} else if body := w.Body.String(); body != `{"results":[100]}`+"\n" {
@ -221,7 +220,7 @@ func TestHandler_Query_Uint64_Protobuf(t *testing.T) {
}
w := httptest.NewRecorder()
r := MustNewHTTPRequest("POST", "/query", strings.NewReader("Count(Bitmap(id=100))"))
r := MustNewHTTPRequest("POST", "/db/d/query", strings.NewReader("Count(Bitmap(id=100))"))
r.Header.Set("Accept", "application/x-protobuf")
h.ServeHTTP(w, r)
if w.Code != http.StatusOK {
@ -246,7 +245,7 @@ func TestHandler_Query_Bitmap_JSON(t *testing.T) {
}
w := httptest.NewRecorder()
h.ServeHTTP(w, MustNewHTTPRequest("POST", "/query?db=d", strings.NewReader("Bitmap(id=100)")))
h.ServeHTTP(w, MustNewHTTPRequest("POST", "/db/d/query", strings.NewReader("Bitmap(id=100)")))
if w.Code != http.StatusOK {
t.Fatalf("unexpected status code: %d", w.Code)
} else if body := w.Body.String(); body != `{"results":[{"attrs":{"a":"b","c":1,"d":true},"bits":[1,3,66,1048577]}]}`+"\n" {
@ -278,7 +277,7 @@ func TestHandler_Query_Bitmap_Profiles_JSON(t *testing.T) {
}
w := httptest.NewRecorder()
h.ServeHTTP(w, MustNewHTTPRequest("POST", "/query?db=d&profiles=true", strings.NewReader("Bitmap(id=100)")))
h.ServeHTTP(w, MustNewHTTPRequest("POST", "/db/d/query?profiles=true", strings.NewReader("Bitmap(id=100)")))
if w.Code != http.StatusOK {
t.Fatalf("unexpected status code: %d", w.Code)
} else if body := w.Body.String(); body != `{"results":[{"attrs":{"a":"b","c":1,"d":true},"bits":[1,3,66,1048577]}],"profiles":[{"id":3,"attrs":{"x":"y"}},{"id":66,"attrs":{"y":123,"z":false}}]}`+"\n" {
@ -296,7 +295,7 @@ func TestHandler_Query_Bitmap_Protobuf(t *testing.T) {
}
w := httptest.NewRecorder()
r := MustNewHTTPRequest("POST", "/query", strings.NewReader("Bitmap(id=100)"))
r := MustNewHTTPRequest("POST", "/db/d/query", strings.NewReader("Bitmap(id=100)"))
r.Header.Set("Accept", "application/x-protobuf")
h.ServeHTTP(w, r)
if w.Code != http.StatusOK {
@ -342,7 +341,6 @@ func TestHandler_Query_Bitmap_Profiles_Protobuf(t *testing.T) {
// Encode request body.
buf, err := proto.Marshal(&internal.QueryRequest{
DB: "d",
Query: "Bitmap(id=100)",
Profiles: true,
})
@ -351,7 +349,7 @@ func TestHandler_Query_Bitmap_Profiles_Protobuf(t *testing.T) {
}
w := httptest.NewRecorder()
r := MustNewHTTPRequest("POST", "/query", bytes.NewReader(buf))
r := MustNewHTTPRequest("POST", "/db/d/query", bytes.NewReader(buf))
r.Header.Set("Content-Type", "application/x-protobuf")
r.Header.Set("Accept", "application/x-protobuf")
h.ServeHTTP(w, r)
@ -397,7 +395,7 @@ func TestHandler_Query_Pairs_JSON(t *testing.T) {
}
w := httptest.NewRecorder()
h.ServeHTTP(w, MustNewHTTPRequest("POST", "/query", strings.NewReader(`TopN(frame=x, n=2)`)))
h.ServeHTTP(w, MustNewHTTPRequest("POST", "/db/d/query", strings.NewReader(`TopN(frame=x, n=2)`)))
if w.Code != http.StatusOK {
t.Fatalf("unexpected status code: %d", w.Code)
} else if body := w.Body.String(); body != `{"results":[[{"id":1,"count":2},{"id":3,"count":4}]]}`+"\n" {
@ -416,7 +414,7 @@ func TestHandler_Query_Pairs_Protobuf(t *testing.T) {
}
w := httptest.NewRecorder()
r := MustNewHTTPRequest("POST", "/query", strings.NewReader(`TopN(frame=x, n=2)`))
r := MustNewHTTPRequest("POST", "/db/d/query", strings.NewReader(`TopN(frame=x, n=2)`))
r.Header.Set("Accept", "application/x-protobuf")
h.ServeHTTP(w, r)
if w.Code != http.StatusOK {
@ -439,7 +437,7 @@ func TestHandler_Query_Err_JSON(t *testing.T) {
}
w := httptest.NewRecorder()
h.ServeHTTP(w, MustNewHTTPRequest("POST", "/query", strings.NewReader(`Bitmap(id=100)`)))
h.ServeHTTP(w, MustNewHTTPRequest("POST", "/db/d/query", strings.NewReader(`Bitmap(id=100)`)))
if w.Code != http.StatusInternalServerError {
t.Fatalf("unexpected status code: %d", w.Code)
} else if body := w.Body.String(); body != `{"error":"marker"}`+"\n" {
@ -455,7 +453,7 @@ func TestHandler_Query_Err_Protobuf(t *testing.T) {
}
w := httptest.NewRecorder()
r := MustNewHTTPRequest("POST", "/query", strings.NewReader(`TopN(frame=x, n=2)`))
r := MustNewHTTPRequest("POST", "/db/d/query", strings.NewReader(`TopN(frame=x, n=2)`))
r.Header.Set("Accept", "application/x-protobuf")
h.ServeHTTP(w, r)
if w.Code != http.StatusInternalServerError {
@ -473,7 +471,7 @@ func TestHandler_Query_Err_Protobuf(t *testing.T) {
// Ensure the handler returns "method not allowed" for non-POST queries.
func TestHandler_Query_MethodNotAllowed(t *testing.T) {
w := httptest.NewRecorder()
NewHandler().ServeHTTP(w, MustNewHTTPRequest("GET", "/query", nil))
NewHandler().ServeHTTP(w, MustNewHTTPRequest("GET", "/db/d/query", nil))
if w.Code != http.StatusMethodNotAllowed {
t.Fatalf("invalid status: %d", w.Code)
}
@ -483,7 +481,7 @@ func TestHandler_Query_MethodNotAllowed(t *testing.T) {
func TestHandler_Query_ErrParse(t *testing.T) {
h := NewHandler()
w := httptest.NewRecorder()
h.ServeHTTP(w, MustNewHTTPRequest("POST", "/query?db=db0&slices=0,1", strings.NewReader("bad_fn(")))
h.ServeHTTP(w, MustNewHTTPRequest("POST", "/db/db0/query?slices=0,1", strings.NewReader("bad_fn(")))
if w.Code != http.StatusBadRequest {
t.Fatalf("unexpected status code: %d", w.Code)
} else if body := w.Body.String(); body != `{"error":"expected comma, right paren, or identifier, found \"\" occurred at line 1, char 8"}`+"\n" {
@ -506,7 +504,7 @@ func TestHandler_DB_Delete(t *testing.T) {
}
// Send request to delete database.
resp, err := http.DefaultClient.Do(MustNewHTTPRequest("DELETE", s.URL+"/db", strings.NewReader(`{"db":"d"}`)))
resp, err := http.DefaultClient.Do(MustNewHTTPRequest("DELETE", s.URL+"/db/d", strings.NewReader("")))
if err != nil {
t.Fatal(err)
}
@ -539,7 +537,7 @@ func TestHandler_DeleteFrame(t *testing.T) {
h := NewHandler()
h.Index = idx.Index
w := httptest.NewRecorder()
h.ServeHTTP(w, MustNewHTTPRequest("DELETE", "/frame", strings.NewReader(`{"db":"d0","frame":"f1"}`)))
h.ServeHTTP(w, MustNewHTTPRequest("DELETE", "/db/d0/frame/f1", strings.NewReader("")))
if w.Code != http.StatusOK {
t.Fatalf("unexpected status code: %d", w.Code)
} else if body := w.Body.String(); body != `{}`+"\n" {
@ -558,7 +556,7 @@ func TestHandler_SetDBTimeQuantum(t *testing.T) {
h := NewHandler()
h.Index = idx.Index
w := httptest.NewRecorder()
h.ServeHTTP(w, MustNewHTTPRequest("PATCH", "/db/time_quantum", strings.NewReader(`{"db":"d0","time_quantum":"ymdh"}`)))
h.ServeHTTP(w, MustNewHTTPRequest("PATCH", "/db/d0/time-quantum", strings.NewReader(`{"time_quantum":"ymdh"}`)))
if w.Code != http.StatusOK {
t.Fatalf("unexpected status code: %d", w.Code)
} else if body := w.Body.String(); body != `{}`+"\n" {
@ -581,7 +579,7 @@ func TestHandler_SetFrameTimeQuantum(t *testing.T) {
h := NewHandler()
h.Index = idx.Index
w := httptest.NewRecorder()
h.ServeHTTP(w, MustNewHTTPRequest("PATCH", "/frame/time_quantum", strings.NewReader(`{"db":"d0","frame":"f1","time_quantum":"ymdh"}`)))
h.ServeHTTP(w, MustNewHTTPRequest("PATCH", "/db/d0/frame/f1/time-quantum", strings.NewReader(`{"time_quantum":"ymdh"}`)))
if w.Code != http.StatusOK {
t.Fatalf("unexpected status code: %d", w.Code)
} else if body := w.Body.String(); body != `{}`+"\n" {
@ -625,9 +623,9 @@ func TestHandler_DB_AttrStore_Diff(t *testing.T) {
// Send block checksums to determine diff.
resp, err := http.Post(
s.URL+"/db/attr/diff?db=d",
s.URL+"/db/d/attr/diff",
"application/json",
strings.NewReader(`{"db":"d", "blocks":`+string(MustMarshalJSON(blks))+`}`),
strings.NewReader(`{"blocks":`+string(MustMarshalJSON(blks))+`}`),
)
if err != nil {
t.Fatal(err)
@ -675,9 +673,9 @@ func TestHandler_Frame_AttrStore_Diff(t *testing.T) {
// Send block checksums to determine diff.
resp, err := http.Post(
s.URL+"/frame/attr/diff?db=d",
s.URL+"/db/d/frame/meta/attr/diff",
"application/json",
strings.NewReader(`{"db":"d", "frame":"meta", "blocks":`+string(MustMarshalJSON(blks))+`}`),
strings.NewReader(`{"blocks":`+string(MustMarshalJSON(blks))+`}`),
)
if err != nil {
t.Fatal(err)

View file

@ -125,12 +125,11 @@ func (m *AttrMap) GetAttrs() []*Attr {
}
type QueryRequest struct {
DB string `protobuf:"bytes,1,opt,name=DB,proto3" json:"DB,omitempty"`
Query string `protobuf:"bytes,2,opt,name=Query,proto3" json:"Query,omitempty"`
Slices []uint64 `protobuf:"varint,3,rep,packed,name=Slices" json:"Slices,omitempty"`
Profiles bool `protobuf:"varint,4,opt,name=Profiles,proto3" json:"Profiles,omitempty"`
Quantum string `protobuf:"bytes,5,opt,name=Quantum,proto3" json:"Quantum,omitempty"`
Remote bool `protobuf:"varint,6,opt,name=Remote,proto3" json:"Remote,omitempty"`
Query string `protobuf:"bytes,1,opt,name=Query,proto3" json:"Query,omitempty"`
Slices []uint64 `protobuf:"varint,2,rep,packed,name=Slices" json:"Slices,omitempty"`
Profiles bool `protobuf:"varint,3,opt,name=Profiles,proto3" json:"Profiles,omitempty"`
Quantum string `protobuf:"bytes,4,opt,name=Quantum,proto3" json:"Quantum,omitempty"`
Remote bool `protobuf:"varint,5,opt,name=Remote,proto3" json:"Remote,omitempty"`
}
func (m *QueryRequest) Reset() { *m = QueryRequest{} }
@ -458,14 +457,8 @@ func (m *QueryRequest) MarshalTo(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
if len(m.DB) > 0 {
dAtA[i] = 0xa
i++
i = encodeVarintPublic(dAtA, i, uint64(len(m.DB)))
i += copy(dAtA[i:], m.DB)
}
if len(m.Query) > 0 {
dAtA[i] = 0x12
dAtA[i] = 0xa
i++
i = encodeVarintPublic(dAtA, i, uint64(len(m.Query)))
i += copy(dAtA[i:], m.Query)
@ -482,13 +475,13 @@ func (m *QueryRequest) MarshalTo(dAtA []byte) (int, error) {
dAtA4[j3] = uint8(num)
j3++
}
dAtA[i] = 0x1a
dAtA[i] = 0x12
i++
i = encodeVarintPublic(dAtA, i, uint64(j3))
i += copy(dAtA[i:], dAtA4[:j3])
}
if m.Profiles {
dAtA[i] = 0x20
dAtA[i] = 0x18
i++
if m.Profiles {
dAtA[i] = 1
@ -498,13 +491,13 @@ func (m *QueryRequest) MarshalTo(dAtA []byte) (int, error) {
i++
}
if len(m.Quantum) > 0 {
dAtA[i] = 0x2a
dAtA[i] = 0x22
i++
i = encodeVarintPublic(dAtA, i, uint64(len(m.Quantum)))
i += copy(dAtA[i:], m.Quantum)
}
if m.Remote {
dAtA[i] = 0x30
dAtA[i] = 0x28
i++
if m.Remote {
dAtA[i] = 1
@ -835,10 +828,6 @@ func (m *AttrMap) Size() (n int) {
func (m *QueryRequest) Size() (n int) {
var l int
_ = l
l = len(m.DB)
if l > 0 {
n += 1 + l + sovPublic(uint64(l))
}
l = len(m.Query)
if l > 0 {
n += 1 + l + sovPublic(uint64(l))
@ -1691,35 +1680,6 @@ func (m *QueryRequest) Unmarshal(dAtA []byte) error {
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field DB", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPublic
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthPublic
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.DB = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Query", wireType)
}
@ -1748,7 +1708,7 @@ func (m *QueryRequest) Unmarshal(dAtA []byte) error {
}
m.Query = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 3:
case 2:
if wireType == 2 {
var packedLen int
for shift := uint(0); ; shift += 7 {
@ -1810,7 +1770,7 @@ func (m *QueryRequest) Unmarshal(dAtA []byte) error {
} else {
return fmt.Errorf("proto: wrong wireType = %d for field Slices", wireType)
}
case 4:
case 3:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Profiles", wireType)
}
@ -1830,7 +1790,7 @@ func (m *QueryRequest) Unmarshal(dAtA []byte) error {
}
}
m.Profiles = bool(v != 0)
case 5:
case 4:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Quantum", wireType)
}
@ -1859,7 +1819,7 @@ func (m *QueryRequest) Unmarshal(dAtA []byte) error {
}
m.Quantum = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 6:
case 5:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Remote", wireType)
}
@ -2616,40 +2576,40 @@ func init() { proto.RegisterFile("public.proto", fileDescriptorPublic) }
var fileDescriptorPublic = []byte{
// 570 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x8c, 0x54, 0xcb, 0x6e, 0xd3, 0x40,
0x14, 0x65, 0x62, 0xe7, 0x75, 0x93, 0x56, 0x61, 0x04, 0xc8, 0x42, 0x28, 0xb2, 0x2c, 0x16, 0xde,
0x90, 0x4a, 0xe5, 0x03, 0x10, 0x6e, 0x5a, 0xc9, 0x42, 0x54, 0xed, 0xb4, 0x62, 0xc7, 0xc2, 0x2d,
0x43, 0xb1, 0xe4, 0x17, 0x33, 0xe3, 0x45, 0x96, 0x2c, 0xf8, 0x07, 0xc4, 0x17, 0xc0, 0x9f, 0xb0,
0xe4, 0x13, 0x50, 0xf8, 0x11, 0x74, 0xe7, 0x61, 0x7b, 0x55, 0xb1, 0x9b, 0x73, 0x4e, 0xee, 0xf8,
0x9e, 0x39, 0xf7, 0x06, 0x96, 0x4d, 0x7b, 0x53, 0xe4, 0xb7, 0x9b, 0x46, 0xd4, 0xaa, 0xa6, 0xb3,
0xbc, 0x52, 0x5c, 0x54, 0x59, 0x11, 0x25, 0x30, 0x49, 0x72, 0x55, 0x66, 0x0d, 0xa5, 0xe0, 0x27,
0xb9, 0x92, 0x01, 0x09, 0xbd, 0xd8, 0x67, 0xfa, 0x4c, 0x9f, 0xc3, 0xf8, 0xb5, 0x52, 0x42, 0x06,
0xa3, 0xd0, 0x8b, 0x17, 0xc7, 0x87, 0x1b, 0x57, 0xb7, 0x41, 0x9a, 0x19, 0x31, 0xda, 0x80, 0x7f,
0x91, 0xe5, 0x82, 0xae, 0xc0, 0x7b, 0xc3, 0x77, 0x01, 0x09, 0x49, 0xec, 0x33, 0x3c, 0xd2, 0x47,
0x30, 0x3e, 0xa9, 0xdb, 0x4a, 0x05, 0x23, 0xcd, 0x19, 0x10, 0xbd, 0x07, 0x2f, 0xc9, 0x15, 0x7d,
0x0a, 0x33, 0xf3, 0xe9, 0x74, 0x6b, 0x6b, 0x3a, 0x4c, 0x9f, 0xc1, 0xfc, 0x42, 0xd4, 0x1f, 0xf3,
0x82, 0xa7, 0x5b, 0x5b, 0xdc, 0x13, 0xa8, 0x5e, 0xe7, 0x25, 0x97, 0x2a, 0x2b, 0x9b, 0xc0, 0x0b,
0x49, 0xec, 0xb1, 0x9e, 0x88, 0x5e, 0xc1, 0xd4, 0xfe, 0x94, 0x1e, 0xc2, 0xa8, 0xbb, 0x7c, 0x94,
0x6e, 0xff, 0xd3, 0xcf, 0x0f, 0x02, 0x3e, 0x9e, 0x86, 0x86, 0xe6, 0xc6, 0x10, 0x05, 0xff, 0x7a,
0xd7, 0x70, 0xdb, 0x92, 0x3e, 0xd3, 0x10, 0x16, 0x57, 0x4a, 0xe4, 0xd5, 0xdd, 0xbb, 0xac, 0x68,
0xb9, 0xee, 0x67, 0xce, 0x86, 0x14, 0x3a, 0x4d, 0x2b, 0x65, 0x64, 0x5f, 0xb7, 0xdb, 0x61, 0xf4,
0x92, 0xd4, 0x75, 0x61, 0xc4, 0x71, 0x48, 0xe2, 0x19, 0xeb, 0x09, 0xba, 0x06, 0x38, 0x2b, 0xea,
0xcc, 0xd6, 0x4e, 0x42, 0x12, 0x13, 0x36, 0x60, 0xa2, 0x23, 0x98, 0x62, 0xa7, 0x6f, 0xb3, 0xa6,
0xf7, 0x46, 0xee, 0xf3, 0xf6, 0x9d, 0xc0, 0xf2, 0xb2, 0xe5, 0x62, 0xc7, 0xf8, 0xe7, 0x96, 0x4b,
0x85, 0x4f, 0xb4, 0x4d, 0xac, 0xc5, 0xd1, 0x36, 0xc1, 0xc8, 0xb4, 0xae, 0x2d, 0xce, 0x99, 0x01,
0xf4, 0x09, 0x4c, 0xae, 0x8a, 0xfc, 0x96, 0xcb, 0xc0, 0xd3, 0xe3, 0x61, 0x11, 0x3a, 0xb3, 0x6f,
0x2d, 0xb5, 0xb3, 0x19, 0xeb, 0x30, 0x0d, 0x60, 0x7a, 0xd9, 0x66, 0x95, 0x6a, 0x4b, 0xed, 0x6b,
0xce, 0x1c, 0xc4, 0xdb, 0x18, 0x2f, 0x6b, 0x65, 0x1c, 0xcd, 0x98, 0x45, 0xd1, 0x17, 0x02, 0x07,
0xb6, 0x39, 0xd9, 0xd4, 0x95, 0xe4, 0x98, 0xc0, 0xa9, 0x10, 0x2e, 0x81, 0x53, 0x21, 0xe8, 0x11,
0x4c, 0x19, 0x97, 0x6d, 0xa1, 0x5c, 0x88, 0x8f, 0x7b, 0xa3, 0xae, 0xb6, 0x2d, 0x14, 0x73, 0xbf,
0xa2, 0x2f, 0x06, 0x2d, 0x7a, 0xba, 0xe2, 0x61, 0x5f, 0x61, 0x95, 0xbe, 0xeb, 0xe8, 0x2b, 0x81,
0xc5, 0xe0, 0x1e, 0x1a, 0xbb, 0x05, 0xd1, 0x4d, 0x2c, 0x8e, 0x57, 0x7d, 0xb1, 0xe1, 0x99, 0x5b,
0xa0, 0x25, 0x90, 0x73, 0x3b, 0x18, 0xe4, 0x1c, 0xe3, 0xc0, 0xa5, 0x70, 0xdf, 0x1c, 0xc4, 0x81,
0x34, 0x33, 0x22, 0xbe, 0xd1, 0xc9, 0xa7, 0xac, 0xba, 0xe3, 0x1f, 0xec, 0xf3, 0x39, 0x18, 0xfd,
0x24, 0x70, 0x90, 0x96, 0x4d, 0x2d, 0xd4, 0x3d, 0x49, 0x9d, 0x89, 0xac, 0xe4, 0x2e, 0x29, 0x0d,
0x90, 0xd5, 0xd9, 0xe8, 0x39, 0xf4, 0x99, 0x01, 0x7a, 0xca, 0xec, 0x6e, 0x61, 0x50, 0x18, 0x61,
0x4f, 0xe0, 0x94, 0x75, 0xcb, 0x25, 0x83, 0xb1, 0x96, 0x07, 0x0c, 0xea, 0xdd, 0x7a, 0xc9, 0x60,
0x12, 0x7a, 0xb1, 0xc7, 0x06, 0x4c, 0xb2, 0xfa, 0xb5, 0x5f, 0x93, 0xdf, 0xfb, 0x35, 0xf9, 0xb3,
0x5f, 0x93, 0x6f, 0x7f, 0xd7, 0x0f, 0x6e, 0x26, 0xfa, 0x7f, 0xe6, 0xe5, 0xbf, 0x00, 0x00, 0x00,
0xff, 0xff, 0x36, 0x47, 0xff, 0x96, 0x77, 0x04, 0x00, 0x00,
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x8c, 0x54, 0x4b, 0x6e, 0xd4, 0x40,
0x10, 0xa5, 0x6d, 0xcf, 0xaf, 0x26, 0x19, 0x0d, 0x2d, 0x40, 0x16, 0x42, 0x23, 0xcb, 0x62, 0xe1,
0x0d, 0x13, 0x29, 0x1c, 0x00, 0xe1, 0x4c, 0x22, 0x8d, 0x10, 0x51, 0xd2, 0x89, 0xd8, 0xb1, 0x70,
0x42, 0x13, 0x2c, 0xf9, 0x47, 0x77, 0x7b, 0x31, 0x4b, 0x16, 0x6c, 0x38, 0x01, 0x47, 0x80, 0x9b,
0xb0, 0xe4, 0x08, 0x68, 0xb8, 0x08, 0xaa, 0xfe, 0xd8, 0x66, 0x83, 0xd8, 0xf5, 0x7b, 0xe5, 0xea,
0xae, 0xf7, 0xaa, 0xca, 0x70, 0xd0, 0xb4, 0x37, 0x45, 0x7e, 0xbb, 0x6e, 0x44, 0xad, 0x6a, 0x3a,
0xcd, 0x2b, 0xc5, 0x45, 0x95, 0x15, 0x71, 0x0a, 0xe3, 0x34, 0x57, 0x65, 0xd6, 0x50, 0x0a, 0x41,
0x9a, 0x2b, 0x19, 0x92, 0xc8, 0x4f, 0x02, 0xa6, 0xcf, 0xf4, 0x29, 0x8c, 0x5e, 0x2a, 0x25, 0x64,
0xe8, 0x45, 0x7e, 0x32, 0x3f, 0x5e, 0xac, 0x5d, 0xde, 0x1a, 0x69, 0x66, 0x82, 0xf1, 0x1a, 0x82,
0x8b, 0x2c, 0x17, 0x74, 0x09, 0xfe, 0x2b, 0xbe, 0x0b, 0x49, 0x44, 0x92, 0x80, 0xe1, 0x91, 0x3e,
0x80, 0xd1, 0x49, 0xdd, 0x56, 0x2a, 0xf4, 0x34, 0x67, 0x40, 0xfc, 0x16, 0xfc, 0x34, 0x57, 0xf4,
0x31, 0x4c, 0xcd, 0xd3, 0xdb, 0x8d, 0xcd, 0xe9, 0x30, 0x7d, 0x02, 0xb3, 0x0b, 0x51, 0xbf, 0xcf,
0x0b, 0xbe, 0xdd, 0xd8, 0xe4, 0x9e, 0xc0, 0xe8, 0x75, 0x5e, 0x72, 0xa9, 0xb2, 0xb2, 0x09, 0xfd,
0x88, 0x24, 0x3e, 0xeb, 0x89, 0xf8, 0x05, 0x4c, 0xec, 0xa7, 0x74, 0x01, 0x5e, 0x77, 0xb9, 0xb7,
0xdd, 0xfc, 0xa7, 0x9e, 0x6f, 0x04, 0x02, 0x3c, 0x0d, 0x05, 0xcd, 0x8c, 0x20, 0x0a, 0xc1, 0xf5,
0xae, 0xe1, 0xb6, 0x24, 0x7d, 0xa6, 0x11, 0xcc, 0xaf, 0x94, 0xc8, 0xab, 0xbb, 0x37, 0x59, 0xd1,
0x72, 0x5d, 0xcf, 0x8c, 0x0d, 0x29, 0x54, 0xba, 0xad, 0x94, 0x09, 0x07, 0xba, 0xdc, 0x0e, 0xa3,
0x96, 0xb4, 0xae, 0x0b, 0x13, 0x1c, 0x45, 0x24, 0x99, 0xb2, 0x9e, 0xa0, 0x2b, 0x80, 0xb3, 0xa2,
0xce, 0x6c, 0xee, 0x38, 0x22, 0x09, 0x61, 0x03, 0x26, 0x3e, 0x82, 0x09, 0x56, 0xfa, 0x3a, 0x6b,
0x7a, 0x6d, 0xe4, 0x5f, 0xda, 0xbe, 0x10, 0x38, 0xb8, 0x6c, 0xb9, 0xd8, 0x31, 0xfe, 0xb1, 0xe5,
0x52, 0x61, 0x8b, 0x34, 0xb6, 0x2a, 0x0d, 0xa0, 0x8f, 0x60, 0x7c, 0x55, 0xe4, 0xb7, 0xdc, 0x38,
0x15, 0x30, 0x8b, 0x50, 0x89, 0xf5, 0x56, 0x6a, 0xa1, 0x53, 0xd6, 0x61, 0x1a, 0xc2, 0xe4, 0xb2,
0xcd, 0x2a, 0xd5, 0x96, 0x5a, 0xe4, 0x8c, 0x39, 0x88, 0xb7, 0x31, 0x5e, 0xd6, 0xca, 0x09, 0xb4,
0x28, 0xfe, 0x44, 0xe0, 0xd0, 0x16, 0x23, 0x9b, 0xba, 0x92, 0x1c, 0x1d, 0x3f, 0x15, 0xc2, 0x39,
0x7e, 0x2a, 0x04, 0x3d, 0x82, 0x09, 0xe3, 0xb2, 0x2d, 0x94, 0x6b, 0xda, 0xc3, 0x5e, 0x98, 0xcb,
0x6d, 0x0b, 0xc5, 0xdc, 0x57, 0xf4, 0xd9, 0x5f, 0x25, 0x62, 0xc6, 0xfd, 0x3e, 0xc3, 0x46, 0xfa,
0xaa, 0xe3, 0xcf, 0x04, 0xe6, 0x83, 0x7b, 0x68, 0xe2, 0x16, 0x42, 0x17, 0x31, 0x3f, 0x5e, 0xf6,
0xc9, 0x86, 0x67, 0x6e, 0x61, 0x0e, 0x80, 0x9c, 0xdb, 0x41, 0x20, 0xe7, 0x68, 0x3f, 0x2e, 0x81,
0x7b, 0x73, 0x60, 0x3f, 0xd2, 0xcc, 0x04, 0xd1, 0xa3, 0x93, 0x0f, 0x59, 0x75, 0xc7, 0xdf, 0x69,
0x8f, 0xa6, 0xcc, 0xc1, 0xf8, 0x3b, 0x81, 0xc3, 0x6d, 0xd9, 0xd4, 0x42, 0xb9, 0xce, 0x2c, 0xc0,
0xdb, 0xa4, 0xd6, 0x0a, 0x6f, 0x93, 0x62, 0xa7, 0xce, 0x44, 0x56, 0x9a, 0xe1, 0x9b, 0x31, 0x03,
0x90, 0xd5, 0xbd, 0xd1, 0xed, 0x08, 0x98, 0x01, 0x7a, 0xaa, 0xec, 0x2e, 0xc9, 0x30, 0xd0, 0x2d,
0xec, 0x09, 0x9c, 0xaa, 0x6e, 0x99, 0x64, 0x38, 0xd2, 0xe1, 0x01, 0x83, 0xf1, 0x6e, 0x9d, 0x64,
0x38, 0x8e, 0xfc, 0xc4, 0x67, 0x03, 0x26, 0x5d, 0xfe, 0xd8, 0xaf, 0xc8, 0xcf, 0xfd, 0x8a, 0xfc,
0xda, 0xaf, 0xc8, 0xd7, 0xdf, 0xab, 0x7b, 0x37, 0x63, 0xfd, 0x5f, 0x79, 0xfe, 0x27, 0x00, 0x00,
0xff, 0xff, 0x37, 0xb6, 0x15, 0x22, 0x67, 0x04, 0x00, 0x00,
}

View file

@ -37,12 +37,11 @@ message AttrMap {
}
message QueryRequest {
string DB = 1;
string Query = 2;
repeated uint64 Slices = 3;
bool Profiles = 4;
string Quantum = 5;
bool Remote = 6;
string Query = 1;
repeated uint64 Slices = 2;
bool Profiles = 3;
string Quantum = 4;
bool Remote = 5;
}
message QueryResponse {

View file

@ -45,7 +45,7 @@ func TestMain_Set_Quick(t *testing.T) {
if err := client.CreateFrame(context.Background(), "d", cmd.Frame, pilosa.FrameOptions{}); err != nil && err != pilosa.ErrFrameExists {
t.Fatal(err)
}
if _, err := m.Query("db=d", fmt.Sprintf(`SetBit(id=%d, frame=%q, profileID=%d)`, cmd.ID, cmd.Frame, cmd.ProfileID)); err != nil {
if _, err := m.Query("d", "", fmt.Sprintf(`SetBit(id=%d, frame=%q, profileID=%d)`, cmd.ID, cmd.Frame, cmd.ProfileID)); err != nil {
t.Fatal(err)
}
}
@ -61,7 +61,7 @@ func TestMain_Set_Quick(t *testing.T) {
},
},
}) + "\n"
if res, err := m.Query("db=d", fmt.Sprintf(`Bitmap(id=%d, frame=%q)`, id, frame)); err != nil {
if res, err := m.Query("d", "", fmt.Sprintf(`Bitmap(id=%d, frame=%q)`, id, frame)); err != nil {
t.Fatal(err)
} else if res != exp {
t.Fatalf("unexpected result:\n\ngot=%s\n\nexp=%s\n\n", res, exp)
@ -84,7 +84,7 @@ func TestMain_Set_Quick(t *testing.T) {
},
},
}) + "\n"
if res, err := m.Query("db=d", fmt.Sprintf(`Bitmap(id=%d, frame=%q)`, id, frame)); err != nil {
if res, err := m.Query("d", "", fmt.Sprintf(`Bitmap(id=%d, frame=%q)`, id, frame)); err != nil {
t.Fatal(err)
} else if res != exp {
t.Fatalf("unexpected result (reopen):\n\ngot=%s\n\nexp=%s\n\n", res, exp)
@ -120,36 +120,36 @@ func TestMain_SetBitmapAttrs(t *testing.T) {
}
// Set bits on different bitmaps in different frames.
if _, err := m.Query("db=d", `SetBit(id=1, frame="x.n", profileID=100)`); err != nil {
if _, err := m.Query("d", "", `SetBit(id=1, frame="x.n", profileID=100)`); err != nil {
t.Fatal(err)
} else if _, err := m.Query("db=d", `SetBit(id=2, frame="x.n", profileID=100)`); err != nil {
} else if _, err := m.Query("d", "", `SetBit(id=2, frame="x.n", profileID=100)`); err != nil {
t.Fatal(err)
} else if _, err := m.Query("db=d", `SetBit(id=2, frame="z", profileID=100)`); err != nil {
} else if _, err := m.Query("d", "", `SetBit(id=2, frame="z", profileID=100)`); err != nil {
t.Fatal(err)
} else if _, err := m.Query("db=d", `SetBit(id=3, frame="neg", profileID=100)`); err != nil {
} else if _, err := m.Query("d", "", `SetBit(id=3, frame="neg", profileID=100)`); err != nil {
t.Fatal(err)
}
// Set bitmap attributes.
if _, err := m.Query("db=d", `SetBitmapAttrs(id=1, frame="x.n", x=100)`); err != nil {
if _, err := m.Query("d", "", `SetBitmapAttrs(id=1, frame="x.n", x=100)`); err != nil {
t.Fatal(err)
} else if _, err := m.Query("db=d", `SetBitmapAttrs(id=2, frame="x.n", x=-200)`); err != nil {
} else if _, err := m.Query("d", "", `SetBitmapAttrs(id=2, frame="x.n", x=-200)`); err != nil {
t.Fatal(err)
} else if _, err := m.Query("db=d", `SetBitmapAttrs(id=2, frame="z", x=300)`); err != nil {
} else if _, err := m.Query("d", "", `SetBitmapAttrs(id=2, frame="z", x=300)`); err != nil {
t.Fatal(err)
} else if _, err := m.Query("db=d", `SetBitmapAttrs(id=3, frame="neg", x=-0.44)`); err != nil {
} else if _, err := m.Query("d", "", `SetBitmapAttrs(id=3, frame="neg", x=-0.44)`); err != nil {
t.Fatal(err)
}
// Query bitmap x.n/1.
if res, err := m.Query("db=d", `Bitmap(id=1, frame="x.n")`); err != nil {
if res, err := m.Query("d", "", `Bitmap(id=1, frame="x.n")`); err != nil {
t.Fatal(err)
} else if res != `{"results":[{"attrs":{"x":100},"bits":[100]}]}`+"\n" {
t.Fatalf("unexpected result: %s", res)
}
// Query bitmap x.n/2.
if res, err := m.Query("db=d", `Bitmap(id=2, frame="x.n")`); err != nil {
if res, err := m.Query("d", "", `Bitmap(id=2, frame="x.n")`); err != nil {
t.Fatal(err)
} else if res != `{"results":[{"attrs":{"x":-200},"bits":[100]}]}`+"\n" {
t.Fatalf("unexpected result: %s", res)
@ -160,19 +160,19 @@ func TestMain_SetBitmapAttrs(t *testing.T) {
}
// Query bitmaps after reopening.
if res, err := m.Query("db=d&profiles=true", `Bitmap(id=1, frame="x.n")`); err != nil {
if res, err := m.Query("d", "profiles=true", `Bitmap(id=1, frame="x.n")`); err != nil {
t.Fatal(err)
} else if res != `{"results":[{"attrs":{"x":100},"bits":[100]}]}`+"\n" {
t.Fatalf("unexpected result(reopen): %s", res)
}
if res, err := m.Query("db=d&profiles=true", `Bitmap(id=3, frame="neg")`); err != nil {
if res, err := m.Query("d", "profiles=true", `Bitmap(id=3, frame="neg")`); err != nil {
t.Fatal(err)
} else if res != `{"results":[{"attrs":{"x":-0.44},"bits":[100]}]}`+"\n" {
t.Fatalf("unexpected result(reopen): %s", res)
}
// Query bitmap x.n/2.
if res, err := m.Query("db=d", `Bitmap(id=2, frame="x.n")`); err != nil {
if res, err := m.Query("d", "", `Bitmap(id=2, frame="x.n")`); err != nil {
t.Fatal(err)
} else if res != `{"results":[{"attrs":{"x":-200},"bits":[100]}]}`+"\n" {
t.Fatalf("unexpected result: %s", res)
@ -193,19 +193,19 @@ func TestMain_SetProfileAttrs(t *testing.T) {
}
// Set bits on bitmap.
if _, err := m.Query("db=d", `SetBit(id=1, frame="x.n", profileID=100)`); err != nil {
if _, err := m.Query("d", "", `SetBit(id=1, frame="x.n", profileID=100)`); err != nil {
t.Fatal(err)
} else if _, err := m.Query("db=d", `SetBit(id=1, frame="x.n", profileID=101)`); err != nil {
} else if _, err := m.Query("d", "", `SetBit(id=1, frame="x.n", profileID=101)`); err != nil {
t.Fatal(err)
}
// Set profile attributes.
if _, err := m.Query("db=d", `SetProfileAttrs(id=100, foo="bar")`); err != nil {
if _, err := m.Query("d", "", `SetProfileAttrs(id=100, foo="bar")`); err != nil {
t.Fatal(err)
}
// Query bitmap.
if res, err := m.Query("db=d&profiles=true", `Bitmap(id=1, frame="x.n")`); err != nil {
if res, err := m.Query("d", "profiles=true", `Bitmap(id=1, frame="x.n")`); err != nil {
t.Fatal(err)
} else if res != `{"results":[{"attrs":{},"bits":[100,101]}],"profiles":[{"id":100,"attrs":{"foo":"bar"}}]}`+"\n" {
t.Fatalf("unexpected result: %s", res)
@ -216,7 +216,7 @@ func TestMain_SetProfileAttrs(t *testing.T) {
}
// Query bitmap after reopening.
if res, err := m.Query("db=d&profiles=true", `Bitmap(id=1, frame="x.n")`); err != nil {
if res, err := m.Query("d", "profiles=true", `Bitmap(id=1, frame="x.n")`); err != nil {
t.Fatal(err)
} else if res != `{"results":[{"attrs":{},"bits":[100,101]}],"profiles":[{"id":100,"attrs":{"foo":"bar"}}]}`+"\n" {
t.Fatalf("unexpected result(reopen): %s", res)
@ -237,19 +237,19 @@ func TestMain_SetProfileAttrsWithColumnOption(t *testing.T) {
}
// Set bits on bitmap.
if _, err := m.Query("db=d", `SetBit(id=1, frame="x.n", col=100)`); err != nil {
if _, err := m.Query("d", "", `SetBit(id=1, frame="x.n", col=100)`); err != nil {
t.Fatal(err)
} else if _, err := m.Query("db=d", `SetBit(id=1, frame="x.n", col=101)`); err != nil {
} else if _, err := m.Query("d", "", `SetBit(id=1, frame="x.n", col=101)`); err != nil {
t.Fatal(err)
}
// Set profile attributes.
if _, err := m.Query("db=d", `SetProfileAttrs(col=100, foo="bar")`); err != nil {
if _, err := m.Query("d", "", `SetProfileAttrs(col=100, foo="bar")`); err != nil {
t.Fatal(err)
}
// Query bitmap.
if res, err := m.Query("db=d&profiles=true", `Bitmap(id=1, frame="x.n")`); err != nil {
if res, err := m.Query("d", "profiles=true", `Bitmap(id=1, frame="x.n")`); err != nil {
t.Fatal(err)
} else if res != `{"results":[{"attrs":{},"bits":[100,101]}],"profiles":[{"id":100,"attrs":{"foo":"bar"}}]}`+"\n" {
t.Fatalf("unexpected result: %s", res)
@ -281,7 +281,7 @@ func TestMain_FrameRestore(t *testing.T) {
}
// Write data on first cluster.
if _, err := m0.Query("db=d", `
if _, err := m0.Query("d", "", `
SetBit(id=1, frame="f", profileID=100)
SetBit(id=1, frame="f", profileID=1000)
SetBit(id=1, frame="f", profileID=100000)
@ -294,7 +294,7 @@ func TestMain_FrameRestore(t *testing.T) {
}
// Query bitmap on first cluster.
if res, err := m0.Query("db=d", `Bitmap(id=1, frame="f")`); err != nil {
if res, err := m0.Query("d", "", `Bitmap(id=1, frame="f")`); err != nil {
t.Fatal(err)
} else if res != `{"results":[{"attrs":{},"bits":[100,1000,100000,200000,400000,600000,800000]}]}`+"\n" {
t.Fatalf("unexpected result: %s", res)
@ -317,7 +317,7 @@ func TestMain_FrameRestore(t *testing.T) {
}
// Query bitmap on second cluster.
if res, err := m2.Query("db=d", `Bitmap(id=1, frame="f")`); err != nil {
if res, err := m2.Query("d", "", `Bitmap(id=1, frame="f")`); err != nil {
t.Fatal(err)
} else if res != `{"results":[{"attrs":{},"bits":[100,1000,100000,200000,400000,600000,800000]}]}`+"\n" {
t.Fatalf("unexpected result: %s", res)
@ -431,8 +431,8 @@ func (m *Main) Client() *pilosa.Client {
}
// Query executes a query against the program through the HTTP API.
func (m *Main) Query(rawQuery, query string) (string, error) {
resp := MustDo("POST", m.URL()+"/query?"+rawQuery, query)
func (m *Main) Query(db, rawQuery, query string) (string, error) {
resp := MustDo("POST", m.URL()+fmt.Sprintf("/db/%s/query?", db)+rawQuery, query)
if resp.StatusCode != http.StatusOK {
return "", fmt.Errorf("invalid status: %d, body=%s", resp.StatusCode, resp.Body)
}