[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [OSSTEST PATCH 5/7] Database locking: Tcl: for errorCode, use pg_exec, not pg_execute
We would like to be able to retry db transactions. To do this we need to know why they failed (if they did). But pg_execute does not set errorCode. (This is clearly a bug.) And since it immediately discards a failed statement, any error information has been lost by the time pg_execute returns. So, instead, use pg_exec, and manually mess about with fishing suitable information out of a failed statement handle, and generating an appropriate errorCode. There are no current consumers of this errorCode: that will come in a moment. A wrinkle is that as a result it is no longer possible to use db-execute on a SELECT statement nor db-execute-array on a non-SELECT statement. This is because the 1. the `ok' status that we have to check for is different for statements which are commands and ones which return tupes and 2. we need to fish a different return value out of the statement handle (-cmdTuples vs -numTuples). But all uses in the codebase are now fine for this distinction. Signed-off-by: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx> --- tcl/JobDB-Executive.tcl | 54 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 3 deletions(-) diff --git a/tcl/JobDB-Executive.tcl b/tcl/JobDB-Executive.tcl index bbce6fc..ed9abbb 100644 --- a/tcl/JobDB-Executive.tcl +++ b/tcl/JobDB-Executive.tcl @@ -121,13 +121,61 @@ proc db-execute-debug {stmt} { puts stderr "EXECUTING >$stmt<" } } + +proc db--exec-check {shvar stmt expected_status body} { + # pg_execute does not set errorCode and it throws away the + # statement handle so we can't get the error out. So + # use pg_exec, as wrapped up here. + + # db--exec-check executes stmt and checks that the status is + # `expected_status'. If OK, executes body with $shvar set to the + # stmt handle. Otherwise throws with errorCode + # {OSSTEST-PSQL <pg-status> <pg-sqlstate>} + + global errorInfo errorCode + upvar 1 $shvar sh + + set sh [pg_exec dbh $stmt] + + set rc [catch { + set status [pg_result $sh -status] + if {[string compare $status $expected_status]} { + set emsg [pg_result $sh -error] + set sqlstate [pg_result $sh -error sqlstate] + if {![string length $emsg]} { + set emsg "osstest expected status $expected_status got $status" + } + set context [pg_result $sh -error context] + error $emsg \ + " while executing SQL\n$stmt\n in SQL context\n$context" \ + [list OSSTEST-PSQL $status $sqlstate] + } + uplevel 1 $body + } emsg] + + set ei $errorInfo + set ec $errorCode + catch { pg_result $sh -clear } + + return -code $rc -errorinfo $ei -errorcode $ec $emsg +} + proc db-execute {stmt} { db-execute-debug $stmt - uplevel 1 [list pg_execute dbh $stmt] + db--exec-check sh $stmt PGRES_COMMAND_OK { + return [pg_result $sh -cmdTuples] + } } -proc db-execute-array {arrayvar stmt args} { +proc db-execute-array {arrayvar stmt {body {}}} { db-execute-debug $stmt - uplevel 1 [list pg_execute -array $arrayvar dbh $stmt] $args + db--exec-check sh $stmt PGRES_TUPLES_OK { + set nrows [pg_result $sh -numTuples] + for {set row 0} {$row < $nrows} {incr row} { + uplevel 1 [list pg_result $sh -tupleArray $row $arrayvar] + uplevel 1 $body + } + return $nrows + } } proc lock-tables {tables} { -- 1.7.10.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |