GreenBean/README.md
Vufer be9be042b8 feat(core): Реализация автоматических связей через соглашения
• Добавлена автоматическая детекция типов связей
• Реализован Proxy-доступ к связям через свойства
• Поддержка каскадного удаления данных
• Добавлены транзакции с откатом состояния
• Обновлена документация и примеры использования

Миграция:
- Вместо методов xown()/shared() используйте прямое присваивание
- Методы getXown() заменены на доступ через свойства
2025-02-17 23:23:00 +03:00

243 lines
8.1 KiB
Markdown
Raw Permalink 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.

# GreenBean Документация
## 🌱 Введение
**GreenBean** — это современная ORM для Node.js, сочетающая простоту RedBeanPHP с мощью JavaScript.
Работает поверх JSON-хранилища, идеально подходит для прототипов, MVP и приложений с гибкой схемой данных.
### Ключевые концепции:
- **Динамическая схема** — не требует предварительного описания моделей
- **Живые объекты** — изменения сохраняются автоматически
- **Соглашения вместо конфигурации** — автоматическое разрешение связей
- **Транзакционный подход** — атомарные операции изменения данных
## 🛠 Установка
```bash
npm install greenbean uuid
```
## 🎯 Быстрый старт
### Создание простого блога
```javascript
import GreenBean from 'greenbean';
// 1. Инициализация
const gb = new GreenBean('blog.json', {
autoSave: true // Автосохранение при изменениях
});
// 2. Создание сущностей
const author = await gb.dispense('Author', {
name: 'Анна',
bio: 'JS разработчик из Москвы'
});
const post = await gb.dispense('Post', {
title: 'Мой первый пост',
content: '...'
});
// 3. Установка связей
post.author = author; // Один-ко-многим
post.tags = [ // Многие-ко-многим
await gb.dispense('Tag', {name: 'программирование'}),
await gb.dispense('Tag', {name: 'учебник'})
];
// 4. Добавление комментариев (Один-ко-многим)
post.comments = [
await gb.dispense('Comment', {text: 'Отличный пост!'}),
await gb.dispense('Comment', {text: 'Спасибо за статью'})
];
// 5. Получение связанных данных
const loadedPost = await gb.load('Post', post.id);
console.log('Автор:', (await loadedPost.author).name);
console.log('Теги:', await loadedPost.tags);
console.log('Комментарии:', await loadedPost.comments);
```
## 🔄 Жизненный цикл бина
1. **Создание**`dispense()`
2. **Модификация** — прямое изменение свойств
3. **Сохранение** — автоматическое или через `store()`
4. **Удаление**`trash()`
```javascript
// Пример жизненного цикла
const user = await gb.dispense('User'); // 1. Создание
user.name = 'Иван'; // 2. Модификация
await gb.store(user); // 3. Сохранение
await gb.trash(user); // 4. Удаление
```
## 🤝 Работа со связями
### Правила именования
| Тип связи | Паттерн | Пример |
|-----------------|---------------------------|---------------------|
| Один-ко-многим | `parent.children` | `user.posts` |
| Многие-ко-многим | `parent_relation` таблица | `post_tags` |
| Один-к-одному | `parent.prop` + уникальность | `user.profile` |
### Практические примеры
#### 1. Социальная сеть
```javascript
// Пользователь и друзья (многие-ко-многим)
const user = await gb.dispense('User');
user.friends = [
await gb.dispense('User', {name: 'Мария'}),
await gb.dispense('User', {name: 'Петр'})
];
// Группы (один-ко-многим)
const group = await gb.dispense('Group');
group.members = [
await gb.dispense('User', {name: 'Анна'}),
await gb.dispense('User', {name: 'Сергей'})
];
```
#### 2. Электронная коммерция
```javascript
// Заказ и товары (многие-ко-многим)
const order = await gb.dispense('Order');
order.products = [
await gb.dispense('Product', {name: 'Ноутбук'}),
await gb.dispense('Product', {name: 'Чехол'})
];
// Платежная информация (один-к-одному)
order.payment = await gb.dispense('Payment', {
amount: 999.99,
status: 'completed'
});
```
## 🔍 Расширенный поиск
### Поддерживаемые операторы
```javascript
const results = await gb.find('User', {
age: { gt: 18, lt: 30 }, // Больше 18 и меньше 30
name: { like: 'Ив%' }, // Начинается с "Ив"
email: { neq: null }, // Email не null
rating: { between: [4, 5] } // Рейтинг от 4 до 5
});
```
### Сортировка и пагинация
```javascript
const posts = await gb.find('Post',
{ status: 'published' },
{
limit: 10,
offset: 20,
order: { created: 'DESC' }
}
);
```
## 🛡 Транзакции и безопасность
```javascript
try {
await gb.transaction(async () => {
const product = await gb.dispense('Product');
product.stock -= 1;
const order = await gb.dispense('Order');
order.items = [product];
if (product.stock < 0) {
throw new Error('Нет в наличии');
}
});
} catch (error) {
console.error('Ошибка транзакции:', error.message);
}
```
## 🧊 Заморозка данных
```javascript
// Защита от изменений
gb.freeze();
try {
const user = await gb.dispense('User'); // Ошибка!
} catch (e) {
console.error('База заморожена');
}
// Временная разморозка
gb.freeze(false);
const tempUser = await gb.dispense('User');
gb.freeze(true);
```
## 🧩 Лучшие практики
### 1. Сервисные классы
```javascript
class UserService {
constructor(gb) {
this.gb = gb;
}
async register(userData) {
const user = await this.gb.dispense('User', userData);
user.verificationToken = crypto.randomBytes(32).toString('hex');
return this.gb.store(user);
}
}
```
### 2. Валидация данных
```javascript
function validatePost(post) {
const errors = [];
if (!post.title || post.title.length < 5) {
errors.push('Название слишком короткое');
}
if (!post.content || post.content.length < 100) {
errors.push('Минимум 100 символов в содержании');
}
return errors;
}
```
### 3. Обработка ошибок
```javascript
async function safeDeleteUser(userId) {
try {
const user = await gb.load('User', userId);
await gb.trash(user);
return true;
} catch (error) {
console.error(`Ошибка удаления пользователя ${userId}:`, error);
return false;
}
}
```
## 📚 Полное API
### Основные методы
| Метод | Параметры | Возвращает | Описание |
|-----------------------|----------------------|--------------------|--------------------------|
| `dispense(type, props)` | Тип, свойства | Бин | Создает новый объект |
| `store(bean)` | Бин | ID | Сохраняет изменения |
| `load(type, id)` | Тип, ID | Бин/null | Загружает по ID |
| `find(type, criteria)` | Тип, критерии | Массив бинов | Поиск с фильтрацией |
| `trash(bean)` | Бин | void | Удаляет объект и связи |
### Настройки
```javascript
new GreenBean('data.json', {
autoSave: false, // Автоматическое сохранение
freeze: false, // Начальное состояние блокировки
cacheTTL: 300000 // Время жизни кеша (5 минут)
});
```
## 📜 Лицензия
MIT License © 2025 Rockzo development
```