Introduction
When I decided to write a small shopping list program (www.fridayshopping.com) for my own personal use, I planned to use Microsoft's Compact Framework for storing the data using XML serialization APIs. Unfortunately, I discovered that there was no such API available for the Compact Framework at the time. So since the amount of data I was planning to store was small, I decided to develop my own very simple database framework, instead of using some professional DB package that would be expensive and memory consuming.
Storage Files
Databases are stored as plain XML files. As mentioned, Compact Framework does not provide support for XML Serialization/Deserialization, so I had to implement a simple version myself, using XML readers and writers. Each database table is stored in a separate XML file. When a database table is loaded, the file is parsed and read entirely into memory. This makes it suitable for relatively small databases. When the database is saved, the entire memory content is written back into an XML file.
File Structure
In order to be able to access a unique record, each record in a database is identified by a unique sequential key. The NextKey
sequential key is stored at the top of the database file, so that each new record that is added will use it and increment it for the usage of the next record added. All other fields are stored subsequently as regular XML elements. In the following example, there are two books in the database.
<Books>
<NextKey>
<value>2</value>
</NextKey>
<Book>
<Key>
<value>0</value>
</Key>
<name>The Bible</name>
<author>God</author>
<isbn>0000000000</isbn>
</Book>
<Book>
<Key>
<value>1</value>
</Key>
<name>The Da Vinci Code</name>
<author>Dan Brown</author>
<isbn>0385504209</isbn>
</Book>
</Books>
Define Your Database Classes
Each database is comprised from two classes.
The class that represents each data record. It extends the ItemBase
class. The main role of this class is to define record members and handle serialization / deserialization of data from and into the members.
The class that represents the container of the database records. We use the ListItemTypeAttribute
to define the class that is contained in this container. It extends the ItemListBase
class. In most cases, the class will not have any implementation. Here is a sample code that defines the Books
database:
public class Book : ItemBase
{
public string name;
public string author;
public string isbn;
public Book()
{
}
public Book(string name)
{
this.name = name;
}
protected override void SerializeMembers(System.Xml.XmlTextWriter xmlWriter)
{
base.SerializeMembers(xmlWriter);
xmlWriter.WriteElementString("name", name);
xmlWriter.WriteElementString("author", author);
xmlWriter.WriteElementString("isbn", isbn);
}
public override void DeserializeMembers(System.Xml.XmlNodeReader xmlReader)
{
base.DeserializeMembers(xmlReader);
if (xmlReader.IsStartElement("name"))
{
name = xmlReader.ReadElementString();
}
if (xmlReader.IsStartElement("author"))
{
author = xmlReader.ReadElementString();
}
if (xmlReader.IsStartElement("isbn"))
{
isbn = xmlReader.ReadElementString();
}
}
}
[ListItemTypeAttribute(typeof(Book))]
public class Books : ItemListBase
{
public Books()
{
}
}
Creating Database and Adding items
Now that we have the Books
database defined, we are ready to use it. First, we create an empty database.
Books books = new Books();
Now we define one Book
record and add it to the Books
database.
Book book1 = new Book("The Bible");
book1.author = "God";
book1.isbn = "000-000-001";
Key justAddedKey = books.Add(book1);
Save it into an XML file books.xml.
books.Save("Books.xml");
Loading Database and Retrieving Items
When we load a database from the XML file, the file is parsed according to the type of the database container that is passed. All database items are deserialized and stored in the database. The items are also hashed so that they can be accessed quickly using the database's sequential key. In this example, we load the Books
database and get an item using a key.
books = (Books)Books.Load(typeof(Books), "books.xml");
Book searchedBook = (Book)books.GetItem(justAddedKey);
Summary
If you are considering writing a .NET app that uses a small personal database, especially if you plan to run it on a memory constrained device such as Pocket PC, you should consider this framework. It's pretty bare-boned, but it has the basic functionality to store and retrieve records from XML formatted files.
History
- 24th May, 2006: Initial post