Update README.md

This commit is contained in:
Григорий Сафронов 2025-11-29 15:14:47 +00:00
parent 7881ccb00f
commit a777132814

366
README.md
View File

@ -19,7 +19,7 @@
<h3 align="center">futriix</h3>
<p align="center">
<b>Futriix-встроенная распределённая субд в сервер-приложений (falcot) с поддержкой модулей на языке lua, написанная на языке Rust</b> <br>
<b>Futriix-встроенная в сервер-приложений распределённая субд с поддержкой модулей на языке lua, написанная на языке Rust</b> <br>
<br />
<br />
<!-- <a href="">Сообщить об ошибке</a>
@ -66,7 +66,7 @@
<!-- ABOUT THE PROJECT -->
## О проекте
Falcot - это http сервер-приложений со встроенной мультимодельной NOSQL СУБД **futriix** с минимальным количеством блокировок, которая написана на языке программирования Rust. <br>
Futriix - это http сервер-приложений со встроенной одноимённой мультимодельной NOSQL СУБД с минимальным количеством блокировок, которая написана на языке программирования Rust. <br>
Поддерживает следующие модели хранения данных:
- модель временных рядов (time series)
@ -97,7 +97,6 @@ Falcot - это http сервер-приложений со встроенной
* **Кластер** - это группа компьютеров, объединённых высокоскоростными каналами связи для решения сложных вычислительных задач и представляющая с точки зрения пользователя группу серверов, объединенных для работы как единая система.
* **FutBot** - это интеллектуальный помощник в мессенджере Телеграмм, помогающий осущесвлять быстрый поиск по документации проекта.
* **Сервер-приложений (англ. application-server)** - это программное обеспечение, которое обеспечивает выполнение бизнес-логики и обработку запросов от клиентов (например, веб-браузеров или мобильных приложений). Он служит платформой для развертывания и управления приложениями, имея встроенные интепретаторы и/или компиляторы популярных языков программирования (php,go,python), что обеспечивает взаимодействие между пользователями, базами данных и другими системами.
* **futriix** - это сервер проекта futriix.
* **Интерактивная оболочка (неофициальное название "clif")** - это клиент для работы со встроенной СУБД.
* **workflow (англ. workflow — «поток работы»)** — это принцип организации рабочих процессов, в соответствии с которым повторяющиеся задачи представлены как последовательность стандартных шагов.
* **wait-free" (дословно с англ. wait-free — «свободный от ожидания»)**-класс неблокирующих алгоритмов, в которых каждая операция должна завершаться за конечное число шагов независимо от активности других потоков.
@ -108,9 +107,9 @@ Falcot - это http сервер-приложений со встроенной
<p align="right">(<a href="#readme-top">К началу</a>)</p>
##
**Почему именно HTAP? Анализ характеристик falcot:**
**Почему именно HTAP? Анализ характеристик Futriix:**
OLTP (Online Transactional Processing- Онлайн оработка транзакций) черты, присущие falcot:
OLTP (Online Transactional Processing- Онлайн оработка транзакций) черты, присущие Futriix:
1. **Поддержка транзакций - есть BEGIN/COMMIT/ROLLBACK**
2. **CRUD операции - полноценные Create, Read, Update, Delete**
@ -120,7 +119,7 @@ OLTP (Online Transactional Processing- Онлайн оработка транз
<br>
<br>
OLAP (Online Analytical Processing- Оперативная аналитическая обработка) черты, присущие falcot:
OLAP (Online Analytical Processing- Оперативная аналитическая обработка) черты, присущие Futriix:
1. **Документо-ориентированная модель - удобна для аналитических запросов**
@ -130,7 +129,7 @@ OLAP (Online Analytical Processing- Оперативная аналитичес
<br>
<br>
HTAP (Hybrid Transactional Analytical Processing- Гибридная обработка транзакций) черты, присущие falcot:
HTAP (Hybrid Transactional Analytical Processing- Гибридная обработка транзакций) черты, присущие Futriix:
1. **Единая платформа - обрабатывает и транзакции, и аналитику**
@ -141,7 +140,7 @@ HTAP (Hybrid Transactional Analytical Processing- Гибридная обраб
<br>
<br>
Если посмотреть на архитектурные особенности falcot, то можно заметить следующее:
Если посмотреть на архитектурные особенности Futriix, то можно заметить следующее:
1. **Wait-free доступ подходит для concurrent transactional workload**
2. **Document-oriented модель удобна для analytical queries**
@ -151,7 +150,7 @@ HTAP (Hybrid Transactional Analytical Processing- Гибридная обраб
<br>
> [!CAUTION]
> **falcot НЕ поддерживает:**
> **Futriix НЕ поддерживает:**
> * Полноценные распределённые транзакции
> * Сложные ограничения (constraints)
> * Хранилища типа "Семейство столбцов" (Columnar Storage) для аналитики
@ -163,7 +162,7 @@ HTAP (Hybrid Transactional Analytical Processing- Гибридная обраб
<br>
> [!NOTE]
>**Falcot** - это lightweight HTAP система, занимающая нишу прагматичного HTAP - достаточно мощная для большинства реальных задач, но без > избыточной сложности enterprise-решений, **с акцентом на:**
>**Futriix** - это lightweight HTAP система, занимающая нишу прагматичного HTAP - достаточно мощная для большинства реальных задач, но без > избыточной сложности enterprise-решений, **с акцентом на:**
> * Простоту использования через Lua-интерфейс
> * Гибридную модель для mixed workloads
> * Wait-free performance для concurrent access
@ -177,9 +176,9 @@ HTAP (Hybrid Transactional Analytical Processing- Гибридная обраб
Проект распространяется под 3-пунктной лицензией BSD. Подробнсти в файле `LICENSE.txt`.
Эта лицензия является одной из самых демократичных лицензий свободного программного обеспечения. Она позволяет использовать, изменять и распространять код в коммерческих целях без каких-либо ограничений, за исключением сохранения уведомления об авторских правах.
В том числе, Вы можете использовать falcot и futriix в своих коммерческих продуктах, приложениях или сервисах, не беспокоясь о каких-либо юридических ограничениях, связанных с лицензией.
В том числе, Вы можете использовать Futriix и futriix в своих коммерческих продуктах, приложениях или сервисах, не беспокоясь о каких-либо юридических ограничениях, связанных с лицензией.
Все дополнительное программное обеспечение (включая модули на языке lua, утилиту тестирования) предоставляются "как есть", без гарантий и обязательств со стороны разработчиков. Разработчики не несут ответственности за прямой или косвенный ущерб, вызванный использованием открытого кода falcot и futriix или технических решений, использующих этот код.
Все дополнительное программное обеспечение (включая модули на языке lua, утилиту тестирования) предоставляются "как есть", без гарантий и обязательств со стороны разработчиков. Разработчики не несут ответственности за прямой или косвенный ущерб, вызванный использованием открытого кода Futriix и futriix или технических решений, использующих этот код.
<p align="right">(<a href="#readme-top">К началу</a>)</p>
@ -219,11 +218,11 @@ HTAP (Hybrid Transactional Analytical Processing- Гибридная обраб
1. Копируем репозиторий
```sh
$ git clone https://source.futriix.ru/gvsafronov/falcot
$ git clone https://source.futriix.ru/gvsafronov/Futriix
```
2. Переходим в каталог с исходном кодом src
```sh
$ cd falcot/
$ cd Futriix/
```
3. Компилируем Futriix с помощью пакетного менеджера `Cargo`
```sh
@ -232,23 +231,20 @@ HTAP (Hybrid Transactional Analytical Processing- Гибридная обраб
> [!WARNING]
> **Futriix может быть скомпилирован для следующих операционных систем: `Linux`, `OSX`, `Open Indiana`, `FreeBSD`, но сборка для этих операционных систем не проводилась!!!**
<br>
4. Запускаем сервера futriix'а с помощью команды `./falcot`
4. Запускаем сервера futriix'а с помощью команды `./Futriix`
```sh
$ ./falcot
$ ./Futriix
````
Если проект был успешно скомпилирован, то при его запуске в терминале вы увидите, следующие сообщение:
Если проект был успешно скомпилирован, то при его запуске в терминале вы увидите, похожее сообщение:
<br>
```sh
Loading configuration from: config.toml
Database initialized with system collections
Falcot Database Server
Version: 1.0.0
Futriix Database Server
Features: Wait-Free Architecture, Master-Master Replication, Lua Scripting, HTTP/HTTPS Support
HTTP server started on 127.0.0.1:8082
Starting Lua interpreter...
Lua interpreter ready. Type 'inbox.start' to enter database mode.
Type 'exit' to quit.
lua>
@ -340,9 +336,9 @@ $ cargo test --test integration_tests --release -- --nocapture
## Тестирование
В состав проекта, входит утилита `integration_tests.rs` **integration_tests.rs** - это интеграционный тестовый набор, который при запуске создает и выполняет сразу несколько различных типов тестов. С её помощью можно запустить как сразу все тесты, так и определённый тест.
Вышеописанная утилита - является мощным инструментом для комплексного тестирования всей системы Falcot, позволяющий быстро выявлять проблемы на разных уровнях приложения и обеспечивать высокое качество кода.
Вышеописанная утилита - является мощным инструментом для комплексного тестирования всей системы Futriix, позволяющий быстро выявлять проблемы на разных уровнях приложения и обеспечивать высокое качество кода.
**Falcot поддерживает пять типов тестов:**
**Futriix поддерживает пять типов тестов:**
* **Регрессионный тест - проверяет базовую функциональность**
* **Unit-тест - тестирует конкретный модуль (индексы)**
@ -428,53 +424,47 @@ $ cargo test --test integration_tests test -- --nocapture
<!-- USAGE EXAMPLES -->
## Примеры команд субд
```sh
./falcot config.toml
./Futriix config.toml
В интерактивном режиме:
Loading configuration from: config.toml
Database initialized with system collections
Falcot Database Server
Version: 1.0.0
Futriix Database Server
Features: Wait-Free Architecture, Master-Master Replication, Lua Scripting, HTTP/HTTPS Support
HTTP server started on 127.0.0.1:8082
Starting Lua interpreter...
Lua interpreter ready. Type 'inbox.start' to enter database mode.
Type 'exit' to quit.
lua> falcot_log("Добро пожаловать в Falcot!")
LUA: Добро пожаловать в Falcot!
Type 'inbox.start' to enter database mode.
lua> inbox.start
Entering database mode. Type CRUD commands or 'inbox.stop' to exit.
falcot:~> create users '{"name": "Иван", "age": 25, "city": "Москва"}'
futriix:~> create users '{"name": "Иван", "age": 25, "city": "Москва"}'
Document created with ID: a1b2c3d4-e5f6-7890-abcd-ef1234567890
falcot:~> create users '{"name": "Мария", "age": 30, "city": "Санкт-Петербург"}'
futriix:~> create users '{"name": "Мария", "age": 30, "city": "Санкт-Петербург"}'
Document created with ID: b2c3d4e5-f6g7-8901-bcde-f23456789012
falcot:~> list users
futriix:~> list users
Documents in collection: [{"_id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","name":"Иван","age":25,"city":"Москва"},{"_id":"b2c3d4e5-f6g7-8901-bcde-f23456789012","name":"Мария","age":30,"city":"Санкт-Петербург"}]
falcot:~> begin trans1
futriix:~> begin trans1
Transaction started successfully
falcot:~> create products '{"name": "Ноутбук", "price": 50000, "category": "электроника"}'
futriix:~> create products '{"name": "Ноутбук", "price": 50000, "category": "электроника"}'
Document created with ID: c3d4e5f6-g7h8-9012-cdef-345678901234
falcot:~> create products '{"name": "Телефон", "price": 25000, "category": "электроника"}'
futriix:~> create products '{"name": "Телефон", "price": 25000, "category": "электроника"}'
Document created with ID: d4e5f6g7-h8i9-0123-defg-456789012345
falcot:~> commit trans1
futriix:~> commit trans1
Transaction committed successfully
falcot:~> inbox.stop
futriix:~> inbox.stop
Exiting database mode. Back to Lua interpreter.
lua> procedure create count_users '
function count_users()
local result = falcot_db.query("users", "{}")
local result = Futriix_db.query("users", "{}")
local count = 0
for _ in string.gmatch(result, "\\\"name\\\":") do
count = count + 1
@ -489,7 +479,7 @@ lua> procedure call count_users
Procedure result: Всего пользователей: 2
lua> exit
Shutting down Falcot server...
Shutting down Futriix server...
```
**Параллельно запускаем в другом терминале:**
@ -497,7 +487,7 @@ Shutting down Falcot server...
```sh
#### Проверка HTTP API
curl http://127.0.0.1:8082/api/
#### {"status": "ok", "message": "Falcot Server is running"}
#### {"status": "ok", "message": "Futriix Server is running"}
#### Получение списка пользователей
curl http://127.0.0.1:8082/api/query?collection=users
@ -508,9 +498,9 @@ curl http://127.0.0.1:8082/api/query?collection=users
## Обработка статических страниц
Запуск статических веб-страниц, из сервера приложений falcot
Запуск статических веб-страниц, из сервера приложений Futriix
Falcot имеет встроенную поддержку статических файлов:
Futriix имеет встроенную поддержку статических файлов:
Настройка статических файлов:
```sh
@ -520,7 +510,7 @@ Falcot имеет встроенную поддержку статических
```
Разместите файлы в каталоге static:
```sh
falcot/
Futriix/
├── static/
│ ├── index.html
│ ├── style.css
@ -547,7 +537,7 @@ http://127.0.0.1:8082/images/logo.png
http://127.0.0.1:8082/api-docs.html
```
**Falcot поддерживает следующие типы файлов:**
**Futriix поддерживает следующие типы файлов:**
* HTML (.html)
* CSS (.css)
@ -567,7 +557,7 @@ http://127.0.0.1:8082/api-docs.html
## Репликация
Сервер-приложенй falcot поддерживает синхронную мастер-мастер репликацию.
Сервер-приложенй Futriix поддерживает синхронную мастер-мастер репликацию.
За управление репликацией отвечает секция `[replication]` в конфигурационном файле `config.toml`
```sh
@ -604,22 +594,22 @@ $ cargo run -- config3.toml
```sh
-- replication_test.lua
falcot_log("Testing replication...")
Futriix_log("Testing replication...")
-- Добавляем данные на основном сервере
local doc1 = falcot_db.create("test_data", '{"type": "main", "value": "from_server_1"}')
local doc2 = falcot_db.create("test_data", '{"type": "main", "value": "from_server_1_again"}')
local doc1 = Futriix_db.create("test_data", '{"type": "main", "value": "from_server_1"}')
local doc2 = Futriix_db.create("test_data", '{"type": "main", "value": "from_server_1_again"}')
falcot_log("Documents created on main server: " .. doc1 .. ", " .. doc2)
Futriix_log("Documents created on main server: " .. doc1 .. ", " .. doc2)
-- Ждем синхронизации
falcot_log("Waiting for replication...")
Futriix_log("Waiting for replication...")
os.execute("sleep 3") -- Ждем дольше интервала синхронизации
-- Проверяем на репликах (это нужно делать с разных клиентов)
falcot_log("Checking replicated data...")
local all_data = falcot_db.query("test_data", "{}")
falcot_log("All data: " .. all_data)
Futriix_log("Checking replicated data...")
local all_data = Futriix_db.query("test_data", "{}")
Futriix_log("All data: " .. all_data)
```
**Мониторинг репликации**
@ -629,13 +619,13 @@ falcot_log("All data: " .. all_data)
lua> inbox.start
# Проверяем статус репликации
falcot:~> print(falcot.engine.replication.status())
futriix:~> print(Futriix.engine.replication.status())
# Смотрим список узлов
falcot:~> print("Nodes: " .. table.concat(falcot.engine.replication.get_nodes(), ", "))
futriix:~> print("Nodes: " .. table.concat(Futriix.engine.replication.get_nodes(), ", "))
# Запускаем принудительную синхронизацию
falcot:~> falcot.engine.replication.sync()
futriix:~> Futriix.engine.replication.sync()
```
<p align="right">(<a href="#readme-top">К началу</a>)</p>
@ -718,70 +708,70 @@ curl http://127.0.0.1:8082/api/stats
```sh
-- error_handling.lua
falcot_log("Testing replication error handling")
Futriix_log("Testing replication error handling")
-- Пытаемся добавить данные при недоступности реплик
local success, result = pcall(function()
return falcot_db.create("test_collection", '{"data": "test"}')
return Futriix_db.create("test_collection", '{"data": "test"}')
end)
if success then
falcot_log("Data created successfully: " .. result)
Futriix_log("Data created successfully: " .. result)
-- Проверяем статус репликации
local rep_status = falcot.engine.replication.status()
local rep_status = Futriix.engine.replication.status()
if rep_status ~= "active" then
falcot_log("Warning: Replication is not active. Status: " .. rep_status)
Futriix_log("Warning: Replication is not active. Status: " .. rep_status)
end
else
falcot_error("Failed to create data: " .. result)
Futriix_error("Failed to create data: " .. result)
-- Пытаемся работать в offline режиме
falcot_log("Trying offline operation...")
local offline_data = falcot_db.query("test_collection", "{}")
falcot_log("Offline data available: " .. #offline_data)
Futriix_log("Trying offline operation...")
local offline_data = Futriix_db.query("test_collection", "{}")
Futriix_log("Offline data available: " .. #offline_data)
end
```
## Резервное копирование
Для встроенной в сервер-приложений falcot, субд **futriix** предусмотрен механизм восстановления из резервных копий (бекапов)
Для встроенной в сервер-приложений Futriix, субд **futriix** предусмотрен механизм восстановления из резервных копий (бекапов)
Бекапы можно создавать c помощью языка lua.
**Создание бекапа через lua**
```sh
-- Создаем бэкап
local result = falcot.engine.backup.start()
print(result) -- "Backup created successfully: /falcot/backups/backup_20231201_143022.json"
local result = Futriix.engine.backup.start()
print(result) -- "Backup created successfully: /Futriix/backups/backup_20231201_143022.json"
-- Или через прямое обращение к функции
local result = falcot_db.backup_start()
local result = Futriix_db.backup_start()
print(result)
-- Создаем несколько тестовых документов перед бэкапом
falcot_db.create('products', '{"name": "Laptop", "price": 999.99, "category": "electronics"}')
falcot_db.create('products', '{"name": "Phone", "price": 499.99, "category": "electronics"}')
falcot_db.create('users', '{"name": "Alice", "email": "alice@example.com", "role": "admin"}')
Futriix_db.create('products', '{"name": "Laptop", "price": 999.99, "category": "electronics"}')
Futriix_db.create('products', '{"name": "Phone", "price": 499.99, "category": "electronics"}')
Futriix_db.create('users', '{"name": "Alice", "email": "alice@example.com", "role": "admin"}')
-- Создаем бэкап с данными
local backup_result = falcot.engine.backup.start()
local backup_result = Futriix.engine.backup.start()
```
**Восстановление из бекапа**
```sh
-- Восстанавливаем из конкретного бэкапа
local restore_result = falcot.engine.backup.restore('/falcot/backups/backup_20231201_143022.json')
local restore_result = Futriix.engine.backup.restore('/Futriix/backups/backup_20231201_143022.json')
print(restore_result) -- "Backup restored successfully"
-- Или через прямое обращение
local restore_result = falcot_db.backup_restore('/falcot/backups/backup_20231201_143022.json')
local restore_result = Futriix_db.backup_restore('/Futriix/backups/backup_20231201_143022.json')
-- Проверяем, что данные восстановились
local users = falcot_db.read('users', 'user123')
local products = falcot_db.query('products', '{}')
local users = Futriix_db.read('users', 'user123')
local products = Futriix_db.query('products', '{}')
print('Users:', users)
print('Products count:', #products)
@ -791,14 +781,14 @@ print('Products count:', #products)
```sh
#### Создаем бэкап
backup start
# Output: Backup created successfully: /falcot/backups/backup_20231201_143022.json
# Output: Backup created successfully: /Futriix/backups/backup_20231201_143022.json
#### Восстанавливаем из бэкапа
backup restore /falcot/backups/backup_20231201_143022.json
backup restore /Futriix/backups/backup_20231201_143022.json
#### Output: Backup restored successfully
#### Смотрим список доступных бэкапов
!ls /falcot/backups/
!ls /Futriix/backups/
#### Output: backup_20231201_143022.json backup_20231202_020001.json
#### Создаем тестовые данные
@ -809,7 +799,7 @@ create users '{"name": "Test User", "email": "test@example.com"}'
backup start
delete products test_product_id
delete users test_user_id
backup restore /falcot/backups/backup_20231201_143022.json
backup restore /Futriix/backups/backup_20231201_143022.json
read products test_product_id
#### Данные восстановяться
```
@ -818,21 +808,21 @@ read products test_product_id
```sh
-- Триггер для создания бэкапа при критических изменениях
falcot_db.add_trigger('auto_backup_on_change', 'after_update', 'config', [[
Futriix_db.add_trigger('auto_backup_on_change', 'after_update', 'config', [[
local config = json.decode(document)
if config.critical_setting then
-- Создаем бэкап при изменении критических настроек
local backup_result = falcot_db.backup_start()
falcot_log('Auto-backup created due to config change: ' .. backup_result)
local backup_result = Futriix_db.backup_start()
Futriix_log('Auto-backup created due to config change: ' .. backup_result)
end
]])
-- Триггер для бэкапа перед массовыми операциями
falcot_db.add_trigger('backup_before_bulk_operation', 'before_delete', 'users', [[
Futriix_db.add_trigger('backup_before_bulk_operation', 'before_delete', 'users', [[
-- Проверяем, это одиночное удаление или массовая операция
if bulk_operation then
local backup_result = falcot_db.backup_start()
falcot_log('Backup created before bulk operation: ' .. backup_result)
local backup_result = Futriix_db.backup_start()
Futriix_log('Backup created before bulk operation: ' .. backup_result)
end
]])
@ -891,8 +881,8 @@ curl -X DELETE http://127.0.0.1:8082/api/delete \
## Аутентификация
Для повышения безопасности в сервере-приложений falcot используется `Аутентификация`.
За параметры авторизации отвечает секция `[security]` в конфигурационном файле `./falcot/config.toml`
Для повышения безопасности в сервере-приложений Futriix используется `Аутентификация`.
За параметры авторизации отвечает секция `[security]` в конфигурационном файле `./Futriix/config.toml`
```sh
[security]
@ -947,7 +937,7 @@ password_hashing_rounds = 12
## HTTPS
Сервер-приложенй falcot поддерживает протоколы https и http2.
Сервер-приложенй Futriix поддерживает протоколы https и http2.
Утилита `generate_certs` - Генерация сертификатов
Назначение: Генерация самоподписанных SSL/TLS сертификатов для HTTPS.
@ -1013,7 +1003,7 @@ curl http://localhost:8082/api/status
## ACL
**ACL** - это система управления доступом, которая позволяет разрешать или запрещать подключения к серверу на основе IP-адресов.
Как работает ACL в Falcot:
Как работает ACL в Futriix:
Принцип работы:
@ -1097,7 +1087,7 @@ denied_ips = [
## Индексы
Falcot поддерживает два стандартных типа индекса: первичные индексы и вторичные индексы
Futriix поддерживает два стандартных типа индекса: первичные индексы и вторичные индексы
**Различия между первичным и вторичным индексом**
@ -1114,7 +1104,7 @@ Falcot поддерживает два стандартных типа инде
```sh
-- Поиск по ID (использует первичный индекс)
local document = falcot_db.read("users", "550e8400-e29b-41d4-a716-446655440000")
local document = Futriix_db.read("users", "550e8400-e29b-41d4-a716-446655440000")
```
2. **Вторичный индекс (Secondary Index)**
@ -1131,10 +1121,10 @@ local document = falcot_db.read("users", "550e8400-e29b-41d4-a716-446655440000")
```sh
-- Неуникальный индекс по полю 'email'
falcot_db.create_index("users", "email_idx", "email", false)
Futriix_db.create_index("users", "email_idx", "email", false)
-- Уникальный индекс по полю 'username'
falcot_db.create_index("users", "username_idx", "username", true)
Futriix_db.create_index("users", "username_idx", "username", true)
```
@ -1148,49 +1138,49 @@ $ cargo run
$ lua> inbox.start
#### Создаем коллекцию пользователей
falcot:~> create users '{"name": "Alice", "age": 30, "email": "alice@example.com"}'
falcot:~> create users '{"name": "Bob", "age": 25, "email": "bob@example.com"}'
falcot:~> create users '{"name": "Charlie", "age": 35, "email": "charlie@example.com"}'
futriix:~> create users '{"name": "Alice", "age": 30, "email": "alice@example.com"}'
futriix:~> create users '{"name": "Bob", "age": 25, "email": "bob@example.com"}'
futriix:~> create users '{"name": "Charlie", "age": 35, "email": "charlie@example.com"}'
#### Создаем вторичный индекс по полю "name"
falcot:~> index create users name_index name
futriix:~> index create users name_index name
#### Создаем уникальный индекс по полю "email"
falcot:~> index create users email_index email unique
futriix:~> index create users email_index email unique
#### Ищем по индексу name
falcot:~> index query users name_index "Alice"
futriix:~> index query users name_index "Alice"
#### Ищем по индексу email
falcot:~> index query users email_index "bob@example.com"
futriix:~> index query users email_index "bob@example.com"
#### Пытаемся создать дубликат email (должна быть ошибка)
falcot:~> create users '{"name": "Another Bob", "age": 28, "email": "bob@example.com"}'
futriix:~> create users '{"name": "Another Bob", "age": 28, "email": "bob@example.com"}'
```
**Создание и использование индексов через Lua скрипты:**
```sh
-- create_indexes.lua
falcot_log("Creating indexes...")
Futriix_log("Creating indexes...")
-- Создаем индексы
falcot_db.create_index("users", "name_index", "name", false)
falcot_db.create_index("users", "email_index", "email", true)
Futriix_db.create_index("users", "name_index", "name", false)
Futriix_db.create_index("users", "email_index", "email", true)
-- Добавляем данные
falcot_db.create("users", '{"name": "Alice", "age": 30, "email": "alice@example.com"}')
falcot_db.create("users", '{"name": "Bob", "age": 25, "email": "bob@example.com"}')
Futriix_db.create("users", '{"name": "Alice", "age": 30, "email": "alice@example.com"}')
Futriix_db.create("users", '{"name": "Bob", "age": 25, "email": "bob@example.com"}')
-- Поиск по индексу
local result = falcot_db.query_by_index("users", "name_index", "Alice")
falcot_log("Search result: " .. result)
local result = Futriix_db.query_by_index("users", "name_index", "Alice")
Futriix_log("Search result: " .. result)
-- Проверка уникальности (должна вызвать ошибку)
local status, err = pcall(function()
falcot_db.create("users", '{"name": "Another", "age": 28, "email": "bob@example.com"}')
Futriix_db.create("users", '{"name": "Another", "age": 28, "email": "bob@example.com"}')
end)
if not status then
falcot_error("Unique constraint violation: " .. err)
Futriix_error("Unique constraint violation: " .. err)
end
```
@ -1231,7 +1221,7 @@ end
```sh
-- Попытка создать документ с существующим ID вызовет ошибку
local status, err = pcall(function()
falcot_db.create("users", '{"id": "existing_id", "name": "Duplicate"}')
Futriix_db.create("users", '{"id": "existing_id", "name": "Duplicate"}')
end)
```
@ -1240,15 +1230,15 @@ end)
```sh
-- При unique=true попытка дублирования вызовет ошибку
local status, err = pcall(function()
falcot_db.create("users", '{"email": "existing@example.com", "name": "Duplicate"}')
falcot_db.create("users", '{"email": "existing@example.com", "name": "Duplicate2"}')
Futriix_db.create("users", '{"email": "existing@example.com", "name": "Duplicate"}')
Futriix_db.create("users", '{"email": "existing@example.com", "name": "Duplicate2"}')
end)
if not status then
falcot_error("Unique constraint violation: " .. err)
Futriix_error("Unique constraint violation: " .. err)
end
```
Таким образом, первичный индекс в falcot - это автоматически создаваемый уникальный индекс для поля `id`, в то время как вторичные индексы создаются вручную для оптимизации произвольных запросов и могут быть как уникальными, так и неуникальными.
Таким образом, первичный индекс в Futriix - это автоматически создаваемый уникальный индекс для поля `id`, в то время как вторичные индексы создаются вручную для оптимизации произвольных запросов и могут быть как уникальными, так и неуникальными.
<p align="right">(<a href="#readme-top">К началу</a>)</p>
@ -1270,7 +1260,7 @@ end
```sh
#### Гарантируем уникальность email в коллекции users
falcot:~> constraint add users unique_email unique email
futriix:~> constraint add users unique_email unique email
#### Где:
#### - users: коллекция
@ -1283,7 +1273,7 @@ falcot:~> constraint add users unique_email unique email
```sh
#### Ограничиваем возраст пользователей (18-120 лет)
falcot:~> constraint add users age_range range age "{\"min\":18,\"max\":120}"
futriix:~> constraint add users age_range range age "{\"min\":18,\"max\":120}"
#### Где range - тип ограничения, можно передавать JSON значение
```
@ -1292,20 +1282,20 @@ falcot:~> constraint add users age_range range age "{\"min\":18,\"max\":120}"
```sh
#### Проверяем формат email
falcot:~> constraint add users email_pattern pattern email "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
futriix:~> constraint add users email_pattern pattern email "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
```
**Пример Внешний ключ (foreign key)**
```sh
#### Связываем заказы с пользователями
falcot:~> constraint add orders user_foreign_key foreign user_id "users/id"
futriix:~> constraint add orders user_foreign_key foreign user_id "users/id"
```
**Просмотр ограничений**
```sh
#### Список всех constraints для коллекции
falcot:~> constraint list users
futriix:~> constraint list users
#### Пример вывода:
#### Constraints for collection 'users':
@ -1318,7 +1308,7 @@ falcot:~> constraint list users
```sh
#### Удаляем ограничение
falcot:~> constraint remove users unique_email
futriix:~> constraint remove users unique_email
```
@ -1327,14 +1317,14 @@ falcot:~> constraint remove users unique_email
## Хранимые процедуры
**Хранимая процедура в falcot** это откомпилированная во внутреннее представление сервера СУБД подпрограмма, хранящаяся в базе данных. Хранимые процедуры пишутся на специальном языке хранимых процедур и триггеров, в котором имеются операторы присваивания, ветвлений и циклов, а также можно использовать операторы SQL, такие как INSERT, DELETE, UPDATE и SELECT.
**Хранимая процедура в Futriix** это откомпилированная во внутреннее представление сервера СУБД подпрограмма, хранящаяся в базе данных. Хранимые процедуры пишутся на специальном языке хранимых процедур и триггеров, в котором имеются операторы присваивания, ветвлений и циклов, а также можно использовать операторы SQL, такие как INSERT, DELETE, UPDATE и SELECT.
**Создание хранимой процедуры**
```sh
-- Создание хранимой процедуры для расчета статистики
local procedure_code = [[ function calculate_stats(collection_name)
local documents = falcot_db.query(collection_name, "{}")
local documents = Futriix_db.query(collection_name, "{}")
local count = 0
local total_age = 0
@ -1352,7 +1342,7 @@ falcot:~> constraint remove users unique_email
```sh
-- Сохраняем процедуру
falcot_db.create_procedure("calculate_stats", procedure_code)
Futriix_db.create_procedure("calculate_stats", procedure_code)
```
**Работа с хранимыми процедурами в lua интерпретаторе:**
@ -1361,7 +1351,7 @@ falcot_db.create_procedure("calculate_stats", procedure_code)
-- Создание процедуры
procedure create calculate_stats '
function calculate_stats(collection_name)
local result = falcot_db.query(collection_name, "{}")
local result = Futriix_db.query(collection_name, "{}")
local count = 0
for _ in string.gmatch(result, "\\\"_id\\\":") do
count = count + 1
@ -1381,7 +1371,7 @@ procedure call calculate_stats
# Создание процедуры
procedure create user_stats '
function calculate_user_stats()
local users = falcot_db.query("users", "{}")
local users = Futriix_db.query("users", "{}")
local count = 0
for _ in string.gmatch(users, "\\\"name\\\":") do
count = count + 1
@ -1402,7 +1392,7 @@ procedure call user_stats
## Триггеры
Falcot помимо хранимых процедур поддерживает триггеры (обратные вызовы), которые можно создавать тремя способами:
Futriix помимо хранимых процедур поддерживает триггеры (обратные вызовы), которые можно создавать тремя способами:
- через lua-shell
- через интерактивную оболочку
@ -1413,8 +1403,8 @@ Falcot помимо хранимых процедур поддерживает
```sh
-- Создаем триггер, который логирует создание документов в коллекции 'users'
falcot_db.add_trigger('log_user_creation', 'after_create', 'users', [[
falcot_log('New user created with data: ' .. document)
Futriix_db.add_trigger('log_user_creation', 'after_create', 'users', [[
Futriix_log('New user created with data: ' .. document)
-- Можно добавить дополнительную логику, например:
-- - Отправка уведомления
-- - Валидация данных
@ -1422,7 +1412,7 @@ falcot_db.add_trigger('log_user_creation', 'after_create', 'users', [[
]])
-- Триггер для проверки данных перед обновлением
falcot_db.add_trigger('validate_user_update', 'before_update', 'users', [[
Futriix_db.add_trigger('validate_user_update', 'before_update', 'users', [[
local user_data = json.decode(document)
if not user_data.email or not user_data.email:match('^[^@]+@[^@]+%.[^@]+$') then
error('Invalid email format')
@ -1433,11 +1423,11 @@ falcot_db.add_trigger('validate_user_update', 'before_update', 'users', [[
]])
-- Триггер для очистки связанных данных при удалении
falcot_db.add_trigger('cleanup_user_data', 'before_delete', 'users', [[
Futriix_db.add_trigger('cleanup_user_data', 'before_delete', 'users', [[
-- Удаляем связанные записи из других коллекций
falcot_db.delete('user_sessions', id)
falcot_db.delete('user_preferences', id)
falcot_log('Cleaned up user data for ID: ' .. id)
Futriix_db.delete('user_sessions', id)
Futriix_db.delete('user_preferences', id)
Futriix_log('Cleaned up user data for ID: ' .. id)
]])
```
@ -1448,14 +1438,14 @@ falcot_db.add_trigger('cleanup_user_data', 'before_delete', 'users', [[
inbox.start
##### Создаем триггер для логирования
trigger add log_creation after_create orders "falcot_log('New order created: ' .. document)"
trigger add log_creation after_create orders "Futriix_log('New order created: ' .. document)"
#### Триггер для автоматического обновления статистики
trigger add update_stats after_create orders [[
-- Увеличиваем счетчик заказов
local stats = falcot_db.read('statistics', 'order_count') or '0'
local stats = Futriix_db.read('statistics', 'order_count') or '0'
local count = tonumber(stats) + 1
falcot_db.update('statistics', 'order_count', tostring(count))
Futriix_db.update('statistics', 'order_count', tostring(count))
]]
#### Триггер для проверки цены перед созданием
@ -1473,19 +1463,19 @@ trigger add validate_price before_create products [[
```sh
-- Создаем документ - сработает триггер after_create
falcot_db.create('users', '{"name": "John", "email": "john@example.com", "age": 25}')
Futriix_db.create('users', '{"name": "John", "email": "john@example.com", "age": 25}')
-- В логах появится: "LUA: New user created with data: {"name": "John", "email": "john@example.com", "age": 25}"
-- Попытка создать пользователя с невалидным email
falcot_db.create('users', '{"name": "Invalid", "email": "invalid", "age": 30}')
Futriix_db.create('users', '{"name": "Invalid", "email": "invalid", "age": 30}')
-- Получим ошибку: "Invalid email format"
-- Обновляем пользователя
falcot_db.update('users', 'user123', '{"name": "John Updated", "email": "john.new@example.com", "age": 26}')
Futriix_db.update('users', 'user123', '{"name": "John Updated", "email": "john.new@example.com", "age": 26}')
-- Сработает триггер before_update для валидации
-- Удаляем пользователя
falcot_db.delete('users', 'user123')
Futriix_db.delete('users', 'user123')
-- Сработает триггер before_delete для очистки связанных данных
```
@ -1497,16 +1487,16 @@ falcot_db.delete('users', 'user123')
> [!CAUTION]
> **Реализация Lua-скриптов имеет экспериментальный статус, что в некоторых случаях может вызвать аварийное завершение работы сервера!**
В Falcot реализовано несколько способов запуска Lua-скриптов
В Futriix реализовано несколько способов запуска Lua-скриптов
**Способ 1: Непосредственный ввод кода в lua-интерпретатор**
```sh
lua> falcot_log("Привет, мир!")
lua> Futriix_log("Привет, мир!")
LUA: Привет, мир!
lua> local x = 10 + 5
lua> falcot_log("Результат: " .. x)
lua> Futriix_log("Результат: " .. x)
LUA: Результат: 15
```
@ -1514,10 +1504,10 @@ LUA: Результат: 15
```sh
lua> local script = [[
>> for i = 1, 3 do
>> falcot_log("Итерация: " .. i)
>> Futriix_log("Итерация: " .. i)
>> end
>> ]]
lua> falcot.engine.execute_script(script)
lua> Futriix.engine.execute_script(script)
LUA: Итерация: 1
LUA: Итерация: 2
LUA: Итерация: 3
@ -1525,7 +1515,7 @@ LUA: Итерация: 3
**Способ 3: Запуск из файла**
1. **`lua_scripts` - это каталог (директория), где хранятся Lua-скрипты для выполнения сервером Falcot**
1. **`lua_scripts` - это каталог (директория), где хранятся Lua-скрипты для выполнения сервером Futriix**
2. **При запуске сервера автоматически выполняются скрипты из `auto_execute` списка, находящиеся в этой директории**
3. **Сервер автоматически создает этот каталог при первом запуске, если он не существует**
@ -1534,12 +1524,12 @@ LUA: Итерация: 3
1. **Сервер при запуске создает каталог lua_scripts (если его нет)**
2. **В этот каталог можно помещать Lua-скрипты**
3. **Скрипты из списка auto_execute выполняются автоматически при старте сервера**
4. **Другие скрипты можно выполнять вручную через Lua-интерпретатор командой falcot.engine.lua.execute("имя_скрипта.lua")**
4. **Другие скрипты можно выполнять вручную через Lua-интерпретатор командой Futriix.engine.lua.execute("имя_скрипта.lua")**
```sh
Пример структуры каталогов falcot:
Пример структуры каталогов Futriix:
lua_scripts/
├── init.lua (автоматически выполняется при старте)
@ -1554,28 +1544,28 @@ lua_scripts/
### Примеры lua-скриптов
```sh
-- Простой Lua скрипт для демонстрации
falcot_log("Запуск примера Lua скрипта")
Futriix_log("Запуск примера Lua скрипта")
-- Создание документа
falcot_db.create("users", '{"name": "John", "age": 30, "email": "john@example.com"}')
Futriix_db.create("users", '{"name": "John", "age": 30, "email": "john@example.com"}')
-- Чтение документа
local result = falcot_db.read("users", "some-document-id")
falcot_log("Результат чтения: " .. result)
local result = Futriix_db.read("users", "some-document-id")
Futriix_log("Результат чтения: " .. result)
```
```sh
-- Математические операции
local x = 10
local y = 20
falcot_log("Сумма: " .. (x + y))
Futriix_log("Сумма: " .. (x + y))
-- Циклы и условия
for i = 1, 5 do
if i % 2 == 0 then
falcot_log("Четное число: " .. i)
Futriix_log("Четное число: " .. i)
else
falcot_log("Нечетное число: " .. i)
Futriix_log("Нечетное число: " .. i)
end
end
@ -1608,7 +1598,7 @@ rollback transaction_456
## Шардинг
Встроенная в falcot СУБД **futriix** поддерживает горинзонтальный шардинг, т.е. горизонтальное масштабирование.
Встроенная в Futriix СУБД **futriix** поддерживает горинзонтальный шардинг, т.е. горизонтальное масштабирование.
По умолчанию шардинг производится `по алгоритму Hash-based с консистентным хэшированием`. Шифрование производится согласно алгоритму `SipHasher13`.
Но также поддерживается возможность управлять шардингом вручную. Ниже приведены команды по управлению шардингом:
@ -1616,7 +1606,7 @@ rollback transaction_456
```sh
#### Добавляем новый узел шардинга
falcot:~> shard add node1 127.0.0.1:8084 1024
futriix:~> shard add node1 127.0.0.1:8084 1024
#### Где:
#### - node1: идентификатор узла
@ -1628,14 +1618,14 @@ falcot:~> shard add node1 127.0.0.1:8084 1024
```sh
#### Удаляем узел из кластера
falcot:~> shard remove node1
futriix:~> shard remove node1
```
**Пример миграции между шардами узла**
```sh
#### Мигрируем данные коллекции между узлами
falcot:~> shard migrate users node1 node2 user_id
futriix:~> shard migrate users node1 node2 user_id
#### Где:
#### - users: коллекция для миграции
@ -1648,7 +1638,7 @@ falcot:~> shard migrate users node1 node2 user_id
```sh
#### Показывает статус всего кластера
falcot:~> shard status
futriix:~> shard status
#### Пример вывода:
#### === Cluster Status ===
@ -1668,20 +1658,20 @@ falcot:~> shard status
```sh
#### Запускает автоматическую ребалансировку
falcot:~> cluster rebalance
futriix:~> cluster rebalance
```
**Пример создания шардированной системы пользователей**
```sh
#### Добавляем узлы
falcot:~> shard add node1 127.0.0.1:8081 1024
falcot:~> shard add node2 127.0.0.1:8082 1024
futriix:~> shard add node1 127.0.0.1:8081 1024
futriix:~> shard add node2 127.0.0.1:8082 1024
#### Создаем constraints для пользователей
falcot:~> constraint add users unique_email unique email
falcot:~> constraint add users valid_age range age "{\"min\":13,\"max\":150}"
falcot:~> constraint add users valid_username pattern username "^[a-zA-Z0-9_]{3,20}$"
futriix:~> constraint add users unique_email unique email
futriix:~> constraint add users valid_age range age "{\"min\":13,\"max\":150}"
futriix:~> constraint add users valid_username pattern username "^[a-zA-Z0-9_]{3,20}$"
#### Распределяем пользователей по шардам
shard migrate users node1 node2 user_id
@ -1691,13 +1681,13 @@ shard migrate users node1 node2 user_id
```sh
#### Проверяем статус
falcot:~> shard status
futriix:~> shard status
#### Если нужно перебалансировать
falcot:~> cluster rebalance
futriix:~> cluster rebalance
#### Проверяем constraints
falcot:~> constraint list users
futriix:~> constraint list users
```
<p align="right">(<a href="#readme-top">К началу</a>)</p>
@ -1705,7 +1695,7 @@ falcot:~> constraint list users
## Сферы применения
Идеальными сферами применения проекта falcot, являются следующие:
Идеальными сферами применения проекта Futriix, являются следующие:
1. **Микросервисы с потребностью в оперативной аналитике**
2. **Работающая в режиме реального времени панель мониторинга - для администрирования бекенда**
@ -1713,15 +1703,15 @@ falcot:~> constraint list users
4. **Прототипирование перед выбором специализированного решения**
<br>
<b>Пример функциональных возможностей falcot классов OLTP и OLAP для микросервисов с потребностью в оперативной аналитике</b>
<b>Пример функциональных возможностей Futriix классов OLTP и OLAP для микросервисов с потребностью в оперативной аналитике</b>
<br>
```sh
-- OLTP-операция: быстрая транзакция
falcot_db.update("users", "user123", '{"balance": 100}')
Futriix_db.update("users", "user123", '{"balance": 100}')
-- OLAP-операция: аналитический запрос
local analytics = falcot_db.query("transactions", '{"date": {"$gt": "2024-01-01"}}')
local analytics = Futriix_db.query("transactions", '{"date": {"$gt": "2024-01-01"}}')
```
<p align="right">(<a href="#readme-top">К началу</a>)</p>
@ -1747,14 +1737,18 @@ local analytics = falcot_db.query("transactions", '{"date": {"$gt": "2024-01-01"
- [x] Исправить ошибки записи журнала логов (в журнал лога кроме текущего времени добавить текущий год)
- [x] Реализовать утилиту тестирования сервера на количество запросов на чтение/запись
- [x] Переписать асинхронную мастер-мастер репликацию на синхронную мастер-мастер репликацию
- [ ] Реализовать журнал WAL
- [ ] Реализовать графический веб-интерфейс для упраления кластером
- [x] Реализовать автоматический шардинг с консистентным хэшированием
- [ ] Реализовать поддержку алгоритма Raft
- [x] Реализовать базовый журнал WAL
- [ ] Реализовать графический веб-интерфейс для управления кластером
- [ ] Реализовать автоматический шардинг с консистентным хэшированием
- [ ] Реализовать полноценную поддержку алгоритма Raft (с автоматическим перевывыбором лидера, с доменом отказа)
- [ ] Реализовать полноценную поддержку кластеризации с обработкой состояний "split-brain"
- [ ] Реализовать поддержку SQL
- [ ] Реализовать поддержку ACID-транзакций
- [ ] Интегрировать интеллектуального помощник FutBot на официальный сайт
- [ ] Реализовать полноценного интеллектуального помощника FutBot, задачами которого будут быстрый поиск ответов на вопросы, возникающие при эксплуатации субд Futrix.
- [ ] Интегрировать интеллектуального помощник FutBot в веб-интерфейс
- [ ] Реализовать внешние транзакции
- [ ] Интеграцию с мониторинговыми системами (Prometheus, Grafana)
- [ ] Реализовать полноценную систему бекапирования с возможностью определения корректности созданного бекапа и кроссдацентровых решений по автоматическому копироваю бекапа в другой дацентр
- [] Реализовать полноценную систему авторизации на основе RBAC
См. [Открытые проблемы](https://source.futriix.ru/gvsafronov/futriixw/issues) полный список предлагаемых функций (и известных проблем).
@ -1770,4 +1764,4 @@ local analytics = falcot_db.query("transactions", '{"date": {"$gt": "2024-01-01"
Ссылка на Интеллектуальный помощник - [FutBot](https://t.me/Futriix_bot)
<p align="right">(<a href="#readme-top">К началу</a>)</p>
<p align="right">(<a href="#readme-top">К началу</a>)</p>