20 March 2009

Ressurection : xSiteable Framework

I've just started in my new job (yes, more on that later, I know, I know) and was flipping through a lot of my old projects over the years, big and small, and I was looking for some old Information Architecture / prototyping tool / website generator application I made with some help from IA superstar Donna Spencer (nee Maurer) back when I lived in Canberra, Australia.

I found three generations of the xSiteable project. Generation 1 is the one a lot of people have found online and used, the XSLT framework for generating Topic Maps based websites. I meant to continue with generation 2, the xSiteable Publishing Framework (which runs the Topic Maps-based National Treasures website for the National Library of Australia) but never got around to polishing it enough for publication, and before I came to my senses I was way into developing generation 3, which I now call the xSiteable Framework (which sports a full REST stack, Topic Maps. And yes, I'm still too lazy to polish it enough for publication (which includes writing tons of documentation), at least as of now, but I showed this latest incarnation to a friend lately, and he said I had to write something about it. Well, specifically how my object model is set up, because it's quite different from the normal way to deal with OO paradigms.

First of all, PHP is dynamic, and has some cool "magic" functions in the OO model which one can use for funky stuff. Instead of just extending the normal stuff with some extras I've gone and embraced it completely, and changed my programming paradigms and conventions at the same time. Let's just jump in with some example code;
// Check (and fetch) all users with a given email
$usercheck = $this->database->users->_find ( 'email', 'lucky@bingo.com' ) ;
Tables are are contextually defined in databases, so $this->database->users points directly to the 'users' table in the database. (Well, they're not really table names, but for this example it works that way) The framework checks all levels of granularity, and will always return FALSE or the part-object of which you want, so for example ;
// Get the domain of a users email address
$domain = $this->database->users->ajohanne->email->__after ( '@' ) ;
Again, it's like a tree-structure of data, a stream of granularity to get in and out of the data. This does require you to know the schema (and change the code if you change the schema), but apart from that, in a stable environment, this really is helpfull (it's also cached, so it's really fast, too).

You might also have noticed ... users->ajohanne->email .... Where did that "ajohanne" bit come from? Well, as things are designed, again the framework will try to find stuff that isn't already found, so "ajohanne" it will automatically look up in designated fields. All objects that extend the framework have two very important fields, one being the integer primary identifier, the second one the qualified unique name (so not a normal name as such, but a most often a computer generated one that isn't normally a number. Often systems will use things like a username, say, as a qualified name, and hence "ajohanne" was my username in one such system). Why do this?

Well, PHP is dynamic, so in my static example above, explicitly using 'ajohanne' as part of the query, isn't the best way to go in more flexible systems, but just pop your found user in dynamically instead;
$domain = $this->database->users->$username->email->__after ( '@' ) ;
Easy. And this applies to all parts of the tree, so this works as well ;
$domain = $this->database->$some_table->$some_id->$some_field->__after ( '@' ) ;
No, from the two examples above we might see a different pattern, too. All data parts has unrestrained names, all query operations use an underscore, and all string operations uses two underlines. (__after is a shortcut for substr ($str, strpos ( $str, $pattern ) ), and I've got a heap of little helpers like this built in ) Through this I always know what the type of the object interface is, and with PHP magic functions these types are easy to pull down and react to. As some of my objects are extendable, I need to pass _* and __* functionality up and down the object tree.

Traditionally, we use getters and setters ;
$u = $obj->getUsername() ;
$obj->setUsername ( $u ) ;
I turn them all into properties, so ;
$u = $obj->username ;
$obj->username = $u ;
But they are still full internal functions to the object, and this is another magic function in PHP ;
class obj extends xs_SimpleObject {
function getUsername () {
...
}
function setUsername ( $value ) {
...
}
}
The framework isn't just about object persistence. In fact, it is not about that. I hate ORMs in the sense that they still drag your OO applications back into the relational database stoneage with some sugar on top. In fact what I've done is to implement a TMRM model in a relational database layer, so it's a generic meta model (Topic Maps) driving that backend and not tables, table names, lookup tables, and all that mess. In fact, crazy as it sounds, there's only four tables in the whole darn thing. I'm relying on backend RDBM systems to be good at what they should be good at; clever indeces, and easier joins in a recursive environment (which, when all data is in the one table, it indeed is recursive), where systems use filters to derive joins instead of doing complex cross-operations (which takes lots of time and resources to pull off, and is the main bottleneck in pretty much any application ever created which has a database backend.

A long time ago I thought that the link between persistent URI's for identity management in Topic Maps and the URI (and using links as application state) in REST were made for eachother, and I wanted to try it out. In fact, that fact alone was the very inspiration for me to do the 3rd generation of xSiteable, hacking out code that basically has one URI for every part of the Topic Map, for every part of the TM API, and for other parts of your application. Here's some sample URIs ;
http://mysite.com/prospect/12
http://mysite.com/api/tm/topics/of_type:booking
http://mysite.com/admin/db/prospects
At each of these there are GET, PUT, POST and DELETE options, so when I create a new prospect, it's a POST to http://mysite.com/prospect or a direct PUT to http://mysite.com/prospect/[new_id], for example.

All in all, this means I have many ways into the system and its data, none of them more correct than the other as they all resolve to topics in the topic map. This lowers the need for error checking greatly, and the application is more like a huge proxy for a Topic Map with a REST interface. It's a cute and very effective way of doing it. I'm trying various scaling tests, and with the latest Topic Maps distribution protocols that I can use for distributing the map across any cluster, it's looking really sexy (although I still have some work to do in this area, but the basics rock!).

Anyway, there's a quick intro. I guess I should follow this up with some more coded details of examples. Yeah, maybe next week, as I need to get some other stuff done now, but I like the object model I've got in place, and it's so easy to work with without losing the need for complex stuff. Take care.

13 March 2009

And so a new era begins

Well, yeah, it would be easy to think my headline had anything to do with changing my life, move to the other side of the planet, new job under new circumstances doing new and kick-ass things (more on all this later), but no, this is about how I wanted to "just have a look" at something which buggered my computer up, and how it changed things for the better.

So, many eons ago, I was a Linux hacker. Well, not a true hacker, but I used to adminster a Red Hat box and create some custom programs in C++. Hmm, must have been, like, about 15 years ago, as part of my civil service (military service is mandatory in Norway, which didn't fit well with my non-violent ideals) which was at the same time I ventured into the Internet as well. So, a long, long time ago, in a place I'd rather just forget about, I fiddled and meddled in the dark arts of software computing. I've always stayed in contact with Linux, but my main OS from that time on has always been in various evil Windows incarnations.

Last week I bought a new computer, a slick Toshiba Satellite P300, that came with Windows Vista. Ugh. I had big reservations against Vista, but I was in a hurry, and thought to myself that surely, it can't be that bad, right?

Well, it was. Slow, sluggish, confusing, and I seemed to have little or no control over who went online to download anything they felt like. I thought, in a quiet moment while the internet connection was bogged down by the virus program or the updater or some other bloody download I couldn't figure out, that perhaps I should finally check out my good old friend, Linux, to see what he was up to these days. I went to the distro I know has got a good load of feedback, Ubuntu, downloaded an ISO (Gutsy Gibbon, 7.10) and burned myself a CD. I popped it in, and without thinking too clearly installed it using the automatic partitioning tool.

It's that tool that made a boo-boo of sorts, and managed to wreck my Windows install; I couldn't boot into it anymore, no matter how much I tried to fix it (I've got a bit of partitioning and formatting experience through the years, luckily). So I was more or less forced to have a deep look at it to see if it could do the things I need to do.

First, the whole install took no time at all. Vista felt like an eternity with multiple restarts (over 50 minutes on my laptop), Ubuntu just copied files over, did some juggeling, and one restart (about 20 minutes). Nice.

Secondly, the Gnome desktop environment is great. I installed some extra Compiz stuff as well, and I'm quite blown away with the options, effects and stuff you can do. The standard applications and tools is more than enough for most things, perhaps with the exception of something for all the web developers out there, but that brings me to the next point;

Installing Apache2, PHP5 and MySQL/SQLite was amazingly easy, even with the extensions I need, just "sudo apt-get" a few packages, and the rest is done for you. Locate the config files in /etc/apache2 and /etc/php5, and I was done in 5 minutes, including setting up a few projects that I work on that simply Just Worked (TM) straight out of the box. I was never able to get this right so fast on Windows, and yet here it was almost too easy. I'm very impressed.

Same with NetBeans, Ruby, Python, Firefox and extensions, it all just is find the file for the packager (based on the Debian packager) and the rest is easy. The selection of software is very good, and I've been using my system as a professional for a couple of weeks without a single hitch. It's found all my hardware as well, except perhaps my Lexmark 7600 series Wireless printer (which I haven't really seriously tried to install yet, only poked around) and some glitches with hibernate and suspend (but given the time it takes for this baby to properly close and boot up again, I'm not really saving much time trying to hibernate anyways).

All in all, my first impressions are really positive, and I'm glad I had an install glitch; I love my new Ubuntu, and I can't wait to get more serious about it and Linux again. I think I've made the permanent switch.

4 March 2009

Want to feel like a second-class citizen?

Want to feel like a second-class citizen? Easy; move to a small town down the coast of Australia, and work from home with Internet-stuff for a company abroad, and feel the small-town "injernett-whatsi-bobby" pull-the-other-one mindset as you try to just rent a house to live in.

What fun this was. I can't show "payslips" as the company exists in "the injernett", a mythical place where no paper exists, and if there's no paper, there's no traversal of real things that will satisfy real-estate agents. No matter how I tell it or what I write or how I document (even my friggin' contract wasn't good enough because it was just printed off my printer! Unlike their shit?!), unless I'm a bloody janitor or pool-cleaner who gets cash in hand and gives people little receipts it seems I can't get a house around here.

I think this crash between old and new ways of earning a living is biting my bum right now. Anyone with a clue who could help out? (If you got property here you rent out and read this by accident, could you notify your real-estate agents that they truly suck? Thanks) We're in Kiama just south of Wollongong (my wife is from here, and she did indeed warn me of their backwards ways) but I foresee we will have to move elsewhere unless something comes up pretty soon.

Apart from that, things are going great, but more on that later after this silliness is sorted.