BookNest is a text-based library management system that combines learning objectives from OOP, binary persistence, dates/deadlines, search, reporting, CSV import, and simple role management (Admin/Staff).
Run it yourself in seconds — no build required:
docker run -it --rm ghcr.io/domisko/booknest:latestDefault login:
admin/admin
- Media Model:
Bookwith author list, publisher, edition, location, genre, price,MediaType,maxLoanPeriodDays,createdAt,createdBy/lastModifiedBy. - Physical Copies: Unique
inventoryIDper copy; multiple copies per ISBN are possible. - Members (Borrower): Name, Email, Address,
registrationDate,status(Active/Blocked). - History:
Loanstores loan, due date, and return – includingperformedBy(the employee who performed the action). - Employee Management: Roles
Admin/Staff, login/logout, create/deactivate/reactivate, reset password (demo hash). - Search: Books (Title/ISBN/Author) and members (ID/Email/Name) – both with paginated output (increments of 10, "m/+" for more).
- Reporting: Daily report (loans/returns, sorted, including totals per
MediaType), due report. - CSV Import: Books and members via
import/books.csvorimport/members.csv. - Persistence & Autosave: Binary file
library.bin(Version 5). Data is automatically saved after every mutating action. - UI: Pure console menu with "pinned" screen (clear screen between actions).
- Benchmark Mode: Optional UI timer that shows the duration after actions (in ms). Toggleable in the "Settings" menu.
- Profile: Debug (local toolchain). Targets:
BookNest(App),unit_tests(Catch2-based tests). - Build & Tests (Example):
cmake --build cmake-build-debug --target unit_tests && ./cmake-build-debug/unit_tests - Run the App:
cmake --build cmake-build-debug --target BookNest && ./cmake-build-debug/BookNest
- Start the App → Login: Default admin
admin/admin. - Optional: Create further accounts under "Employee (Admin)".
- Import: As admin, select
[5] Import (Admin)in the main menu and importbooks.csv/members.csvfromimport/. - Then try out search/loan/return/reports.
-
Main Menu:
- [1] Books
- [2] Members
- [3] Reports
- [4] Employee (Admin)
- [5] Import (Admin)
- [0] Logout
All menus display a consistent footer with
[0] Backor[0] Logout.
Note: In some IDE run consoles, the scroll history remains visible. For a "clean" pinned display, please use the system terminal (macOS Terminal, iTerm2, Windows Terminal).
- Book:
maxLoanPeriodDayscontrols the due date upon loan.isAvailableindicates the status of the copy. - Borrower:
status == Activeis a prerequisite for borrowing.registrationDateis set upon creation. - Loan: Contains
loanDate,dueDate,returnDate(0 = open) andperformedBy. - Employee:
Role::Adminvs.Role::Staff. Only admins manage employees.
Location of files (default): import/books.csv and import/members.csv (in project root). Fallback: ../import/....
- Required:
ISBN;Title - Optional:
Authors(separated by|),Publisher,Edition,Location,Genre,Price,MaxLoanDays,MediaType(Book/Buch,Magazine/Magazin/Zeitschrift,DVD,EBook/E-Book/E_Buch,Other/Sonstiges),CreatedBy
Example:
ISBN;Title;Authors;Publisher;Edition;Location;Genre;Price;MaxLoanDays;MediaType;CreatedBy
978-3-16-148410-0;Clean Code;Robert C. Martin;Prentice Hall;;REG-A12;Programming;39.90;14;Book;domi
- Required:
Name;Email;Address - Optional:
RegistrationDate(YYYY-MM-DD),Status(Active/Blocked)- If these fields are missing, they are automatically set (Registration Date = now, Status = Active).
- Invalid values are ignored; default values remain.
Example:
Name;Email;Address
Max Mustermann;max@test.de;Musterweg 1
- Daily Report (
Library::showDailyReport):- Lists loans and returns of a day (time, medium, borrower,
performedBy, due date). - Additional totals per
MediaTypeand grand totals.
- Lists loans and returns of a day (time, medium, borrower,
- Due Report (
Library::getDueReport):- Open loans, sorted by remaining time (overdue first), limitable.
Header:
- Magic:
BNES(4 bytes) - Version:
uint32_t(currently 5)
Sections (in order):
- Books (count, then fields per book including authors vector)
- Borrowers (count, then fields including
registrationDateandstatus) - Employees (count, then fields including role, active flag)
- Loans (count, then fields including
performedBy) - Counters (next IDs)
All strings/vectors are prefixed with a length field, as implemented in Utils::writeString.
- Passwords are saved with a very simple hash for demo purposes (
Utils::simpleHash). For production systems, definitely use a real password hashing library (e.g., bcrypt, argon2). - During development, the
library.binfile can be deleted in case of schema changes (no backward compatibility required).
- Catch2-based unit tests cover, among others: loan/return flow, due date calculation, search, persistence roundtrip, employee auth/RBAC,
performedBy.
With Docker, you can quickly test BookNest – including persistent data and CSV import via volume.
- Docker and optionally Docker Compose v2
docker build -t booknest:latest .
For the best interactive experience (clean terminal), use:
# Create folders and run the app
mkdir -p data import
docker compose run --rm booknestThe --rm flag ensures that the container is removed after you exit, keeping your system clean.
If you prefer the standard way:
docker compose up --buildNote: docker compose up might prefix lines with booknest-1 |. Use run for a native feel.
Volumes:
./data→/app/data(containslibrary.bin)./import→/app/import(placebooks.csv/members.csvhere)
Log in as admin in the program (admin/admin) → Main Menu [5] Import (Admin).
To reset the database (delete all imported books and members):
- Stop any running container.
- Delete the binary file:
rm data/library.bin - Restart the app:
docker compose run --rm booknest
- Activation: Main Menu →
[6] Settings→ "Toggle Benchmark". Status is displayed (ON/OFF). - Output format: After relevant actions, a line like
(Books-Search in 12.3 ms)appears. - Measured actions include: loading/saving, book/member search, loan/return, reports, CSV import.
- See
docs/UserGuide.mdfor a step-by-step guide.
This project is part of a study portfolio (DLBMINPAPCC01). The code serves demonstration and learning purposes.
- Standard operation uses linear searches over vectors with paginated output. In this configuration, 50k–100k books and a comparable number of members are well usable on typical hardware.
- For larger datasets, optional in-memory indices can be added (e.g.,
unordered_mapfor ID/ISBN/Email), allowing exact lookups in O(1). Startup time then increases once due to index construction (O(n)). - Memory and I/O scale largely linearly with the number of records. For reliable tests, the Benchmark Mode (Settings) and CSV import of large amounts of data are recommended.
