Archive for January 6, 2006

Data Access Objects – The Revisit

My speel on the changes to the Partholan DAO layer. One of those self-review points I noted earlier.

I suppose one should point out what the DAO is. Data Access Objects and related Transfer (or Data) objects encapsulate all the code for handling Database Tables and Rows. If you’re familiar with Design Patterns you can probably contrast to the Data Access and Data Access Object patterns, or the related Table Data Gateway and Row Data Gateway patterns.

PHPPatterns.com probably sums up the intent very nicely.

Now the problem with linking Objects to Tables is matching – how do you match object properties to database fields, object methods to database reads/writes. The current method used by Quantum Star SE (via Partholan and GameEngine libraries) is to utilise ADOdb-Lite as Data Access (i.e. it actually executes any SQL statements) and to pre-define the Data Access Objects and Value Objects.

Its the pre-defining that leaves a sour taste in my mouth. Basically these do all the exact same thing, and even do almost the exact same SQL operations. So why am I even writting all these out by hand? There could possibly be dozens of these families, with others required for user modules and plugins perhaps. Will I have everyone draw these up by hand – a tedious and incredibly mind-numbing experience?

Since all these related DAO classes are almost identical (except for the Gateway classes which construct more complex SQL logic and conditionals) its possible to generate the lot dynamically using just the meta information for a database table. Now that meta info is already available – the database schema is defined in an AXMLS xml schema file. The generated files can then easily be cached, after a single instance parse/compile/generate cycle.

Plus the entire thing is re-usable!

Almost as nice even the files themselves could be reduced by half by streamlining the static fromArray() and public getArray() methods to use a simple get_object_vars() call. In time a mechanism for re-freshing the cached classes could be instated, and the whole system would work without the slightest developer interference.

Not getting too far ahead – its worth noting similar (and probably more expansive) alternatives exist – Propel to name just one. Plus some recent Zend Framework blog posts indicate an ActiveRecords module. The reason for something new in Partholan is the same reason for Partholan to exist in the first place – I rely on 3rd party libraries. So since I have no intention of rewriting ADOdb-Lite, or fiddling with adoSchema, or reworking the DB Facade class yet again, the fastest approach is to just add the extra functionality and be done with it – its not exactly a mind-boggling unit of work…

The End of the Header Injection

Injection, Splitting, whatever… It has a few terms associated.

Header Injections is a security exploit whereby a user can manipulate the headers outputted from an application. It’s not the most well known of exploit – overshadowed largely by XSS, SQL Injections and their ilk…but it does exist unfortunately so ignoring it is not an option.

Consider the following piece of PHP for instance.

header(‘Location: ‘ . $_GET['myurl']);

Any user can compose a url-encoded append to the GET variable to insert additional headers, which of course is not a good thing.

The good news for those either unaware of the exploit (and those with even) is the formal announcement of the change to the PHP header() function by Derrick Rethans – that PHP 4.4.2 now includes a limitation in the function to allow only one header to be sent via the function. Multiple headers will now require separate header() calls.

This may lead to some backwards compatibility breaks, but its a more secure behaviour.

Looking in from the Other End

It’s that time of year again – the babbling self-criticism of my own code. ;-)

The year gone out has not left much to self-review. QS2 is no longer with us, so any self-criticism today will not involve swearing profusely at the spahgetti mesh of Solar Empire code…

But there are a few critical areas identified in QS and Partholan. Hopefully I can resolve these over the coming month, and lets face it, QS-Evolved is far far easier to maintain than that…other version.

First up is Input Filtering and Validation. I hate it. It relies on several definition files, and validation is not automated in any way whatsoever. I’d prefer something a little more quick and easy than keeping each segregated – and its entirely possible with a superclass. The worst thing about all this is that there’s no standard API – just a bug blocky hand written array. It works – but its hardly user friendly.

Second: Templates. I had a grand idea once of language specific templates. Most of that is now defunct (a victim of changing assupmtions). So I’m left with designing a new internationalisation scheme (of some description). As a result my honest intentions have floundered and QS is still without a translation scheme. Its intolerable!

Third: That cursed DB class is still annoying me. Everytime I look at it I feel the driving need to rewrite it properly. Its one of the few classes still carried over from earlier QS3 drafts and its still using that error reporting hack-in from QS2. It shouldn’t be a huge job, the class is suppossed to be a simple wrapper for ADOdb-Lite that integrates Logging and Error Reporting, with a little performance and debugging code thrown in. Somehow I managed to avoid most of those requirements when editing it from Matt’s original. Its not evil – just needs more work.

Fourth: My data objects and base Data Access classes are too restrictive. I should probably have something that runs automatically on the database’s meta information for any table, with some caching, and auto-generation of the data objects. I’ve already drawn up a DataObjectGenerator that is basic but useful – I’m not building a Framework institution here so anything simple and fast will work. I have a few ideas here – and its been done lots of times in the past for PHP so probably no need to re-invent wheels.

Fifth: This may be an issue at some stage (personally I’m not too worried but people will notice). One of the side-effects of my design are a large number of includes. And bound to grow too. Also the method of inclusion is a little ad-hoc. Not sure there’s much to do since the layout is perfectly logical and very re-useable. I’ll probably be stuck with it unless some unimaginable inspiration strikes…

Sixth: The Data Access layer ignores any potential use of sql JOINs. This could get nasty… But for the moment it makes the code more segregated, and by effect easier to maintain and work with in isolation from other work units.

Seventh: There’s a bug I haven’t yet been able to replicate. Appears to escape all incoming SQL statements parsed from the ADO XML install file for the database schema. Persistence will pay off one way or the other…

Eighth: We’ve proven SSL certainly does not work with QS just yet. That should have been resolved by now given that some folk are certainly testing on that environment.

These are some of the more irate points I came up with. ;-) With these resolved I’ll feel a bit happier, and more comfortable with how everything is now working. That said many of these are design issues, the functional side of the application is so far not showing any major issues. Everything works as it should, we are completely compatible with MySQL and PostgreSQL (all versions), and PHP5.1 or lower. Something I need to do at some stage is stress test and figure out where the performance bottlenexks are located.