Files
futriix/README.md

981 lines
46 KiB
Markdown
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.
<!-- Improved compatibility of К началу link: See: https://github.com/othneildrew/Best-README-Template/pull/73 -->
<a id="readme-top"></a>
<!--
*** Thanks for checking out the Best-README-Template. If you have a suggestion
*** that would make this better, please fork the repo and create a pull request
*** or simply open an issue with the tag "enhancement".
*** Don't forget to give the project a star!
*** Thanks again! Now go create something AMAZING! :D
-->
<!-- PROJECT LOGO -->
<br />
<div align="center">
<!-- <a href="https://github.com/othneildrew/Best-README-Template"> -->
<img src="Logo.png" height=100 alt="Logo.png"></img>
</a>
<p align="center">
<h3> <b>Futriis-это легковесная, распределённая wait-free и lock-free дружественная in-memory СУБД,
реализованная на Go с поддержкой плагинов на языке lua для операционных систем на базе Solaris (ядра Illumos)</b> <br></h3>
<br />
<br />
<!-- <a href="">Сообщить об ошибке</a>
&middot;
<!-- <a href="">Предложение новой функциональности</a> -->
</p>
</div>
## Краткая документация проекта FutriiS
<!-- TABLE OF CONTENTS -->
<br>
<!-- <details> -->
<summary><b>Содержание</b></summary></br>
<ol>
<li>
<a href="#о-проекте">О проекте</a>
<li><a href="#лицензия">Лицензия</a></li>
<li><a href="#глоссарий">Глоссарий</a></li>
<li><a href="#типы-данных-субд">Типы данных субд</a></li>
<li><a href="#системные-требования">Системные требования</a></li>
<li><a href="#подготовка-и-компиляция">Подготовка и компиляция</a></li>
<li><a href="#тестирование">Тестирование</a></li>
<li><a href="#crud-операции">CRUD операции</a></li>
<li><a href="#индексы">Индексы</a></li>
<li><a href="#транзакции">Транзакции</a></li>
<li><a href="#кластеризация-и-шардинг">Кластеризация и шардинг</a></li>
<li><a href="#ограничения">Ограничения</a></li>
<li><a href="#import-export">Import-Export</a></li>
<li><a href="#lua-плагины">Lua-плагины</a></li>
<li><a href="acl">ACL</a></li>
<li><a href="#http-api">HTTP API</a></li>
<li><a href="#триггеры">Триггеры</a></li>
<li><a href="#сжатие-данных">Сжатие данных</a></li>
<li><a href="#графический-интерфейс">Графический интерфейс</a></li>
<li><a href="#дорожная-карта">Дорожная карта</a></li>
<li><a href="#контакты">Контакты</a></li>
</ol>
<!-- </details> -->
## О проекте
> [!CAUTION]
> **ALPHA VERSION**<br><br>**Категорически не использовать в продакшене, так как это экспериментальная версия!!!**
futriis - это легковесная, распределённая wait-free и lock-free дружественная in-memory СУБД, реализованная на Go с поддержкой плагинов на языке lua использующая алгоритм консенсуса Raft.
Данная субд была разработана, в первую очередь для эксплуатации на операционных системах на базе Solaris: OpenIndiana, Oracle Solaris.
Но также она совместима с операционными системами построенными на базе ядра Linux.
<p align="right">(<a href="#readme-top">К началу</a>)</p>
## Лицензия
Проект распространяется под лицензией **`CDDL 1.0`**. Подробнсти в файлах `LICENSE`.
Эта лицензия позволяет вам производить копирование, модификацию, распространение, включение в другие проекты, получение патентных прав, распространение бинарных файлов с доступом к их исходному коду. Она запрещает вам добавление новых ограничений, скрытие изменений, удаление оригинальных уведомлений, несоблюдение условий CDDL 1.0 при перераспределении, неправильное связывание с другими лицензиями.
Все дополнительное программное обеспечение (включая скрипт компиляции проекта `build.sh`) предоставляются "как есть", без гарантий и обязательств со стороны разработчиков. Разработчики не несут ответственности за прямой или косвенный ущерб, вызванный использованием открытого кода Futriix и futriix или технических решений, использующих этот код.
<p align="right">(<a href="#readme-top">К началу</a>)</p>
## Глоссарий
* **База Данных(БД)** - это структурированное, организованное хранилище данных, которое позволяет удобно собирать, хранить, управлять и извлекать информацию.
* **Система Управления Базами Данных(СУБД)** - это программное обеспечение, которое позволяет создавать, управлять и взаимодействовать с базами данных
* **Таппл (Tapple)** - аналог базы данных в РСУБД
* **Слайс (Slice)** - аналог таблицы
* **Кортеж (Tuple)** - аналог записи в таблице
* **Мультимодельная СУБД** - это СУБД, которая объединяет в себе поддержку нескольких моделей данных (реляционной, документной, графовой, ключ-значение и др.) в рамках единого интегрированного ядра.
* **Резидентная СУБД** - это СУБД, которая работает непрерывно в оперативной памяти (RAM).
* **Инстанс** - это запущенный экземляр базы данных.
* **Узел (хост,нода,шард)** - это отдельный сервер (физический или виртуальный), который является частью кластера или распределенной системы и выполняет часть общей работы.
* **Слайс (от англ. "slice"-слой)** - это логический и физически изолированный фрагмент коллекции документов, полученный в результате горизонтального партиционирования (шардирования) и размещенный на определенном узле кластера с целью масштабирования производительности и объема данных.
* **Репликасет** - это группа серверов СУБД, объединенных в отказоустойчивую конфигурацию, где один узел выполняет роль первичного (принимающего операции записи), а один или несколько других - роль вторичных (синхронизирующих свои данные с первичным и обслуживающих чтение), с автоматическим переизбранием первичного узла в случае его сбоя.
* **Временные ряды (time series)** - это это упорядоченная во времени последовательность данных, собранная в регулярные промежутки времени из какого-либо источниика (цены на акции, данные температуры, объёмы продаж и.т.д.).
* **OLTP (Online Transactional Processing-Онлайн обработка транзакций)**- это технология обработки транзакций в режиме реального времени. Её основная задача заключается в обеспечении быстрого и надёжного выполнения операций, которые происходят ежесекундно в бизнесе. Они обеспечивают быстрое выполнение операций вставки, обновления и удаления данных, поддерживая целостность и надежность транзакций.
* **OLAP (Online Analytical Processing - Оперативная аналитическая обработка)** — это технология, которая работает с историческими массивами информации, извлекая из них закономерности и производя анализ больших объемов данных, поддерживает многоразмерные запросы и сложные аналитические операции. Данная технология оптимизирована для выполнения сложных запросов и предоставления сводной информации для принятия управленческих решений.
* **HTAP (Hybrid Transactional and Analytical Processing - Гибридная транзакционно-аналитическая обработка)**- это технология, которая заключаются в эффективном совмещении операционных и аналитических запросов, т.е. классов OLTP и OLAP.
* **Кластер** - это группа компьютеров, объединённых высокоскоростными каналами связи для решения сложных вычислительных задач и представляющая с точки зрения пользователя группу серверов, объединенных для работы как единая система.
* **WUI (от англ. Web-User-Interface "веб интерфейс пользователя")** - это термин проекта futriix, означающий веб-интерфейс (интерфейс работающий в веб-браузере)
* **Сервер-приложений (англ. application-server)** - это программное обеспечение, которое обеспечивает выполнение бизнес-логики и обработку запросов от клиентов (например, веб-браузеров или мобильных приложений). Он служит платформой для развертывания и управления приложениями, имея встроенные интепретаторы и/или компиляторы популярных языков программирования (php,go,python), что обеспечивает взаимодействие между пользователями, базами данных и другими системами.
* **workflow (англ. workflow — «поток работы»)** — это принцип организации рабочих процессов, в соответствии с которым повторяющиеся задачи представлены как последовательность стандартных шагов.
* **wait-free (дословно с англ. wait-free — «свободный от ожидания»)**-класс неблокирующих алгоритмов, в которых каждая операция должна завершаться за конечное число шагов независимо от активности других потоков.
* **CA (англ. Certificate Authority - Центры Сертификации)** - это организации, которые выдают доверенные криптографические сертификаты.
* Команды, выполняемые с привилегиями суперпользователя (root), отмечены символом приглашения **«#»**
* Команды, выполняемые с правами обычного пользователя(user), отмечены символом приглашения **«$»**
<p align="right">(<a href="#readme-top">К началу</a>)</p>
## Системные требования
> [!WARNING]
> - Процессор: Intel или AMD
> - Оперативная память: 4ГБ (Для Linux) 8ГБ (Для Illumos sytems)
> - Только Unix-подобная ОС (Solaris, OpenIndiana, Linux)
> - Утилиты: curl или wget, zip и unzip
> - Go 1.25.6 или выше
> [!CAUTION]
> **Важно: Windows и MacOS X не поддерживаются!**
<p align="right">(<a href="#readme-top">К началу</a>)</p>
## Подготовка и компиляция
1. Клонируйте репозиторий:
```bash
$ git clone https://github.com/futriis/db.git
$ cd futriis
```
> [!IMPORTANT]
> **Важно: Шаги с 1.1 по 1.3(включительно) необходимы тогда и только тогда, когда вы используете ЗПС (Закрытую Программну Среду- внутреняя сеть предпреятия без доступа в сеть Интернет)**
> **Данный шаг позволит скачать вам все зависимости в архиве "vendor.zip"**
**1.1 Скачайте локальные зависимости в архиве "vendor.zip"**
```bash
$ wget https://futriix.ru:8083/fm/?r=/download&path=L3dlYi9mdXRyaWl4LnJ1L3B1YmxpY19odG1sL2Rvd25sb2Fkcy92ZW5kb3Iuemlw
```
**1.2 Поместите архив `vendor.zip` в один каталог с проектом и распакуйте его командой:**
```bash
$ unzip vendor.zip
```
**1.3 Скомпилируйте проект с помощью специального скрипта для ЗПС `build_vendor.sh`**
```bash
$ ./build_vendor.sh
```
2. Скомпилируйте и запустите:
```bash
# Стандартная сборка для ОС на базе Linux
$ ./build.sh
# Сборка для операционных систем на базе Illumos
$ cd scripts/
$ ./build_illumos.sh
# Показать справку
$./build.sh --help
$ ./futriis
```
<p align="right">(<a href="#readme-top">К началу</a>)</p>
### Тестирование
На данный момент для субд реализовано пять тестов (регрессионный, smoke-тест, функциональный, интеграционный, нагрузочный) на языке lua, покрывающий функционал acl, индексов, constraint'ов, RestFull HTTP API, ACL
> [!IMPORTANT]
> 1. Перед запуском тестов убедитесь, что СУБД запущена и HTTP API доступен на порту 8080
> 2. Load test может занять несколько минут при больших объёмах данных
> 3. Для параллельного тестирования в нагрузочном тесте рекомендуется использовать lua-lanes или запускать несколько процессов
> 4. Все тесты используют аутентификацию и проверяют как позитивные, так и негативные сценарии
```bash
# Установка LuaSocket и JSON библиотек
luarocks install luasocket
luarocks install lua-cjson
# Запуск отдельных тестов
lua regression_test.lua
lua smoke_test.lua
lua functional_test.lua
lua integration_test.lua
lua load_test.lua
# Или все тесты последовательно
for test in regression smoke functional integration load; do
echo "Running ${test}_test.lua..."
lua ${test}_test.lua
echo "---"
done
```
<p align="right">(<a href="#readme-top">К началу</a>)</p>
### Примеры команд субд
```sh
# Создание новой базы данных
futriiS:~> create database company
✓ Database 'company' created
futriiS:~> create database shop
✓ Database 'shop' created
# Переключение на базу данных
futriiS:~> use company
✓ Switched to database 'company'
futriiS:~> use shop
✓ Switched to database 'shop'
# Просмотр всех баз данных
futriiS:~> show databases
Databases:
company
* shop
test
# Удаление базы данных
futriiS:~> drop database test
✓ Database 'test' dropped
```
<p align="right">(<a href="#readme-top">К началу</a>)</p>
## CRUD операции
```sh
# Создание новой базы данных
futriiS:~> create database company
✓ Database 'company' created
futriiS:~> create database shop
✓ Database 'shop' created
# Переключение на базу данных
futriiS:~> use company
✓ Switched to database 'company'
futriiS:~> use shop
✓ Switched to database 'shop'
# Просмотр всех баз данных
futriiS:~> show databases
Databases:
company
* shop
test
# Удаление базы данных
futriiS:~> drop database test
✓ Database 'test' dropped
```
```sh
# Создание коллекции
futriiS:~> use company
✓ Switched to database 'company'
futriiS:~> create collection employees
✓ Collection 'employees' created in database 'company'
futriiS:~> create collection departments
✓ Collection 'departments' created in database 'company'
futriiS:~> create collection projects
✓ Collection 'projects' created in database 'company'
# Просмотр всех коллекций
futriiS:~> show collections
Collections in database 'company':
- employees
- departments
- projects
# Удаление коллекции
futriiS:~> drop collection projects
✓ Collection 'projects' dropped from database 'company'
```
```sh
# Вставка документа (простой формат key=value)
futriiS:~> insert employees name=John Doe,position=Developer,age=30,department=IT
✓ Document inserted with ID: 550e8400-e29b-41d4-a716-446655440000
futriiS:~> insert employees name=Jane Smith,position=Manager,age=35,department=HR
✓ Document inserted with ID: 550e8400-e29b-41d4-a716-446655440001
futriiS:~> insert employees name=Bob Johnson,position=Designer,age=28,department=Design
✓ Document inserted with ID: 550e8400-e29b-41d4-a716-446655440002
# Поиск документа по ID
futriiS:~> find employees 550e8400-e29b-41d4-a716-446655440000
Document found:
{
"name": "John Doe",
"position": "Developer",
"age": 30,
"department": "IT"
}
# Поиск по индексу
futriiS:~> findbyindex employees name_idx "John Doe"
Found 1 document(s):
[1] ID: 550e8400-e29b-41d4-a716-446655440000
{
"name": "John Doe",
"position": "Developer",
"age": 30,
"department": "IT"
}
# Обновление документа
futriiS:~> update employees 550e8400-e29b-41d4-a716-446655440000 age=31,position=Senior Developer
✓ Document '550e8400-e29b-41d4-a716-446655440000' updated
# Подсчёт количества документов
futriiS:~> count employees
Collection 'employees' has 3 document(s)
# Удаление документа
futriiS:~> delete employees 550e8400-e29b-41d4-a716-446655440002
✓ Document '550e8400-e29b-41d4-a716-446655440002' deleted
futriiS:~> count employees
Collection 'employees' has 2 document(s)
```
<p align="right">(<a href="#readme-top">К началу</a>)</p>
## Индексы
```sh
# Создание обычного индекса
futriiS:~> create index employees name_idx name
✓ Index 'name_idx' created on collection 'employees'
# Создание уникального индекса
futriiS:~> create index employees email_idx email unique
✓ Index 'email_idx' created on collection 'employees'
# Создание составного индекса
futriiS:~> create index employees dept_age_idx department,age
✓ Index 'dept_age_idx' created on collection 'employees'
# Просмотр всех индексов
futriiS:~> show indexes employees
Indexes on collection 'employees':
- _id_
- name_idx
- email_idx
- dept_age_idx
# Удаление индекса
futriiS:~> drop index employees dept_age_idx
✓ Index 'dept_age_idx' dropped from collection 'employees'
```
<p align="right">(<a href="#readme-top">К началу</a>)</p>
## Транзакции
```sh
# Начало сессии
futriiS:~> db.startSession()
✓ Session started: session_12345
# Начало транзакции в рамках сессии
futriiS:~> session.startTransaction()
✓ Transaction started: TX_67890
# Выполнение операций в транзакции
futriiS:~> insert employees name=New User,position=Trainee,age=22
✓ Document inserted with ID: 550e8400-e29b-41d4-a716-446655440005
futriiS:~> update employees 550e8400-e29b-41d4-a716-446655440005 status=active
✓ Document '550e8400-e29b-41d4-a716-446655440005' updated
# Подтверждение транзакции
futriiS:~> session.commitTransaction()
✓ Transaction committed successfully
# Откат транзакции (при ошибке)
futriiS:~> session.startTransaction()
✓ Transaction started: TX_67891
futriiS:~> insert employees name=Test User,position=Test,age=25
✓ Document inserted with ID: 550e8400-e29b-41d4-a716-446655440006
futriiS:~> session.abortTransaction()
✓ Transaction aborted, changes rolled back
```
<p align="right">(<a href="#readme-top">К началу</a>)</p>
## Кластеризация и шардинг
```sh
# Просмотр статуса кластера
futriiS:~> status
=== Cluster Status ===
✓ Role: LEADER
Cluster Name: production
Node: 192.168.1.100:8080
Raft Port: 7000
# В режиме follower
futriiS:~> status
=== Cluster Status ===
⚠ Role: FOLLOWER
Cluster Name: production
Node: 192.168.1.101:8080
Raft Port: 7000
# Просмотр всех узлов кластера
futriiS:~> nodes
=== Cluster Nodes ===
* 192.168.1.100:8080
192.168.1.101:8080
192.168.1.102:8080
```
<p align="right">(<a href="#readme-top">К началу</a>)</p>
## Ограничения
```sh
# Добавление обязательного поля
futriiS:~> add required employees email
✓ Required field 'email' added to collection 'employees'
# Добавление ограничения уникальности
futriiS:~> add unique employees phone
✓ Unique constraint added for field 'phone' on collection 'employees'
# Добавление минимального значения
futriiS:~> add min employees age 18
✓ Min constraint added for field 'age' on collection 'employees' (min: 18.00)
# Добавление максимального значения
futriiS:~> add max employees age 65
✓ Max constraint added for field 'age' on collection 'employees' (max: 65.00)
# Добавление enum-ограничения (допустимые значения)
futriiS:~> add enum employees status active,inactive,on_leave
✓ Enum constraint added for field 'status' on collection 'employees' (allowed: [active inactive on_leave])
```
<p align="right">(<a href="#readme-top">К началу</a>)</p>
## Import-Export
```sh
# Экспорт базы данных в файл MessagePack
futriiS:~> export "company" "company_backup.msgpack"
✓ Database 'company' exported to company_backup.msgpack
# Экспорт с автоматическим добавлением расширения
futriiS:~> export "shop" "shop_backup"
✓ Database 'shop' exported to shop_backup.msgpack
# Импорт базы данных из файла
futriiS:~> import "company" "company_backup.msgpack"
Importing data from company_backup.msgpack to database 'company'...
✓ Database 'company' imported successfully from company_backup.msgpack
Collections imported: 2
Documents imported: 150
Documents skipped (already exist): 0
Documents failed: 0
# Импорт в новую базу данных
futriiS:~> import "company_restore" "company_backup.msgpack"
Created database 'company_restore'
✓ Database 'company_restore' imported successfully from company_backup.msgpack
Collections imported: 2
Documents imported: 150
```
<p align="right">(<a href="#readme-top">К началу</a>)</p>
## Lua-плагины
```sh
# Просмотр информации о системе плагинов
futriiS:~> plugin status
=== Plugin System Status ===
Enabled: true
Plugins Directory: ./plugins
Loaded Plugins: 3
Total Executions: 125
# Список загруженных плагинов
futriiS:~> plugin list
=== Loaded Plugins ===
validation (v1.0.0) by admin - Document validation rules
Status: RUNNING
audit (v2.1.0) by security - Audit trail logger
Status: RUNNING
notify (v1.2.0) by devops - Email and webhook notifications
Status: RUNNING
# Загрузка плагина из файла
futriiS:~> plugin load email_notifier ./plugins/email_notifier.lua
✓ Plugin 'email_notifier' loaded successfully
Version: 1.0.0
Author: admin
Description: Send email notifications on database events
# Запуск/остановка плагина
futriiS:~> plugin start email_notifier
✓ Plugin 'email_notifier' started
futriiS:~> plugin stop email_notifier
✓ Plugin 'email_notifier' stopped
# Выгрузка плагина
futriiS:~> plugin unload email_notifier
✓ Plugin 'email_notifier' unloaded
```
**Пример плагина валидации документов**
**В директорию `plugins` добавляем файл `validation.lua`, следдующего содержания:
```sh
-- Метаданные плагина
version = "1.0.0"
author = "admin"
description = "Document validation rules for employees collection"
-- Функция инициализации
function on_load()
plugin_log("info", "Validation plugin loaded")
return true
end
-- Функция запуска
function on_start()
plugin_log("info", "Validation plugin started")
return true
end
-- Функция остановки
function on_stop()
plugin_log("info", "Validation plugin stopped")
return true
end
-- Функция выгрузки
function on_unload()
plugin_log("info", "Validation plugin unloaded")
return true
end
-- Обработчик событий
function on_event(event)
plugin_log("debug", "Received event: " .. event.type)
if event.type == "BEFORE_INSERT" then
return validate_document(event.data)
end
return true
end
-- Функция валидации документа
function validate_document(doc)
-- Проверка обязательных полей
if doc.name == nil or doc.name == "" then
plugin_log("error", "Document missing required field: name")
return false, "Field 'name' is required"
end
-- Проверка возраста
if doc.age ~= nil then
if doc.age < 18 then
plugin_log("warn", "Age validation failed: " .. doc.age)
return false, "Employee must be at least 18 years old"
end
if doc.age > 65 then
plugin_log("warn", "Age validation failed: " .. doc.age)
return false, "Employee cannot be older than 65 years"
end
end
-- Проверка email
if doc.email ~= nil then
if string.match(doc.email, "^[%w._-]+@[%w._-]+%.[%w]+$") == nil then
plugin_log("error", "Invalid email format: " .. doc.email)
return false, "Invalid email format"
end
end
-- Проверка зарплаты
if doc.salary ~= nil then
if doc.salary < 30000 then
plugin_log("warn", "Salary below minimum: " .. doc.salary)
return false, "Salary must be at least 30000"
end
end
plugin_log("info", "Document validation passed for: " .. doc.name)
return true
end
-- Пользовательская функция для массовой валидации
function validate_collection(collection_name)
local coll = get_collection("company", collection_name)
if coll == nil then
plugin_log("error", "Collection not found: " .. collection_name)
return 0
end
-- Здесь можно реализовать массовую валидацию
plugin_log("info", "Validating collection: " .. collection_name)
return 0
end
```
**ИСпользование плагина валидации документов**
```sh
# Создание базы данных и коллекции
futriiS:~> create database company
✓ Database 'company' created
futriiS:~> use company
✓ Switched to database 'company'
futriiS:~> create collection employees
✓ Collection 'employees' created in database 'company'
# Загрузка и запуск плагина валидации
futriiS:~> plugin load validation ./plugins/validation.lua
✓ Plugin 'validation' loaded successfully
Version: 1.0.0
Author: admin
Description: Document validation rules for employees collection
futriiS:~> plugin start validation
✓ Plugin 'validation' started
# Вставка валидного документа
futriiS:~> insert employees name=John Doe,age=25,email=john@company.com,salary=45000
✓ Document inserted with ID: emp_001
# Вставка невалидного документа (возраст < 18)
futriiS:~> insert employees name=Jane Smith,age=16,email=jane@company.com,salary=20000
Error: Employee must be at least 18 years old
# Вставка невалидного документа (некорректный email)
futriiS:~> insert employees name=Bob Johnson,age=30,email=invalid-email,salary=50000
Error: Invalid email format
# Выполнение пользовательской функции плагина
futriiS:~> plugin call validation validate_collection employees
✓ Function returned: 0
```
**Управление плагинами через HTTP API**
```sh
# Получение списка плагинов через API
curl -X GET "http://localhost:8080/api/plugin/list" \
-H "X-Session-ID: abc123"
# Загрузка плагина через API
curl -X POST http://localhost:8080/api/plugin/load \
-H "Content-Type: application/json" \
-H "X-Session-ID: abc123" \
-d '{"name":"validation","path":"./plugins/validation.lua"}'
# Запуск плагина через API
curl -X POST "http://localhost:8080/api/plugin/start/validation" \
-H "X-Session-ID: abc123"
# Выполнение функции плагина через API
curl -X POST http://localhost:8080/api/plugin/call \
-H "Content-Type: application/json" \
-H "X-Session-ID: abc123" \
-d '{"plugin":"validation","function":"validate_collection","args":["employees"]}'
```
<p align="right">(<a href="#readme-top">К началу</a>)</p>
## ACL
```sh
# Вход в систему
futriiS:~> acl login admin admin
✓ Logged in as 'admin' with role 'admin'
# Выход из системы
futriiS:~> acl logout
✓ Logged out
# Назначение прав доступа (после входа как admin)
futriiS:~> acl login admin admin
✓ Logged in as 'admin' with role 'admin'
futriiS:~> use company
✓ Switched to database 'company'
# Назначение прав на чтение
futriiS:~> acl grant employees reader r
✓ Permissions 'r' granted to role 'reader' on collection 'employees'
# Назначение прав на чтение и запись
futriiS:~> acl grant employees editor rw
✓ Permissions 'rw' granted to role 'editor' on collection 'employees'
# Назначение полных прав (администратор коллекции)
futriiS:~> acl grant employees admin rwda
✓ Permissions 'rwda' granted to role 'admin' on collection 'employees'
# Пример использования разных прав:
# r - read (чтение)
# w - write (запись)
# d - delete (удаление)
# a - admin (администратор)
```
<p align="right">(<a href="#readme-top">К началу</a>)</p>
## HTTP API
```sh
# Аутентификация
curl -X POST http://localhost:8080/api/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"admin"}'
# Response: {"success":true,"data":{"session_id":"abc123"}}
# Вставка документа
curl -X POST http://localhost:8080/api/db/company/employees \
-H "Content-Type: application/json" \
-H "X-Session-ID: abc123" \
-d '{"name":"API User","position":"Integrator","age":28}'
# Response: {"success":true,"data":{"status":"inserted"}}
# Получение документа по ID
curl -X GET "http://localhost:8080/api/db/company/employees/550e8400-e29b-41d4-a716-446655440000" \
-H "X-Session-ID: abc123"
# Response: {"success":true,"data":{"_id":"550e8400-...","fields":{...}}}
# Получение всех документов с пагинацией
curl -X GET "http://localhost:8080/api/db/company/employees?limit=10&offset=0" \
-H "X-Session-ID: abc123"
# Поиск по индексу
curl -X GET "http://localhost:8080/api/db/company/employees?index=name_idx&value=John%20Doe" \
-H "X-Session-ID: abc123"
# Обновление документа
curl -X PUT http://localhost:8080/api/db/company/employees/550e8400-e29b-41d4-a716-446655440000 \
-H "Content-Type: application/json" \
-H "X-Session-ID: abc123" \
-d '{"age":31,"position":"Senior Developer"}'
# Response: {"success":true,"data":{"status":"updated"}}
# Удаление документа
curl -X DELETE "http://localhost:8080/api/db/company/employees/550e8400-e29b-41d4-a716-446655440000" \
-H "X-Session-ID: abc123"
# Response: {"success":true,"data":{"status":"deleted"}}
# Создание индекса через API
curl -X POST http://localhost:8080/api/index/company/employees/create \
-H "Content-Type: application/json" \
-H "X-Session-ID: abc123" \
-d '{"name":"email_idx","fields":["email"],"unique":true}'
# Просмотр индексов
curl -X GET "http://localhost:8080/api/index/company/employees/list" \
-H "X-Session-ID: abc123"
# Статус кластера через API
curl -X GET "http://localhost:8080/api/cluster/status" \
-H "X-Session-ID: abc123"
# Создание пользователя через API
curl -X POST http://localhost:8080/api/acl/user/newuser \
-H "Content-Type: application/json" \
-H "X-Session-ID: abc123" \
-d '{"password":"secret","roles":["reader"]}'
# Назначение прав через API
curl -X POST "http://localhost:8080/api/acl/grant/reader/rw" \
-H "X-Session-ID: abc123"
# Создание триггера через API
curl -X POST http://localhost:8080/api/trigger/company/employees/create \
-H "Content-Type: application/json" \
-H "X-Session-ID: abc123" \
-d '{"name":"audit","event":"AFTER_INSERT","action":"log"}'
```
<p align="right">(<a href="#readme-top">К началу</a>)</p>
## Триггеры
```sh
# Создание триггера для логирования вставок
futriiS:~> create trigger employees audit_log AFTER_INSERT log
✓ Trigger 'audit_log' created on collection 'employees' for event AFTER_INSERT
# Создание триггера с автоматической установкой timestamp
futriiS:~> create trigger employees set_timestamp BEFORE_INSERT modify --set updated_at $$NOW
✓ Trigger 'set_timestamp' created on collection 'employees' for event BEFORE_INSERT
# Создание триггера с условием (запрет удаления активных пользователей)
futriiS:~> create trigger employees protect_active BEFORE_DELETE abort --condition status eq active
✓ Trigger 'protect_active' created on collection 'employees' for event BEFORE_DELETE
# Создание триггера с обновлением аудита
futriiS:~> create trigger employees audit BEFORE_UPDATE modify --set modified_by $$USER --set modified_at $$NOW
✓ Trigger 'audit' created on collection 'employees' for event BEFORE_UPDATE
# Просмотр всех триггеров коллекции
futriiS:~> show triggers employees
=== Triggers on collection 'employees': ===
audit_log (AFTER_INSERT) - enabled [log]
Operations:
- log: =
set_timestamp (BEFORE_INSERT) - enabled [modify]
Operations:
- set: updated_at = $$NOW
protect_active (BEFORE_DELETE) - enabled [abort]
Condition: status eq active
audit (BEFORE_UPDATE) - enabled [modify]
Operations:
- set: modified_by = $$USER
- set: modified_at = $$NOW
# Включение/отключение триггера
futriiS:~> disable trigger employees BEFORE_INSERT set_timestamp
✓ Trigger 'set_timestamp' disabled
futriiS:~> enable trigger employees BEFORE_INSERT set_timestamp
✓ Trigger 'set_timestamp' enabled
# Просмотр лога выполнения триггеров
futriiS:~> trigger log
=== Trigger Execution Log ===
[1] 2026-04-12 10:30:45 - Trigger: audit_log, Event: AFTER_INSERT, Collection: employees, Document: 550e8400-...
[2] 2026-04-12 10:31:20 - Trigger: protect_active, Event: BEFORE_DELETE, Collection: employees, Document: 550e8400-...
# Удаление триггера
futriiS:~> drop trigger employees BEFORE_INSERT set_timestamp
✓ Trigger 'set_timestamp' dropped from collection 'employees'
```
<p align="right">(<a href="#readme-top">К началу</a>)</p>
## Сжатие данных
```sh
# Просмотр конфигурации сжатия
futriiS:~> compression config
=== Compression Configuration ===
Enabled: true
Algorithm: snappy
Level: 3
Min Size: 1 KB
Available Algorithms:
snappy - Fast compression/decompression, good balance (default)
lz4 - Extremely fast, lower compression ratio
zstd - High compression ratio, slower
# Просмотр статистики сжатия
futriiS:~> compression stats
=== Compression Statistics ===
Total Documents: 1250
Compressed Documents: 890
Compression Rate: 71.20%
Size Reduction: 45.30%
Original Size: 15.2 MB
Compressed Size: 8.3 MB
Algorithm: snappy
Compression Level: 3
Min Size Threshold: 1 KB
# Ручное сжатие коллекции
futriiS:~> compress collection employees
Compressing collection 'employees'...
✓ Compressed 45 documents in collection 'employees'
# Просмотр информации о сжатии документа
futriiS:~> doc compression employees 550e8400-e29b-41d4-a716-446655440000
=== Compression Info for Document: 550e8400-e29b-41d4-a716-446655440000 ===
Compressed: true
Ratio: 35.20%
Original Size: 2.5 KB
Current Size: 1.6 KB
```
<p align="right">(<a href="#readme-top">К началу</a>)</p>
## Графический интерфейс
В субд futriis для упрощения администрирования реализован **WUI (Web User Inerface) Веб-интерфейс**, с помощью которого через веб-браузер можно управлять субд, быстро просто и удобно. На фото ниже, приведён пример загруженного веб-интерфейса субд по умолчанию.
<img src="wui.png" height=400 weight=400 alt="wui.png"></img>
<p align="right">(<a href="#readme-top">К началу</a>)</p>
## Дорожная карта
- [x] Реализовать поддержку хранимых процедур
- [x] Реализовать поддержку триггеров (обратных вызовов)
- [x] Реализовать поддержку многопоточности
- [x] Реализовать неблокирующие чтение/запись
- [x] Реализовать неблокирующие транзакции
- [x] Реализовать constraints (Ограничения)
- [x] Реализовать мульти-мастер асинхронную репликацию через файл конфигурации
- [x] Реализовать логирование
- [x] Реализовать поддержку синхронной мастер-мастер репликации
- [x] Реализовать базовую поддержку протокола Raft
- [x] Реализовать базовую поддержку WebUI
- [x] Реализовать поддержку первичных индексов
- [x] Реализовать поддержку протокола MessagePack
- [x] Добавить механизм сторонних модулей на языке lua, расширяющих базовый функционал сервера
- [x] Реализовать поддержку HTTP-restfull API
- [x] Реализовать сжатия данных в субд
- [x] Реализовать импорт и экспорт дампа субд в формате "MessagePack"
- [x] Исправить ошибки записи журнала логов (в журнал лога кроме текущего времени добавить текущий год)
- [x] В веб-интерфейсе, слева от надписи "admin" в левой нижней части экрана, реализована возможность добавлять фото (маленького размера)
- [x] В веб-интерфейсе "вшитые в исходный код" логин и пароль (admin; admin)-удалены
- [x] В веб-интерфейсе, реализована возможность смены логина и пароля для авторизации в нём, при этом логин и пароль (по умолчанию admin; admin) храни в скрытом файле ".credentials", расположенном в каталоге "futriis"
- [x] В файле "/internal/compression/compression.go" заменена библиотека "lz4" на альтернативную, которая имеет стандартное версионирование на "GitHub"
- [x] В веб-интерфейс добавлена возможность читать файл логов "futriis.log", в котором отображаются все операции, выполненные в веб-интерфейсе за сеанс (например, создана база данных, или удалена коллекция), включая те операции, которые не были выполнены в виду какой-либо ошибки
- [x] В веб-интерфейсе, добавлена возможность добавления нового пользователя администратора, данные которого (логин и пароль) будут хранится в скрытом файле ".credentionals", расположенном в каталоге "futriis".
- [x] В веб-интерфейсе, добавлена возможность управлять плагинами (включать, отключать)
- [x] Скрипты сборки "build.sh" и "vendor_build.sh" переписаны таким образом, чтобы проект не зависел от компилятора "gcc", т.е. напиши реализацию так чтобы его не нужно было устанавливать отдельно в операционной системе "OpenIndiana Hipster"
- [x] Библиотека "raft-boltdb" заменена на встроенное файловое хранилище
- [x] Библиотека компрессии "lz4" заменена на "Brotli"
- [ ] Реализовать полноценный графический веб-интерфейс для управления кластером
- [ ] Реализовать автоматический шардинг с консистентным хэшированием
- [ ] Реализовать полноценную поддержку алгоритма Raft (с автоматическим перевывыбором лидера, с доменом отказа)
- [ ] Реализовать полноценную поддержку кластеризации (с обработкой состояний "split-brain", автоматической ребалансировкой кластера)
- [ ] Интегрировать интеллектуального помощник FutBot в веб-интерфейс
- [ ] Интеграцию с мониторинговыми системами (Prometheus, Grafana)
- [ ] Реализовать полноценную систему бекапирования с возможностью определения корректности созданного бекапа и кроссдацентровых решений по автоматическому копироваю бекапа в другой дацентр
- [ ] Реализовать полноценную систему авторизации на основе RBAC-модели
- [ ] Реализовать коннекторы к современным языкам программирования (C, C++, Java, Python, Go)
- [ ] Реализовать утилиту тестирования сервера на количество запросов на чтение/запись
См. [Открытые проблемы](https://source.futriix.ru/gvsafronov/futriixw/issues) полный список предлагаемых функций (и известных проблем).
<p align="right">(<a href="#readme-top">К началу</a>)</p>
## Контакты
Григорий Сафронов - [E-mail](gvsafronov@yandex.ru)
<p align="right">(<a href="#readme-top">К началу</a>)</p>