Skip to content

Commit cd04467

Browse files
authored
Go: add delete search (infiniflow#14014)
### What problem does this PR solve? As title. ### Type of change - [x] New Feature (non-breaking change which adds functionality) --------- Signed-off-by: Jin Hai <haijin.chn@gmail.com>
1 parent 56810ec commit cd04467

4 files changed

Lines changed: 91 additions & 0 deletions

File tree

internal/dao/search.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,3 +145,18 @@ func (dao *SearchDAO) QueryByTenantIDAndID(tenantID string, searchID string) ([]
145145
err := DB.Where("tenant_id = ? AND id = ? AND status = ?", tenantID, searchID, "1").Find(&searches).Error
146146
return searches, err
147147
}
148+
149+
// DeleteByID deletes a search by ID (soft delete by setting status to "0")
150+
// Reference: Python common_service.py::delete_by_id
151+
func (dao *SearchDAO) DeleteByID(id string) error {
152+
return DB.Model(&entity.Search{}).Where("id = ?", id).Update("status", "0").Error
153+
}
154+
155+
// Accessible4Deletion checks if a search can be deleted by a specific user
156+
// Reference: Python search_service.py::accessible4deletion
157+
// Returns true if the search exists, is valid, and was created by the user
158+
func (dao *SearchDAO) Accessible4Deletion(searchID string, userID string) bool {
159+
var search entity.Search
160+
err := DB.Where("id = ? AND created_by = ? AND status = ?", searchID, userID, "1").First(&search).Error
161+
return err == nil
162+
}

internal/handler/search.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,3 +251,61 @@ func (h *SearchHandler) GetSearch(c *gin.Context) {
251251
"message": "success",
252252
})
253253
}
254+
255+
// DeleteSearch delete a search app
256+
// @Summary Delete Search App
257+
// @Description Delete a search app by ID
258+
// @Tags search
259+
// @Accept json
260+
// @Produce json
261+
// @Param search_id path string true "search app ID"
262+
// @Success 200 {object} map[string]interface{}
263+
// @Router /api/v1/searches/{search_id} [delete]
264+
func (h *SearchHandler) DeleteSearch(c *gin.Context) {
265+
// Get current user from context (same as Python current_user)
266+
user, errorCode, errorMessage := GetUser(c)
267+
if errorCode != common.CodeSuccess {
268+
jsonError(c, errorCode, errorMessage)
269+
return
270+
}
271+
userID := user.ID
272+
273+
// Get search_id from path parameter (same as Python <search_id>)
274+
searchID := c.Param("search_id")
275+
if searchID == "" {
276+
c.JSON(http.StatusBadRequest, gin.H{
277+
"code": common.CodeBadRequest,
278+
"data": nil,
279+
"message": "search_id is required",
280+
})
281+
return
282+
}
283+
284+
// Delete search with permission check
285+
err := h.searchService.DeleteSearch(userID, searchID)
286+
if err != nil {
287+
// Check if it's an authorization error
288+
if err.Error() == "no authorization" {
289+
c.JSON(http.StatusOK, gin.H{
290+
"code": common.CodeAuthenticationError,
291+
"data": false,
292+
"message": "No authorization.",
293+
})
294+
return
295+
}
296+
// Delete failed error
297+
c.JSON(http.StatusOK, gin.H{
298+
"code": common.CodeDataError,
299+
"data": nil,
300+
"message": err.Error(),
301+
})
302+
return
303+
}
304+
305+
// Return success response (same as Python get_json_result(data=True))
306+
c.JSON(http.StatusOK, gin.H{
307+
"code": common.CodeSuccess,
308+
"data": true,
309+
"message": "success",
310+
})
311+
}

internal/router/router.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ func (r *Router) Setup(engine *gin.Engine) {
197197
searches.GET("", r.searchHandler.ListSearches)
198198
searches.POST("", r.searchHandler.CreateSearch)
199199
searches.GET("/:search_id", r.searchHandler.GetSearch)
200+
searches.DELETE("/:search_id", r.searchHandler.DeleteSearch)
200201
}
201202

202203
file := v1.Group("/files")

internal/service/search.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,3 +233,20 @@ func (s *SearchService) GetSearchDetail(userID string, searchID string) (*entity
233233

234234
return search, nil
235235
}
236+
237+
// DeleteSearch deletes a search app by ID
238+
func (s *SearchService) DeleteSearch(userID string, searchID string) error {
239+
// Step 1: Check deletion permission (same as Python SearchService.accessible4deletion)
240+
// Python: cls.model.select().where(cls.model.id == search_id, cls.model.created_by == user_id, cls.model.status == StatusEnum.VALID.value).first()
241+
if !s.searchDAO.Accessible4Deletion(searchID, userID) {
242+
return fmt.Errorf("no authorization")
243+
}
244+
245+
// Step 2: Execute delete (same as Python SearchService.delete_by_id)
246+
// Python: cls.model.delete().where(cls.model.id == pid).execute()
247+
if err := s.searchDAO.DeleteByID(searchID); err != nil {
248+
return fmt.Errorf("failed to delete search App %s: %w", searchID, err)
249+
}
250+
251+
return nil
252+
}

0 commit comments

Comments
 (0)