init elowdb go-port commit

This commit is contained in:
41 changed files with 7273 additions and 0 deletions

592
examples/insert/insert.go Normal file
View File

@@ -0,0 +1,592 @@
package main
import (
"fmt"
"log"
"time"
"linedb/pkg/linedb"
)
// testSingleInsert тестирует вставку одной записи
func testSingleInsert() {
// Создаем базу данных
db := linedb.NewLineDb(nil)
// Инициализируем базу данных
initOptions := &linedb.LineDbInitOptions{
CacheSize: 1000,
CacheTTL: 10 * time.Second,
DBFolder: "./data/test-linedb-insert",
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": "john_doe",
"email": "john@example.com",
"isActive": true,
"role": "user",
"createdAt": time.Now().Unix(),
}
// Вставляем данные
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))
if len(users) > 0 {
if record, ok := users[0].(map[string]any); ok {
fmt.Printf(" ID: %v, Username: %s\n", record["id"], record["username"])
}
}
}
// testArrayInsert тестирует вставку массива записей
func testArrayInsert() {
// Создаем базу данных
db := linedb.NewLineDb(nil)
// Инициализируем базу данных
initOptions := &linedb.LineDbInitOptions{
CacheSize: 1000,
CacheTTL: 10 * time.Second,
DBFolder: "./data/test-linedb-insert",
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()
// Создаем массив продуктов
products := []any{
map[string]any{
"id": 1,
"name": "Laptop",
"price": 999.99,
"category": "Electronics",
"inStock": true,
},
map[string]any{
"id": 2,
"name": "Mouse",
"price": 29.99,
"category": "Electronics",
"inStock": true,
},
map[string]any{
"id": 3,
"name": "Keyboard",
"price": 79.99,
"category": "Electronics",
"inStock": false,
},
}
// Вставляем данные
if err := db.Insert(products, "products", linedb.LineDbAdapterOptions{}); err != nil {
log.Printf("Failed to insert products: %v", err)
return
}
// Читаем данные
productsData, err := db.Read("products", linedb.LineDbAdapterOptions{})
if err != nil {
log.Printf("Failed to read products: %v", err)
return
}
fmt.Printf(" Продуктов в базе: %d\n", len(productsData))
for i, product := range productsData {
if record, ok := product.(map[string]any); ok {
fmt.Printf(" %d. ID: %v, Name: %s, Price: %v\n", i+1, record["id"], record["name"], record["price"])
}
}
}
// testAutoID тестирует автоматическую генерацию ID
func testAutoID() {
// Создаем базу данных
db := linedb.NewLineDb(nil)
// Инициализируем базу данных
initOptions := &linedb.LineDbInitOptions{
CacheSize: 1000,
CacheTTL: 10 * time.Second,
DBFolder: "./data/test-linedb-insert",
Collections: []linedb.JSONLFileOptions{
{
CollectionName: "orders",
AllocSize: 256,
IndexedFields: []string{"id", "customerId"},
},
},
}
if err := db.Init(true, initOptions); err != nil {
log.Printf("Failed to init database: %v", err)
return
}
defer db.Close()
// Создаем заказы без ID
orders := []any{
map[string]any{
"customerId": 1,
"amount": 150.00,
"status": "pending",
"createdAt": time.Now().Unix(),
},
map[string]any{
"customerId": 2,
"amount": 75.50,
"status": "completed",
"createdAt": time.Now().Unix(),
},
}
// Вставляем данные
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))
for i, order := range ordersData {
if record, ok := order.(map[string]any); ok {
fmt.Printf(" %d. ID: %v, Customer: %v, Amount: %v\n", i+1, record["id"], record["customerId"], record["amount"])
}
}
}
// testPartitionedCollections тестирует партиционированные коллекции
func testPartitionedCollections() {
// Создаем базу данных
db := linedb.NewLineDb(nil)
// Инициализируем базу данных с партиционированными коллекциями
initOptions := &linedb.LineDbInitOptions{
CacheSize: 1000,
CacheTTL: 10 * time.Second,
DBFolder: "./data/test-linedb-insert",
Collections: []linedb.JSONLFileOptions{
{
CollectionName: "users_2024",
AllocSize: 256,
IndexedFields: []string{"id", "username"},
},
{
CollectionName: "users_2023",
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()
// Создаем пользователей для разных партиций
users2024 := []any{
map[string]any{
"id": 1,
"username": "user_2024_1",
"email": "user1@2024.com",
"year": 2024,
},
map[string]any{
"id": 2,
"username": "user_2024_2",
"email": "user2@2024.com",
"year": 2024,
},
}
users2023 := []any{
map[string]any{
"id": 3,
"username": "user_2023_1",
"email": "user1@2023.com",
"year": 2023,
},
}
// Вставляем данные в разные партиции
if err := db.Insert(users2024, "users_2024", linedb.LineDbAdapterOptions{}); err != nil {
log.Printf("Failed to insert users 2024: %v", err)
return
}
if err := db.Insert(users2023, "users_2023", linedb.LineDbAdapterOptions{}); err != nil {
log.Printf("Failed to insert users 2023: %v", err)
return
}
// Читаем данные из обеих партиций
users2024Data, err := db.Read("users_2024", linedb.LineDbAdapterOptions{})
if err != nil {
log.Printf("Failed to read users 2024: %v", err)
return
}
users2023Data, err := db.Read("users_2023", linedb.LineDbAdapterOptions{})
if err != nil {
log.Printf("Failed to read users 2023: %v", err)
return
}
fmt.Printf(" Пользователей 2024: %d\n", len(users2024Data))
fmt.Printf(" Пользователей 2023: %d\n", len(users2023Data))
}
// testUniquenessCheck тестирует проверку уникальности
func testUniquenessCheck() {
// Создаем базу данных
db := linedb.NewLineDb(nil)
// Инициализируем базу данных
initOptions := &linedb.LineDbInitOptions{
CacheSize: 1000,
CacheTTL: 10 * time.Second,
DBFolder: "./data/test-linedb-insert",
Collections: []linedb.JSONLFileOptions{
{
CollectionName: "unique_users",
AllocSize: 256,
IndexedFields: []string{"id", "email"},
},
},
}
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": "unique_user",
"email": "unique@example.com",
"isActive": true,
}
// Вставляем данные
if err := db.Insert(user, "unique_users", linedb.LineDbAdapterOptions{}); err != nil {
log.Printf("Failed to insert user: %v", err)
return
}
// Пытаемся вставить пользователя с тем же email
duplicateUser := map[string]any{
"id": 2,
"username": "duplicate_user",
"email": "unique@example.com", // Тот же email
"isActive": true,
}
if err := db.Insert(duplicateUser, "unique_users", linedb.LineDbAdapterOptions{}); err != nil {
fmt.Printf(" Ожидаемая ошибка дублирования: %v\n", err)
} else {
fmt.Printf(" Дублирование не обнаружено\n")
}
// Читаем данные
users, err := db.Read("unique_users", linedb.LineDbAdapterOptions{})
if err != nil {
log.Printf("Failed to read users: %v", err)
return
}
fmt.Printf(" Уникальных пользователей: %d\n", len(users))
}
// testDifferentDataTypes тестирует различные типы данных
func testDifferentDataTypes() {
// Создаем базу данных
db := linedb.NewLineDb(nil)
// Инициализируем базу данных
initOptions := &linedb.LineDbInitOptions{
CacheSize: 1000,
CacheTTL: 10 * time.Second,
DBFolder: "./data/test-linedb-insert",
Collections: []linedb.JSONLFileOptions{
{
CollectionName: "mixed_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()
// Создаем данные разных типов
mixedData := []any{
map[string]any{
"id": 1,
"type": "string",
"value": "Hello World",
"isString": true,
},
map[string]any{
"id": 2,
"type": "number",
"value": 42.5,
"isNumber": true,
},
map[string]any{
"id": 3,
"type": "boolean",
"value": true,
"isBool": true,
},
map[string]any{
"id": 4,
"type": "array",
"value": []any{1, 2, 3, "four"},
"isArray": true,
},
map[string]any{
"id": 5,
"type": "object",
"value": map[string]any{"nested": "value", "count": 10},
"isObject": true,
},
}
// Вставляем данные
if err := db.Insert(mixedData, "mixed_data", linedb.LineDbAdapterOptions{}); err != nil {
log.Printf("Failed to insert mixed data: %v", err)
return
}
// Читаем данные
data, err := db.Read("mixed_data", linedb.LineDbAdapterOptions{})
if err != nil {
log.Printf("Failed to read mixed data: %v", err)
return
}
fmt.Printf(" Записей с разными типами данных: %d\n", len(data))
for i, record := range data {
if item, ok := record.(map[string]any); ok {
fmt.Printf(" %d. ID: %v, Type: %s\n", i+1, item["id"], item["type"])
}
}
}
// testBulkInsert тестирует массовую вставку
func testBulkInsert() {
// Создаем базу данных
db := linedb.NewLineDb(nil)
// Инициализируем базу данных
initOptions := &linedb.LineDbInitOptions{
CacheSize: 10000,
CacheTTL: 10 * time.Second,
DBFolder: "./data/test-linedb-insert",
Collections: []linedb.JSONLFileOptions{
{
CollectionName: "bulk_items",
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()
// Создаем большое количество записей
var bulkItems []any
for i := 1; i <= 1000; i++ {
item := map[string]any{
"id": i,
"name": fmt.Sprintf("Item %d", i),
"category": fmt.Sprintf("Category %d", (i-1)%10+1),
"price": float64(i) * 1.5,
"inStock": i%2 == 0,
"createdAt": time.Now().Unix(),
}
bulkItems = append(bulkItems, item)
}
// Вставляем данные
startTime := time.Now()
if err := db.Insert(bulkItems, "bulk_items", linedb.LineDbAdapterOptions{}); err != nil {
log.Printf("Failed to insert bulk items: %v", err)
return
}
insertTime := time.Since(startTime)
// Читаем данные
startTime = time.Now()
items, err := db.Read("bulk_items", linedb.LineDbAdapterOptions{})
if err != nil {
log.Printf("Failed to read bulk items: %v", err)
return
}
readTime := time.Since(startTime)
fmt.Printf(" Массовая вставка: %d записей за %v\n", len(items), insertTime)
fmt.Printf(" Чтение: %d записей за %v\n", len(items), readTime)
}
// testMultipleCollections тестирует работу с множественными коллекциями
func testMultipleCollections() {
// Создаем базу данных
db := linedb.NewLineDb(nil)
// Инициализируем базу данных с множественными коллекциями
initOptions := &linedb.LineDbInitOptions{
CacheSize: 1000,
CacheTTL: 10 * time.Second,
DBFolder: "./data/test-linedb-insert",
Collections: []linedb.JSONLFileOptions{
{
CollectionName: "customers",
AllocSize: 256,
IndexedFields: []string{"id", "email"},
},
{
CollectionName: "orders",
AllocSize: 256,
IndexedFields: []string{"id", "customerId"},
},
{
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()
// Создаем данные для разных коллекций
customers := []any{
map[string]any{
"id": 1,
"name": "John Doe",
"email": "john@example.com",
"isActive": true,
},
map[string]any{
"id": 2,
"name": "Jane Smith",
"email": "jane@example.com",
"isActive": true,
},
}
orders := []any{
map[string]any{
"id": 1,
"customerId": 1,
"amount": 150.00,
"status": "completed",
},
map[string]any{
"id": 2,
"customerId": 2,
"amount": 75.50,
"status": "pending",
},
}
products := []any{
map[string]any{
"id": 1,
"name": "Laptop",
"price": 999.99,
"category": "Electronics",
},
map[string]any{
"id": 2,
"name": "Mouse",
"price": 29.99,
"category": "Electronics",
},
}
// Вставляем данные в разные коллекции
if err := db.Insert(customers, "customers", linedb.LineDbAdapterOptions{}); err != nil {
log.Printf("Failed to insert customers: %v", err)
return
}
if err := db.Insert(orders, "orders", linedb.LineDbAdapterOptions{}); err != nil {
log.Printf("Failed to insert orders: %v", err)
return
}
if err := db.Insert(products, "products", linedb.LineDbAdapterOptions{}); err != nil {
log.Printf("Failed to insert products: %v", err)
return
}
// Читаем данные из всех коллекций
customersData, _ := db.Read("customers", linedb.LineDbAdapterOptions{})
ordersData, _ := db.Read("orders", linedb.LineDbAdapterOptions{})
productsData, _ := db.Read("products", linedb.LineDbAdapterOptions{})
fmt.Printf(" Коллекций: 3\n")
fmt.Printf(" Клиентов: %d\n", len(customersData))
fmt.Printf(" Заказов: %d\n", len(ordersData))
fmt.Printf(" Продуктов: %d\n", len(productsData))
}

138
examples/insert/main.go Normal file
View File

@@ -0,0 +1,138 @@
package main
import (
"fmt"
"os"
"strconv"
"strings"
)
func main() {
// Очищаем тестовые данные
os.RemoveAll("./data/test-linedb-insert")
fmt.Println("=== LineDb Insert Operations Demo ===")
// Получаем номера тестов из аргументов командной строки
testNumbers := parseTestNumbers()
// Выполняем тесты
if len(testNumbers) == 0 {
// Если номера не указаны, выполняем все тесты
runAllTests()
} else {
// Выполняем только указанные тесты
runSelectedTests(testNumbers)
}
fmt.Println("\n=== Все тесты завершены ===")
}
// parseTestNumbers парсит номера тестов из аргументов командной строки
func parseTestNumbers() []int {
if len(os.Args) < 2 {
return []int{}
}
// Получаем аргумент после имени программы
arg := os.Args[1]
// Проверяем, что это не флаг помощи
if arg == "-h" || arg == "--help" || arg == "help" {
printUsage()
return []int{}
}
// Разбиваем по запятой
parts := strings.Split(arg, ",")
var numbers []int
for _, part := range parts {
part = strings.TrimSpace(part)
if part == "" {
continue
}
num, err := strconv.Atoi(part)
if err != nil {
fmt.Printf("Ошибка: '%s' не является числом\n", part)
printUsage()
return []int{}
}
// Проверяем диапазон
if num < 1 || num > 8 {
fmt.Printf("Ошибка: номер теста %d должен быть от 1 до 8\n", num)
printUsage()
return []int{}
}
numbers = append(numbers, num)
}
return numbers
}
// printUsage выводит справку по использованию
func printUsage() {
fmt.Println("\nИспользование:")
fmt.Println(" go run main.go # Запустить все тесты")
fmt.Println(" go run main.go 1 # Запустить только тест 1")
fmt.Println(" go run main.go 1,3 # Запустить тесты 1 и 3")
fmt.Println(" go run main.go 2,3,4 # Запустить тесты 2, 3 и 4")
fmt.Println(" go run main.go help # Показать эту справку")
fmt.Println("\nДоступные тесты:")
fmt.Println(" 1 - Вставка одной записи")
fmt.Println(" 2 - Вставка массива записей")
fmt.Println(" 3 - Автоматическая генерация ID")
fmt.Println(" 4 - Партиционированные коллекции")
fmt.Println(" 5 - Проверка уникальности")
fmt.Println(" 6 - Различные типы данных")
fmt.Println(" 7 - Массовая вставка")
fmt.Println(" 8 - Множественные коллекции")
os.Exit(0)
}
// runAllTests запускает все тесты
func runAllTests() {
testSingleInsert()
testArrayInsert()
testAutoID()
testPartitionedCollections()
testUniquenessCheck()
testDifferentDataTypes()
testBulkInsert()
testMultipleCollections()
}
// runSelectedTests запускает только выбранные тесты
func runSelectedTests(numbers []int) {
for _, num := range numbers {
switch num {
case 1:
fmt.Println("1. Вставка одной записи")
testSingleInsert()
case 2:
fmt.Println("2. Вставка массива записей")
testArrayInsert()
case 3:
fmt.Println("3. Автоматическая генерация ID")
testAutoID()
case 4:
fmt.Println("4. Партиционированные коллекции")
testPartitionedCollections()
case 5:
fmt.Println("5. Проверка уникальности")
testUniquenessCheck()
case 6:
fmt.Println("6. Различные типы данных")
testDifferentDataTypes()
case 7:
fmt.Println("7. Массовая вставка")
testBulkInsert()
case 8:
fmt.Println("8. Множественные коллекции")
testMultipleCollections()
}
}
}

View File

@@ -0,0 +1 @@
{"createdAt":1754974407,"email":"john@example.com","id":1,"isActive":true,"role":"user","username":"john_doe"}