PMS2 – Coming Soon to an Interweb Near You
A long, long time myself and two friends were working on a college project where the entire goal as I saw it was to “create” stuff. Mono was a wee lad back in 2003, but I still preferred it to Java any day of the week. So myself, Phil Tricca, and Joseph Scaduto created a whole framework for creating what are now called “learning communities” in Mono/Gtk#/mod_mono.
One of the pieces we needed was a databases abstraction layer (we had grand ideas) so we first sought to flush out the ObjectSpaces API for Mono. Sadly, Microsoft couldn’t get their act together so we built our own. So in honor of Microsoft we called it Phil-And-Matt Spaces, shortened to PMS. After it’s original debut it sat on the selves for quite some time until I started working for Konica Minolta Business Solutions and was tasked with creating Printgroove. PMS hit the spot (man that sounds funny) – it was far from bad, but it certainly wasn’t awesome. At the point of its resurrection it needed a face lift, but never got one.
It’s now been years since Printgroove got started and PMS has continued to work well for it and numerous other projects – but I’ve got an itch that must be scratched. So while working on a small web service only project I’ve been adding in a couple dozen extra hours to mature PMS – or basically throw away it’s entire user facing API.
Here’s a sneak peak of whats to come:
// - Pull IDbConnection from pool based on unique name (from config file)
// - This is useful if you have multiple databases to chat with
// - Not specifying a name will load the one marked default or the first one found
using (DbBroker cxt = new DbBroker("name-mapping-to-config-connection-string")) {
// SELECT member.* FROM member WHERE username LIKE '%a%' ORDER BY id
// Enumerate through results without storing Member objects in container
foreach (Member m in cxt.Query<Member>().Like("username", "%a%").OrderBy("id").Exec())
Console.WriteLine(" : " + m);
// Use raw SQL and ignore chainable methods for generation
// Store results in List<Member> and then iterate through it
string sql = "SELECT member.* FROM member where username LIKE '%a%' ORDER BY id";
foreach (Member m in cxt.Exec<Member>().Objects<List<Member>>(sql))
Console.WriteLine(" : " + m);
// get first member
Console.WriteLine("first: " + cxt.Query<Member>().Exec().First());
// a short-cut to get the first member since we aren't filtering etc
Console.WriteLine("first: " + cxt.Exec<Member>().First());
// SELECT COUNT(member.*) FROM member WHERE id > 50000
// Use generics to cast the output of ExecuteScalar to an Int32
Console.WriteLine("count: " + cxt.Query<Member>().Filter("id > 50000").Exec().Count<int>());
// Directly call ExecuteScalar but use generics to cast the output
sql = "SELECT id FROM member WHERE username='mimetnet'";
Console.WriteLine("scalar: " + cxt.Exec<Member>().Scalar<int>(sql));
// Directly call ExecuteReader() with our generated SQL
// SELECT id,username FROM member WHERE id > 68665
using (IDataReader reader = cxt.Query<Member>()
.GreaterThan("id", 68665)
.SetColumns("id,username")
.Exec()
.Reader()) {
while (reader.Read()) {
Console.WriteLine("Member(id={0}, name='{1}')", reader[0], reader[1]);
}
}
}
Please send me your thoughts/concerns/nightmares.