BookStore is a digital book management system, written in C# and targeting the .NET Framework 2.0 on the Windows OS. It uses the db4o fully object-oriented database management system for the storing and querying of books.
The application allows the user to store all of its digital books (CHM, HTML, DOCX, PDF, EPUB, ODF, RTF, TXT, etc.) in a central single-file database repository, without the need to keep the books as individual files and folders on the disc, thus reducing disc fragmentation and easing content cohesion and portability (by copying the books database to a memory stick, for example).
The books to be imported can be either file-based books (such as a single PDF document) or folder-based books (such as a website offline copy). Books can be loaded one-at-a-time or many-at-once (bulk-load). Once imported, each book can be displayed or deleted.
Each book stored in the system is characterized by 5 attributes:
- Set of authors
- Set of tags
- Publishing house
- Year of publishing
The user can then query a particular set of books, based upon a combination of the aforementioned attributes. The querying system contains two layers:
- An inter-category layer - The corresponding query types are
AND queries (for which the query result must satisfy each selected category) and
OR queries (for which the query result satisfies at least one of the designated categories)
- An intra-category layer - the related query types are
AND queries (only in the case of multiple selection availability, meaning the set of authors and set of tags) and
OR queries. The semantics for these query types are similar to the inter-category queries.
The application supports multi-user access on the same PC, as each user can have its own database, without any interference with the data of other users. Also, since the user is able to select the application's working folders, the solution can be run by any user, irrespective of its privileges on the system.
The Underlying DBMS
At the start of the application's development, I looked into small-footprint programmable open-source database management systems available. I found two potential candidates: SQLite and db4o. Due to an interest in dabbling into an OODBMS for research purposes, I chose db4o.
Object-oriented databases have attracted considerable interest due to their promise to completely remove the disparity between the object-oriented data model and the entity-relationship model, called impedance mismatch.
These databases expose means through which objects can be queried and stored using the same model that it employed by the application’s programming language. Another way of putting it would be saying that an OODBMS extends the programming language with transparently persistent data, concurrency control, data recovery, associative queries and other capabilities. Object-oriented databases have bindings to most modern programming languages and platforms, including C++, Java, .NET, Perl, Python, Objective-C and Visual Basic.
The impedance mismatch is a collection of technical and conceptual difficulties, often encountered when a relational (SQL) database management system is being used in an object-oriented application.
It relates to aspects of information hiding, inheritance and polymorphism, syntax and semantics, as well as security features.
The diagram below reveals the usage of the composite design pattern. A
Book contains an
IDiscEntry, which can be either a
File or a
Folder can contain many
IDiscEntrys, those, of course, being files or folders. A
File contains one or many
Buffers, which are used to read / write data from / to disc using contiguous memory blocks. If a file is small, it may require only one
Buffer object, but if its size is great it could use many such objects.
As the relational databases world does not have an approximate correspondent to the inheritance relation of the object-oriented world, modeling this concept into a SQL-compliant database is a painful, full of compromises experience, as shown next.
The db4o Solution
db4o provides a simple uniform interface for storing new objects and updating existing objects:
objectContainer.Store(myObject). The object is stored anew or updated up to a specifically-defined update depth inside the object graph.
There are three methods for querying objects in db4o. Two of them use a declarative syntax, while the third is based on navigational semantics. The table underneath reveals the querying options in db4o.
Transactional support is not a feature that is dependent on the type of DBMS used. db4o makes transactional support available to the client programmer, as revealed in the subsequent example.
Address address = new Address("Teodor Mihali St.", "Cluj-Napoca", "Romania");
Person person = new Person("Mihnea Radulescu", address);
IObjectContainer db = Db4oFactory.OpenFile("Persons.yap");
The application contains around 55 types (mostly classes), organized into 5 namespaces:
DataAccess - Types relevant to the interaction with the db4o database management system
DiscAccess - Classes for reading the book file content from disc, persisting it to the database and writing the book files to disc for displaying
RegistryAccess - A single class used for storing per-user database location and temporary folder path
BookEntities - Application business-logic classes, exposing the book data and meta-data, as well as the book querying engine
BookStoreGUI - Windows Forms GUI functionality types (
The application developed is a well-chosen example of using the strengths of OODBMS’ in real-world scenarios. It manages the storage, visualization and tag-based querying of the digital books of the user by allowing the viewing of the content of books already stored, deleting existing books, searching for books based upon a criterion or combination of criteria and adding new books to the application's database. It benefits from object-oriented persistence features in terms of natural and straightforward development, as well as performance opportunities.
Also, as collateral db4o-related benefits to implementing the required functionality of the application, I:
- created a uniform fully transactional wrapper to updating and querying in db4o (
- added the means to store and retrieve an external file (BLOB) of any size, by repeatedly accessing buffer-size database-controlled sections of the file (
Source Code and Application Download
The complete source code of the
BookStore application (a Google Code project) can be accessed here. If one is only interested in the binaries, they can be downloaded from this link.
I would gladly welcome contributions and feedback to this BookStore.NET open-source (GPL v3) project, being interested in particular in a Mono port of this project.
-  The Microsoft Developer Network (MSDN) pages
- Version 0.1 - Initial submission - 09/03/2010
- Version 0.2 - Updated content, sources and binaries - 21/09/2011
- Version 0.3 - Reengineered code with significant bug fixes - 24/04/2012