Right or wrong I normally leave that kind of work up to the database rather
than caching it in memory.
I wonder how it would work to write a sql-based database in memory for cache
handling.
Something like:
ns_db cache $postgres "select * from postgresql" to $ram
ns_db select $ram "select * from ram_cache_table where x=1"
ns_db dml $ram "update ram_cache_table set order='sent'"
ns_db flush_cache $ram $db
or something.
Anyhow, here's the caching scheme I came up with tonight.
It uses parallel lists for columns so that you can use lsearch to locate a
specific row.
# procedure
proc vt_cache_query {db sql args} {
set selection [ns_db select $db $sql]
set varprefix {dbcache}
if {[llength $args] > 0} {
set varprefix [lindex $args 0]
}
uplevel "set ${varprefix}_field_names \[list \]"
set first_run 0
while {[ns_db getrow $db $selection]} {
set col_counter_i 0
set col_limit [ns_set size $selection]
while {$col_counter_i < $col_limit} {
uplevel "lappend ${varprefix}_[ns_set key $selection
$col_counter_i] \{[ns_set value $selection $col_counter_i]\}"
if {$first_run == 0} {
uplevel "lappend \"${varprefix}_field_names\"
\{[ns_set key $selection $col_counter_i]\}"
}
incr col_counter_i
}
incr first_run
}
}
# sample code
set db [ns_db gethandle]
vt_cache_query $db "select * from users" users
set current_row [lsearch $users_user_id 3]
foreach item ${users_field_names} {
ns_write "$item = [lindex [set users_${item}] $current_row ]<br>"
}
ns_write "[lindex $users_first_names $current_row] [lindex $users_last_name
$current_row]"
On Friday 17 January 2003 09:19 pm, Peter M. Jansson wrote:
> I got this...
>
> On Fri, 17 Jan 2003, Dossy wrote:
> > Generally, when I find myself needing things like, say, a list of
> > arrays, in Tcl, they tend to be design smells. It's the "I can write
> > Perl in any language!" syndrome.
>
> ....and this:
>
> On Fri, 17 Jan 2003, Brett Schwarz wrote:
> > I am just curious, can you give an example of something that is giving
> > you a hard time?
>
> OK. When I'm building a substantial app, there's a lot of data floating
> around. When I'm pulling data out of the database, I often will have
> something where I have a brand that has customers that have orders that
> have line items, and I want to store those. I think managing complexity
> by abstracting the data is good programming practice. When I've done this
> in the 7.x-era Tcl, I've done it by using an array with specially-crafted
> indices, and using wrapper functions so I can do things like "set orders
> [customers orders $customer_id]" and get a list of order IDs. But I find
> my array implementations to be kludgy (more a defect of the class of
> solutions, rather than the particular implementation), so I'm always
> looking for something better. Also, I want to do a lot of the persistence
> work only once, so I want routines that pull records from the database
> based on criteria I specify, and carry them in a cache, and then notice
> when I modify the records so I can then do a "cache commit" to do all the
> updates. And I want to write those routines to be generic, so I don't
> have to rewrite them again for each database table. (I really did this for
> one project, and it mostly worked, but it was fragile.) Recently, I've
> gotten to do some work in WebObjects, which has a lot of this done, but in
> Java, and I still find value in the Tcl/AOLserver approach, so I'm looking
> to apply some of these ideas in Tcl, but the data structures as I knew
> them felt too constraining. I think the 8.4 list implementation is a step
> in the right direction; I don't know if it's really what I'm looking for,
> but I think it will be cleaner (and probably faster, given the
> implementation differences between arrays and lists) than the array
> implementation I've done.
>
> Pete.