Typos
(except me.)
This commit is contained in:
@ -117,9 +117,9 @@
|
||||
|
||||
Відсутність ефективних систем управління пакунками призводить до численних проблем у процесі розробки. Розробники стикаються з труднощами при пошуку потрібних бібліотек, виникають конфлікти версій, ускладнюється процес оновлення залежностей, а також з'являються проблеми з безпекою через використання застарілих версій компонентів. Це суттєво сповільнює процес розробки та може призвести до значних фінансових втрат.
|
||||
|
||||
Метою цієї курсової роботи є розробка інформаційної системи "Репозиторій пакунків. Колаборація над пакунками", яка спрощує процес менеджменту пакунків, створення їх відносин, керування залежностями, та надання користувачам різних ролей у розвитку репозиторію. У процесі роботи над системою було проведено детальний аналіз схожої системи AUR@aur, котра ефективно використовується для надання користувачам дистрибутиву Arch Linux@archlinux можливості публікувати свої пакунки. Було спроектовано реляційну базу даних і розроблено комп'ютерну програму, яка дозволяє взаємодіяти з репозиторієм.
|
||||
Метою цієї курсової роботи є розробка інформаційної системи "Репозиторій пакунків. Колаборація над пакунками", яка спрощує процес менеджменту пакунків, створення їх відносин, керування залежностями, та надання користувачам різних ролей у розвитку репозиторію. У процесі роботи над системою було проведено детальний аналіз схожої системи AUR @aur, котра ефективно використовується для надання користувачам дистрибутиву Arch Linux @archlinux можливості публікувати свої пакунки. Було спроектовано реляційну базу даних і розроблено комп'ютерну програму, яка дозволяє взаємодіяти з репозиторієм.
|
||||
|
||||
Комп'ютерну програму повністю написано мовою програмування Rust@rust, для графічного інтерфейсу використовується бібліотека iced@iced, для взаємодії з базою даних використовується бібліотека SQLx@sqlx. Інформація зберігається у базі даних MySQL@mysql. Розробка виконувалася у текстовому редакторі Neovim@neovim.
|
||||
Комп'ютерну програму повністю написано мовою програмування Rust @rust, для графічного інтерфейсу використовується бібліотека iced @iced, для взаємодії з базою даних використовується бібліотека SQLx @sqlx. Інформація зберігається у базі даних MySQL @mysql. Розробка виконувалася у текстовому редакторі Neovim @neovim.
|
||||
|
||||
= Аналіз та концептуальне моделювання предметної області //{{{1
|
||||
#v(-spacing)
|
||||
@ -130,7 +130,7 @@
|
||||
|
||||
Для створення ефективної системи управління пакунками необхідно ретельно проаналізувати існуючі рішення та їх особливості. Такий аналіз допомагає виявити найбільш важливі функціональні можливості та уникнути потенційних проблем при проектуванні власної системи.
|
||||
|
||||
В якості системи аналогу розглянемо Arch User Repository (AUR)@aur -- репозиторій користувацьких пакунків для дистрибутиву Arch Linux@archlinux. AUR є яскравим прикладом успішної реалізації концепції кооперативної розробки та управління пакунками. Система надає користувачам можливість самостійно створювати та поширювати пакунки, які не входять до офіційних репозиторіїв пакунків Arch Linux.
|
||||
В якості системи аналогу розглянемо Arch User Repository (AUR)@aur -- репозиторій користувацьких пакунків для дистрибутиву Arch Linux @archlinux. AUR є яскравим прикладом успішної реалізації концепції кооперативної розробки та управління пакунками. Система надає користувачам можливість самостійно створювати та поширювати пакунки, які не входять до офіційних репозиторіїв пакунків Arch Linux.
|
||||
|
||||
При відвідуванні головної сторінки AUR @aur_main можна побачити статистку свого облікового запису, всього репозиторію а також останні оновлення пакунків. За допомогою поля пошуку можна перейти до сторінки пошуку пакунків @aur_search.
|
||||
|
||||
@ -224,7 +224,7 @@
|
||||
Важливою особливістю репозиторіїв пакунків є можливість керувати програмним забезпеченням та надавати користувачам доступ до актуальних версій програм. У репозиторіях пакунків основний документообіг пов'язаний з управлінням інформацією пакунків, їх відносинами та залежностями. Репозиторії ведуть облік завантажень пакунків та формують звітність про їх використання для аналізу популярності та стабільності.
|
||||
|
||||
Отже, документообіг репозиторію пакунків складається з наступних документів:
|
||||
- опис пакунку: назва пакунку, версія, розробник, ліцензія, короткий опис функціональності, детальний опис можливостей, вимоги до системи, інструкції зі встановлення та налаштування, історія змін версій;
|
||||
- інформація пакунку: назва, версія, опис, веб-покликання на веб-ресурс пакунку, дата позначення, дата створення, дата оновлення;
|
||||
- файл потреб пакунку: унікальний ідентифікатор пакунку, назва, версія, архітектура процесора, список залежностей (обов'язкових та опціональних), конфлікти з іншими пакунками, контрольні суми файлів, розмір встановленого пакунку;
|
||||
- журнал активності пакунку: статистика завантажень, оцінки користувачів, коментарі, повідомлення про помилки, запити на оновлення, історія модифікацій;
|
||||
- інструкція зі збірки: скрипт для автоматизованої збірки пакунку, список додаткових залежностей для збірки, параметри конфігурації, інструкції з тестування, відомості про середовище збірки та тестування, контактна інформація супроводжувача пакунку.
|
||||
@ -256,7 +256,7 @@
|
||||
+ облікові записи користувачів обов'язково мають:
|
||||
+ унікальний юзернейм не довше 31 символу;
|
||||
+ унікальну пошту не довше 255 символів;
|
||||
+ надійно збережений пароль за допомогою використання алгоритму argon2@argon2;
|
||||
+ надійно збережений пароль за допомогою використання алгоритму argon2 @argon2;
|
||||
+ останній час використання облікового запису.
|
||||
+ бази пакунків мають:
|
||||
+ обов'язкову унікальну назву не довше 127 символів;
|
||||
@ -337,7 +337,7 @@
|
||||
+ час останнього оновлення пакунку.
|
||||
|
||||
// Info retrieval {{{2
|
||||
Інформаційна система повинна надавати можливість перегляду наступної інформації:
|
||||
Інформаційна система повинна надавати можливість перегляду інформації, а також формування текстових звітів з наступних елементів:
|
||||
+ інформація пакунку:
|
||||
+ назва пакунку;
|
||||
+ версія пакунку;
|
||||
@ -388,7 +388,7 @@
|
||||
+ створення нового облікового запису за допомогою реєстрації з наступними даними:
|
||||
+ унікальний юзернеймом;
|
||||
+ унікальна пошта;
|
||||
+ пароль довше 7 символів, який буде надійно збережений системою за допомогою алгоритму argon2@argon2.
|
||||
+ пароль довше 7 символів, який буде надійно збережений системою за допомогою алгоритму argon2 @argon2.
|
||||
+ використання існуючого облікового запису за допомогою автентифікації з наступними даними:
|
||||
+ юзернейм або електрона пошта, система повинна зрозуміти що користувач використовує;
|
||||
+ пароль котрий при пропуску через argon2 буде однаковим з збереженим паролем облікового запису.
|
||||
@ -469,7 +469,7 @@
|
||||
- сутність "Тип відношення": назва виду відношення;
|
||||
- сутність "Відношення": архітектура, умова, назва пакунку з яким є відношення.
|
||||
|
||||
Між цими сутностями існують наступні зв’язки:
|
||||
Між цими сутностями існують наступні зв'язки:
|
||||
|
||||
- "Користувач" - "Роль": один до жодного або багатьох;
|
||||
- "База пакунку" - "Роль": один до жодного або багатьох;
|
||||
@ -480,7 +480,7 @@
|
||||
- "Пакунок" - "Відношення": один до жодного або багатьох;
|
||||
- "Тип відношення" - "Відношення": один до жодного або багатьох.
|
||||
|
||||
Зобразимо визначені сутності та відповідні зв’язки у вигляді ER-діаграми @er_diagram.
|
||||
Зобразимо визначені сутності та відповідні зв'язки у вигляді ER-діаграми @er_diagram.
|
||||
|
||||
#img("img/er_diagram.png", "ER-діаграма концептуальної моделі")
|
||||
|
||||
@ -526,7 +526,7 @@
|
||||
[База пакунку id], [id],
|
||||
[База пакунку], [PackageBases],
|
||||
[База пакунку], [base],
|
||||
[Веб-покликання], [url],
|
||||
[Веб-покликання], [URL],
|
||||
[Версія], [version],
|
||||
[Відношення id], [id],
|
||||
[Відношення], [PackageRelations],
|
||||
@ -570,7 +570,7 @@
|
||||
+ від первинного ключа id залежать всі неключові атрибути, а саме: name, email, password, last_used, created_at, updated_at;
|
||||
+ таблиця відповідає всім вимогам 3НФ: всі атрибути атомарні (1НФ), всі неключові атрибути залежать безпосередньо від первинного ключа id (2НФ), а також відсутні транзитивні залежності.
|
||||
+ Таблиця Packages:
|
||||
+ від первинного ключа id залежать всі неключові атрибути, а саме: base, name, version, description, url, flagged_at, created_at, updated_at;
|
||||
+ від первинного ключа id залежать всі неключові атрибути, а саме: base, name, version, description, URL, flagged_at, created_at, updated_at;
|
||||
+ таблиця відповідає всім вимогам 3НФ: всі атрибути атомарні (1НФ), всі неключові атрибути залежать безпосередньо від первинного ключа id (2НФ), а також відсутні транзитивні залежності.
|
||||
+ Таблиця PackageBases:
|
||||
+ від первинного ключа id залежать всі неключові атрибути, а саме: name, description, created_at, updated_at;
|
||||
@ -608,7 +608,7 @@
|
||||
|
||||
При визначенні первинного ключа особлива увага приділяється семантичному аналізу даних. Зокрема можна помітити потребу бачити яку роль має користувач для кожного пакунку. Тому найкращим ключовими атрибутами стануть "Пакунок id" та "Роль id". Вони надають можливість унікально ідентифікувати універсальне відношення та їх сполучення охоплює всі атрибути відношення.
|
||||
|
||||
Всі визначені атрибути є неподільними, а значення атомарні. Сполучений первиний ключ, який складаєтсья з "Пакунок id" та "Роль id", дозволяє унікально ідентифікувати кожний кортеж. Ключові поля не мають порожніх значень, кортежі не мають фіксованого порядку, тому, універсальне вдношення Т знаходиться в першій нормальній формі (1НФ).
|
||||
Всі визначені атрибути є неподільними, а значення атомарні. Сполучений первинний ключ, який складається з "Пакунок id" та "Роль id", дозволяє унікально ідентифікувати кожний кортеж. Ключові поля не мають порожніх значень, кортежі не мають фіксованого порядку, тому, універсальне відношення Т знаходиться в першій нормальній формі (1НФ).
|
||||
|
||||
Для перевірки універсального відношення Т на відповідність другій нормальній формі (2НФ) @normalization, проаналізуємо його на існування часткових функціональних залежностей неключових атрибутів від частини первинного ключа @normal_t_dep.
|
||||
|
||||
@ -616,7 +616,7 @@
|
||||
- "Роль id": Пакунок id, Назва, Версія, Опис, Веб-покликання, Дата позначення, Дата створення, Дата оновлення, База пакунку id, Назва, Опис, Дата створення, Дата оновлення;
|
||||
- "Пакунок id": Роль id, Коментар, Тип ролі id, Назва, Опис, Користувач id, Ім'я, Електронна пошта, Пароль Дата логіну, Дата створення, Дата оновлення.
|
||||
|
||||
Можемо зробити висновок, що відношення не знаходиться в другій нормальній формі, адже деякі атрибути мають неповні функціональні залежності (залежать лише від частини ключа). Для приведення універсального відношення Т до другої нормальної форми виділимо з нього два універсальних відношення Т1 та Т2 @normal_t12, де Т1 буде містити атрибути які повінстю залежать від частини ключа "Роль id", а Т2 буде містити атрибути які повінстю залежать від частини ключа "Пакунок id".
|
||||
Можемо зробити висновок, що відношення не знаходиться в другій нормальній формі, адже деякі атрибути мають неповні функціональні залежності (залежать лише від частини ключа). Для приведення універсального відношення Т до другої нормальної форми виділимо з нього два універсальних відношення Т1 та Т2 @normal_t12, де Т1 буде містити атрибути які повністю залежать від частини ключа "Роль id", а Т2 буде містити атрибути які повністю залежать від частини ключа "Пакунок id".
|
||||
|
||||
Т1 та Т2 зберігають першу нормальну форму (1НФ) та не містять неповних функціональних залежностей, оскільки кожне з них має лише один ключовий атрибут. Таким чином, можна зробити висновок, що ці відношення відповідають вимогам другої нормальної форми (2НФ).
|
||||
|
||||
@ -649,52 +649,67 @@
|
||||
= Опис програми //{{{1
|
||||
#v(-spacing)
|
||||
== Загальні відомості //{{{2
|
||||
Для забеспечення простоти, ефективності та елегантності розробки інформаційної системи "Репозиторій пакунків. Колаборація над пакунками" було використано операційну систему Arch Linux@archlinux та текстовий редактор Neovim@neovim.
|
||||
Для забезпечення простоти, ефективності та елегантності розробки інформаційної системи "Репозиторій пакунків. Колаборація над пакунками" було використано операційну систему Arch Linux @archlinux та текстовий редактор Neovim @neovim.
|
||||
|
||||
Для реалізації всієї комп'ютерної програми було обрано сучасну мову програмування Rust@rust, яка є надзвичайно швидкою, надійною та продуктивною. За зберігання даних відповідає база даних MySQL@mysql, вона відома своєю стабільнітю, можливостями та швидкістю. Для взаємодії з базою даних було обрано бібліотеку SQLx@sqlx, вона є дуже гарно спроектованим проектом, розрахована на асинхроні операції та підтримку багатьох баз даних на низькому рівні. Для написання інтерфейсу комп'ютерної програми було обрано бібліотеку iced@iced, ця бібліотека фокусується на простоті та безпеці програм з графічним інтерфейсом за допомогю дотримання принципів проектування Elm@elm.
|
||||
Для реалізації всієї комп'ютерної програми було обрано сучасну мову програмування Rust @rust, яка є надзвичайно швидкою, надійною та продуктивною. За зберігання даних відповідає база даних MySQL @mysql, вона відома своєю стабільністю, можливостями та швидкістю. Для взаємодії з базою даних було обрано бібліотеку SQLx @sqlx, вона є дуже гарно спроектованим проектом, розрахована на асинхронні операції та підтримку багатьох баз даних на низькому рівні. Для написання інтерфейсу комп'ютерної програми було обрано бібліотеку iced @iced, ця бібліотека фокусується на простоті та безпеці програм з графічним інтерфейсом за допомогою дотримання принципів проектування Elm @elm.
|
||||
|
||||
== Виклик і завантаження //{{{2
|
||||
Користувач може взаємодіяти з ком'ютерною програмою після встановки її до своєї операційної системи та запуску бази даних.
|
||||
Інформаційна система була розроблена з використанням мови Rust @rust, тому результуюча комп'ютерна програма є невимогливою до потужностей комп'ютеру, не потребує сторонніх залежностей і може бути використана у вигляді самодостатнього файлу виконання.
|
||||
|
||||
Для зберігання даних використовується СУБД MySQL@mysql. База даних та комп'ютерна програма можуть знаходитись на різних пристроях. Перед тим як кінцевий користувач приступить до використання програми, системний адміністратор, котрий відповідає за роботу інформаційної системи, має налаштувати змінну середовища "DATABASE_URL" в котрій буде адреса до налаштованого екземпляру MySQL. Для максимальної зручності налаштування рекомендуєтсья використовувати контейнерізацю за допомогою Docker@docker, особливо рекомендується його інструмент Compose@compose.
|
||||
Для розгортання та запуску системи необхідно використовувати Linux сумісну операційну систему, наприклад Arch Linux @archlinux, та виконати наступні кроки:
|
||||
+ збірка комп'ютерної програми:
|
||||
+ встановити Docker @docker та Docker Compose @compose;
|
||||
+ встановити інструменти для компіляції вихідного коду Rust. Інструкції можна знайти на офіційному вебсайті Rust @rust;
|
||||
+ завантажити вихідний код комп'ютерної програми з публічного репозиторію Gitea @repo;
|
||||
+ перейти у теку завантаженого вихідного коду та скомпілювати комп'ютерну програму за допомогою команди "cargo c --release".
|
||||
+ запуск бази даних:
|
||||
+ в завантаженій теці вихідного коду потрібно перейти у теку "assets";
|
||||
+ у останній строчці файлу з назвою "compose.yaml" потрібно змінити "password" на надійний пароль;
|
||||
+ в теці "assets" потрібно виконати команду "docker compose up -d".
|
||||
+ запуск програми:
|
||||
+ виконати команду "export DATABASE_URL=\"mysql:\//root:password\@localhost:3306/repository\"". Слід зауважити, що "password" слід замінити на виставлений пароль у файлі "compose.yaml";
|
||||
+ будь-де в теці вихідного коду комп'ютерної програми запустити команду "cargo r --release".
|
||||
|
||||
Інформаційна система була розроблена з використанням мови Rust@rust, тому результуюча програма не потребує залежностей під час виконання і може бути використана у вигляді самодостатнього файлу виконання.
|
||||
Слід зауважити, що змінна середовища "DATABASE_URL" є обов'язковою для виконання програми. В цій змінній лежить адреса до налаштованого екземпляру СУБД MySQL. Через складність самостійного налаштування СУБД MySQL, для максимальної зручності рекомендується використовувати контейнеризацію за допомогою Docker @docker, особливо рекомендується його інструмент Compose @compose, який спростить задачу до однієї команди "docker compose up -d".
|
||||
|
||||
== Призначення і логічна структура //{{{2
|
||||
Інформаційна система полегшує колаборацію над пакунками у репозиторії для розробників. Система забеспечує інтуїтивний інтерфейс для навігації по пакункам, їх залежностям з відносинами, та користувачам. Перелік основних функцій системи:
|
||||
- управління пакунками та їх метаданими;
|
||||
- система користувацьких акаунтів;
|
||||
- система різних рівней доступу користувачей до пакунків;
|
||||
- пошу та категоризація пакунків за багатьма факторами;
|
||||
Інформаційна система полегшує кооперацію над пакунками у репозиторії для розробників. Система забезпечує інтуїтивний інтерфейс для навігації по пакункам, їх залежностям з відносинами, та користувачам. Перелік основних функцій системи:
|
||||
- управління пакунками та їх інформацією;
|
||||
- система користувацьких облікових записів;
|
||||
- система різних рівнів доступу облікових записів до пакунків;
|
||||
- пошук та катетеризація пакунків за багатьма факторами;
|
||||
- надання аналітичної інформації про репозиторій, пакунки та користувачів.
|
||||
|
||||
Під час розробки було використано гексагональну архітектуру@hexagonal, також відому як "архітектура портів та адаптерів". Структура проекту складаєтсья з кількох рівнів @repo_structure:
|
||||
Під час розробки було використано гексагональну архітектуру @hexagonal проектування, також відому як "архітектура портів та адаптерів", завдяки чому частини проекту є чітко розділеними @repo_structure.
|
||||
|
||||
#img("img/repo/structure.png", "Структура проeкту")
|
||||
|
||||
Структура проекту складається з кількох рівнів:
|
||||
+ Шар взаємодії з базою даних (тека data):
|
||||
+ декларація інтерфейсу взаємодії (тека ports);
|
||||
+ імплементації взаємодії (тека adapters).
|
||||
+ Шар сервісів для бізенс логіки програми (тека service), cервіси мають:
|
||||
+ декларацію репозиторію який бере дані з задекларованого шару бази даних (файли з назвою repository);
|
||||
+ імплементацію адаптеру репозиторію який оперує отриманням даних з шару імплементації бази даних (файли з назвою adapter);
|
||||
+ декларацію контракту який будується на репозиторії і описує дані з котрими буде працювати сервіс (файли з назвою contract);
|
||||
+ імплеменацію сервісу котрий оперує над даними контракту та здійснює логічні операції з обчисленнями (файли з назвою service).
|
||||
+ Шар графічного інтерфесу (тека src) використовує контракти з шару сервісів для валідації даних від користувача та надсилання запитів до логічної частини застосунку.
|
||||
+ Головний файл проекту (тека src, файл main.rs) відповідає за конпонування всих шарів:
|
||||
+ імплементації інтерфейсів взаємодії (тека adapters).
|
||||
+ Шар сервісів для бізнес-логіки програми (тека service); сервіси мають:
|
||||
+ файли з назвою repository -- декларація інтерфейсу репозиторію який використовує дані з частини декларації інтерфейсу шару бази даних;
|
||||
+ файли з назвою adapter -- імплементація інтерфейсу репозиторію який оперує отриманням даних з частини імплементацій інтерфейсів взаємодії шару бази даних;
|
||||
+ файли з назвою contract -- декларація контракту (інтерфейсу) який будується на інтерфейсі репозиторію і описує дані з котрими буде працювати сервіс;
|
||||
+ файли з назвою service -- імплементація сервісу котрий оперує над даними з контракту, здійснює логічні операції та обчислення над цими даними.
|
||||
+ Шар графічного інтерфейсу (тека src) використовує контракти з шару сервісів для перевірки даних від користувача та надсилання запитів до логічної частини комп'ютерної програми.
|
||||
+ Головний файл проекту (тека src, файл main.rs) відповідає за компонування всіх шарів:
|
||||
+ встановлення підключення до бази даних;
|
||||
+ ініціалізацю адаптерів бази даних;
|
||||
+ ініціалізацію адаптерів бази даних;
|
||||
+ ініціалізацію адаптерів репозиторіїв за допомогою створених підключень та адаптерів бази даних;
|
||||
+ запуск сервісів передаючи їм створені репозиторії;
|
||||
+ відображення та менеджмент графічних частин застосунку яким передаються сервіси.
|
||||
+ запуск сервісів за допомогою створених репозиторіїв;
|
||||
+ ініціалізація графічних елементів передав їм створені сервіси;
|
||||
+ відображення та менеджмент графічних частин комп'ютерної програми.
|
||||
|
||||
#img("img/repo/structure.png", "Структура проєкту")
|
||||
|
||||
Проєкт має всі використані під час розробки ресурси, такі як SQL скрипти та Docker Compose@compose файли, за допомогою яких можна створити тестову базу даних та наповнити її даними.
|
||||
Вихідний код проекту @repo має в собі всі використані під час розробки ресурси, такі як SQL скрипти та Docker Compose @compose файли, за допомогою яких можна створити тестову базу даних наповнену даними.
|
||||
|
||||
== Опис фізичної моделі бази даних //{{{2
|
||||
Для інформаційної системи створено базу даних яка має дев’ять таблиць. Код для її створення яких описаний нижче.
|
||||
Для інформаційної системи створено базу даних яка має дев'ять таблиць. Код для її створення описаний нижче.
|
||||
|
||||
Таблиця "Users" містить інформацію про користувачів системи та має таку структуру:
|
||||
- id - службове додатнє число, необхідне для ідентифікації таблиці та забезпечення надійної роботи бази даних;
|
||||
- ім'я - унікальне текстове поле яке зберігає ім'я користувача (довжина до 31 символа), не може бути порожнім;
|
||||
- id - службове додатне число, необхідне для ідентифікації таблиці та забезпечення надійної роботи бази даних;
|
||||
- ім'я - унікальне текстове поле яке зберігає ім'я користувача (довжина до 31 символу), не може бути порожнім;
|
||||
- пошта - унікальне текстове поле яке зберігає електронну пошту користувача (довжина до 255 символів), не може бути порожнім;
|
||||
- пароль - текстове поле яке зберігає хеш пароля (довжина до 255 символів), не може бути порожнім;
|
||||
- останній логін - зберігає дату останнього використання облікового запису, може бути порожнім;
|
||||
@ -717,7 +732,7 @@ CREATE TABLE Users (
|
||||
```
|
||||
|
||||
Таблиця "PackageBases" містить інформацію про бази пакунків:
|
||||
- id - службове додатнє число, необхідне для ідентифікації таблиці та забезпечення надійної роботи бази даних;
|
||||
- id - службове додатне число, необхідне для ідентифікації таблиці та забезпечення надійної роботи бази даних;
|
||||
- назва - унікальне текстове поле, зберігає назву базового пакунку (до 127 символів), не може бути порожнім;
|
||||
- опис - текстове поле (до 510 символів), може бути порожнім, зберігає опис пакунку;
|
||||
- час створення - зберігає дату створення бази пакунку, не може бути порожнім;
|
||||
@ -736,7 +751,7 @@ CREATE TABLE PackageBases (
|
||||
```
|
||||
|
||||
Таблиця "PackageBaseRoles" визначає ролі користувачів для роботи з пакунками:
|
||||
- id - службове додатнє число, необхідне для ідентифікації таблиці та забезпечення надійної роботи бази даних;
|
||||
- id - службове додатне число, необхідне для ідентифікації таблиці та забезпечення надійної роботи бази даних;
|
||||
- назва - унікальне текстове поле, зберігає назву ролі (наприклад: submitter, packager; довжина до 31 символу), не може бути порожнім;
|
||||
- опис - текстове поле яке описує роль (до 255 символів), може бути порожнім.
|
||||
|
||||
@ -750,9 +765,9 @@ CREATE TABLE PackageBaseRoles (
|
||||
```
|
||||
|
||||
Таблиця "PackageBaseUserRoles" описує ролі користувачів для баз пакунків:
|
||||
- база пакунку - числове поле (ціле додатнє число), зовнішній ключ на таблицю PackageBases;
|
||||
- користувач - числове поле (ціле додатнє число), зовнішній ключ на таблицю Users;
|
||||
- роль - числове поле (ціле додатнє число), зовнішній ключ на таблицю PackageBaseRoles;
|
||||
- база пакунку - числове поле (ціле додатне число), зовнішній ключ на таблицю PackageBases;
|
||||
- користувач - числове поле (ціле додатне число), зовнішній ключ на таблицю Users;
|
||||
- роль - числове поле (ціле додатне число), зовнішній ключ на таблицю PackageBaseRoles;
|
||||
- коментар - текстове поле для збереження приміток (до 255 символів), може бути порожнім;
|
||||
- (base, user, role) - складний (композитний) первинний ключ, необхідний для ідентифікації таблиці та забезпечення надійної роботи бази даних;
|
||||
|
||||
@ -773,8 +788,8 @@ CREATE TABLE PackageBaseUserRoles (
|
||||
```
|
||||
|
||||
Таблиця "Packages" містить інформацію про окремі пакунки:
|
||||
- id - службове додатнє число, необхідне для ідентифікації таблиці та забезпечення надійної роботи бази даних;
|
||||
- база - зовнішній ключ (ціле додатнє число) на таблицю PackageBases;
|
||||
- id - службове додатне число, необхідне для ідентифікації таблиці та забезпечення надійної роботи бази даних;
|
||||
- база - зовнішній ключ (ціле додатне число) на таблицю PackageBases;
|
||||
- назва - унікальне текстове поле для збереження назви пакунку (до 127 символів), не може бути порожнім;
|
||||
- версія - текстове поле для збереження версії пакунку (до 127 символів), не може бути порожнім;
|
||||
- опис - текстове поле для збереження опису пакунку (до 255 символів), може бути порожнім;
|
||||
@ -802,7 +817,7 @@ CREATE TABLE Packages (
|
||||
```
|
||||
|
||||
Таблиця "DependencyTypes" визначає типи залежностей:
|
||||
- id - службове додатнє число, необхідне для ідентифікації таблиці та забезпечення надійної роботи бази даних;
|
||||
- id - службове додатне число, необхідне для ідентифікації таблиці та забезпечення надійної роботи бази даних;
|
||||
- назва - унікальне текстове поле, зберігає назву типу залежності (наприклад: depends, makedepends; довжина до 31 символу), не може бути порожнім.
|
||||
|
||||
```
|
||||
@ -814,7 +829,7 @@ CREATE TABLE DependencyTypes (
|
||||
```
|
||||
|
||||
Таблиця "PackageDependencies" відображає залежності пакунків:
|
||||
- id - службове додатнє число, необхідне для ідентифікації таблиці та забезпечення надійної роботи бази даних;
|
||||
- id - службове додатне число, необхідне для ідентифікації таблиці та забезпечення надійної роботи бази даних;
|
||||
- архітектура - текстове поле, зберігає цільову архітектуру залежності (до 63 символів), може бути порожнім;
|
||||
- умова - текстове поле, яке зберігає умову залежності (до 255 символів), може бути порожнім;
|
||||
- опис - текстове поле, зберігає опис залежності (до 127 символів), може бути порожнім;
|
||||
@ -840,8 +855,8 @@ CREATE TABLE PackageDependencies (
|
||||
```
|
||||
|
||||
Таблиця "RelationTypes" визначає типи зв'язків між пакунками:
|
||||
- id - службове додатнє число, необхідне для ідентифікації таблиці та забезпечення надійної роботи бази даних;
|
||||
- назва - унікальне текстове поле яке зберігає назву зв'яку (наприклад: conflicts, provides; довжина до 31 символу), не може бути порожнім.
|
||||
- id - службове додатне число, необхідне для ідентифікації таблиці та забезпечення надійної роботи бази даних;
|
||||
- назва - унікальне текстове поле яке зберігає назву зв'язку (наприклад: conflicts, provides; довжина до 31 символу), не може бути порожнім.
|
||||
|
||||
```
|
||||
-- conflicts, provides, replaces, etc.
|
||||
@ -852,9 +867,9 @@ CREATE TABLE RelationTypes (
|
||||
```
|
||||
|
||||
Таблиця "PackageRelations" описує зв'язки між пакунками:
|
||||
- id - службове додатнє число, необхідне для ідентифікації таблиці та забезпечення надійної роботи бази даних;
|
||||
- архітектура - текстове поле, зберігає цільову архітектуру зв'яку (до 63 символів), може бути порожнім;
|
||||
- умова - текстове поле, яке зберігає умову зв'яку (до 255 символів), може бути порожнім;
|
||||
- id - службове додатне число, необхідне для ідентифікації таблиці та забезпечення надійної роботи бази даних;
|
||||
- архітектура - текстове поле, зберігає цільову архітектуру зв'язку (до 63 символів), може бути порожнім;
|
||||
- умова - текстове поле, яке зберігає умову зв'язку (до 255 символів), може бути порожнім;
|
||||
- пакунок - зовнішній ключ на таблицю Packages;
|
||||
- тип зв'язку - зовнішній ключ на таблицю RelationTypes;
|
||||
- тип зв'язку з пакунком - текстове поле, зберігає назву пакунку, з яким є зв'язок (до 127 символів), не може бути порожнім.
|
||||
@ -877,29 +892,29 @@ CREATE TABLE PackageRelations (
|
||||
|
||||
== Опис програмної реалізації //{{{2
|
||||
|
||||
При запуску комп'ютерної програми стартовим екраном є сторінка логіну @repo_login. Користувачі з існуючими акаунтами можуть увійти у свій акаунт за допомогою пошти або юзернема та свого паролю який надійно та безпечно зберігається в базі даних у зашифрованому вигляді.
|
||||
При запуску комп'ютерної програми стартовим екраном є сторінка логіну @repo_login. Користувачі з існуючими обліковими записами можуть увійти у свій обліковий запис за допомогою пошти або юзернейма та свого паролю який надійно та безпечно зберігається в базі даних у зашифрованому вигляді.
|
||||
|
||||
#img("img/repo/login.png", "Сторінка логіну")
|
||||
|
||||
Якщо у користувача немає акаунту, то він може натиснути на кнопку реєстраці для переходу на сторікну реєстарції @repo_register. Щоб створити новий акаунт. Користувач має надати ім'я користувача, електрону пошту та пароль.
|
||||
Якщо у користувача немає облікового запису, то він може натиснути на кнопку реєстрації для переходу на сторінку реєстрації @repo_register. Щоб створити новий обліковий запис. Користувач має надати ім'я користувача, електрону пошту та пароль.
|
||||
|
||||
Форми логіну та реєстрації перевіряють дані на валідність та не будуть робити зайвих запитів, якщо надана інформація не відповідає правилам інформаційної системи. У випадку перевірок. які не можуть бути зроблені локально, система надішле запит до бази даних і відобразить результат у графічному інтерфейсі програми.
|
||||
Форми логіну та реєстрації перевіряють дані на валідність та не будуть робити зайвих запитів, якщо надана інформація не відповідає правилам інформаційної системи. У випадку перевірок. Які не можуть бути зроблені локально, система надішле запит до бази даних і відобразить результат у графічному інтерфейсі програми.
|
||||
|
||||
#img("img/repo/register.png", "Сторінка реєстрації")
|
||||
|
||||
Після успішного логіну або реєстрації програма перейде на сторінку пошуку @repo_search, яка надає можливість шукати пакунки з багатьма способами фільтрування та сортування результатів. При наведені курсору миші на елементи пошуку можна побачити стисле пояснення їх функціоналу.
|
||||
|
||||
Назва пакунку, його бази та його веб-покликання на ресурс є інтерактивними. Якщо натиснути на назву пакунку, то відкриється вікно з переглядом інформації та статистики про пакунок. Якщо натиснути на назву бази пакунку, то відкриється відкно де буде інформація про базу пакунку. При натисканні на веб-покликання, воно відкриєтсья в веб-браузері, котрий стоїть за замовчуванням в операціній системі користувача.
|
||||
Назва пакунку, його бази та його веб-покликання на ресурс є інтерактивними. Якщо натиснути на назву пакунку, то відкриється вікно з переглядом інформації та статистики про пакунок. Якщо натиснути на назву бази пакунку, то відкриється вікно де буде інформація про базу пакунку. При натисканні на веб-покликання, воно відкриється в веб-браузері, котрий стоїть за замовчуванням в операційній системі користувача.
|
||||
|
||||
#img("img/repo/search.png", "Сторінка пошуку")
|
||||
|
||||
Розглянемо на прикладі сторінки пошуку обробку запиту на основі даних з графічного інтерфейсу котрі ввів користувач.
|
||||
|
||||
Коли користувач натискає кнопку "Go", або натискає клавішу "Enter" у текстовому полі пошуку, генерується внутрішнє повідомлення "Search". Обробник повідомлень сторінки пошуку отримує це повідомлення, та починає валідацію даних текстового поля та створення структури даних з параметрами пошуку. Після чого, якщо на момент запиту не виконується інших пошукових запитів, дані з параметрами пошуку передаються до сервісу пошуку. Сервіс передає дані до адаптеру репозиторію пошуку. Адаптер репозиторію пошуку встановлює з'єднання до бази даних, і робить запит до адаптеру репозиторію пошуку бази даних з встановленим з'єднанням, після чого він закриє з'єднання до бази даних. Адаптер репозиторію пошуку бази даних використовує передане йому підключення для виконання комплексного SQL запиту який будується на основі переданих йому параметрів пошуку. Після отримання результату з бази даних, він конвертує його у набір записів інформації про пакунок. Цей набір записів буде переданий назад до адаптеру репозиторію пошуку, потім до сервісу, й у кінці передається у повідомленні "RequestResult" до сторінки пошуку, яка зможе відобразити кожен запис як рядок у таблиці.
|
||||
Коли користувач натискає кнопку "Go", або натискає клавішу "Enter" у текстовому полі пошуку, генерується внутрішнє повідомлення "Search". Обробник повідомлень сторінки пошуку отримує це повідомлення, та починає перевірку даних текстового поля та створення структури даних з параметрами пошуку. Після чого, якщо на момент запиту не виконується інших пошукових запитів, дані з параметрами пошуку передаються до сервісу пошуку. Сервіс передає дані до адаптеру репозиторію пошуку. Адаптер репозиторію пошуку встановлює з'єднання до бази даних, і робить запит до адаптеру репозиторію пошуку бази даних з встановленим з'єднанням, після чого він закриє з'єднання до бази даних. Адаптер репозиторію пошуку бази даних використовує передане йому підключення для виконання комплексного SQL запиту який будується на основі переданих йому параметрів пошуку. Після отримання результату з бази даних, він конвертує його у набір записів інформації про пакунок. Цей набір записів буде переданий назад до адаптеру репозиторію пошуку, потім до сервісу, й у кінці передається у повідомленні "RequestResult" до сторінки пошуку, яка зможе відобразити кожен запис як рядок у таблиці.
|
||||
|
||||
Якщо на будь-якому рівні абстракції виникне помилка, то вона буде передана до графічного інтерфейсу сторінки пошуку і користувач буде сповіщений про виникнення помилки.
|
||||
|
||||
Код обробника повідомлення "Search" з валідацією даних:
|
||||
У шарі графічного інтерфейсу екрану пошуку обробник повідомлення "Search" перевіряє дані пошукового запиту та надсилає їх до шару сервісу у пошуковий сервіс:
|
||||
```
|
||||
let search_data = Data {
|
||||
mode: self.mode.into(),
|
||||
@ -930,15 +945,14 @@ return Some(
|
||||
);
|
||||
```
|
||||
|
||||
Код функції пошуку сервісу пошуку:
|
||||
У шарі сервісу функція пошуку насилає дані до репозиторію пошуку:
|
||||
```
|
||||
async fn search(&self, data: Data) -> Result<Vec<search::Entry>> {
|
||||
self.repository.search(data.into()).await
|
||||
}
|
||||
```
|
||||
|
||||
Код функції пошуку адаптеру репозиторію пошуку:
|
||||
|
||||
У репозиторію пошуку функція пошуку встановлює підключення до сховища даних та надсилає дані пошукового запиту до шару взаємодії з базою даних:
|
||||
```
|
||||
async fn search(&self, data: Data) -> Result<Vec<Entry>> {
|
||||
let c = self.driver.open_connection().await?;
|
||||
@ -949,7 +963,7 @@ async fn search(&self, data: Data) -> Result<Vec<Entry>> {
|
||||
}
|
||||
```
|
||||
|
||||
Код функції пошуку адаптеру репозиторію пошуку бази даних:
|
||||
У шарі взаємодії з базою даних функція пошуку, на основі отриманих даних, будує комплексний динамічний запит та надсилає його використовуючи отримане з репозиторію пошуку підключення до сховища даних:
|
||||
```
|
||||
async fn search(connection: &E, data: Data) -> Result<Vec<Entry>> {
|
||||
let mut builder = QueryBuilder::new(
|
||||
@ -1061,7 +1075,7 @@ async fn search(connection: &E, data: Data) -> Result<Vec<Entry>> {
|
||||
}
|
||||
```
|
||||
|
||||
Код обробки для повідомлення "RequestResult":
|
||||
Після чого результат приходить у вигляді повідомлення "RequestResult" яке оброблюється в шарі графічного інтерфейсу:
|
||||
```
|
||||
Message::RequestResult(r) => match &*r {
|
||||
Ok(v) => self.state = State::Table(Table(v.clone())),
|
||||
@ -1069,7 +1083,7 @@ Message::RequestResult(r) => match &*r {
|
||||
},
|
||||
```
|
||||
|
||||
Код відображення таблиці результату пошуку:
|
||||
Після отриманого результату пошуку, він буде відображений у вигляді таблиці:
|
||||
```
|
||||
pub fn view(&self) -> Element<'static, Message> {
|
||||
let mut table: Vec<_> = [
|
||||
@ -1124,16 +1138,16 @@ pub fn view(&self) -> Element<'static, Message> {
|
||||
}
|
||||
```
|
||||
|
||||
Подібну реалізацію мають всі частини програми. Представлений програмний код демонструє ефективну реалізацію принципів гексагональної архітектури@hexagonal. Структура коду чітко відображає розділення на рівні, кожен з яких відповідає за визначену функціональну роль, що є ключовою характеристикою даної архітектурної парадигми. Цей підхід надає чітке розмежування відповідальності де кожен компонент системи, від інтерфейсу користувача до адаптерів баз даних, має чітко визначений набір обов'язків. Це полегшує процес розробки та спрощує підтримку програмного забезпечення у довгостроковій перспективі. Незалежність бізнес-логіки від інфраструктурних рішень дозволяє спростити процес міграції до простого доповнення арсеналу адаптерів. Сервісний шар, що містить основну бізнес-логіку пошуку, не залежить від конкретних технологій зберігання даних або реалізації графічного інтерфейсу, тому його можна буде використати в інших проектах. Крім того, модульна архітектура дозволяє проводити ізольоване тестування кожного компонента, за допомогою використання макетів (mock objects) для залежностей що забезпечить глибоке покриття коду тестами.
|
||||
Подібну реалізацію мають всі частини програми. Представлений програмний код демонструє ефективну реалізацію принципів гексагональної архітектури @hexagonal. Структура коду чітко відображає розділення на рівні, кожен з яких відповідає за визначену функціональну роль, що є ключовою характеристикою даної архітектурної парадигми. Цей підхід надає чітке розмежування відповідальності де кожен компонент системи, від інтерфейсу користувача до адаптерів баз даних, має чітко визначений набір обов'язків. Це полегшує процес розробки та спрощує підтримку програмного забезпечення у довгостроковій перспективі. Незалежність бізнес-логіки від інфраструктурних рішень дозволяє спростити процес міграції до простого доповнення арсеналу адаптерів. Сервісний шар, що містить основну бізнес-логіку пошуку, не залежить від конкретних технологій зберігання даних або реалізації графічного інтерфейсу, тому його можна буде використати в інших проектах. Крім того, модульна архітектура дозволяє проводити ізольоване тестування кожного компонента, за допомогою використання макетів (mock objects) для залежностей що забезпечить глибоке покриття коду тестами.
|
||||
|
||||
#nheading("Висновки") //{{{1
|
||||
|
||||
В результаті виконання курсової роботи було розроблено інформаційну систему "Репозиторій пакунків" для організації ефективної колаборації над програмними пакунками. В процесі розробки було проведено ґрунтовний аналіз предметної області, визначено ключові вимоги до системи та спроектовано оптимальну структуру бази даних для зберігання інформації про пакунки, їх версії, залежності, користувачів та їхні ролі.
|
||||
В результаті виконання курсової роботи було розроблено інформаційну систему "Репозиторій пакунків" для організації ефективної кооперації над програмними пакунками. В процесі розробки було проведено ґрунтовний аналіз предметної області, визначено ключові вимоги до системи та спроектовано оптимальну структуру бази даних для зберігання інформації про пакунки, їх версії, залежності, користувачів та їхні ролі.
|
||||
|
||||
Створена система забезпечує зручний інтерфейс для пошуку пакунків, управління пакунками та колаборації між розробниками. Реалізовано функціонал створення та оновлення пакунків, відстеження залежностей та взаємозв'язків між пакунками, а також систему ролей для контролю доступу.
|
||||
Створена система забезпечує зручний інтерфейс для пошуку пакунків, управління пакунками та кооперації між розробниками. Реалізовано функціонал створення та оновлення пакунків, відстеження залежностей та взаємозв'язків між пакунками, а також систему ролей для контролю доступу.
|
||||
|
||||
База даних спроектована на основі реляційної моделі та нормалізована до третьої нормальної форми, що забезпечує оптимальну структуру даних та відсутність їх надлишковості. Під час розробки було використано мову програмування Rust@rust, систему управління базами даних MySQL@mysql та графічну бібліотеку iced@iced. Крім того використовуєтсья контейнеризація за допомогою Docker@docker та Docker Compose@compose що забезпечує надійність роботи системи, її масштабованість та простоту розгортання в різних середовищах.
|
||||
База даних спроектована на основі реляційної моделі та нормалізована до третьої нормальної форми, що забезпечує оптимальну структуру даних та відсутність їх надлишковості. Під час розробки було використано мову програмування Rust @rust, систему управління базами даних MySQL @mysql та графічну бібліотеку iced @iced. Крім того використовується контейнеризація за допомогою Docker @docker та Docker Compose @compose що забезпечує надійність роботи системи, її масштабованість та простоту розгортання в різних середовищах.
|
||||
|
||||
Розроблена інформаційна система значно спрощує процес управління та отримання інформації про програмні пакунки. Вона відповідає поставленим завданням та має потенціал подальшої реалізації завдяки використанню дуже модульної архітектури моделювання програмного забеспечення, відомої як Гексагональна архітектура@hexagonal.
|
||||
Розроблена інформаційна система значно спрощує процес управління та отримання інформації про програмні пакунки. Вона відповідає поставленим завданням та має потенціал подальшої реалізації завдяки використанню дуже модульної архітектури моделювання програмного забезпечення, відомої як Гексагональна архітектура @hexagonal.
|
||||
|
||||
// vim:sts=2:sw=2:fdl=0:fdm=marker:cms=/*%s*/
|
||||
|
Reference in New Issue
Block a user