My latest project is called NNDB.
I’ve worked with databases for quite a long time now, and for a while I’ve been thinking about how they work under the hood. I know very little about it, but I thought I could learn a bit by trying to implement something similar myself.
I’m interested in how queries work against joined tables, how to implement indices and so on.
I’ve also been feeling that I want to do some C++ as an open source project. I do it all day at work, and for some problems it feels like the right tool for the job.
NNDB is sort-of like an in-memory database, but it works with C++ types for its columns, instead of a fixed set like varchar, int etc. You can put your own value-typed classes in the columns, and all values are type-checked at compile time.
It’s always struck me as strange that with a traditional code+SQL setup you have to keep your SQL in sync with your code manually. Of course, there are lots of trendy Object-Relational-Mapping thingies that solve that problem, but I felt it could be approached from another direction: instead of generating code to match your data, or generating SQL to match your code, why not specify your data structure in code?
In NNDB you define a table something like this:
typedef nndb::Values< unsigned long, std::string, std::string, MyDate > PersonValues; class PersonTable : public nndb::Table{ public: enum Columns { id, first_name, last_name, date_of_birth }; };
Actually, defining your own class is unnecessary, but it’s nice to have an enum to name your columns, and making a class gives you a nice place to put it.
To insert a row you do something like this:
PersonTable person_table; person_table.Insert( PersonValues( 0, "Andy", "Balaam", MyDate( 12000000 ) ) );
You can do simple queries with WHERE and ORDER BY clauses, and I’m working on indexes.
After that will come JOINs, and anything else that takes my fancy.
I don’t anticipate NNDB being useful to anyone – it’s really for me to understand why things are as they are in the world of databases. However, you never know – it may turn out to be a fast and convenient way to store data in the C++ world. I think some of the applications that use databases don’t really need the kind of concurrent multi-user network-accessible features they have, but really just want to search, join and store reliably, and NNDB might one day grow into something that can find a niche.
To explore more, check out the complete example.
“instead of generating code to match your data, or generating SQL to match your code, why not specify your data structure in code?”
See LISP :)
PS: Really cool C++ project!
Thanks! I am actually currently reading http://mitpress.mit.edu/sicp/full-text/book/book.html and loving it. It turns out pretty much all the interesting stuff in template metaprogramming is almost identical to how you would do the same thing in LISP.
Two projects that might be interesting to you, though quite far from C++ userland.
PG’OCamlm by Richard Jones: http://pgocaml.berlios.de/
A statically typed relational algebra by Mauricio Fernandez:
http://eigenclass.org/hiki/addressing-orm-problem-typed-relational-algebra
Thanks Guillaume – really interesting projects, and further really interesting links at the bottom of the second one. I knew someone else must have done something like this before…
In self-augmenting language it is possible to build something like this on top of a real database, which I think would be very difficult in C++.
I have been having thoughts about what my ideal language would be. Recently I have been wondering about whether it’s possible to create a self-augmenting language that is also compiled in a traditional way, and type-safe in the C++ sense. Essentially I want to be able to extend the C++ compiler at compile time.