Update internal/storage/collection.go
This commit is contained in:
1 parent
3b5458305b
commit
84ce12a4d3
1 file changed
+29
@@ -55,6 +55,9 @@ type Collection struct {
|
|||||||
// MVCC - многоверсионность
|
// MVCC - многоверсионность
|
||||||
mvccManager *MVCCManager // MVCC менеджер для управления версиями
|
mvccManager *MVCCManager // MVCC менеджер для управления версиями
|
||||||
mvccEnabled bool // Включен ли MVCC
|
mvccEnabled bool // Включен ли MVCC
|
||||||
|
|
||||||
|
// ИСПРАВЛЕНО: Блокировка для согласованности индексов при SoftDelete
|
||||||
|
indexMu sync.Mutex // Защита атомарности операций с индексами
|
||||||
}
|
}
|
||||||
|
|
||||||
// CollectionMetadata содержит метаданные коллекции
|
// CollectionMetadata содержит метаданные коллекции
|
||||||
@@ -857,9 +860,12 @@ func (c *Collection) Update(id string, updates map[string]interface{}) error {
|
|||||||
// Выполняем триггеры BEFORE_UPDATE
|
// Выполняем триггеры BEFORE_UPDATE
|
||||||
c.executeTriggers("BEFORE_UPDATE", id, newDoc.GetFields())
|
c.executeTriggers("BEFORE_UPDATE", id, newDoc.GetFields())
|
||||||
|
|
||||||
|
// ИСПРАВЛЕНО: Блокируем индексы для атомарности
|
||||||
|
c.indexMu.Lock()
|
||||||
// Сначала удаляем старые индексы, потом добавляем новые
|
// Сначала удаляем старые индексы, потом добавляем новые
|
||||||
c.removeFromIndexes(oldDoc)
|
c.removeFromIndexes(oldDoc)
|
||||||
c.addToIndexes(newDoc)
|
c.addToIndexes(newDoc)
|
||||||
|
c.indexMu.Unlock()
|
||||||
|
|
||||||
// Сохраняем обновлённый документ
|
// Сохраняем обновлённый документ
|
||||||
c.docs.Store(id, newDoc)
|
c.docs.Store(id, newDoc)
|
||||||
@@ -883,6 +889,7 @@ func (c *Collection) Update(id string, updates map[string]interface{}) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Delete удаляет документ по ID
|
// Delete удаляет документ по ID
|
||||||
|
// ИСПРАВЛЕНО: Атомарность SoftDelete и удаления из индексов
|
||||||
func (c *Collection) Delete(id string) error {
|
func (c *Collection) Delete(id string) error {
|
||||||
val, ok := c.docs.Load(id)
|
val, ok := c.docs.Load(id)
|
||||||
if !ok {
|
if !ok {
|
||||||
@@ -895,6 +902,9 @@ func (c *Collection) Delete(id string) error {
|
|||||||
c.executeTriggers("BEFORE_DELETE", id, doc.GetFields())
|
c.executeTriggers("BEFORE_DELETE", id, doc.GetFields())
|
||||||
|
|
||||||
if c.metadata.Settings.SoftDelete {
|
if c.metadata.Settings.SoftDelete {
|
||||||
|
// ИСПРАВЛЕНО: Блокируем индексы для атомарности SoftDelete и удаления из индексов
|
||||||
|
c.indexMu.Lock()
|
||||||
|
|
||||||
// Мягкое удаление
|
// Мягкое удаление
|
||||||
doc.SoftDelete()
|
doc.SoftDelete()
|
||||||
c.docs.Store(id, doc)
|
c.docs.Store(id, doc)
|
||||||
@@ -902,11 +912,16 @@ func (c *Collection) Delete(id string) error {
|
|||||||
// Удаляем из индексов при мягком удалении
|
// Удаляем из индексов при мягком удалении
|
||||||
c.removeFromIndexes(doc)
|
c.removeFromIndexes(doc)
|
||||||
|
|
||||||
|
c.indexMu.Unlock()
|
||||||
|
|
||||||
// Аудит мягкого удаления
|
// Аудит мягкого удаления
|
||||||
AuditDocumentOperation("SOFT_DELETE", c.dbName, c.name, id, map[string]interface{}{
|
AuditDocumentOperation("SOFT_DELETE", c.dbName, c.name, id, map[string]interface{}{
|
||||||
"deleted_at": doc.DeletedAt,
|
"deleted_at": doc.DeletedAt,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
|
// ИСПРАВЛЕНО: Блокируем индексы для атомарности физического удаления
|
||||||
|
c.indexMu.Lock()
|
||||||
|
|
||||||
// Физическое удаление
|
// Физическое удаление
|
||||||
// Удаляем из индексов
|
// Удаляем из индексов
|
||||||
c.removeFromIndexes(doc)
|
c.removeFromIndexes(doc)
|
||||||
@@ -914,6 +929,8 @@ func (c *Collection) Delete(id string) error {
|
|||||||
// Удаляем документ
|
// Удаляем документ
|
||||||
c.docs.Delete(id)
|
c.docs.Delete(id)
|
||||||
|
|
||||||
|
c.indexMu.Unlock()
|
||||||
|
|
||||||
// Аудит физического удаления
|
// Аудит физического удаления
|
||||||
AuditDocumentOperation("DELETE", c.dbName, c.name, id, nil)
|
AuditDocumentOperation("DELETE", c.dbName, c.name, id, nil)
|
||||||
}
|
}
|
||||||
@@ -944,12 +961,17 @@ func (c *Collection) PermanentDelete(id string) error {
|
|||||||
return fmt.Errorf("document is not soft deleted, use Delete() instead")
|
return fmt.Errorf("document is not soft deleted, use Delete() instead")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ИСПРАВЛЕНО: Блокируем индексы для атомарности
|
||||||
|
c.indexMu.Lock()
|
||||||
|
|
||||||
// Удаляем из индексов
|
// Удаляем из индексов
|
||||||
c.removeFromIndexes(doc)
|
c.removeFromIndexes(doc)
|
||||||
|
|
||||||
// Удаляем документ
|
// Удаляем документ
|
||||||
c.docs.Delete(id)
|
c.docs.Delete(id)
|
||||||
|
|
||||||
|
c.indexMu.Unlock()
|
||||||
|
|
||||||
// Обновляем метаданные
|
// Обновляем метаданные
|
||||||
c.docCount.Add(-1)
|
c.docCount.Add(-1)
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
@@ -964,6 +986,7 @@ func (c *Collection) PermanentDelete(id string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// RestoreDeleted восстанавливает мягко удалённый документ
|
// RestoreDeleted восстанавливает мягко удалённый документ
|
||||||
|
// ИСПРАВЛЕНО: Атомарность восстановления и добавления в индексы
|
||||||
func (c *Collection) RestoreDeleted(id string) error {
|
func (c *Collection) RestoreDeleted(id string) error {
|
||||||
val, ok := c.docs.Load(id)
|
val, ok := c.docs.Load(id)
|
||||||
if !ok {
|
if !ok {
|
||||||
@@ -976,12 +999,18 @@ func (c *Collection) RestoreDeleted(id string) error {
|
|||||||
return fmt.Errorf("document is not deleted")
|
return fmt.Errorf("document is not deleted")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ИСПРАВЛЕНО: Блокируем индексы для атомарности
|
||||||
|
c.indexMu.Lock()
|
||||||
|
|
||||||
doc.Restore()
|
doc.Restore()
|
||||||
|
|
||||||
// Восстанавливаем индексы
|
// Восстанавливаем индексы
|
||||||
c.addToIndexes(doc)
|
c.addToIndexes(doc)
|
||||||
|
|
||||||
c.docs.Store(id, doc)
|
c.docs.Store(id, doc)
|
||||||
|
|
||||||
|
c.indexMu.Unlock()
|
||||||
|
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
c.metadata.UpdatedAt = time.Now().UnixMilli()
|
c.metadata.UpdatedAt = time.Now().UnixMilli()
|
||||||
c.mu.Unlock()
|
c.mu.Unlock()
|
||||||
|
|||||||
Reference in new issue
Block a user