490 lines
18 KiB
Markdown
490 lines
18 KiB
Markdown
#############################################################
|
||
# Полный список команд во встроенной СУБД futriix #
|
||
#############################################################
|
||
|
||
#### Функции файлов
|
||
|
||
```sh
|
||
futriix.wal - Write-Ahead Log файл СУБД:
|
||
```
|
||
* Функция: Обеспечивает durability данных
|
||
* Содержит: Все операции записи перед их применением к основному хранилищу
|
||
* Назначение: Восстановление данных после сбоев
|
||
|
||
```sh
|
||
wal.log - Лог операций Write-Ahead Log:
|
||
```
|
||
* Функция: Дублирующий лог для отладки и мониторинга
|
||
* Содержит: Те же операции что и futriix.wal, но в читаемом формате
|
||
* Назначение: Анализ операций записи
|
||
|
||
```sh
|
||
futriix.log - Основной лог субд:
|
||
```
|
||
* Функция: Логирование работы всей СУБД
|
||
* Содержит: Информационные сообщения, ошибки, предупреждения
|
||
* Назначение: Мониторинг и отладка работы системы
|
||
|
||
```sh
|
||
history_with_timestamps - Файл лог сервера-приложений falcot
|
||
```
|
||
|
||
* Функция: Логирование работы всего сервера приложений
|
||
* Содержит: Введённые команды в сервере приложения, текущие дату и время (временную метку)
|
||
* Назначение: Мониторинг и отладка работы системы
|
||
|
||
** Эти файлы создаются автоматически при выполнении операций записи в базу данных через Lua интерпретатор или HTTP API.
|
||
|
||
|
||
## Тестирование
|
||
|
||
```sh
|
||
cargo test
|
||
```
|
||
### Запуск только unit-тестов
|
||
```sh
|
||
cargo test unit_test
|
||
```
|
||
### Запуск конкретного unit-теста
|
||
```sh
|
||
cargo test test_storage_engine_unit
|
||
```
|
||
### Запуск тестов с выводом
|
||
```sh
|
||
cargo test -- --nocapture
|
||
```
|
||
|
||
### Переход в режим базы данных
|
||
```sh
|
||
inbox.start
|
||
```
|
||
|
||
### Команды для заполнения WAL файла
|
||
|
||
####Все команды CRUD должны логирироваться в WAL файл, который называется "futriix.wal", что обеспечивает durability данных.
|
||
#### Замечание: После выполнения любых команд CRUD - файл "futriix.wal" должен будет содержать записи всех выполненных операций, а именно: создания, изменения и удаления документа.
|
||
Создания, изменения и удаления пространства.
|
||
|
||
|
||
### Выход из режима базы данных
|
||
```sh
|
||
exit
|
||
```
|
||
|
||
|
||
##Базовые команды
|
||
|
||
### Выход из приложения
|
||
```sh
|
||
exit
|
||
```
|
||
|
||
### Переключение между режимами
|
||
```sh
|
||
inbox.start # Переход в режим базы данных
|
||
exit # Возврат в режим Lua из режима базы данных а также выход из режима Lua и возврат в терминал операционной системы
|
||
```
|
||
|
||
### Команды CRUD операций
|
||
|
||
### Создание пространства (синоним термина "база данных")
|
||
```sh
|
||
create.space users
|
||
```
|
||
|
||
|
||
### Удаление простраства (синоним термина "база данных")
|
||
```sh
|
||
delete.space <space_name>
|
||
```
|
||
|
||
### Создание документа (синоним термина "коллекция")
|
||
```sh
|
||
create <collection> <key> <json_value>
|
||
create users user1 '{"name": "John", "age": 30}'
|
||
create products prod1 '{"title": "Laptop", "price": 999.99}'
|
||
```
|
||
|
||
### Чтение документа
|
||
```sh
|
||
read <collection> <key>
|
||
read users user1
|
||
read products prod1
|
||
```
|
||
|
||
### Изменение (синоним термина "обновление") документа
|
||
```sh
|
||
update <collection> <key> <json_value>
|
||
update users user1 '{"name": "John Doe", "age": 31}'
|
||
```
|
||
|
||
### Удаление документа
|
||
```sh
|
||
delete <collection> <key>
|
||
delete users user1
|
||
```
|
||
|
||
### Создание кортежа (синоним термина "вложенного документа в документ")
|
||
```sh
|
||
create.tuple <space> <tuple_id> <json_value>
|
||
create.tuple users profile1 '{"type": "user_profile", "premium": true}'
|
||
```
|
||
|
||
### Чтение кортежа (синоним термина "вложенного документа в документ")
|
||
```sh
|
||
read.tuple <space> <tuple_id>
|
||
read.tuple users profile1 '{"type": "user_profile", "premium": true}'
|
||
```
|
||
|
||
### Удаление кортежа (синоним термина "вложенного документа в документ")
|
||
```sh
|
||
delete.tuple <space> <tuple_id> <json_value>
|
||
delete.tuple users profile1 '{"type": "user_profile", "premium": true}'
|
||
```
|
||
|
||
### Создание кортежей в пространстве
|
||
```sh
|
||
create.tuple users tuple1 '{"type": "profile", "data": {"premium": true, "settings": {"theme": "dark"}}}'
|
||
```
|
||
|
||
### Удаление кортежей в пространстве
|
||
```sh
|
||
delete.tuple users tuple1
|
||
```
|
||
|
||
##Команды для работы с индексами
|
||
|
||
|
||
### Типы индексов:
|
||
* hash : для точных поисков
|
||
* timeindex : для диапазонных запросов
|
||
* fulltext: для полнотекстового поиска
|
||
* spatial : для пространственных данных
|
||
|
||
### Создание первичного индекса
|
||
```sh
|
||
create.primary.index <collection>
|
||
create.primary.index users
|
||
create.primary.index products
|
||
```
|
||
|
||
### Поиск по всем индексам или по конкретному индексу
|
||
```sh
|
||
search.all.index <collection>
|
||
search.secondary.index <collection>
|
||
```
|
||
|
||
### Удаление первичного индекса
|
||
```sh
|
||
create.primary.index <collection>
|
||
create.primary.index users
|
||
create.primary.index products
|
||
```
|
||
|
||
### Создание вторичного индекса
|
||
```sh
|
||
create.secondary.index <collection> <field_name> <index_type>
|
||
create.secondary.index users email hash
|
||
create.secondary.index users age btree
|
||
create.secondary.index users name fulltext
|
||
create.secondary.index locations coordinates spatial
|
||
```
|
||
|
||
### Удаление вторичного индекса
|
||
```sh
|
||
drop.primary.index <collection>
|
||
drop.primary.index users
|
||
create.primary.index products
|
||
```
|
||
|
||
### Удаление всех индексов, которые созданы на данный момент в субд
|
||
```sh
|
||
drop.all.index <collection>
|
||
```
|
||
|
||
### Импорт находящихся данных в субд из файла в формате ".csv"
|
||
```sh
|
||
futriiX:~> mode.csv
|
||
futriiX(csv-mode): import /path/to/your/file.csv
|
||
file.csv sucessfully loaded
|
||
futriiX(csv-mode): exit
|
||
futriiX:~>
|
||
```
|
||
|
||
### Экспорт находящихся данных в субд в файл в формате ".csv"
|
||
```sh
|
||
futriiX:~> mode.csv
|
||
futriiX(csv-mode): export /path/to/your/file.csv
|
||
file.csv sucessfully unloaded
|
||
futriiX(csv-mode): exit
|
||
futriiX:~>
|
||
```
|
||
|
||
## Команды по работе с кластером
|
||
|
||
### Статус кластера (собран кластер в данный момент или нет)
|
||
```sh
|
||
status
|
||
cluster.status
|
||
```
|
||
|
||
|
||
### Команды Raft кластера
|
||
```sh
|
||
## Добавление узла
|
||
add.node <node_url>
|
||
add.node http://raft1.example.com:9080
|
||
```
|
||
|
||
### Удаление узла из кластера
|
||
```sh
|
||
remove.node <node_id>
|
||
remove.node node123
|
||
```
|
||
|
||
### Список raft.узлов (данная команда отображает узлы, которые объеденены протоколом raft и их текущую роль (leader or follower))
|
||
```sh
|
||
list.raft.nodes
|
||
```
|
||
|
||
### Настройка пользователей и прав
|
||
|
||
```sh
|
||
# Создание пользователя с полными правами
|
||
lua> add_user("admin", {can_read = true, can_write = true, can_create = true, can_delete = true, allowed_collections = {}})
|
||
|
||
# Создание пользователя только для чтения определенных коллекций
|
||
lua> add_user("analyst", {can_read = true, can_write = false, can_create = false, can_delete = false, allowed_collections = {"sales", "reports"}})
|
||
|
||
# Создание редактора с ограниченными правами
|
||
lua> add_user("editor", {can_read = true, can_write = true, can_create = true, can_delete = false, allowed_collections = {"articles", "comments"}})
|
||
```
|
||
|
||
### Проверка прав доступа
|
||
|
||
```sh
|
||
|
||
# Проверка прав чтения
|
||
lua> can_read("analyst", "sales")
|
||
true
|
||
|
||
lua> can_read("analyst", "users")
|
||
false
|
||
|
||
# Проверка прав записи
|
||
lua> can_write("editor", "articles")
|
||
true
|
||
|
||
lua> can_write("editor", "users")
|
||
false
|
||
|
||
# Проверка прав создания
|
||
lua> can_create("editor", "articles")
|
||
true
|
||
|
||
# Проверка прав удаления
|
||
lua> can_delete("editor", "articles")
|
||
false
|
||
```
|
||
|
||
### Практические сценарии с ACL
|
||
|
||
```sh
|
||
# Инициализация системы прав
|
||
lua> function init_acl()
|
||
>> add_user("admin", {can_read = true, can_write = true, can_create = true, can_delete = true, allowed_collections = {}})
|
||
>> add_user("manager", {can_read = true, can_write = true, can_create = true, can_delete = false, allowed_collections = {"orders", "customers"}})
|
||
>> add_user("viewer", {can_read = true, can_write = false, can_create = false, can_delete = false, allowed_collections = {"products"}})
|
||
>> end
|
||
lua> init_acl()
|
||
|
||
# Безопасное создание документа с проверкой прав
|
||
lua> function secure_create(user, collection, key, value)
|
||
>> if not can_create(user, collection) then return "Access denied" end
|
||
>> return insert(collection, key, value)
|
||
>> end
|
||
|
||
lua> secure_create("manager", "orders", "order_001", {customer = "john", amount = 100})
|
||
Document inserted
|
||
|
||
lua> secure_create("viewer", "orders", "order_002", {customer = "jane", amount = 200})
|
||
Access denied
|
||
```
|
||
|
||
### Базовые операции с транзакциями
|
||
|
||
```sh
|
||
# Начало транзакции
|
||
lua> begin("tx_order_001")
|
||
|
||
# Добавление операций в транзакцию
|
||
lua> add_operation("tx_order_001", {operation = "create", collection = "orders", key = "order_001", value = {customer_id = "cust_123", total = 150.75, status = "pending"}})
|
||
|
||
lua> add_operation("tx_order_001", {operation = "update", collection = "customers", key = "cust_123", value = {last_order = "order_001", total_spent = 1200.50}})
|
||
|
||
lua> add_operation("tx_order_001", {operation = "create", collection = "payments", key = "pay_001", value = {order_id = "order_001", amount = 150.75, status = "processed"}})
|
||
|
||
# Фиксация транзакции
|
||
lua> commit("tx_order_001")
|
||
```
|
||
|
||
### Пример №1 перевод средств между счетами
|
||
```sh
|
||
|
||
# Функция перевода средств
|
||
lua> function transfer_funds(from_acc, to_acc, amount)
|
||
>> local tx_id = "tx_transfer_" .. os.time()
|
||
>> begin(tx_id)
|
||
>>
|
||
>> local from_balance = get("accounts", from_acc).balance
|
||
>> if from_balance < amount then
|
||
>> rollback(tx_id)
|
||
>> return "Insufficient funds"
|
||
>> end
|
||
>>
|
||
>> add_operation(tx_id, {operation = "update", collection = "accounts", key = from_acc, value = {balance = from_balance - amount}})
|
||
>>
|
||
>> local to_balance = get("accounts", to_acc).balance
|
||
>> add_operation(tx_id, {operation = "update", collection = "accounts", key = to_acc, value = {balance = to_balance + amount}})
|
||
>>
|
||
>> add_operation(tx_id, {operation = "create", collection = "transactions", key = "tx_" .. os.time(), value = {from = from_acc, to = to_acc, amount = amount, date = os.date()}})
|
||
>>
|
||
>> return commit(tx_id)
|
||
>> end
|
||
|
||
# Использование функции перевода
|
||
lua> transfer_funds("acc_001", "acc_002", 500.00)
|
||
```
|
||
###Пример №2 Создание заказа с резервированием товаров
|
||
|
||
```sh
|
||
# Комплексная транзакция создания заказа
|
||
lua> begin("tx_complete_order_789")
|
||
|
||
# 1. Создание заказа
|
||
lua> add_operation("tx_complete_order_789", {operation = "create", collection = "orders", key = "order_789", value = {customer = "john_doe", items = {{product = "prod_1", qty = 2}, {product = "prod_2", qty = 1}}, total = 299.99, status = "created"}})
|
||
|
||
# 2. Обновление инвентаря
|
||
lua> add_operation("tx_complete_order_789", {operation = "update", collection = "inventory", key = "prod_1", value = {quantity = get("inventory", "prod_1").quantity - 2}})
|
||
|
||
lua> add_operation("tx_complete_order_789", {operation = "update", collection = "inventory", key = "prod_2", value = {quantity = get("inventory", "prod_2").quantity - 1}})
|
||
|
||
# 3. Обновление клиента
|
||
lua> add_operation("tx_complete_order_789", {operation = "update", collection = "customers", key = "john_doe", value = {order_count = get("customers", "john_doe").order_count + 1, total_spent = get("customers", "john_doe").total_spent + 299.99}})
|
||
|
||
# Фиксация
|
||
lua> commit("tx_complete_order_789")
|
||
```
|
||
|
||
### Пример №3 Обработка ошибок и откат
|
||
|
||
```sh
|
||
# Транзакция с проверкой и откатом при ошибке
|
||
lua> begin("tx_safe_update")
|
||
|
||
lua> add_operation("tx_safe_update", {operation = "update", collection = "products", key = "prod_1", value = {price = 99.99}})
|
||
|
||
# Проверяем условие перед коммитом
|
||
lua> if get("products", "prod_1").stock < 0 then
|
||
>> print("Negative stock detected, rolling back")
|
||
>> rollback("tx_safe_update")
|
||
>> else
|
||
>> commit("tx_safe_update")
|
||
>> end
|
||
```
|
||
|
||
### Пример №4 Комбинированные примеры: ACL + транзакции
|
||
|
||
```sh
|
||
# Безопасная бизнес-функция
|
||
lua> function secure_business_operation(user, operation_data)
|
||
>> -- Проверка прав
|
||
>> if not can_create(user, "orders") then return "No order creation permission" end
|
||
>> if not can_update(user, "inventory") then return "No inventory update permission" end
|
||
>>
|
||
>> -- Начало транзакции
|
||
>> local tx_id = "tx_secure_" .. os.time()
|
||
>> begin(tx_id)
|
||
>>
|
||
>> -- Операции
|
||
>> add_operation(tx_id, {operation = "create", collection = "orders", key = operation_data.order_id, value = operation_data.order})
|
||
>> add_operation(tx_id, {operation = "update", collection = "inventory", key = operation_data.product_id, value = {stock = get("inventory", operation_data.product_id).stock - operation_data.quantity}})
|
||
>>
|
||
>> -- Фиксация
|
||
>> return commit(tx_id)
|
||
>> end
|
||
|
||
# Использование
|
||
lua> secure_business_operation("manager", {order_id = "order_999", order = {customer = "alice", total = 150}, product_id = "prod_5", quantity = 3})
|
||
```
|
||
|
||
###Пример №5 Управление транзакциями
|
||
|
||
```sh
|
||
# Просмотр статуса транзакций (если такая функция реализована)
|
||
lua> function shows()
|
||
>> -- В реальной реализации здесь был бы вызов метода для получения списка транзакций
|
||
>> print("Active transactions management")
|
||
>> end
|
||
|
||
# Откат транзакции при таймауте
|
||
lua> function timeout_rollback(tx_id, timeout_seconds)
|
||
>> local start_time = os.time()
|
||
>> while os.time() - start_time < timeout_seconds do
|
||
>> -- Ждем завершения
|
||
>> end
|
||
>> rollback(tx_id)
|
||
>> return "Transaction rolled back due to timeout"
|
||
>> end
|
||
```
|
||
|
||
###Пример №4 Практические команды для повседневного использования
|
||
|
||
```sh
|
||
# Быстрое создание пользователя с правами
|
||
lua> add_user("api_user", {can_read = true, can_write = true, can_create = true, can_delete = false, allowed_collections = {"sessions", "cache"}})
|
||
|
||
# Простая транзакция обновления
|
||
lua> begin("tx_quick_update")
|
||
lua> add_operation("tx_quick_update", {operation = "update", collection = "config", key = "app_settings", value = {version = "1.2.3", updated_at = os.date()}})
|
||
lua> commit("tx_quick_update")
|
||
|
||
# Проверка системы перед операциями
|
||
lua> can_read("current_user", "target_collection") and "Access granted" or "Access denied"
|
||
```
|
||
|
||
### Пример создания пользователя с зашифрованным паролем, с помощью алгоритма шифрования MD-5
|
||
|
||
```sh
|
||
-- 1. Создаем пространство
|
||
lua> create_space("users")
|
||
|
||
-- 2. Создаем процедуры
|
||
lua> create_procedure("create_user", 'function create_user(username, password, user_data) return create_user_with_password("users", username, password, user_data) end')
|
||
|
||
lua> create_procedure("authenticate_user", 'function authenticate_user(username, password) local success, message = verify_user_password("users", username, password) return {success = success, message = message} end')
|
||
|
||
-- 3. Создаем пользователя
|
||
lua> call_procedure("create_user", '["alice", "password123", {"name": "Alice", "role": "user"}]')
|
||
Command executed successfully
|
||
|
||
-- 4. Проверяем аутентификацию
|
||
lua> local result = call_procedure("authenticate_user", '["alice", "password123"]')
|
||
lua> print(result)
|
||
{success = true, message = "Password correct"}
|
||
|
||
-- 5. Проверяем неправильный пароль
|
||
lua> local wrong_result = call_procedure("authenticate_user", '["alice", "wrongpass"]')
|
||
lua> print(wrong_result)
|
||
{success = false, message = "Password incorrect"}
|
||
```
|
||
|
||
|
||
|
||
|
||
(i to the second power)
|
||
|
||
|
||
|
||
|