Files
elowdb-go/examples/delete/delete.go
2026-04-07 15:04:38 +06:00

642 lines
19 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package main
import (
"fmt"
"log"
"time"
"direct-dev.ru/gitea/GiteaAdmin/elowdb-go"
)
// testDeleteOneRecordByID тестирует удаление одной записи по ID
func testDeleteOneRecordByID() {
// Создаем базу данных
db := linedb.NewLineDb(nil)
// Инициализируем базу данных
initOptions := &linedb.LineDbInitOptions{
CacheSize: 1000,
CacheTTL: 10 * time.Second,
DBFolder: "./data/test-linedb-delete",
Collections: []linedb.JSONLFileOptions{
{
CollectionName: "users",
AllocSize: 256,
IndexedFields: []string{"id", "username"},
},
},
}
if err := db.Init(true, initOptions); err != nil {
log.Printf("Failed to init database: %v", err)
return
}
defer db.Close()
// Создаем тестовые данные
user := map[string]any{
"id": 1,
"username": "test_user",
"email": "test@example.com",
"isActive": true,
}
// Вставляем данные
if err := db.Insert(user, "users", linedb.LineDbAdapterOptions{}); err != nil {
log.Printf("Failed to insert user: %v", err)
return
}
// Читаем данные
users, err := db.Read("users", linedb.LineDbAdapterOptions{})
if err != nil {
log.Printf("Failed to read users: %v", err)
return
}
fmt.Printf(" Записей до удаления: %d\n", len(users))
// Удаляем запись по ID
deleted, err := db.Delete(map[string]any{"id": 1}, "users", linedb.LineDbAdapterOptions{})
if err != nil {
log.Printf("Failed to delete user: %v", err)
return
}
fmt.Printf(" Удалено записей: %d\n", len(deleted))
// Проверяем результат
users, err = db.Read("users", linedb.LineDbAdapterOptions{})
if err != nil {
log.Printf("Failed to read users after delete: %v", err)
return
}
fmt.Printf(" Записей после удаления: %d\n", len(users))
}
// testDeleteOneRecordByTextFilter тестирует удаление одной записи по текстовому фильтру
func testDeleteOneRecordByTextFilter() {
// Создаем базу данных
db := linedb.NewLineDb(nil)
// Инициализируем базу данных
initOptions := &linedb.LineDbInitOptions{
CacheSize: 1000,
CacheTTL: 10 * time.Second,
DBFolder: "./data/test-linedb-delete",
Collections: []linedb.JSONLFileOptions{
{
CollectionName: "products",
AllocSize: 256,
IndexedFields: []string{"id", "name"},
},
},
}
if err := db.Init(true, initOptions); err != nil {
log.Printf("Failed to init database: %v", err)
return
}
defer db.Close()
// Создаем тестовые данные
product := map[string]any{
"id": 1,
"name": "Test Product",
"price": 99.99,
"category": "Electronics",
}
// Вставляем данные
if err := db.Insert(product, "products", linedb.LineDbAdapterOptions{}); err != nil {
log.Printf("Failed to insert product: %v", err)
return
}
// Читаем данные
products, err := db.Read("products", linedb.LineDbAdapterOptions{})
if err != nil {
log.Printf("Failed to read products: %v", err)
return
}
fmt.Printf(" Записей до удаления: %d\n", len(products))
// Удаляем запись по текстовому фильтру
deleted, err := db.Delete("name == 'Test Product'", "products", linedb.LineDbAdapterOptions{})
if err != nil {
log.Printf("Failed to delete product: %v", err)
return
}
fmt.Printf(" Удалено записей: %d\n", len(deleted))
// Проверяем результат
products, err = db.Read("products", linedb.LineDbAdapterOptions{})
if err != nil {
log.Printf("Failed to read products after delete: %v", err)
return
}
fmt.Printf(" Записей после удаления: %d\n", len(products))
}
// testDeleteMultipleRecordsByArray тестирует удаление нескольких записей по массиву данных
func testDeleteMultipleRecordsByArray() {
// Создаем базу данных
db := linedb.NewLineDb(nil)
// Инициализируем базу данных
initOptions := &linedb.LineDbInitOptions{
CacheSize: 1000,
CacheTTL: 10 * time.Second,
DBFolder: "./data/test-linedb-delete",
Collections: []linedb.JSONLFileOptions{
{
CollectionName: "orders",
AllocSize: 256,
IndexedFields: []string{"id", "status"},
},
},
}
if err := db.Init(true, initOptions); err != nil {
log.Printf("Failed to init database: %v", err)
return
}
defer db.Close()
// Создаем массив тестовых данных
orders := []any{
map[string]any{
"id": 1,
"status": "pending",
"amount": 100.0,
"customerId": 1,
},
map[string]any{
"id": 2,
"status": "completed",
"amount": 200.0,
"customerId": 2,
},
map[string]any{
"id": 3,
"status": "pending",
"amount": 150.0,
"customerId": 1,
},
}
// Вставляем данные
if err := db.Insert(orders, "orders", linedb.LineDbAdapterOptions{}); err != nil {
log.Printf("Failed to insert orders: %v", err)
return
}
// Читаем данные
ordersData, err := db.Read("orders", linedb.LineDbAdapterOptions{})
if err != nil {
log.Printf("Failed to read orders: %v", err)
return
}
fmt.Printf(" Записей до удаления: %d\n", len(ordersData))
// Удаляем несколько записей по массиву фильтров
deleteFilters := []any{
map[string]any{"id": 1},
map[string]any{"id": 2},
}
deleted, err := db.Delete(deleteFilters, "orders", linedb.LineDbAdapterOptions{})
if err != nil {
log.Printf("Failed to delete orders: %v", err)
return
}
fmt.Printf(" Удалено записей: %d\n", len(deleted))
// Проверяем результат
ordersData, err = db.Read("orders", linedb.LineDbAdapterOptions{})
if err != nil {
log.Printf("Failed to read orders after delete: %v", err)
return
}
fmt.Printf(" Записей после удаления: %d\n", len(ordersData))
}
// testDeleteByPartialMatch тестирует удаление записей по частичному совпадению
func testDeleteByPartialMatch() {
// Создаем базу данных
db := linedb.NewLineDb(nil)
// Инициализируем базу данных
initOptions := &linedb.LineDbInitOptions{
CacheSize: 1000,
CacheTTL: 10 * time.Second,
DBFolder: "./data/test-linedb-delete",
Collections: []linedb.JSONLFileOptions{
{
CollectionName: "customers",
AllocSize: 256,
IndexedFields: []string{"id", "name"},
},
},
}
if err := db.Init(true, initOptions); err != nil {
log.Printf("Failed to init database: %v", err)
return
}
defer db.Close()
// Создаем массив тестовых данных
customers := []any{
map[string]any{
"id": 1,
"name": "John Doe",
"email": "john@example.com",
},
map[string]any{
"id": 2,
"name": "Jane Smith",
"email": "jane@example.com",
},
map[string]any{
"id": 3,
"name": "John Smith",
"email": "john.smith@example.com",
},
}
// Вставляем данные
if err := db.Insert(customers, "customers", linedb.LineDbAdapterOptions{}); err != nil {
log.Printf("Failed to insert customers: %v", err)
return
}
// Читаем данные
customersData, err := db.Read("customers", linedb.LineDbAdapterOptions{})
if err != nil {
log.Printf("Failed to read customers: %v", err)
return
}
fmt.Printf(" Записей до удаления: %d\n", len(customersData))
// Удаляем записи по частичному совпадению
deleted, err := db.Delete(
map[string]any{"name": "John"},
"customers",
linedb.LineDbAdapterOptions{StrictCompare: false},
)
if err != nil {
log.Printf("Failed to delete customers: %v", err)
return
}
fmt.Printf(" Удалено записей с именем 'John': %d\n", len(deleted))
// Проверяем результат
customersData, err = db.Read("customers", linedb.LineDbAdapterOptions{})
if err != nil {
log.Printf("Failed to read customers after delete: %v", err)
return
}
fmt.Printf(" Записей после удаления: %d\n", len(customersData))
}
// testDeleteFromPartitionedCollections тестирует удаление из партиционированных коллекций
func testDeleteFromPartitionedCollections() {
// Создаем базу данных
db := linedb.NewLineDb(nil)
// Инициализируем базу данных с партициями
initOptions := &linedb.LineDbInitOptions{
CacheSize: 1000,
CacheTTL: 10 * time.Second,
DBFolder: "./data/test-linedb-delete",
Collections: []linedb.JSONLFileOptions{
{
CollectionName: "logs",
AllocSize: 256,
IndexedFields: []string{"id", "level"},
},
},
Partitions: []linedb.PartitionCollection{
{
CollectionName: "logs",
PartIDFnStr: "level",
},
},
}
if err := db.Init(true, initOptions); err != nil {
log.Printf("Failed to init database: %v", err)
return
}
defer db.Close()
// Создаем логи для разных уровней
logs := []any{
map[string]any{
"id": 1,
"level": "error",
"message": "Critical error occurred",
"timestamp": time.Now().Unix(),
},
map[string]any{
"id": 2,
"level": "info",
"message": "User logged in",
"timestamp": time.Now().Unix(),
},
map[string]any{
"id": 3,
"level": "error",
"message": "Another error",
"timestamp": time.Now().Unix(),
},
}
// Вставляем данные
if err := db.Insert(logs, "logs", linedb.LineDbAdapterOptions{}); err != nil {
log.Printf("Failed to insert logs: %v", err)
return
}
// Читаем данные
logsData, err := db.Read("logs", linedb.LineDbAdapterOptions{})
if err != nil {
log.Printf("Failed to read logs: %v", err)
return
}
fmt.Printf(" Записей до удаления: %d\n", len(logsData))
// Удаляем логи с уровнем 'error'
deleted, err := db.Delete(map[string]any{"level": "error"}, "logs", linedb.LineDbAdapterOptions{})
if err != nil {
log.Printf("Failed to delete error logs: %v", err)
return
}
fmt.Printf(" Удалено записей с уровнем 'error': %d\n", len(deleted))
// Проверяем результат
logsData, err = db.Read("logs", linedb.LineDbAdapterOptions{})
if err != nil {
log.Printf("Failed to read logs after delete: %v", err)
return
}
fmt.Printf(" Записей после удаления: %d\n", len(logsData))
}
// testDeleteEdgeCases тестирует граничные случаи удаления
func testDeleteEdgeCases() {
// Создаем базу данных
db := linedb.NewLineDb(nil)
// Инициализируем базу данных
initOptions := &linedb.LineDbInitOptions{
CacheSize: 1000,
CacheTTL: 10 * time.Second,
DBFolder: "./data/test-linedb-delete",
Collections: []linedb.JSONLFileOptions{
{
CollectionName: "test_data",
AllocSize: 256,
IndexedFields: []string{"id", "type"},
},
},
}
if err := db.Init(true, initOptions); err != nil {
log.Printf("Failed to init database: %v", err)
return
}
defer db.Close()
// Тест удаления несуществующей записи
fmt.Println(" Тест удаления несуществующей записи:")
deleted, err := db.Delete(map[string]any{"id": 999}, "test_data", linedb.LineDbAdapterOptions{})
if err != nil {
log.Printf("Failed to delete non-existent record: %v", err)
return
}
fmt.Printf(" Удалено несуществующих записей: %d\n", len(deleted))
// Тест удаления пустого массива
fmt.Println(" Тест удаления пустого массива:")
deleted, err = db.Delete([]any{}, "test_data", linedb.LineDbAdapterOptions{})
if err != nil {
log.Printf("Failed to delete empty array: %v", err)
return
}
fmt.Printf(" Удалено записей из пустого массива: %d\n", len(deleted))
// Тест удаления записей с разными типами ID
fmt.Println(" Тест удаления записей с разными типами ID:")
// Вставляем запись со строковым ID
stringIDData := map[string]any{
"id": "user-1",
"name": "Test String Id User",
"type": "string_id",
}
if err := db.Insert(stringIDData, "test_data", linedb.LineDbAdapterOptions{}); err != nil {
log.Printf("Failed to insert string ID data: %v", err)
return
}
// Удаляем запись со строковым ID
deleted, err = db.Delete("id == 'user-1'", "test_data", linedb.LineDbAdapterOptions{})
if err != nil {
log.Printf("Failed to delete string ID record: %v", err)
return
}
fmt.Printf(" Удалено записей со строковым ID: %d\n", len(deleted))
}
// testDeletePerformance тестирует производительность удаления
func testDeletePerformance() {
// Создаем базу данных
db := linedb.NewLineDb(nil)
// Инициализируем базу данных
initOptions := &linedb.LineDbInitOptions{
CacheSize: 10000,
CacheTTL: 10 * time.Second,
DBFolder: "./data/test-linedb-delete",
Collections: []linedb.JSONLFileOptions{
{
CollectionName: "performance_data",
AllocSize: 1024,
IndexedFields: []string{"id", "category"},
},
},
}
if err := db.Init(true, initOptions); err != nil {
log.Printf("Failed to init database: %v", err)
return
}
defer db.Close()
// Создаем большое количество записей
recordCount := 1000
fmt.Printf(" Создание %d записей для теста производительности...\n", recordCount)
largeDataArray := make([]any, recordCount)
for i := 1; i <= recordCount; i++ {
largeDataArray[i-1] = map[string]any{
"id": i,
"name": fmt.Sprintf("User %d", i),
"category": fmt.Sprintf("Category %d", (i-1)%10+1),
"value": float64(i) * 1.5,
}
}
// Вставляем данные
if err := db.Insert(largeDataArray, "performance_data", linedb.LineDbAdapterOptions{}); err != nil {
log.Printf("Failed to insert large data array: %v", err)
return
}
// Читаем данные для проверки
result, err := db.Read("performance_data", linedb.LineDbAdapterOptions{})
if err != nil {
log.Printf("Failed to read large data: %v", err)
return
}
fmt.Printf(" Записей в базе: %d\n", len(result))
// Удаляем половину записей (четные ID)
startTime := time.Now()
itemsToDelete := make([]any, recordCount/2)
for i := 0; i < recordCount/2; i++ {
itemsToDelete[i] = map[string]any{"id": (i + 1) * 2}
}
deleted, err := db.Delete(itemsToDelete, "performance_data", linedb.LineDbAdapterOptions{})
if err != nil {
log.Printf("Failed to delete large number of records: %v", err)
return
}
endTime := time.Now()
duration := endTime.Sub(startTime)
fmt.Printf(" Удалено записей: %d\n", len(deleted))
fmt.Printf(" Время выполнения: %v\n", duration)
// Проверяем результат
result, err = db.Read("performance_data", linedb.LineDbAdapterOptions{})
if err != nil {
log.Printf("Failed to read data after bulk delete: %v", err)
return
}
fmt.Printf(" Записей после массового удаления: %d\n", len(result))
}
// testDeleteMultipleCollections тестирует удаление из множественных коллекций
func testDeleteMultipleCollections() {
// Создаем базу данных
db := linedb.NewLineDb(nil)
// Инициализируем базу данных с множественными коллекциями
initOptions := &linedb.LineDbInitOptions{
CacheSize: 1000,
CacheTTL: 10 * time.Second,
DBFolder: "./data/test-linedb-delete",
Collections: []linedb.JSONLFileOptions{
{
CollectionName: "users",
AllocSize: 256,
IndexedFields: []string{"id", "username"},
},
{
CollectionName: "posts",
AllocSize: 256,
IndexedFields: []string{"id", "authorId"},
},
{
CollectionName: "comments",
AllocSize: 256,
IndexedFields: []string{"id", "postId"},
},
},
}
if err := db.Init(true, initOptions); err != nil {
log.Printf("Failed to init database: %v", err)
return
}
defer db.Close()
// Создаем данные для разных коллекций
users := []any{
map[string]any{
"id": 1,
"username": "user1",
"email": "user1@example.com",
},
map[string]any{
"id": 2,
"username": "user2",
"email": "user2@example.com",
},
}
posts := []any{
map[string]any{
"id": 1,
"title": "First Post",
"authorId": 1,
"content": "This is the first post",
},
map[string]any{
"id": 2,
"title": "Second Post",
"authorId": 2,
"content": "This is the second post",
},
}
comments := []any{
map[string]any{
"id": 1,
"postId": 1,
"content": "Great post!",
"authorId": 2,
},
map[string]any{
"id": 2,
"postId": 2,
"content": "Nice article",
"authorId": 1,
},
}
// Вставляем данные в разные коллекции
if err := db.Insert(users, "users", linedb.LineDbAdapterOptions{}); err != nil {
log.Printf("Failed to insert users: %v", err)
return
}
if err := db.Insert(posts, "posts", linedb.LineDbAdapterOptions{}); err != nil {
log.Printf("Failed to insert posts: %v", err)
return
}
if err := db.Insert(comments, "comments", linedb.LineDbAdapterOptions{}); err != nil {
log.Printf("Failed to insert comments: %v", err)
return
}
// Удаляем данные из разных коллекций
usersDeleted, _ := db.Delete(map[string]any{"id": 1}, "users", linedb.LineDbAdapterOptions{})
postsDeleted, _ := db.Delete(map[string]any{"authorId": 1}, "posts", linedb.LineDbAdapterOptions{})
commentsDeleted, _ := db.Delete(map[string]any{"postId": 1}, "comments", linedb.LineDbAdapterOptions{})
// Читаем данные из всех коллекций
usersData, _ := db.Read("users", linedb.LineDbAdapterOptions{})
postsData, _ := db.Read("posts", linedb.LineDbAdapterOptions{})
commentsData, _ := db.Read("comments", linedb.LineDbAdapterOptions{})
fmt.Printf(" Удалено пользователей: %d\n", len(usersDeleted))
fmt.Printf(" Удалено постов: %d\n", len(postsDeleted))
fmt.Printf(" Удалено комментариев: %d\n", len(commentsDeleted))
fmt.Printf(" Осталось пользователей: %d\n", len(usersData))
fmt.Printf(" Осталось постов: %d\n", len(postsData))
fmt.Printf(" Осталось комментариев: %d\n", len(commentsData))
}