proc find_next { db_name t col } {
# This proc finds the next numerical value for a given column.
# This is most useful with an "ID" column, such as that in a
# users table where you want to reuse user IDs.
# This proc assumes there is an already open database connection named "dbs" (usually global).
# db_name: The name of the database in case there is more than one in the database file. Can be "".
# t: The table name
# col: The column to process
set val ""
if {$db_name ne ""} {
set sql "SELECT $col FROM $db_name.$t ORDER BY $col ASC"
} else {
set sql "SELECT $col FROM $t ORDER BY $col ASC"
}
if {[catch { set val [dbs eval $sql] }]} {
foreach l [split $::errorInfo \n] {
putlog "ERROR:trace - $l"
}
}
set items [llength $val]
set i 1
while {$i < $items} {
if {[expr [lindex $val $i] + 1] != [lindex $val [expr $i + 1]]} {
return [expr [lindex $val $i] + 1]
}
incr i
}
return [expr [lindex $val $i] + 1]
}
Assuming the table "domain" (in the database "main" which is in the sqlite file "test.db") has the following:
ID | Username
-------------
1 | Ranma
2 | Vadtec
5 | Betwix
7 | Nimrod
When I run the following:
set id [find_next "main" "domain" "id"]
putlog ">> id: $id"
I get:
>> id: 3
When I run the following:
set id [find_next "" "test" "id"]
putlog ">> id: $id"
I get:
>> id: 3
As you can see, the next available ID should be 3, which is returned by find_next in either case. This will work with attached databases as well so long as the proper database name is given for the first parameter to find_next.