New DataFaucet ORM Build Nov 2

Aaargh!

So after having had a really unusual amount of trouble related to the recent changes leading up to the addition of the iterator, I had declared after releasing the iterator CFC that there shouldn't be any new builds for a while. Not that there aren't things to work on, there certainly are planned enhancements. For example right now reinstalling an active record object won't update any columns with modified data types, nor will it prepopulate an existing table with the default value for a new column. Both of those are planned for a future release...

What I hadn't expected however was a FREAKING TYPO in the active record object. Same place. Easy fix, regardless of your relative skill level, because the CF server tells you that "aguments.objectid" is undefined. I'm really surprised by this one actually, because I was pretty certain I'd tested that... but I guess I must have been experiencing source monitoring failure (a false memory) as often happens with the tasks we perform frequently. Of course TDD won't prevent this, because the more often you run your tests, the more likely you are to remember running them successfully when the reality is that you haven't run them.

And oddly enough even though I thought I had tested it, I was also doing a bunch of work with other code that uses the active record and that didn't show this problem either apparently because the only place where I was calling read() with the argument apparently I was also trapping and ignoring errors. Which meant that even though the member plugin for the onTap framework was installing, it was omitting insertions for a number of db records it needed and the security system was just generally not working because it wasn't loading the role and permission records correctly. Oops!

Now that's where TDD would have helped. If I'd had a set of regression tests set up for the member plugin and for DF, I could have run them and seen right away where the problem was, rather than having to go through all that troubleshooting. ;)

Ahh well, it gave me an excuse to enhance the member plugin a little more anyway and set it up to upgrade DF during installation. :)

New Build - Oct 27

I actually need to apologize for yesterday's build. I had made a change to the active record object so that it would clear its properties if you performed a read with a new ID, so for example:

<cfset ar = ds.getActiveRecord("my.record").init() />

<cfset ar.read(1) />
... do other stuff ...

<cfset ar.read(2) />
... do more stuff ...

The idea is that by clearing the properties when 2 is read in this example, you're less likely to get any bleed through of the data from the previous record, from properties that might be lazy-loaded where it doesn't fetch or create the property until the property is requested.

What happened is that I poorly implemented the change and it ended up resetting the properties and then attempting to read in new data from the db but after having reset itself it no longer had an ID to know which record to fetch. Oops!

So when I noticed that this morning I immediately fixed it and uploaded a new build for today.

Nice Surprise

Wow. I think there were actually 10 new downloads today right after the CF Meetup presentation earlier.

I think that's about 2/3rds of the people who attended.

I'm really flattered. :) When I've given presentations to other CFUG groups in the past there's not usually an immediate uptake like that - there's maybe a gradual stream of people downloading it... And I think that's even after having forgotten to give people the URL, so I guess either they assumed it was datafaucet.com or they googled it, but either way they went straight to download it after seeing today's presentation. That's really encouraging! :)

I need to get back to working on the handful of things I need to add and fix though, because I showed a couple of things in the presentation about sequences that are fixed in SVN but not in the latest download distribution yet. :) Hopefully there will be a new release in the next couple days with those changes.

New DataFaucet ORM Build - Oct 13

I just pushed a new release of the DataFaucet core up to the RIAForge server. This release adds a columnMap CFC to resolve some previous issues with the new active-record features for stripping underscores from column names. In the long run I've come to think these features aren't really worth the amount of complexity and/or maintenance involved in adding them.

This release also includes the addition of a schemaExport CFC for exporting the table definitions from your existing database to the XML format used for creating new tables in another database. While this may be useful in copying tables from one database to another, the primary reason for adding this feature is to allow for the schema-diff tool which now powers the active record install method. What this means is that an active record object which could previously install its own database tables can now add new columns to existing tables using the same install() method. The install method exports the existing schema from the database and then uses XSLT to perform a diff between the installed schema in the database and the schema declared in the active record object. Any new tables or columns declared will be added while leaving the existing tables and columns in place. This will make writing software upgrades much easier. :)

Support for foreign keys is still limited but I expect it will be improved in a later version. Right now foreign keys can be added when adding a new column, but if you need to drop them or add them to existing columns, you'll have to perform those operations manually with a separate DDL packet.

The new schemaExport features also still need to be documented. I usually try and add some documentation whenever I add a new feature, but haven't gotten to doing that for this one yet.

Quick Fixes reported by Gabe Roffman

Got a couple of emails this morning from Gabriel Roffman. Some of you may recognize him as being one of the creators of the first iteration of Fusebox. In any event he sent me a couple of emails this morning to mention a couple of issues he was having with DataFaucet.

  • Caching Docs: He couldn't find the documentation for caching. The latest version of DataFaucet today doesn't include any object caching (Transfer does this), however it has always supported Query caching. Documentation for query caching is located in the "select" page, so I've added a couple of links to the menu for the additional items on that page.
  • Confusing Errors: Apparently there was an issue with fetching custom objects from the datasource. If you had an active record for example that you'd placed in /com/mycompany/product.cfc with a syntax error in it, then requesting that object from the datasource via ds.getActiveRecord(className="com.mycompany.product") would result in an error message saying "unable to locate object for COM.MYCOMPANY.PRODUCT". This was confusing of course because the path was correct and it obscured the actual syntax error. So I've resolved this issue in the framework's kernel object.

Thanks Gabe! :)

MySQL

Just uploaded a new revision of the ORM that resolves an issue with MySQL. Apparently even though it wasn't throwing any errors, MySQL wasn't creating foreign key constraints when they're put on the column line in a create table statement... I can understand (I guess) not supporting a particular standard syntax -- what I find odd is that the MySQL server chooses to just ignore the unsupported syntax in this case rather than produce an error that says "I don't understand this syntax!"

Here's a tutorial that mentions the syntax that's needed for MySQL. So the MySQL agent now generates create table statements using this syntax and correctly installs the desired foreign key constraints.

I discovered this actually because someone informed me they were having difficulty installing the Members onTap plugin. This is a plugin for the onTap framework that handles member management and security with a bunch of extras like geographic regions, optional OpenID support for those who want it and an event log with undo/redo features. MySQL was throwing an odd error... "Error Executing Database Query. You can't specify target table 'tap_regionTREE' for update in FROM clause". Why not? If there's one thing I love, it's helpful error messages... this isn't one of them.

It turns out that MySQL can't support any kind of recursion in subqueries. So this works:

update mytable set ...
where id in (select id from othertable)

But this throws the above mentioned error:

update mytable set ...
where id in (select id from mytable)

I had rather assumed this was pretty basic stuff... After all, it's the well established conventional behavior of all programming languages that I know of to process an inner before an outer item. For example, in ColdFusion (as in any language), you might have:

doSomething(a(),b())

And the server will process a() then b() and only *after* both of those have been processed will it process doSomething(a,b), where a and b are the results from the respective functions.

Apparently that's not the case with MySQL because it throws this error if it sees the same table twice... Except the error doesn't tell you that's the reason why it's being thrown. It doesn't mention anything at all about the fact that there's a subquery or the fact that the table appears twice or that there's recursion involved, any of which might threaten to tip you off to the reason for the error.

If you read the text of the error, it appears to be saying "you can't update this table". The closest it comes to hinting at the real problem is its use of the phrase "from clause" which is at best confusing.

So anyway, if you ever see this error message, now you'll know what it means. :)

I had to refactor the nested set for regions in the member plugin so that instead of using a subquery it executes each of those queries and uses a valuelist from them. Which means three trips to the database instead of one. I'm not happy about that, but apparently I don't have much say in the matter. The good news is that regardless of the application, regions won't be modified very often and it won't be a big issue if editing them is a tad sluggish. So even though I may not be very happy about needing to change it this way, it's more of a philosophical pain than a pragmatic issue. It's not going to be a deal-breaker for people using the software. :)

BlogCFC was created by Raymond Camden. This blog is running version 5.5.006.