Sunday, 1 March 2015

CFML: data connection objects instead of data sources

G'day:
A thread on the Lucee forums got me thinking about this: "Messaging Service Concept for Lucee.next". That in itself is an excellent idea, but my mind went off on a tangent whilst I was forming an opinion on it.

Data Connection Objects

First things first, I like how on a CFML server one can pre-roll a data connection at server or app level, then just use a reference to it thereafter. However for quite a while I've not been that convinced that a "data source" represented simply by a string label one uses to identify a connection is the best approach. This makes sense when using tag-based code because string values for tag attributes fit nicely, but with modern code, having to pass a string label to a function seems quite jerry-built to me.

What I was more thinking is shouldn't a data connection be an object? I mean... CFML is an OO language after all. But it seems sometimes the language itself isn't implemented in a very OO way.

What I see is something more like this:

myDataConnection = new MySqlDataConnection(args);

MySqlDataConnection would extend a general DataConnection class, and the CFML engine would ship with all the usual suspects like SqlServerDataConnection, OracleDataConnection etc. These map to the corresponding DSN types one might set in the admin.

Then:

myRecords = myDataConnection.query(sqlString, options, etc);

(same with other operations such as .executeProcedure(), .info(), .insert(), .update() etc).

This sits better with me that this sort of thing:

myRecords = queryExecute(sqlString, {datasource=myDataSource, etc});

I hasten to add I don't think there's much in it, but I think it would help our OO code look more uniformly OO, than having to chop back and forth between dev-written OO code, and CFML's mostly procedural code).

This still works with tag-based code:

<cfquery connection="#myDataConnection#" name="myRecords">
    <!--- etc --->
</cfquery>

Although obviously this is not any better than a string label in this situation.

This also facilitates implementing one's own DataConnection classes which can be similarly used to connect to data repositories that aren't natively supported by the CFML engine. Or to replace the likes of <cfldap> and <cfdirectory> etc which fetch records from a "data repository", but have their own interfaces currently.

Messaging Service Objects

Then we come to this new suggestion of messaging services. The current suggestion is to implement them the same as data sources, but I think this too would be a sitter for having a messaging service object rather than a string label. And what the CFML engine provides is a default implementation, and the interface to adhere to when implementing bespoke messaging services.

This improves CFML's OO, rather than bolting more procedural stuff to it. One of the suggested examples is this:

sendMessage(messagesource="mandrill2", subject="", message="", etc="");

I would instead suggest this:

mandrill2.send(subject="", message="", etc="");

Caching Services

There's also another feature request discussion going on on the Lucee forums as well at the moment, around how to deal with a "cluster scope" ("Clustering the Application Scope"). The original idea was to have some sort of behavioural modification to the application scope, or have a "magic" section of the application scope that behaves differently than the rest of the application scope. Those don't sound like great approaches.

The pain point here is to share data effectively between Lucee instances. This is well-trod ground with third party tooling like MemCached, Ehcache (or even just databases!). I don't think it needs special or magical behaviour.

But it's probably another example taking a more OO approach to things might be good: having the notion of a CacheServiceConnection (or something), which has a uniform interface - to facilitate third-party implementations - and that Lucee just ships with one buit-in wrapper to a caching engine of their choice. From there Lucee writes an RFC sort of document which defines how the interface behaves, and what the expectations of the methods are so that third-parties know how to write implementations that are swappable with the default or other implementations.



This is a bit of an odd article as it talks about data connections instead of data source labels, and then using that as a rationale for messaging connections. And now I've just updated it to include this caching service requirement too. However it's just what I was thinking about a more general and modern (and code-centric) approach to these things we do with CFML. Coincidentally my suggestion for two enhancement requests doing the rounds at the moment take a different approach to what's being suggested, but my suggestion is similar for both of them.

It's also Sunday afternoon and I'm mostly watching the cricket (England v Sri Lanka... its looking good for Sri Lanka at the moment, I think: 168-1 chasing 310, and 20 overs to go. A coupla wickets could change all this, that said).

Anyway, thoughts on data connection objects, messaging service objects, caching services etc? Maybe you can help pad out a more thoroughly considered solution. Or just say "shit article today, Cameron". Shrug.

--
Adam