Index: ChangeLog =================================================================== RCS file: /cvsroot/tcllib/tcllib/modules/struct/ChangeLog,v retrieving revision 1.64 diff -u -w -u -r1.64 ChangeLog --- ChangeLog 16 May 2003 21:47:50 -0000 1.64 +++ ChangeLog 21 May 2003 05:31:42 -0000 @@ -1,3 +1,12 @@ +2003-05-20 Andreas Kupries + + * list.man: + * list.tcl (dbJoin(Keyed)): Extended the commands with an option + -keys. Argument is the name of a variable to store the actual + list of keys into, independent of the output table. As the + latter may not contain all the keys, depending on how and where + key columns are present or not. + 2003-05-16 Andreas Kupries * Extension of the package functionality warrants version bump to 1.4. Index: list.tcl =================================================================== RCS file: /cvsroot/tcllib/tcllib/modules/struct/list.tcl,v retrieving revision 1.6 diff -u -w -u -r1.6 list.tcl --- list.tcl 16 May 2003 21:47:50 -0000 1.6 +++ list.tcl 21 May 2003 05:31:43 -0000 @@ -21,7 +21,7 @@ namespace eval ::struct::list { namespace export list - if 0 { + if {0} { # Possibly in the future. namespace export LlongestCommonSubsequence namespace export LlongestCommonSubsequence2 @@ -777,12 +777,18 @@ # Process options ... set mode inner + set keyvar {} + while {[llength $args]} { - set err [::cmdline::getopt args {inner left right full} opt arg] + set err [::cmdline::getopt args {inner left right full keys.arg} opt arg] if {$err == 1} { + if {[string equal $opt keys]} { + set keyvar $arg + } else { set mode $opt + } } elseif {$err < 0} { - return -code error "wrong#args: dbJoin ?-inner|-left|-right|-full? \{key table\}..." + return -code error "wrong#args: dbJoin ?-inner|-left|-right|-full? ?-keys varname? \{key table\}..." } else { # Non-option argument found, stop processing. break @@ -831,6 +837,11 @@ if {$inner && ([llength $keylist] == 0)} {return {}} } + if {[string length $keyvar]} { + upvar 1 $keyvar keys + set keys $keylist + } + return [MapToTable state $keylist] } @@ -839,10 +850,16 @@ # Process options ... set mode inner + set keyvar {} + while {[llength $args]} { - set err [::cmdline::getopt args {inner left right full} opt arg] + set err [::cmdline::getopt args {inner left right full keys.arg} opt arg] if {$err == 1} { + if {[string equal $opt keys]} { + set keyvar $arg + } else { set mode $opt + } } elseif {$err < 0} { return -code error "wrong#args: dbJoin ?-inner|-left|-right|-full? table..." } else { @@ -891,6 +908,11 @@ if {$inner && ([llength $keylist] == 0)} {return {}} } + if {[string length $keyvar]} { + upvar 1 $keyvar keys + set keys $keylist + } + return [MapToTable state $keylist] } @@ -1103,11 +1125,11 @@ upvar $mapvar map $wvar width set width [llength [lindex [lindex $table 0] 1]] foreach row $table { - foreach {keyval row} $row break + foreach {keyval rowdata} $row break if {[info exists map($keyval)]} { - lappend map($keyval) $row + lappend map($keyval) $rowdata } else { - set map($keyval) [::list $row] + set map($keyval) [::list $rowdata] } } return [array names map] @@ -1120,12 +1142,12 @@ # Phase I - Find all keys in the second table matching keys in the # first. Remember all their rows. foreach row $table { - foreach {keyval row} $row break + foreach {keyval rowdata} $row break if {[info exists map($keyval)]} { if {[info exists used($keyval)]} { - lappend used($keyval) $row + lappend used($keyval) $rowdata } else { - set used($keyval) [::list $row] + set used($keyval) [::list $rowdata] } } ; # else: Nothing to do for missing keys. } @@ -1153,11 +1175,11 @@ set w [llength [lindex $table 0]] foreach row $table { - foreach {keyval row} $row break + foreach {keyval rowdata} $row break if {[info exists used($keyval)]} { - lappend used($keyval) $row + lappend used($keyval) $rowdata } else { - set used($keyval) [::list $row] + set used($keyval) [::list $rowdata] } } @@ -1197,12 +1219,12 @@ # first. Remember all their rows. set w [llength [lindex $table 0]] foreach row $table { - foreach {keyval row} $row break + foreach {keyval rowdata} $row break if {[info exists map($keyval)]} { if {[info exists used($keyval)]} { - lappend used($keyval) $row + lappend used($keyval) $rowdata } else { - set used($keyval) [::list $row] + set used($keyval) [::list $rowdata] } } ; # else: Nothing to do for missing keys. } @@ -1231,12 +1253,12 @@ set w [llength [lindex $table 0]] foreach row $table { - foreach {keyval row} $row break + foreach {keyval rowdata} $row break if {[info exists used($keyval)]} { - lappend used($keyval) $row + lappend used($keyval) $rowdata } else { lappend keylist $keyval - set used($keyval) [::list $row] + set used($keyval) [::list $rowdata] } } Index: struct_list.man =================================================================== RCS file: /cvsroot/tcllib/tcllib/modules/struct/struct_list.man,v retrieving revision 1.3 diff -u -w -u -r1.3 struct_list.man --- struct_list.man 16 May 2003 21:47:50 -0000 1.3 +++ struct_list.man 21 May 2003 05:31:44 -0000 @@ -412,7 +412,7 @@ }] -[call [cmd ::struct::list] [method dbJoin] [opt [option -inner]|[option -left]|[option -right]|[option -full]] \{[arg keycol] [arg table]\}...] +[call [cmd ::struct::list] [method dbJoin] [opt [option -inner]|[option -left]|[option -right]|[option -full]] [opt "[option -keys] [arg varname]"] \{[arg keycol] [arg table]\}...] The method performs a table join according to relational algebra. The execution of any of the possible outer join operation is triggered by @@ -424,6 +424,16 @@ [nl] +If the [option -keys] is present its argument is the name of a +variable to store the full list of found keys into. Depending on the +exact nature of the input table and the join mode the output table may +not contain all the keys by default. In such a case the caller can +declare a variable for this information and then insert it into the +output table on its own, as she will have more information about the +placement than this command. + +[nl] + What is left to explain is the format of the arguments. [nl] @@ -454,7 +464,7 @@ -[call [cmd ::struct::list] [method dbJoinKeyed] [opt [option -inner]|[option -left]|[option -right]|[option -full]] [arg table]...] +[call [cmd ::struct::list] [method dbJoinKeyed] [opt [option -inner]|[option -left]|[option -right]|[option -full]] [opt "[option -keys] [arg varname]"] [arg table]...] The operations performed by this method are the same as described above for [method dbJoin]. The only difference is in the specification