All pastes #469307 Raw Edit

Vadtec

public text v1 · immutable
·published 2007-05-03 17:29 UTC
rendered paste body
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.