feat: keep the materials index in sync and add bm:materials-reindex
- the materials admin syncs after create and update and removes after delete, once the save transaction commits (UseMaterialIndex, set at Boot) - POST and PUT /api/v1/bm/materials sync after the transaction, DELETE removes the document (its statement has no primary key, so no callback) - bm:materials-reindex [--fresh] [--if-configured] ensures the index and syncs every material; it refuses without an engine and runs nightly at 04:15 with --if-configured - TestMaterialSearchAgainstDatabase (Postgres) is written for the final verification phase
This commit is contained in:
@@ -498,6 +498,7 @@ func (h *Handlers) UpsertMaterial(w http.ResponseWriter, r *http.Request) {
|
||||
writeOpaque500(w)
|
||||
return
|
||||
}
|
||||
h.MaterialIndex.Sync(r.Context(), db, m.ID)
|
||||
status := http.StatusOK
|
||||
if created {
|
||||
status = http.StatusCreated
|
||||
@@ -556,6 +557,7 @@ func (h *Handlers) UpdateMaterial(w http.ResponseWriter, r *http.Request) {
|
||||
case taken:
|
||||
writeValidation(w, map[string][]string{"title": {"Another material already has this title and course."}})
|
||||
default:
|
||||
h.MaterialIndex.Sync(r.Context(), db, m.ID)
|
||||
writeManaged(w, r, db, m.ID, http.StatusOK, nil)
|
||||
}
|
||||
}
|
||||
@@ -659,6 +661,9 @@ func (h *Handlers) DeleteMaterial(w http.ResponseWriter, r *http.Request) {
|
||||
writeNotFound(w)
|
||||
return
|
||||
}
|
||||
// The delete statement has no primary key on its model, so no callback
|
||||
// removes the document: remove it now that the transaction committed.
|
||||
h.MaterialIndex.Remove(r.Context(), db, uint(id))
|
||||
// The files go with the material: rows in the transaction, blobs after it.
|
||||
if b := h.Bucket; b != nil && len(keys) > 0 {
|
||||
if bucket := b(); bucket != nil {
|
||||
@@ -734,6 +739,8 @@ func (h *Handlers) managedAccessChange(w http.ResponseWriter, r *http.Request, d
|
||||
writeOpaque500(w)
|
||||
return
|
||||
}
|
||||
// An access change touches only visibility (and the author), which the
|
||||
// search index does not hold, so it does not sync.
|
||||
writeManaged(w, r, db, m.ID, http.StatusOK, nil)
|
||||
}
|
||||
|
||||
|
||||
@@ -322,7 +322,8 @@ func (h *Handlers) UpdateMaterialAccess(w http.ResponseWriter, r *http.Request)
|
||||
// applyMaterialAccess writes a visibility and share change onto m inside
|
||||
// tx. A material with no author gets userID as author (the claim rule).
|
||||
// Only is_private and author_user_id are updated; the shares are replaced
|
||||
// when setShares.
|
||||
// when setShares. The search index holds none of these, so no caller syncs
|
||||
// after it.
|
||||
func applyMaterialAccess(tx *gorm.DB, m *models.Material, userID uint, isPrivate *bool, setShares bool, shares []uint) error {
|
||||
if m.AuthorUserID == nil {
|
||||
id := userID
|
||||
|
||||
Reference in New Issue
Block a user