Sort Only Works With directoryList() When ListInfo Is Query In Lucee 5.2.9.31
When calling the ColdFusion function, directoryList(), you have the option to sort the underlying data-structure by column (ex, "directory ASC"). With Adobe ColdFusion, this works regardless of the return type (listInfo). With Lucee CFML, on the other hand, the sort argument is only applied if the listInfo is "query." This divergence in behavior is called-out on the CFDocs.org site (thank you Shawn Grigson); however, since I ran into this problem yesterday and could not find any information about it via Google, I wanted to clearly articulate the problem for my future self.
To see this behavior in action, let's look at the following recursive directoryList() call:
paths = directoryList(
expandPath( "./demo" ),
true, // Recurse.
"path", // Return a list of full file-paths.
"*.txt",
"directory ASC, name ASC"
);
writeDump( removePathPrefix( paths ) );
// ------------------------------------------------------------------------------- //
// ------------------------------------------------------------------------------- //
/**
* I remove the long, common prefix for the paths so that the data is easier to
* visualize in the demo.
*
* @paths I am the collection of paths being simplified.
* @output false
*/
public array function removePathPrefix( required array paths ) {
var slimPaths = [];
for ( var path in paths ) {
arrayAppend(
slimPaths,
replace( path, "/Users/ben/Sites/bennadel.com/testing-commandbox/lucee-dir-list/", "/" )
);
}
return( slimPaths );
}
As you can see, we're gathering all the files in the "demo" directory, returning the list of "path" values, and then outputting them to the screen. And, here's a side-by-side comparison of the output in Adobe ColdFusion 10 and Luce CFML 5:
As you can see, the directoryList() function in Adobe ColdFusion adheres to the "sort" argument even when it's only returning the paths. Lucee CFML, on the other hand, ignores the "sort" argument altogether and returns the paths as a collection of opaque string values.
NOTE: If you replace the sort directives "ASC" with "DESC", the Lucee output does not change.
To get the directoryList() sort to work the same in both Adobe ColdFusion and Lucee CFML, you have to use the "query" return type (listInfo). When you use the "query" return type, Lucee will apply the correct "sort" to the data:
directoryInfo = directoryList(
expandPath( "./demo" ),
true, // Recurse.
"query", // Return data as a full query.
"*.txt",
"directory ASC, name ASC"
);
writeDump( extractPathsFromQuery( directoryInfo ) );
// ------------------------------------------------------------------------------- //
// ------------------------------------------------------------------------------- //
/**
* I extract the "slim path" from the given directory list query.
*
* @directoryInfo I am the directoryList() query being transformed.
* @output false
*/
public array function extractPathsFromQuery( required query directoryInfo ) {
var slimPaths = [];
for ( var record in directoryInfo ) {
var slimDirectory = replace(
record.directory,
"/Users/ben/Sites/bennadel.com/testing-commandbox/lucee-dir-list/",
"/"
);
arrayAppend(
slimPaths,
// The directoryList() query separates the directory value from the
// filename value. As such, we have to concatenate the two values in
// order to calculate a path that is similar to our last demo.
( slimDirectory & "/" & record.name )
);
}
return( slimPaths );
}
As you can see, we've changed the "type" from "path" to "query". This will get the directoryList() function to return a robust data-structure that contains individual columns for "directory" and "name". Therefore, to get back to the desired single path value, I am looping over the query and concatenating the two column values.
If we run this version, we get the following side-by-side comparison of Adobe ColdFusion 10 and Lucee CFML 5:
As you can see, by using a "listInfo" return type of "query", we get the directoryList() function to return the same values in Adobe ColdFusion and Lucee CFML.
As I said before, this compatibility issue is called-out in the CFDocs.org site. But, yesterday, when this issue started breaking code, I couldn't find anything in Google (searching for things like "lucee directorylist bug" and "lucee directorylist recursive sort"). As such, I just wanted to document the divergent behavior for the next time I get stuck and try to Google for the solution.
Want to use code from this post? Check out the license.
Reader Comments
Ben,
Another way to document it for your future self (and increase the chances of it being fixed altogether), is to open at ticket in the JIRA ;)
I went ahead and opened one for this issue:
https://luceeserver.atlassian.net/browse/LDEV-2152
I will look into it soon.
Best,
Igal
@Igal,
You are a good person -- thank you for doing that. I guess I was hesitant to open a ticket since it appeared to be documented, at least, on the
cfdocs.org
site. I just chalked it up to a difference that I didn't have on my radar. That said, I'm always for creating consistency!Thank you for your kind words, Ben.
In most cases we consider incompatibility with ACF to be a bug. This was more of an observation on cfdocs.org, rather than a documented behavior.
Anyway, I am happy to say that the issue is resolved for Lucee 5.3.2.41
https://luceeserver.atlassian.net/browse/LDEV-2152
We will need to discuss whether to port it back to older versions, as it would have a minor potential of breaking someone else's code on a version that is considered stable.
Best,
Igal
@Igal,
I love how fast Lucee moves and how great the Lucee community is and receptive to this kind of stuff. Really just blown away.
We are just about done with our Lucee conversion at work. It's time for me to sit down and really understand how I can leverage Lucee-specific code.
Thank you for writing this up. I couldn't figure out what the problem was.
@Sabrina,
Update to the latest 5.3.2.x or at least to Lucee 5.3.2.41 which resolves this issue.
Best,
Igal
@Ben,
That's great to hear!
Feel free to reach out if I can be of help, though it's best to contact me directly or at least in the Lucee forum so that I'll see it in a timely manner.
For some reason I got a notification of Sabrina's comment from today but not for yours from Feb 20th.
Best,
Igal
@Igal,
No worries at all. I've been loving Lucee! We've hit a few subtle bumps along the way. In fact, just yesterday, I ran into a difference in the way that Lucee handles empty lists in the
cfqueryparam
tag:www.bennadel.com/blog/3703-cfqueryparam-fails-silently-with-empty-lists-and-in-clauses-in-lucee-5-2-9-40.htm
... but, on balance, it's been awesome. Love the fat-arrow function syntax especially.
That's great to hear!
I, too, love the Labmdas. I actually posted about that recently on LinkedIn with a screenshot from my recent talk at ApacheCon: I Love Lucee!