From 748b034aa8e44546eac120ca5c858aab6b8aecc5 Mon Sep 17 00:00:00 2001 From: Michael Baird Date: Fri, 18 Aug 2017 09:36:45 -0500 Subject: [PATCH 01/12] DeleteView from Frame --- frame.go | 20 ++++++++++++++++++++ frame_test.go | 31 +++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/frame.go b/frame.go index de3dd6fbb..295c3abf2 100644 --- a/frame.go +++ b/frame.go @@ -509,6 +509,26 @@ func (f *Frame) newView(path, name string) *View { return view } +// DeleteView removes a view from the frame. +func (f *Frame) DeleteView(name string) error { + view := f.views[name] + if view == nil { + return ErrInvalidView + } + + // TODO capture errors lower down in this method + _ = view.Close() + + // Delete view directory. + if err := os.RemoveAll(view.Path()); err != nil { + return err + } + + delete(f.views, name) + + return nil +} + // SetBit sets a bit on a view within the frame. func (f *Frame) SetBit(name string, rowID, colID uint64, t *time.Time) (changed bool, err error) { // Validate view name. diff --git a/frame_test.go b/frame_test.go index 8cb48cca8..b560d985e 100644 --- a/frame_test.go +++ b/frame_test.go @@ -307,3 +307,34 @@ func TestFrame_RowLabelValidation(t *testing.T) { } } + +// Ensure frame can open and retrieve a view. +func TestFrame_DeleteView(t *testing.T) { + f := test.MustOpenFrame() + defer f.Close() + + // Create view. + view, err := f.CreateViewIfNotExists("v") + if err != nil { + t.Fatal(err) + } else if view == nil { + t.Fatal("expected view") + } + + err = f.DeleteView("v") + if err != nil { + t.Fatal(err) + } + + if f.View("v") != nil { + t.Fatal("view still exists in frame") + } + + // // Retrieve existing view. + view2, err := f.CreateViewIfNotExists("v") + if err != nil { + t.Fatal(err) + } else if view == view2 { + t.Fatal("failed to create new view") + } +} From 753d89d45e63b746f0543da3e63c282b4b43d699 Mon Sep 17 00:00:00 2001 From: Michael Baird Date: Fri, 18 Aug 2017 14:55:29 -0500 Subject: [PATCH 02/12] handler for delete View --- handler.go | 29 +++++++++++++++++++++++++++++ handler_test.go | 20 ++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/handler.go b/handler.go index f3bf5c786..89f18a20b 100644 --- a/handler.go +++ b/handler.go @@ -116,6 +116,7 @@ func NewRouter(handler *Handler) *mux.Router { router.HandleFunc("/index/{index}/frame/{frame}/restore", handler.handlePostFrameRestore).Methods("POST") router.HandleFunc("/index/{index}/frame/{frame}/time-quantum", handler.handlePatchFrameTimeQuantum).Methods("PATCH") router.HandleFunc("/index/{index}/frame/{frame}/views", handler.handleGetFrameViews).Methods("GET") + router.HandleFunc("/index/{index}/frame/{frame}/view/{view}", handler.handleDeleteView).Methods("DELETE") router.HandleFunc("/index/{index}/input/{input-definition}", handler.handlePostInput).Methods("POST") router.HandleFunc("/index/{index}/input-definition/{input-definition}", handler.handleGetInputDefinition).Methods("GET") router.HandleFunc("/index/{index}/input-definition/{input-definition}", handler.handlePostInputDefinition).Methods("POST") @@ -789,6 +790,34 @@ func (h *Handler) handleGetFrameViews(w http.ResponseWriter, r *http.Request) { } } +// handleDeleteView handles Delete /frame/view request. +func (h *Handler) handleDeleteView(w http.ResponseWriter, r *http.Request) { + indexName := mux.Vars(r)["index"] + frameName := mux.Vars(r)["frame"] + viewName := mux.Vars(r)["view"] + + // Retrieve frame. + f := h.Holder.Frame(indexName, frameName) + if f == nil { + http.Error(w, ErrFrameNotFound.Error(), http.StatusNotFound) + return + } + + if err := f.DeleteView(viewName); err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + + // TODO: Send the delete frame message to all nodes. + + // Encode response. + if err := json.NewEncoder(w).Encode(deleteViewResponse{}); err != nil { + h.logger().Printf("response encoding error: %s", err) + } +} + +type deleteViewResponse struct{} + type getFrameViewsResponse struct { Views []string `json:"views,omitempty"` } diff --git a/handler_test.go b/handler_test.go index 22a1fd4f3..2947fd1b8 100644 --- a/handler_test.go +++ b/handler_test.go @@ -1511,3 +1511,23 @@ func TestHandler_GetTimeStamp(t *testing.T) { t.Fatalf("Expected Ignore nonexistent fields") } } + +// Ensure handler can delete a view. +func TestHandler_DeleteView(t *testing.T) { + hldr := test.MustOpenHolder() + defer hldr.Close() + hldr.MustCreateFragmentIfNotExists("i0", "f0", "v0", 1).MustSetBits(30, (1*SliceWidth)+1) + + h := test.NewHandler() + h.Holder = hldr.Holder + h.Cluster = test.NewCluster(1) + w := httptest.NewRecorder() + h.ServeHTTP(w, test.MustNewHTTPRequest("DELETE", "/index/i0/frame/f0/view/v0", strings.NewReader(""))) + if w.Code != http.StatusOK { + t.Fatalf("unexpected status code: %d", w.Code) + } else if body := w.Body.String(); body != `{}`+"\n" { + t.Fatalf("unexpected body: %s", body) + } else if f := hldr.Index("i0").Frame("f0").View("v0"); f != nil { + t.Fatal("expected nil view") + } +} From 80ab4cd1937b7ccbdaf09f6ff99bc1eadffeb246 Mon Sep 17 00:00:00 2001 From: Michael Baird Date: Fri, 18 Aug 2017 17:08:13 -0500 Subject: [PATCH 03/12] delete only time based views, and handle inverse views --- handler.go | 25 +++++++++++++++++++++++-- handler_test.go | 7 ++++--- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/handler.go b/handler.go index 89f18a20b..d355213db 100644 --- a/handler.go +++ b/handler.go @@ -803,12 +803,33 @@ func (h *Handler) handleDeleteView(w http.ResponseWriter, r *http.Request) { return } - if err := f.DeleteView(viewName); err != nil { + // Check that the view name is an integer. + if _, err := strconv.Atoi(viewName); err != nil { + http.Error(w, "only time based views can be deleted", http.StatusBadRequest) + return + } + + // Check the frame for time quantum. + if f.TimeQuantum() == "" { + http.Error(w, "frame does not contain a Time Quantum", http.StatusBadRequest) + return + } + + // Delete the standard view. + if err := f.DeleteView(ViewStandard + "_" + viewName); err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } - // TODO: Send the delete frame message to all nodes. + // Delete the inverse view. + if f.InverseEnabled() { + if err := f.DeleteView(ViewInverse + "_" + viewName); err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + } + + // TODO: Send the delete view message to all nodes. // Encode response. if err := json.NewEncoder(w).Encode(deleteViewResponse{}); err != nil { diff --git a/handler_test.go b/handler_test.go index 2947fd1b8..c8e0d949c 100644 --- a/handler_test.go +++ b/handler_test.go @@ -1516,18 +1516,19 @@ func TestHandler_GetTimeStamp(t *testing.T) { func TestHandler_DeleteView(t *testing.T) { hldr := test.MustOpenHolder() defer hldr.Close() - hldr.MustCreateFragmentIfNotExists("i0", "f0", "v0", 1).MustSetBits(30, (1*SliceWidth)+1) + hldr.MustCreateFragmentIfNotExists("i0", "f0", pilosa.ViewStandard+"_2017", 1).MustSetBits(30, (1*SliceWidth)+1) + hldr.Index("i0").Frame("f0").SetTimeQuantum("YMD") h := test.NewHandler() h.Holder = hldr.Holder h.Cluster = test.NewCluster(1) w := httptest.NewRecorder() - h.ServeHTTP(w, test.MustNewHTTPRequest("DELETE", "/index/i0/frame/f0/view/v0", strings.NewReader(""))) + h.ServeHTTP(w, test.MustNewHTTPRequest("DELETE", "/index/i0/frame/f0/view/2017", strings.NewReader(""))) if w.Code != http.StatusOK { t.Fatalf("unexpected status code: %d", w.Code) } else if body := w.Body.String(); body != `{}`+"\n" { t.Fatalf("unexpected body: %s", body) - } else if f := hldr.Index("i0").Frame("f0").View("v0"); f != nil { + } else if f := hldr.Index("i0").Frame("f0").View(pilosa.ViewStandard + "_2017"); f != nil { t.Fatal("expected nil view") } } From 941d8a757578926f7b4fdb7aaa700ed3d7d0e07c Mon Sep 17 00:00:00 2001 From: Michael Baird Date: Fri, 18 Aug 2017 09:36:45 -0500 Subject: [PATCH 04/12] DeleteView from Frame --- frame.go | 20 ++++++++++++++++++++ frame_test.go | 31 +++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/frame.go b/frame.go index 19c25eeab..675736d36 100644 --- a/frame.go +++ b/frame.go @@ -513,6 +513,26 @@ func (f *Frame) newView(path, name string) *View { return view } +// DeleteView removes a view from the frame. +func (f *Frame) DeleteView(name string) error { + view := f.views[name] + if view == nil { + return ErrInvalidView + } + + // TODO capture errors lower down in this method + _ = view.Close() + + // Delete view directory. + if err := os.RemoveAll(view.Path()); err != nil { + return err + } + + delete(f.views, name) + + return nil +} + // SetBit sets a bit on a view within the frame. func (f *Frame) SetBit(name string, rowID, colID uint64, t *time.Time) (changed bool, err error) { // Validate view name. diff --git a/frame_test.go b/frame_test.go index 8cb48cca8..b560d985e 100644 --- a/frame_test.go +++ b/frame_test.go @@ -307,3 +307,34 @@ func TestFrame_RowLabelValidation(t *testing.T) { } } + +// Ensure frame can open and retrieve a view. +func TestFrame_DeleteView(t *testing.T) { + f := test.MustOpenFrame() + defer f.Close() + + // Create view. + view, err := f.CreateViewIfNotExists("v") + if err != nil { + t.Fatal(err) + } else if view == nil { + t.Fatal("expected view") + } + + err = f.DeleteView("v") + if err != nil { + t.Fatal(err) + } + + if f.View("v") != nil { + t.Fatal("view still exists in frame") + } + + // // Retrieve existing view. + view2, err := f.CreateViewIfNotExists("v") + if err != nil { + t.Fatal(err) + } else if view == view2 { + t.Fatal("failed to create new view") + } +} From b03e45e3e389aedcee3b6a9590711b631e21dc6c Mon Sep 17 00:00:00 2001 From: Michael Baird Date: Fri, 18 Aug 2017 14:55:29 -0500 Subject: [PATCH 05/12] handler for delete View --- handler.go | 29 +++++++++++++++++++++++++++++ handler_test.go | 20 ++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/handler.go b/handler.go index 1e7d47c69..afad04123 100644 --- a/handler.go +++ b/handler.go @@ -116,6 +116,7 @@ func NewRouter(handler *Handler) *mux.Router { router.HandleFunc("/index/{index}/frame/{frame}/restore", handler.handlePostFrameRestore).Methods("POST") router.HandleFunc("/index/{index}/frame/{frame}/time-quantum", handler.handlePatchFrameTimeQuantum).Methods("PATCH") router.HandleFunc("/index/{index}/frame/{frame}/views", handler.handleGetFrameViews).Methods("GET") + router.HandleFunc("/index/{index}/frame/{frame}/view/{view}", handler.handleDeleteView).Methods("DELETE") router.HandleFunc("/index/{index}/input/{input-definition}", handler.handlePostInput).Methods("POST") router.HandleFunc("/index/{index}/input-definition/{input-definition}", handler.handleGetInputDefinition).Methods("GET") router.HandleFunc("/index/{index}/input-definition/{input-definition}", handler.handlePostInputDefinition).Methods("POST") @@ -789,6 +790,34 @@ func (h *Handler) handleGetFrameViews(w http.ResponseWriter, r *http.Request) { } } +// handleDeleteView handles Delete /frame/view request. +func (h *Handler) handleDeleteView(w http.ResponseWriter, r *http.Request) { + indexName := mux.Vars(r)["index"] + frameName := mux.Vars(r)["frame"] + viewName := mux.Vars(r)["view"] + + // Retrieve frame. + f := h.Holder.Frame(indexName, frameName) + if f == nil { + http.Error(w, ErrFrameNotFound.Error(), http.StatusNotFound) + return + } + + if err := f.DeleteView(viewName); err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + + // TODO: Send the delete frame message to all nodes. + + // Encode response. + if err := json.NewEncoder(w).Encode(deleteViewResponse{}); err != nil { + h.logger().Printf("response encoding error: %s", err) + } +} + +type deleteViewResponse struct{} + type getFrameViewsResponse struct { Views []string `json:"views,omitempty"` } diff --git a/handler_test.go b/handler_test.go index 22a1fd4f3..2947fd1b8 100644 --- a/handler_test.go +++ b/handler_test.go @@ -1511,3 +1511,23 @@ func TestHandler_GetTimeStamp(t *testing.T) { t.Fatalf("Expected Ignore nonexistent fields") } } + +// Ensure handler can delete a view. +func TestHandler_DeleteView(t *testing.T) { + hldr := test.MustOpenHolder() + defer hldr.Close() + hldr.MustCreateFragmentIfNotExists("i0", "f0", "v0", 1).MustSetBits(30, (1*SliceWidth)+1) + + h := test.NewHandler() + h.Holder = hldr.Holder + h.Cluster = test.NewCluster(1) + w := httptest.NewRecorder() + h.ServeHTTP(w, test.MustNewHTTPRequest("DELETE", "/index/i0/frame/f0/view/v0", strings.NewReader(""))) + if w.Code != http.StatusOK { + t.Fatalf("unexpected status code: %d", w.Code) + } else if body := w.Body.String(); body != `{}`+"\n" { + t.Fatalf("unexpected body: %s", body) + } else if f := hldr.Index("i0").Frame("f0").View("v0"); f != nil { + t.Fatal("expected nil view") + } +} From 53930a530fefa052867bba49daae32805abe1d84 Mon Sep 17 00:00:00 2001 From: Michael Baird Date: Fri, 18 Aug 2017 17:08:13 -0500 Subject: [PATCH 06/12] delete only time based views, and handle inverse views --- handler.go | 25 +++++++++++++++++++++++-- handler_test.go | 7 ++++--- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/handler.go b/handler.go index afad04123..63d76d479 100644 --- a/handler.go +++ b/handler.go @@ -803,12 +803,33 @@ func (h *Handler) handleDeleteView(w http.ResponseWriter, r *http.Request) { return } - if err := f.DeleteView(viewName); err != nil { + // Check that the view name is an integer. + if _, err := strconv.Atoi(viewName); err != nil { + http.Error(w, "only time based views can be deleted", http.StatusBadRequest) + return + } + + // Check the frame for time quantum. + if f.TimeQuantum() == "" { + http.Error(w, "frame does not contain a Time Quantum", http.StatusBadRequest) + return + } + + // Delete the standard view. + if err := f.DeleteView(ViewStandard + "_" + viewName); err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } - // TODO: Send the delete frame message to all nodes. + // Delete the inverse view. + if f.InverseEnabled() { + if err := f.DeleteView(ViewInverse + "_" + viewName); err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + } + + // TODO: Send the delete view message to all nodes. // Encode response. if err := json.NewEncoder(w).Encode(deleteViewResponse{}); err != nil { diff --git a/handler_test.go b/handler_test.go index 2947fd1b8..c8e0d949c 100644 --- a/handler_test.go +++ b/handler_test.go @@ -1516,18 +1516,19 @@ func TestHandler_GetTimeStamp(t *testing.T) { func TestHandler_DeleteView(t *testing.T) { hldr := test.MustOpenHolder() defer hldr.Close() - hldr.MustCreateFragmentIfNotExists("i0", "f0", "v0", 1).MustSetBits(30, (1*SliceWidth)+1) + hldr.MustCreateFragmentIfNotExists("i0", "f0", pilosa.ViewStandard+"_2017", 1).MustSetBits(30, (1*SliceWidth)+1) + hldr.Index("i0").Frame("f0").SetTimeQuantum("YMD") h := test.NewHandler() h.Holder = hldr.Holder h.Cluster = test.NewCluster(1) w := httptest.NewRecorder() - h.ServeHTTP(w, test.MustNewHTTPRequest("DELETE", "/index/i0/frame/f0/view/v0", strings.NewReader(""))) + h.ServeHTTP(w, test.MustNewHTTPRequest("DELETE", "/index/i0/frame/f0/view/2017", strings.NewReader(""))) if w.Code != http.StatusOK { t.Fatalf("unexpected status code: %d", w.Code) } else if body := w.Body.String(); body != `{}`+"\n" { t.Fatalf("unexpected body: %s", body) - } else if f := hldr.Index("i0").Frame("f0").View("v0"); f != nil { + } else if f := hldr.Index("i0").Frame("f0").View(pilosa.ViewStandard + "_2017"); f != nil { t.Fatal("expected nil view") } } From ff3190e0d354d906b2220fb0351126fc6edc2067 Mon Sep 17 00:00:00 2001 From: Michael Baird Date: Tue, 22 Aug 2017 11:39:00 -0500 Subject: [PATCH 07/12] Broadcast and handle the DeleteViewMessage --- broadcast.go | 5 + frame.go | 19 ++- frame_test.go | 8 +- handler.go | 27 ++-- internal/private.pb.go | 320 +++++++++++++++++++++++++++++++++-------- internal/private.proto | 6 + server.go | 9 ++ 7 files changed, 317 insertions(+), 77 deletions(-) diff --git a/broadcast.go b/broadcast.go index 866b03d02..0785a21cc 100644 --- a/broadcast.go +++ b/broadcast.go @@ -115,6 +115,7 @@ const ( MessageTypeDeleteFrame = 5 MessageTypeCreateInputDefinition = 6 MessageTypeDeleteInputDefinition = 7 + MessageTypeDeleteView = 8 ) // MarshalMessage encodes the protobuf message into a byte slice. @@ -135,6 +136,8 @@ func MarshalMessage(m proto.Message) ([]byte, error) { typ = MessageTypeCreateInputDefinition case *internal.DeleteInputDefinitionMessage: typ = MessageTypeDeleteInputDefinition + case *internal.DeleteViewMessage: + typ = MessageTypeDeleteView default: return nil, fmt.Errorf("message type not implemented for marshalling: %s", reflect.TypeOf(obj)) } @@ -165,6 +168,8 @@ func UnmarshalMessage(buf []byte) (proto.Message, error) { m = &internal.CreateInputDefinitionMessage{} case MessageTypeDeleteInputDefinition: m = &internal.DeleteInputDefinitionMessage{} + case MessageTypeDeleteView: + m = &internal.DeleteViewMessage{} default: return nil, fmt.Errorf("invalid message type: %d", typ) } diff --git a/frame.go b/frame.go index 675736d36..0b393a5c7 100644 --- a/frame.go +++ b/frame.go @@ -513,8 +513,25 @@ func (f *Frame) newView(path, name string) *View { return view } -// DeleteView removes a view from the frame. +// DeleteView removes the standard and inverse view from the frame. func (f *Frame) DeleteView(name string) error { + // Delete the standard view. + if err := f.deleteView(ViewStandard + "_" + name); err != nil { + return err + } + + // Delete the inverse view. + if f.InverseEnabled() { + if err := f.deleteView(ViewInverse + "_" + name); err != nil { + return err + } + } + + return nil +} + +// deleteView removes view from the frame. +func (f *Frame) deleteView(name string) error { view := f.views[name] if view == nil { return ErrInvalidView diff --git a/frame_test.go b/frame_test.go index b560d985e..8a8db3f27 100644 --- a/frame_test.go +++ b/frame_test.go @@ -313,8 +313,10 @@ func TestFrame_DeleteView(t *testing.T) { f := test.MustOpenFrame() defer f.Close() + viewName := pilosa.ViewStandard + "_v" + // Create view. - view, err := f.CreateViewIfNotExists("v") + view, err := f.CreateViewIfNotExists(viewName) if err != nil { t.Fatal(err) } else if view == nil { @@ -326,12 +328,12 @@ func TestFrame_DeleteView(t *testing.T) { t.Fatal(err) } - if f.View("v") != nil { + if f.View(viewName) != nil { t.Fatal("view still exists in frame") } // // Retrieve existing view. - view2, err := f.CreateViewIfNotExists("v") + view2, err := f.CreateViewIfNotExists(viewName) if err != nil { t.Fatal(err) } else if view == view2 { diff --git a/handler.go b/handler.go index 63d76d479..38254e1ae 100644 --- a/handler.go +++ b/handler.go @@ -803,34 +803,29 @@ func (h *Handler) handleDeleteView(w http.ResponseWriter, r *http.Request) { return } - // Check that the view name is an integer. - if _, err := strconv.Atoi(viewName); err != nil { - http.Error(w, "only time based views can be deleted", http.StatusBadRequest) - return - } - // Check the frame for time quantum. if f.TimeQuantum() == "" { http.Error(w, "frame does not contain a Time Quantum", http.StatusBadRequest) return } - // Delete the standard view. - if err := f.DeleteView(ViewStandard + "_" + viewName); err != nil { + // Delete the view. + if err := f.DeleteView(viewName); err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } - // Delete the inverse view. - if f.InverseEnabled() { - if err := f.DeleteView(ViewInverse + "_" + viewName); err != nil { - http.Error(w, err.Error(), http.StatusBadRequest) - return - } + // Send the delete view message to all nodes. + err := h.Broadcaster.SendSync( + &internal.DeleteViewMessage{ + Index: indexName, + Frame: frameName, + View: viewName, + }) + if err != nil { + h.logger().Printf("problem sending DeleteView message: %s", err) } - // TODO: Send the delete view message to all nodes. - // Encode response. if err := json.NewEncoder(w).Encode(deleteViewResponse{}); err != nil { h.logger().Printf("response encoding error: %s", err) diff --git a/internal/private.pb.go b/internal/private.pb.go index abde718e9..0a9956279 100644 --- a/internal/private.pb.go +++ b/internal/private.pb.go @@ -32,6 +32,7 @@ ClusterStatus FrameSchema Field + DeleteViewMessage */ package internal @@ -405,6 +406,17 @@ func (m *Field) String() string { return proto.CompactTextString(m) } func (*Field) ProtoMessage() {} func (*Field) Descriptor() ([]byte, []int) { return fileDescriptorPrivate, []int{22} } +type DeleteViewMessage struct { + Index string `protobuf:"bytes,1,opt,name=Index,proto3" json:"Index,omitempty"` + Frame string `protobuf:"bytes,2,opt,name=Frame,proto3" json:"Frame,omitempty"` + View string `protobuf:"bytes,3,opt,name=View,proto3" json:"View,omitempty"` +} + +func (m *DeleteViewMessage) Reset() { *m = DeleteViewMessage{} } +func (m *DeleteViewMessage) String() string { return proto.CompactTextString(m) } +func (*DeleteViewMessage) ProtoMessage() {} +func (*DeleteViewMessage) Descriptor() ([]byte, []int) { return fileDescriptorPrivate, []int{23} } + func init() { proto.RegisterType((*IndexMeta)(nil), "internal.IndexMeta") proto.RegisterType((*FrameMeta)(nil), "internal.FrameMeta") @@ -429,6 +441,7 @@ func init() { proto.RegisterType((*ClusterStatus)(nil), "internal.ClusterStatus") proto.RegisterType((*FrameSchema)(nil), "internal.FrameSchema") proto.RegisterType((*Field)(nil), "internal.Field") + proto.RegisterType((*DeleteViewMessage)(nil), "internal.DeleteViewMessage") } func (m *IndexMeta) Marshal() (dAtA []byte, err error) { size := m.Size() @@ -1344,6 +1357,42 @@ func (m *Field) MarshalTo(dAtA []byte) (int, error) { return i, nil } +func (m *DeleteViewMessage) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *DeleteViewMessage) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Index) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintPrivate(dAtA, i, uint64(len(m.Index))) + i += copy(dAtA[i:], m.Index) + } + if len(m.Frame) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintPrivate(dAtA, i, uint64(len(m.Frame))) + i += copy(dAtA[i:], m.Frame) + } + if len(m.View) > 0 { + dAtA[i] = 0x1a + i++ + i = encodeVarintPrivate(dAtA, i, uint64(len(m.View))) + i += copy(dAtA[i:], m.View) + } + return i, nil +} + func encodeFixed64Private(dAtA []byte, offset int, v uint64) int { dAtA[offset] = uint8(v) dAtA[offset+1] = uint8(v >> 8) @@ -1773,6 +1822,24 @@ func (m *Field) Size() (n int) { return n } +func (m *DeleteViewMessage) Size() (n int) { + var l int + _ = l + l = len(m.Index) + if l > 0 { + n += 1 + l + sovPrivate(uint64(l)) + } + l = len(m.Frame) + if l > 0 { + n += 1 + l + sovPrivate(uint64(l)) + } + l = len(m.View) + if l > 0 { + n += 1 + l + sovPrivate(uint64(l)) + } + return n +} + func sovPrivate(x uint64) (n int) { for { n++ @@ -4882,6 +4949,143 @@ func (m *Field) Unmarshal(dAtA []byte) error { } return nil } +func (m *DeleteViewMessage) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPrivate + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DeleteViewMessage: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DeleteViewMessage: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Index", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPrivate + } + 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 ErrInvalidLengthPrivate + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Index = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Frame", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPrivate + } + 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 ErrInvalidLengthPrivate + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Frame = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field View", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPrivate + } + 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 ErrInvalidLengthPrivate + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.View = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPrivate(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthPrivate + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipPrivate(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 @@ -4990,62 +5194,64 @@ var ( func init() { proto.RegisterFile("private.proto", fileDescriptorPrivate) } var fileDescriptorPrivate = []byte{ - // 912 bytes of a gzipped FileDescriptorProto + // 929 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0xc1, 0x6e, 0x23, 0x45, - 0x10, 0x65, 0xec, 0xb1, 0xb1, 0x2b, 0x24, 0xf1, 0x36, 0x61, 0xe5, 0x8d, 0x22, 0x13, 0xf5, 0x81, - 0x0d, 0x91, 0xc8, 0x61, 0x91, 0x56, 0xc0, 0x72, 0x80, 0x8d, 0xb3, 0x8a, 0x05, 0x5e, 0xa0, 0xbd, - 0x5a, 0x6e, 0x48, 0x1d, 0xa7, 0xd8, 0x1d, 0x65, 0x3c, 0x63, 0xa6, 0xdb, 0x49, 0xcc, 0x81, 0x23, - 0xdf, 0x80, 0xc4, 0x91, 0x9f, 0xe1, 0x08, 0x7f, 0x80, 0xc2, 0x85, 0x3f, 0xe0, 0x8a, 0xba, 0xba, - 0x7b, 0x66, 0x3c, 0x8e, 0x13, 0x85, 0x5b, 0xd7, 0xeb, 0xd7, 0x55, 0xaf, 0x6a, 0xaa, 0xca, 0x86, - 0xf5, 0x69, 0x16, 0x9d, 0x4b, 0x8d, 0x07, 0xd3, 0x2c, 0xd5, 0x29, 0x6b, 0x45, 0x89, 0xc6, 0x2c, - 0x91, 0x31, 0xff, 0x0a, 0xda, 0x83, 0xe4, 0x14, 0x2f, 0x87, 0xa8, 0x25, 0xdb, 0x85, 0xb5, 0xc3, - 0x34, 0x9e, 0x4d, 0x92, 0x2f, 0xe5, 0x09, 0xc6, 0xdd, 0x60, 0x37, 0xd8, 0x6b, 0x8b, 0x32, 0x64, - 0x18, 0x2f, 0xa2, 0x09, 0x7e, 0x33, 0x93, 0x89, 0x9e, 0x4d, 0xba, 0x35, 0xcb, 0x28, 0x41, 0xfc, - 0xcf, 0x00, 0xda, 0xcf, 0x32, 0x39, 0x41, 0xf2, 0xb8, 0x0d, 0x2d, 0x91, 0x5e, 0x94, 0xdd, 0xe5, - 0x36, 0x7b, 0x0f, 0x36, 0x06, 0xc9, 0x39, 0x66, 0x0a, 0x8f, 0x12, 0x79, 0x12, 0xe3, 0x29, 0xb9, - 0x6b, 0x89, 0x0a, 0xca, 0x76, 0xa0, 0x7d, 0x28, 0xc7, 0xaf, 0xf1, 0xc5, 0x7c, 0x8a, 0xdd, 0x3a, - 0x39, 0x29, 0x80, 0xfc, 0x76, 0x14, 0xfd, 0x88, 0xdd, 0x70, 0x37, 0xd8, 0x5b, 0x17, 0x05, 0x50, - 0xd5, 0xdb, 0x58, 0xd2, 0xcb, 0x38, 0xbc, 0x25, 0x64, 0xf2, 0x2a, 0xd7, 0xd0, 0x24, 0x0d, 0x0b, - 0x18, 0xe7, 0xb0, 0x31, 0x98, 0x4c, 0xd3, 0x4c, 0x0b, 0x54, 0xd3, 0x34, 0x51, 0xc8, 0x3a, 0x50, - 0x3f, 0xca, 0x32, 0x97, 0x92, 0x39, 0xf2, 0x9f, 0xa0, 0xf3, 0x34, 0x4e, 0xc7, 0x67, 0x7d, 0xa9, - 0xa5, 0xc0, 0x1f, 0x66, 0xa8, 0x34, 0xdb, 0x82, 0x06, 0x15, 0xd7, 0xf1, 0xac, 0x61, 0x50, 0x2a, - 0x90, 0xab, 0x9e, 0x35, 0x0c, 0x4a, 0xef, 0x29, 0xc3, 0x50, 0x58, 0xc3, 0xa0, 0xa3, 0x38, 0x1a, - 0xdb, 0xcc, 0x42, 0x61, 0x0d, 0xc6, 0x20, 0x7c, 0x19, 0xe1, 0x85, 0x4b, 0x87, 0xce, 0x7c, 0x00, - 0xf7, 0x4a, 0xf1, 0x9d, 0xcc, 0xfb, 0xd0, 0x14, 0xe9, 0xc5, 0xa0, 0xaf, 0xba, 0xc1, 0x6e, 0x7d, - 0x2f, 0x14, 0xce, 0xa2, 0xa2, 0xd1, 0x57, 0x35, 0x57, 0x35, 0xba, 0x2a, 0x00, 0xfe, 0x00, 0x1a, - 0x54, 0x41, 0x93, 0x65, 0xf1, 0xd6, 0x1c, 0xf9, 0xaf, 0x01, 0xdc, 0x1b, 0xca, 0x4b, 0x92, 0xa1, - 0xf2, 0x30, 0xc7, 0xd0, 0xce, 0x41, 0x62, 0xaf, 0x3d, 0xda, 0x3f, 0xf0, 0x2d, 0x76, 0xb0, 0xc4, - 0x2f, 0x90, 0xa3, 0x44, 0x67, 0x73, 0x51, 0x3c, 0xde, 0xfe, 0x14, 0x36, 0x16, 0x2f, 0x8d, 0x86, - 0x33, 0x9c, 0xfb, 0x4a, 0x9f, 0xe1, 0xdc, 0xd4, 0xe4, 0x5c, 0xc6, 0x33, 0x5b, 0xbf, 0x50, 0x58, - 0xe3, 0x93, 0xda, 0x47, 0x01, 0xff, 0x0e, 0xd8, 0x61, 0x86, 0x52, 0x23, 0x39, 0x18, 0xa2, 0x52, - 0xf2, 0x15, 0xae, 0xfe, 0x0a, 0xb6, 0xb2, 0xb5, 0x72, 0x65, 0x77, 0xa0, 0x3d, 0x50, 0xae, 0xff, - 0xe8, 0x4b, 0xb4, 0x44, 0x01, 0xf0, 0x7d, 0x60, 0x7d, 0x8c, 0x51, 0xa3, 0x1b, 0x99, 0x1b, 0xfc, - 0xf3, 0x91, 0xd7, 0x72, 0x3b, 0x97, 0x3d, 0x84, 0xd0, 0x4c, 0x0b, 0x49, 0x59, 0x7b, 0xf4, 0x76, - 0x51, 0xba, 0x7c, 0x34, 0x05, 0x11, 0x78, 0xe4, 0x9d, 0xba, 0x09, 0xbb, 0x25, 0xc1, 0x6b, 0xda, - 0xcc, 0x87, 0xaa, 0x57, 0x43, 0xe5, 0x33, 0xeb, 0x42, 0x7d, 0xe6, 0x73, 0xfd, 0xbf, 0xa1, 0x78, - 0xdf, 0xa1, 0xa6, 0x5d, 0x9f, 0x9b, 0x5b, 0xfb, 0x86, 0xce, 0xab, 0x53, 0xae, 0xea, 0xf8, 0x27, - 0x70, 0x21, 0xef, 0xe6, 0xa6, 0x52, 0x39, 0xb3, 0x88, 0x7c, 0x63, 0xb9, 0x09, 0xcb, 0x6d, 0xf6, - 0x10, 0x9a, 0x14, 0x55, 0x75, 0x43, 0xea, 0xdd, 0xcd, 0x8a, 0x1a, 0xe1, 0xae, 0xcd, 0x38, 0xb9, - 0x26, 0x6f, 0xd8, 0x71, 0xb2, 0x16, 0x3b, 0x82, 0xce, 0x20, 0x99, 0xce, 0x74, 0x1f, 0xbf, 0x8f, - 0x92, 0x48, 0x47, 0x69, 0xa2, 0xba, 0x4d, 0x72, 0xf5, 0xa0, 0xac, 0x68, 0x81, 0x21, 0x96, 0x9e, - 0xf0, 0x9f, 0x03, 0xd8, 0xac, 0x80, 0x2b, 0x92, 0xf6, 0x7a, 0x6b, 0x37, 0xeb, 0x7d, 0x0c, 0xcd, - 0x67, 0x11, 0xc6, 0xa7, 0xaa, 0x5b, 0x27, 0x62, 0x6f, 0xa5, 0x1a, 0xa2, 0x09, 0xc7, 0xe6, 0xbf, - 0x05, 0xb0, 0x75, 0x1d, 0xe1, 0x5a, 0x35, 0x3d, 0x80, 0xaf, 0xb3, 0x68, 0x22, 0xb3, 0xf9, 0x17, - 0x38, 0x77, 0x2b, 0xbc, 0x84, 0xb0, 0x6f, 0xe1, 0x7e, 0xc5, 0xd7, 0xe7, 0x63, 0x5b, 0x22, 0x2b, - 0xea, 0xdd, 0x95, 0xa2, 0x2c, 0x4f, 0xac, 0x78, 0xce, 0xff, 0x0d, 0xe0, 0x9d, 0x6b, 0xaf, 0x8a, - 0x7e, 0x0c, 0xca, 0xad, 0xbf, 0x0f, 0x9d, 0x97, 0x66, 0x55, 0xf4, 0x51, 0xe9, 0x28, 0x91, 0x86, - 0xe9, 0x1a, 0x76, 0x09, 0x67, 0x03, 0x68, 0x11, 0x36, 0x94, 0x53, 0x27, 0xf3, 0x83, 0x5b, 0x64, - 0x1e, 0x78, 0xbe, 0xdd, 0x69, 0xf9, 0x73, 0x23, 0x86, 0xb6, 0xae, 0x5f, 0xe1, 0x64, 0x6c, 0x3f, - 0x81, 0xf5, 0x85, 0x07, 0x77, 0xda, 0x73, 0x29, 0xec, 0xf8, 0xdd, 0xb2, 0xa0, 0xe4, 0xe6, 0x29, - 0xfd, 0x18, 0xa0, 0xa0, 0xba, 0x05, 0x70, 0x43, 0x7f, 0x96, 0xc8, 0xfc, 0x18, 0x76, 0xfc, 0xe2, - 0xbb, 0x43, 0x40, 0xdf, 0x2d, 0xb5, 0xa2, 0x5b, 0xb8, 0x04, 0x78, 0x9e, 0x9e, 0xe2, 0x48, 0x4b, - 0x3d, 0x53, 0x86, 0x71, 0x9c, 0x2a, 0xed, 0xfb, 0xc9, 0x9c, 0x69, 0x31, 0x6b, 0xa9, 0xf3, 0x65, - 0x42, 0x06, 0x7b, 0x1f, 0xde, 0x24, 0xa7, 0xe8, 0xdb, 0x66, 0xb3, 0x32, 0xeb, 0xc2, 0xdf, 0xf3, - 0x27, 0xb0, 0x7e, 0x18, 0xcf, 0x94, 0xc6, 0xcc, 0x45, 0xd9, 0x87, 0x86, 0x89, 0xe9, 0x7f, 0x9a, - 0xb6, 0x8a, 0x97, 0x85, 0x14, 0x61, 0x29, 0xfc, 0x31, 0xac, 0x51, 0xb7, 0x8c, 0xc6, 0xaf, 0x71, - 0x22, 0x69, 0xd4, 0xec, 0x04, 0x05, 0x4b, 0xa3, 0xb6, 0x30, 0x32, 0x23, 0x68, 0xac, 0x1e, 0x11, - 0x06, 0x21, 0xfd, 0x79, 0x71, 0x85, 0xa0, 0xff, 0x2d, 0x1d, 0xa8, 0x0f, 0x23, 0xfb, 0x19, 0xea, - 0xc2, 0x1c, 0x09, 0x91, 0x97, 0xd4, 0x26, 0x06, 0x91, 0x97, 0x4f, 0x3b, 0xbf, 0x5f, 0xf5, 0x82, - 0x3f, 0xae, 0x7a, 0xc1, 0x5f, 0x57, 0xbd, 0xe0, 0x97, 0xbf, 0x7b, 0x6f, 0x9c, 0x34, 0xe9, 0xff, - 0xdb, 0x87, 0xff, 0x05, 0x00, 0x00, 0xff, 0xff, 0x29, 0x07, 0x36, 0x04, 0xd0, 0x09, 0x00, 0x00, + 0x10, 0x65, 0xec, 0xb1, 0xb1, 0x2b, 0x24, 0x71, 0x9a, 0xb0, 0xf2, 0x46, 0x91, 0x89, 0xfa, 0xc0, + 0x86, 0x48, 0xe4, 0xb0, 0x48, 0x2b, 0x60, 0x39, 0xc0, 0xc6, 0x59, 0xc5, 0x02, 0x2f, 0xd0, 0x5e, + 0x2d, 0x37, 0xa4, 0x8e, 0x53, 0xec, 0x8e, 0x32, 0x9e, 0x31, 0x33, 0x3d, 0x49, 0xcc, 0x81, 0x23, + 0xdf, 0x80, 0xc4, 0x91, 0x9f, 0xe1, 0x08, 0x7f, 0x80, 0xc2, 0x85, 0x3f, 0xe0, 0xba, 0xea, 0xea, + 0xee, 0x99, 0xf1, 0x38, 0x76, 0x94, 0xbd, 0x75, 0xbd, 0x7e, 0x5d, 0xf5, 0xba, 0xa6, 0xaa, 0xa6, + 0x61, 0x7d, 0x9a, 0x04, 0x17, 0x52, 0xe1, 0xe1, 0x34, 0x89, 0x55, 0xcc, 0x5a, 0x41, 0xa4, 0x30, + 0x89, 0x64, 0xc8, 0xbf, 0x81, 0xf6, 0x20, 0x3a, 0xc3, 0xab, 0x21, 0x2a, 0xc9, 0xf6, 0x60, 0xed, + 0x28, 0x0e, 0xb3, 0x49, 0xf4, 0xb5, 0x3c, 0xc5, 0xb0, 0xeb, 0xed, 0x79, 0xfb, 0x6d, 0x51, 0x86, + 0x34, 0xe3, 0x79, 0x30, 0xc1, 0xef, 0x32, 0x19, 0xa9, 0x6c, 0xd2, 0xad, 0x19, 0x46, 0x09, 0xe2, + 0x7f, 0x7b, 0xd0, 0x7e, 0x9a, 0xc8, 0x09, 0x92, 0xc7, 0x1d, 0x68, 0x89, 0xf8, 0xb2, 0xec, 0x2e, + 0xb7, 0xd9, 0x07, 0xb0, 0x31, 0x88, 0x2e, 0x30, 0x49, 0xf1, 0x38, 0x92, 0xa7, 0x21, 0x9e, 0x91, + 0xbb, 0x96, 0xa8, 0xa0, 0x6c, 0x17, 0xda, 0x47, 0x72, 0xfc, 0x0a, 0x9f, 0xcf, 0xa6, 0xd8, 0xad, + 0x93, 0x93, 0x02, 0xc8, 0x77, 0x47, 0xc1, 0xcf, 0xd8, 0xf5, 0xf7, 0xbc, 0xfd, 0x75, 0x51, 0x00, + 0x55, 0xbd, 0x8d, 0x05, 0xbd, 0x8c, 0xc3, 0x3b, 0x42, 0x46, 0x2f, 0x73, 0x0d, 0x4d, 0xd2, 0x30, + 0x87, 0x71, 0x0e, 0x1b, 0x83, 0xc9, 0x34, 0x4e, 0x94, 0xc0, 0x74, 0x1a, 0x47, 0x29, 0xb2, 0x0e, + 0xd4, 0x8f, 0x93, 0xc4, 0x5e, 0x49, 0x2f, 0xf9, 0x2f, 0xd0, 0x79, 0x12, 0xc6, 0xe3, 0xf3, 0xbe, + 0x54, 0x52, 0xe0, 0x4f, 0x19, 0xa6, 0x8a, 0x6d, 0x43, 0x83, 0x92, 0x6b, 0x79, 0xc6, 0xd0, 0x28, + 0x25, 0xc8, 0x66, 0xcf, 0x18, 0x1a, 0xa5, 0xf3, 0x74, 0x43, 0x5f, 0x18, 0x43, 0xa3, 0xa3, 0x30, + 0x18, 0x9b, 0x9b, 0xf9, 0xc2, 0x18, 0x8c, 0x81, 0xff, 0x22, 0xc0, 0x4b, 0x7b, 0x1d, 0x5a, 0xf3, + 0x01, 0x6c, 0x95, 0xe2, 0x5b, 0x99, 0xf7, 0xa0, 0x29, 0xe2, 0xcb, 0x41, 0x3f, 0xed, 0x7a, 0x7b, + 0xf5, 0x7d, 0x5f, 0x58, 0x8b, 0x92, 0x46, 0x5f, 0x55, 0x6f, 0xd5, 0x68, 0xab, 0x00, 0xf8, 0x7d, + 0x68, 0x50, 0x06, 0xf5, 0x2d, 0x8b, 0xb3, 0x7a, 0xc9, 0x7f, 0xf7, 0x60, 0x6b, 0x28, 0xaf, 0x48, + 0x46, 0x9a, 0x87, 0x39, 0x81, 0x76, 0x0e, 0x12, 0x7b, 0xed, 0xe1, 0xc1, 0xa1, 0x2b, 0xb1, 0xc3, + 0x05, 0x7e, 0x81, 0x1c, 0x47, 0x2a, 0x99, 0x89, 0xe2, 0xf0, 0xce, 0xe7, 0xb0, 0x31, 0xbf, 0xa9, + 0x35, 0x9c, 0xe3, 0xcc, 0x65, 0xfa, 0x1c, 0x67, 0x3a, 0x27, 0x17, 0x32, 0xcc, 0x4c, 0xfe, 0x7c, + 0x61, 0x8c, 0xcf, 0x6a, 0x9f, 0x78, 0xfc, 0x07, 0x60, 0x47, 0x09, 0x4a, 0x85, 0xe4, 0x60, 0x88, + 0x69, 0x2a, 0x5f, 0xe2, 0xf2, 0xaf, 0x60, 0x32, 0x5b, 0x2b, 0x67, 0x76, 0x17, 0xda, 0x83, 0xd4, + 0xd6, 0x1f, 0x7d, 0x89, 0x96, 0x28, 0x00, 0x7e, 0x00, 0xac, 0x8f, 0x21, 0x2a, 0xb4, 0x2d, 0xb3, + 0xc2, 0x3f, 0x1f, 0x39, 0x2d, 0xb7, 0x73, 0xd9, 0x03, 0xf0, 0x75, 0xb7, 0x90, 0x94, 0xb5, 0x87, + 0xef, 0x16, 0xa9, 0xcb, 0x5b, 0x53, 0x10, 0x81, 0x07, 0xce, 0xa9, 0xed, 0xb0, 0x5b, 0x2e, 0x78, + 0x43, 0x99, 0xb9, 0x50, 0xf5, 0x6a, 0xa8, 0xbc, 0x67, 0x6d, 0xa8, 0x2f, 0xdc, 0x5d, 0xdf, 0x34, + 0x14, 0xef, 0x5b, 0x54, 0x97, 0xeb, 0x33, 0xbd, 0x6b, 0xce, 0xd0, 0x7a, 0xf9, 0x95, 0xab, 0x3a, + 0xfe, 0xf3, 0x6c, 0xc8, 0xbb, 0xb9, 0xa9, 0x64, 0x4e, 0x0f, 0x22, 0x57, 0x58, 0xb6, 0xc3, 0x72, + 0x9b, 0x3d, 0x80, 0x26, 0x45, 0x4d, 0xbb, 0x3e, 0xd5, 0xee, 0x66, 0x45, 0x8d, 0xb0, 0xdb, 0xba, + 0x9d, 0x6c, 0x91, 0x37, 0x4c, 0x3b, 0x19, 0x8b, 0x1d, 0x43, 0x67, 0x10, 0x4d, 0x33, 0xd5, 0xc7, + 0x1f, 0x83, 0x28, 0x50, 0x41, 0x1c, 0xa5, 0xdd, 0x26, 0xb9, 0xba, 0x5f, 0x56, 0x34, 0xc7, 0x10, + 0x0b, 0x47, 0xf8, 0xaf, 0x1e, 0x6c, 0x56, 0xc0, 0x25, 0x97, 0x76, 0x7a, 0x6b, 0xab, 0xf5, 0x3e, + 0x82, 0xe6, 0xd3, 0x00, 0xc3, 0xb3, 0xb4, 0x5b, 0x27, 0x62, 0x6f, 0xa9, 0x1a, 0xa2, 0x09, 0xcb, + 0xe6, 0x7f, 0x78, 0xb0, 0x7d, 0x13, 0xe1, 0x46, 0x35, 0x3d, 0x80, 0x6f, 0x93, 0x60, 0x22, 0x93, + 0xd9, 0x57, 0x38, 0xb3, 0x23, 0xbc, 0x84, 0xb0, 0xef, 0xe1, 0x5e, 0xc5, 0xd7, 0x97, 0x63, 0x93, + 0x22, 0x23, 0xea, 0xfd, 0xa5, 0xa2, 0x0c, 0x4f, 0x2c, 0x39, 0xce, 0xff, 0xf7, 0xe0, 0xbd, 0x1b, + 0xb7, 0x8a, 0x7a, 0xf4, 0xca, 0xa5, 0x7f, 0x00, 0x9d, 0x17, 0x7a, 0x54, 0xf4, 0x31, 0x55, 0x41, + 0x24, 0x35, 0xd3, 0x16, 0xec, 0x02, 0xce, 0x06, 0xd0, 0x22, 0x6c, 0x28, 0xa7, 0x56, 0xe6, 0x47, + 0xb7, 0xc8, 0x3c, 0x74, 0x7c, 0x33, 0xd3, 0xf2, 0xe3, 0x5a, 0x0c, 0x4d, 0x5d, 0x37, 0xc2, 0xc9, + 0xd8, 0x79, 0x0c, 0xeb, 0x73, 0x07, 0xee, 0x34, 0xe7, 0x62, 0xd8, 0x75, 0xb3, 0x65, 0x4e, 0xc9, + 0xea, 0x2e, 0xfd, 0x14, 0xa0, 0xa0, 0xda, 0x01, 0xb0, 0xa2, 0x3e, 0x4b, 0x64, 0x7e, 0x02, 0xbb, + 0x6e, 0xf0, 0xdd, 0x21, 0xa0, 0xab, 0x96, 0x5a, 0x51, 0x2d, 0x5c, 0x02, 0x3c, 0x8b, 0xcf, 0x70, + 0xa4, 0xa4, 0xca, 0x52, 0xcd, 0x38, 0x89, 0x53, 0xe5, 0xea, 0x49, 0xaf, 0x69, 0x30, 0x2b, 0xa9, + 0xf2, 0x61, 0x42, 0x06, 0xfb, 0x10, 0xde, 0x26, 0xa7, 0xe8, 0xca, 0x66, 0xb3, 0xd2, 0xeb, 0xc2, + 0xed, 0xf3, 0xc7, 0xb0, 0x7e, 0x14, 0x66, 0xa9, 0xc2, 0xc4, 0x46, 0x39, 0x80, 0x86, 0x8e, 0xe9, + 0x7e, 0x4d, 0xdb, 0xc5, 0xc9, 0x42, 0x8a, 0x30, 0x14, 0xfe, 0x08, 0xd6, 0xa8, 0x5a, 0x46, 0xe3, + 0x57, 0x38, 0x91, 0xd4, 0x6a, 0xa6, 0x83, 0xbc, 0x85, 0x56, 0x9b, 0x6b, 0x99, 0x11, 0x34, 0x96, + 0xb7, 0x08, 0x03, 0x9f, 0x1e, 0x2f, 0x36, 0x11, 0xf4, 0x6e, 0xe9, 0x40, 0x7d, 0x18, 0x98, 0xcf, + 0x50, 0x17, 0x7a, 0x49, 0x88, 0xbc, 0xa2, 0x32, 0xd1, 0x88, 0xd4, 0xff, 0x90, 0x2d, 0x93, 0x76, + 0xfd, 0x87, 0x7f, 0x93, 0x69, 0xef, 0x1e, 0x0a, 0xf5, 0xe2, 0xa1, 0xf0, 0xa4, 0xf3, 0xe7, 0x75, + 0xcf, 0xfb, 0xeb, 0xba, 0xe7, 0xfd, 0x73, 0xdd, 0xf3, 0x7e, 0xfb, 0xb7, 0xf7, 0xd6, 0x69, 0x93, + 0x1e, 0x85, 0x1f, 0xbf, 0x0e, 0x00, 0x00, 0xff, 0xff, 0x9f, 0xcc, 0xe2, 0x4c, 0x25, 0x0a, 0x00, + 0x00, } diff --git a/internal/private.proto b/internal/private.proto index 3173b12a2..68e9a5e5f 100644 --- a/internal/private.proto +++ b/internal/private.proto @@ -131,3 +131,9 @@ message Field { int64 Min = 3; int64 Max = 4; } + +message DeleteViewMessage { + string Index = 1; + string Frame = 2; + string View = 3; +} \ No newline at end of file diff --git a/server.go b/server.go index 97883fae4..8194278ba 100644 --- a/server.go +++ b/server.go @@ -339,6 +339,15 @@ func (s *Server) ReceiveMessage(pb proto.Message) error { if err != nil { return err } + case *internal.DeleteViewMessage: + f := s.Holder.Frame(obj.Index, obj.Frame) + if f == nil { + return fmt.Errorf("Local Frame not found: %s", obj.Frame) + } + err := f.DeleteView(obj.View) + if err != nil { + return err + } } return nil } From 2dfa689d71d2d06b7f81a6e96bf433fea2fe276b Mon Sep 17 00:00:00 2001 From: Michael Baird Date: Tue, 22 Aug 2017 14:52:07 -0500 Subject: [PATCH 08/12] Fragment.Close now returns an error. This required changing the Holder test utility Reopen, since in those cases we needed to close the file before making permission changes that Close() was failing silently on. --- fragment.go | 2 ++ frame.go | 10 +++++++--- holder.go | 4 +++- holder_test.go | 25 ++++++++++++++++++++++++- index.go | 4 +++- test/holder.go | 6 +++--- view.go | 4 +++- 7 files changed, 45 insertions(+), 10 deletions(-) diff --git a/fragment.go b/fragment.go index a517cbd57..bd3ebdad2 100644 --- a/fragment.go +++ b/fragment.go @@ -293,11 +293,13 @@ func (f *Fragment) close() error { // Flush cache if closing gracefully. if err := f.flushCache(); err != nil { f.logger().Printf("fragment: error flushing cache on close: err=%s, path=%s", err, f.path) + return err } // Close underlying storage. if err := f.closeStorage(); err != nil { f.logger().Printf("fragment: error closing storage: err=%s, path=%s", err, f.path) + return err } // Remove checksums. diff --git a/frame.go b/frame.go index 0b393a5c7..ad44cfb56 100644 --- a/frame.go +++ b/frame.go @@ -401,7 +401,9 @@ func (f *Frame) Close() error { // Close all views. for _, view := range f.views { - _ = view.Close() + if err := view.Close(); err != nil { + return err + } } f.views = make(map[string]*View) @@ -537,8 +539,10 @@ func (f *Frame) deleteView(name string) error { return ErrInvalidView } - // TODO capture errors lower down in this method - _ = view.Close() + // Close data files before deletion + if err := view.Close(); err != nil { + return err + } // Delete view directory. if err := os.RemoveAll(view.Path()); err != nil { diff --git a/holder.go b/holder.go index f7c363524..4270c2594 100644 --- a/holder.go +++ b/holder.go @@ -133,7 +133,9 @@ func (h *Holder) Close() error { h.wg.Wait() for _, index := range h.indexes { - index.Close() + if err := index.Close(); err != nil { + return err + } } return nil } diff --git a/holder_test.go b/holder_test.go index 108349bb2..b3947abb8 100644 --- a/holder_test.go +++ b/holder_test.go @@ -34,8 +34,9 @@ func TestHolder_Open(t *testing.T) { if err := os.Mkdir(h.IndexPath("!"), 0777); err != nil { t.Fatal(err) + } else if err := h.Holder.Close(); err != nil { + t.Fatal(err) } - if err := h.Reopen(); err != nil { t.Fatal(err) } else if logOutput := h.LogOutput.String(); !strings.Contains(logOutput, `ERROR opening index: !`) { @@ -49,6 +50,8 @@ func TestHolder_Open(t *testing.T) { if _, err := h.CreateIndex("test", pilosa.IndexOptions{}); err != nil { t.Fatal(err) + } else if err := h.Holder.Close(); err != nil { + t.Fatal(err) } else if err := os.Chmod(h.IndexPath("test"), 0000); err != nil { t.Fatal(err) } @@ -64,6 +67,8 @@ func TestHolder_Open(t *testing.T) { if _, err := h.CreateIndex("test", pilosa.IndexOptions{}); err != nil { t.Fatal(err) + } else if err := h.Holder.Close(); err != nil { + t.Fatal(err) } else if err := os.Truncate(filepath.Join(h.IndexPath("test"), ".meta"), 2); err != nil { t.Fatal(err) } @@ -78,6 +83,8 @@ func TestHolder_Open(t *testing.T) { if _, err := h.CreateIndex("test", pilosa.IndexOptions{}); err != nil { t.Fatal(err) + } else if err := h.Holder.Close(); err != nil { + t.Fatal(err) } else if err := os.Truncate(filepath.Join(h.IndexPath("test"), ".data"), 2); err != nil { t.Fatal(err) } @@ -95,6 +102,8 @@ func TestHolder_Open(t *testing.T) { t.Fatal(err) } else if _, err := idx.CreateFrame("bar", pilosa.FrameOptions{}); err != nil { t.Fatal(err) + } else if err := h.Holder.Close(); err != nil { + t.Fatal(err) } else if err := os.Chmod(filepath.Join(h.Path, "foo", "bar"), 0000); err != nil { t.Fatal(err) } @@ -112,6 +121,8 @@ func TestHolder_Open(t *testing.T) { t.Fatal(err) } else if _, err := idx.CreateFrame("bar", pilosa.FrameOptions{}); err != nil { t.Fatal(err) + } else if err := h.Holder.Close(); err != nil { + t.Fatal(err) } else if err := os.Truncate(filepath.Join(h.Path, "foo", "bar", ".meta"), 2); err != nil { t.Fatal(err) } @@ -128,6 +139,8 @@ func TestHolder_Open(t *testing.T) { t.Fatal(err) } else if _, err := idx.CreateFrame("bar", pilosa.FrameOptions{}); err != nil { t.Fatal(err) + } else if err := h.Holder.Close(); err != nil { + t.Fatal(err) } else if err := os.Truncate(filepath.Join(h.Path, "foo", "bar", ".data"), 2); err != nil { t.Fatal(err) } @@ -147,6 +160,8 @@ func TestHolder_Open(t *testing.T) { t.Fatal(err) } else if _, err := frame.CreateViewIfNotExists(pilosa.ViewStandard); err != nil { t.Fatal(err) + } else if err := h.Holder.Close(); err != nil { + t.Fatal(err) } else if err := os.Chmod(filepath.Join(h.Path, "foo", "bar", "views", "standard"), 0000); err != nil { t.Fatal(err) } @@ -166,6 +181,8 @@ func TestHolder_Open(t *testing.T) { t.Fatal(err) } else if _, err := frame.CreateViewIfNotExists(pilosa.ViewStandard); err != nil { t.Fatal(err) + } else if err := h.Holder.Close(); err != nil { + t.Fatal(err) } else if err := os.Chmod(filepath.Join(h.Path, "foo", "bar", "views", "standard", "fragments"), 0000); err != nil { t.Fatal(err) } @@ -188,6 +205,8 @@ func TestHolder_Open(t *testing.T) { t.Fatal(err) } else if _, err := view.SetBit(0, 0); err != nil { t.Fatal(err) + } else if err := h.Holder.Close(); err != nil { + t.Fatal(err) } else if err := os.Chmod(filepath.Join(h.Path, "foo", "bar", "views", "standard", "fragments", "0"), 0000); err != nil { t.Fatal(err) } @@ -209,6 +228,8 @@ func TestHolder_Open(t *testing.T) { t.Fatal(err) } else if _, err := view.SetBit(0, 0); err != nil { t.Fatal(err) + } else if err := h.Holder.Close(); err != nil { + t.Fatal(err) } else if err := os.Truncate(filepath.Join(h.Path, "foo", "bar", "views", "standard", "fragments", "0"), 2); err != nil { t.Fatal(err) } @@ -232,6 +253,8 @@ func TestHolder_Open(t *testing.T) { t.Fatal(err) } else if err := view.Fragment(0).FlushCache(); err != nil { t.Fatal(err) + } else if err := h.Holder.Close(); err != nil { + t.Fatal(err) } else if err := os.Chmod(filepath.Join(h.Path, "foo", "bar", "views", "standard", "fragments", "0.cache"), 0000); err != nil { t.Fatal(err) } diff --git a/index.go b/index.go index 8f1846c5f..345215690 100644 --- a/index.go +++ b/index.go @@ -248,7 +248,9 @@ func (i *Index) Close() error { // Close all frames. for _, f := range i.frames { - f.Close() + if err := f.Close(); err != nil { + return err + } } i.frames = make(map[string]*Frame) diff --git a/test/holder.go b/test/holder.go index 6bb346ec1..099b9cb7b 100644 --- a/test/holder.go +++ b/test/holder.go @@ -45,9 +45,9 @@ func (h *Holder) Close() error { // Reopen closes the holder and instantiates and opens a new holder. func (h *Holder) Reopen() error { - if err := h.Holder.Close(); err != nil { - return err - } + // if err := h.Holder.Close(); err != nil { + // return err + // } path, logOutput := h.Path, h.Holder.LogOutput h.Holder = pilosa.NewHolder() diff --git a/view.go b/view.go index 31a7a53c0..9fa5fcc8d 100644 --- a/view.go +++ b/view.go @@ -162,7 +162,9 @@ func (v *View) Close() error { // Close all fragments. for _, frag := range v.fragments { - _ = frag.Close() + if err := frag.Close(); err != nil { + return err + } } v.fragments = make(map[uint64]*Fragment) From f5832cda02053eca9a911b96b44198e433202381 Mon Sep 17 00:00:00 2001 From: Michael Baird Date: Tue, 22 Aug 2017 15:13:21 -0500 Subject: [PATCH 09/12] Clarify that Holder Reopen requires Close to be run beforehand. --- handler.go | 2 ++ test/holder.go | 5 +---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/handler.go b/handler.go index 38254e1ae..cfc96c397 100644 --- a/handler.go +++ b/handler.go @@ -27,6 +27,7 @@ import ( "io/ioutil" "log" "net/http" + // Imported for its side-effect of registering pprof endpoints with the server. _ "net/http/pprof" "os" "runtime/debug" @@ -43,6 +44,7 @@ import ( "unicode" + // Allow building Pilosa without the web UI. _ "github.com/pilosa/pilosa/statik" "github.com/rakyll/statik/fs" ) diff --git a/test/holder.go b/test/holder.go index 099b9cb7b..9523db407 100644 --- a/test/holder.go +++ b/test/holder.go @@ -44,11 +44,8 @@ func (h *Holder) Close() error { } // Reopen closes the holder and instantiates and opens a new holder. +// note that the hold most be Closed first func (h *Holder) Reopen() error { - // if err := h.Holder.Close(); err != nil { - // return err - // } - path, logOutput := h.Path, h.Holder.LogOutput h.Holder = pilosa.NewHolder() h.Holder.Path = path From 60a4ad0c528a06915728daa8eb019a461416c83e Mon Sep 17 00:00:00 2001 From: Michael Baird Date: Fri, 25 Aug 2017 08:11:00 -0500 Subject: [PATCH 10/12] Use the full view name in the Delete API. Will need to append the prefix: `standard_`, `inverse_`, or `field_` --- frame.go | 21 ++------------------- frame_test.go | 4 ++-- handler.go | 6 ------ handler_test.go | 7 ++++--- 4 files changed, 8 insertions(+), 30 deletions(-) diff --git a/frame.go b/frame.go index ad44cfb56..332048cf3 100644 --- a/frame.go +++ b/frame.go @@ -515,31 +515,14 @@ func (f *Frame) newView(path, name string) *View { return view } -// DeleteView removes the standard and inverse view from the frame. +// DeleteView removes the view from the frame. func (f *Frame) DeleteView(name string) error { - // Delete the standard view. - if err := f.deleteView(ViewStandard + "_" + name); err != nil { - return err - } - - // Delete the inverse view. - if f.InverseEnabled() { - if err := f.deleteView(ViewInverse + "_" + name); err != nil { - return err - } - } - - return nil -} - -// deleteView removes view from the frame. -func (f *Frame) deleteView(name string) error { view := f.views[name] if view == nil { return ErrInvalidView } - // Close data files before deletion + // Close data files before deletion. if err := view.Close(); err != nil { return err } diff --git a/frame_test.go b/frame_test.go index 8a8db3f27..50f5fdef5 100644 --- a/frame_test.go +++ b/frame_test.go @@ -323,7 +323,7 @@ func TestFrame_DeleteView(t *testing.T) { t.Fatal("expected view") } - err = f.DeleteView("v") + err = f.DeleteView(viewName) if err != nil { t.Fatal(err) } @@ -332,7 +332,7 @@ func TestFrame_DeleteView(t *testing.T) { t.Fatal("view still exists in frame") } - // // Retrieve existing view. + // Recreate view with same name, verify that the old view was not reused. view2, err := f.CreateViewIfNotExists(viewName) if err != nil { t.Fatal(err) diff --git a/handler.go b/handler.go index cfc96c397..f876dc9b7 100644 --- a/handler.go +++ b/handler.go @@ -805,12 +805,6 @@ func (h *Handler) handleDeleteView(w http.ResponseWriter, r *http.Request) { return } - // Check the frame for time quantum. - if f.TimeQuantum() == "" { - http.Error(w, "frame does not contain a Time Quantum", http.StatusBadRequest) - return - } - // Delete the view. if err := f.DeleteView(viewName); err != nil { http.Error(w, err.Error(), http.StatusBadRequest) diff --git a/handler_test.go b/handler_test.go index c8e0d949c..dacb04b38 100644 --- a/handler_test.go +++ b/handler_test.go @@ -1516,19 +1516,20 @@ func TestHandler_GetTimeStamp(t *testing.T) { func TestHandler_DeleteView(t *testing.T) { hldr := test.MustOpenHolder() defer hldr.Close() - hldr.MustCreateFragmentIfNotExists("i0", "f0", pilosa.ViewStandard+"_2017", 1).MustSetBits(30, (1*SliceWidth)+1) + viewName := pilosa.ViewStandard + "_2017" + hldr.MustCreateFragmentIfNotExists("i0", "f0", viewName, 1).MustSetBits(30, (1*SliceWidth)+1) hldr.Index("i0").Frame("f0").SetTimeQuantum("YMD") h := test.NewHandler() h.Holder = hldr.Holder h.Cluster = test.NewCluster(1) w := httptest.NewRecorder() - h.ServeHTTP(w, test.MustNewHTTPRequest("DELETE", "/index/i0/frame/f0/view/2017", strings.NewReader(""))) + h.ServeHTTP(w, test.MustNewHTTPRequest("DELETE", "/index/i0/frame/f0/view/standard_2017", strings.NewReader(""))) if w.Code != http.StatusOK { t.Fatalf("unexpected status code: %d", w.Code) } else if body := w.Body.String(); body != `{}`+"\n" { t.Fatalf("unexpected body: %s", body) - } else if f := hldr.Index("i0").Frame("f0").View(pilosa.ViewStandard + "_2017"); f != nil { + } else if f := hldr.Index("i0").Frame("f0").View(viewName); f != nil { t.Fatal("expected nil view") } } From 52428ee6ac9755e40a01893e27e4a916577dee87 Mon Sep 17 00:00:00 2001 From: Travis Date: Sat, 26 Aug 2017 11:47:59 -0500 Subject: [PATCH 11/12] Correct a comment in the tests --- test/holder.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/holder.go b/test/holder.go index 9523db407..4cd0642e4 100644 --- a/test/holder.go +++ b/test/holder.go @@ -43,8 +43,8 @@ func (h *Holder) Close() error { return h.Holder.Close() } -// Reopen closes the holder and instantiates and opens a new holder. -// note that the hold most be Closed first +// Reopen instantiates and opens a new holder. +// Note that the holder must be Closed first. func (h *Holder) Reopen() error { path, logOutput := h.Path, h.Holder.LogOutput h.Holder = pilosa.NewHolder() From 5cbd31208579fc310f2d64ff4343a4690ca607d5 Mon Sep 17 00:00:00 2001 From: Michael Baird Date: Mon, 28 Aug 2017 09:23:06 -0500 Subject: [PATCH 12/12] Send delete view message to all nodes regardless if the receiving node contains that view. --- handler.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/handler.go b/handler.go index f876dc9b7..c7aa45ac1 100644 --- a/handler.go +++ b/handler.go @@ -807,8 +807,11 @@ func (h *Handler) handleDeleteView(w http.ResponseWriter, r *http.Request) { // Delete the view. if err := f.DeleteView(viewName); err != nil { - http.Error(w, err.Error(), http.StatusBadRequest) - return + // Ingore this error becuase views do not exist on all nodes due to slice distribution. + if err != ErrInvalidView { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } } // Send the delete view message to all nodes.