Forum OpenACS Development: db_custom_list: v4 DB API extension

I'm writing a lot of procs where I want to return query results as lists, but they're not lists of a single field in the DB. Hand- coding lappends inside a db_foreach gets old after a while, so I wrote db_custom_list as an extension to the db API. It works for me, but I was hoping to get input on what I've overlooked in robustness.
proc_doc db_custom_list { statement_name sql tcl } { executes "tcl" within a db_foreach, and appends each result to the returned list example: db_custom_list authors_q $sql {[author_href $author_id $author]} } { return [eval "uplevel { set db_custom_list_list [list] db_foreach $statement_name "$sql" { lappend db_custom_list_list $tcl } set db_custom_list_list }"] }
(Using proc_doc since I'm actually using 3.2, whose ad_proc is different from 4.0's, but both have the same backwards-compatible proc_doc.)
Collapse
Posted by Ben Adida on
You missed db_list_of_lists, which is already part of the DB API
and which does exactly what you describe above....
Collapse
Posted by Jonathan Ellis on
Actually, db_list_of_lists doesn't do this. It just stuffs all the fields in a row into a list, and puts those lists into the resultant list. (I checked the code in case the description was misleading.) db_custom_list (hopefully) allows you to define what gets put in as a list element, whether it's a concatenation of the list fields or a function call based on them or anything else.

I've found one bug in the above code, which is that $tcl should be "$tcl". And also all the backslashes were taken out of my original post. Isn't this a long-standing bug?
Collapse
Posted by Jonathan Ellis on
Yeah, the backslashes around the italicized quotes above were present in the preview but not in what got stuffed in the DB.  So, just note that it should have backslashes before the quotes and brackets inside the uplevel.
Collapse
Posted by Ben Adida on
interesting, you've recreated the Lisp "map" command to some
degree. How often do you need to use this versus the
db_list_of_lists?
Collapse
Posted by Jonathan Ellis on
Since I am doing site development alone (for fun), and I hate writing html, I wrote a few utility function that e.g. spit out a simple table from a list.  So I use this fairly often since I usually don't want my list to consist of raw db fields and I run some other proc to prettify them before stuffing them in the list.

So I don't know how useful that would be in this day and age of templated sites but I like it.  It likely has other applications besides this but that's why I wrote it.

Collapse
Posted by Stephen . on
Couldn't this functionality be rolled into db_list? At the moment it just ignores everything but the first column, but it probably should lappend them all and create the flat list you're looking for.

Although it doesn't state so in the documentation db_multirow takes a tcl code block and an if_no_rows code block. The other db_* procs, like db_list, should be the same.

I think these code blocks are the proper place to escape html for the browser rather than the weird @varname;html@ syntax or whatever proposed for 4.3 (no sign...)