Area 04 · Database manipulation
Library loans with transactions
Record books, members and loans in a relational database, keeping copy counts consistent when books go out and come back.
- Spec no.
- HO-08
- Level
- Exam-level
- Time box
- 2 h 30 min
- Reference
- Java · C#
- Grading
- Self-assessed · rubric is ours, not DICT's
01 Coverage
| Area | Sub-skills practised | Role |
|---|---|---|
| 01 Data manipulation | Validation | Also |
| 04 Database manipulation | Create, Read, Update, Delete | Primary |
Sign up to start coding practice
Read the task freely. An account is required before editing and running a solution. Code runs also need an internet connection.
Sign up or sign in02 Requirements
- Tables books, members and loans with primary and foreign keys (schema below). Turn foreign keys on.
- book title|author|copies and member name add rows and print the new id.
- borrow memberId bookId yyyy-mm-dd: fail with No copies left: title when copies is 0. Otherwise decrement copies and insert a loan due 14 days later, in one transaction.
- return loanId yyyy-mm-dd: set returned only on an open loan and restore one copy, in one transaction. Print No open loan #id otherwise.
- overdue yyyy-mm-dd lists open loans whose due date is before that date, oldest first.
- delete-book id refuses while loans are open, and refuses when past loans still reference it.
- Parameterised queries only.
03 Input and output
- One command per line, as above
- One line per command; overdue prints one line per loan or Nothing overdue on date
book Noli Me Tangere|Jose Rizal|1
book Florante at Laura|Francisco Balagtas|2
member Liza Manalo
member Paolo Tan
borrow 1 1 2026-03-01
borrow 2 1 2026-03-02
borrow 2 2 2026-03-02
return 1 2026-03-10
return 1 2026-03-11
overdue 2026-03-20
delete-book 2
delete-book 1Book #1 added
Book #2 added
Member #1 added
Member #2 added
Loan #1: Noli Me Tangere to Liza Manalo, due 2026-03-15
No copies left: Noli Me Tangere
Loan #2: Florante at Laura to Paolo Tan, due 2026-03-16
Returned loan #1
No open loan #1
Overdue on 2026-03-20: loan #2 Florante at Laura (Paolo Tan), due 2026-03-16
Cannot delete book #2: it has open loans
Cannot delete book #1: it has loan historyMatch the sample exactly first, then write at least two test inputs of your own.
04 Edge cases to test
- Borrowing the last copy twice
- Returning the same loan twice
- An unknown member or book id
- A badly formatted date
05 Database
Engine: SQLite (Java: org.xerial sqlite-jdbc; C#: Microsoft.Data.Sqlite). An embedded database needs no server, which suits a timed sitting.
- Schema and the key SQL statements are shown below.
- Any embedded or local database is fine in practice; the reference uses SQLite.
PRAGMA foreign_keys = ON;
CREATE TABLE books (
id INTEGER PRIMARY KEY,
title TEXT NOT NULL,
author TEXT NOT NULL,
copies INTEGER NOT NULL CHECK (copies >= 0)
);
CREATE TABLE members (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL
);
CREATE TABLE loans (
id INTEGER PRIMARY KEY,
book_id INTEGER NOT NULL REFERENCES books(id),
member_id INTEGER NOT NULL REFERENCES members(id),
borrowed TEXT NOT NULL, -- ISO date, e.g. 2026-03-01
due TEXT NOT NULL,
returned TEXT -- NULL while the book is out
);
-- Borrow (in one transaction):
-- SELECT title, copies FROM books WHERE id = ?; -- must have copies > 0
-- UPDATE books SET copies = copies - 1 WHERE id = ?;
-- INSERT INTO loans(book_id, member_id, borrowed, due)
-- VALUES (?, ?, ?, date(?, '+14 days'));
-- Return:
-- UPDATE loans SET returned = ? WHERE id = ? AND returned IS NULL;
-- UPDATE books SET copies = copies + 1 WHERE id = (SELECT book_id FROM loans WHERE id = ?);
-- Overdue on a date:
-- SELECT l.id, b.title, m.name, l.due FROM loans l
-- JOIN books b ON b.id = l.book_id JOIN members m ON m.id = l.member_id
-- WHERE l.returned IS NULL AND l.due < ? ORDER BY l.due;
-- Delete a book only when it has no open loans:
-- SELECT COUNT(*) FROM loans WHERE book_id = ? AND returned IS NULL; -- must be 0
-- DELETE FROM books WHERE id = ?;06 Starter outline and hints
create tablesborrow: begin; check copies; update; insert; commit (rollback on error)return: begin; update loan where returned is null; update copies; commitoverdue: join loans, books, members
Hint 1
SQLite can compute the due date for you: date(?, '+14 days').
Hint 2
Turn off auto-commit (Java) or use BeginTransaction (C#) for the two-step changes.
07 Practice rubric
| Criterion | Sub-skills | Look for | Pts |
|---|---|---|---|
| Schema | Create | Keys, foreign keys and a CHECK on copies. | 20 |
| Borrow and return | UpdateCreate | Both changes commit together or not at all. | 30 |
| Queries | Read | Overdue join is correct and ordered. | 25 |
| Delete rules | Delete | Open loans and history both block deletion with clear messages. | 15 |
| Validation | Validation | Dates and ids checked before touching the database. | 10 |
| Total | 100 | ||
Our own weighting for practice. It is not the DICT scoring scheme.
08 Self-check
Tick only what you have verified by running your own program.
Loading saved checks…
09 Reference solution
Both versions compiled and reproduced the sample output on Java 21 and .NET 8 when this site was built. Reference solutions are in Java and C#. The 2023 FAQ copy also lists C, C++ and Visual Basic 6.0 / .NET; the same structure carries over, but you will need your language's own file and database APIs.
Try the whole brief first. The reference is one correct approach, not the only one, and reading it early removes most of the practice value.
10 Exam-day habits
- Work without internet search to simulate exam conditions.
- Type the sample input yourself and compare your output line by line before you look at the reference.