Version 17 of MetaKit Tips and Tricks

Updated 2017-11-21 18:05:14 by dbohdan

A page for code snippets for MetaKit


CMcC found layout format annoying in its terseness, so wrote a simple wrapper to allow comments:

    proc layout {string} {
        set result ""
        foreach line [split $string \n] {
            set line [string trim [lindex [split $line \#] 0]]
            if {$line eq ""} continue
            foreach {name t} [split $line :] break
            if {$t eq ""} {
                set t "S"
            }
            #puts stderr "Layout: $line -> $name:$t"
            append result "$name:$t" \n
        }
        return $result
    }

Example:

    set trouble_layout [layout {
        user        # user with trouble
        mid        # message id
        error:I        # error code
        text        # error text
    }]
        
    ::mk::view layout $db.trouble $trouble_layout

How do I get a 'distinct' item result set?

Partnumber 0001 0001 0001 0003 0004 0006 0006

and you want to retrieve the unique values only -- such as:

Partnumber 0001 0002 0003 0004 0006

 # code here

LES answers: see lsort -unique: [L1 ]


LES on 20070527: Suppose you have these values: John 48 male. You can't enter them like this. The correct way is name John age 48 sex male. That requirement is annoying, especially when importing from CSV. So I made this proc:

 proc  mk.row.importvalues  {View Properties Values}          {
 
         if          {[llength $Properties] != [llength $Values]}  {
                 puts {Error: "Properties" and "Values" must be lists and have the same number of elements.}
                 return
         }
         
         for          {set i 0}  {$i < [llength $Values]}  {incr i}  {
                 lappend ImportValues [lindex $Properties $i]
                 lappend ImportValues [lindex $Values $i]
         }
         
         mk::row append $View $ImportValues
 }

Example:

 mk.row.importvalues $view "name age sex" "John 48 male"

or

 foreach line $all_lines_of_a_file {
         mk.importvalues $view "name age sex" $line
 }

Remove the commas from every line if it is a CSV:

 foreach line $all_lines_of_a_file {
         mk.importvalues $view "name age sex" [string map {, ""} $line]
 }

MSH on 20070527 LES Try replacing your for loop with

 foreach Prop $Properties Val $Values {
     lappend ImportValues $Prop $Val
 }

It should be a little faster


jnc on 20100913: MetaKit supports hashed keys which greatly decreases the query time for the said keys. On a table with 16,800 records, MetaKit was actually faster with hash access than SQLite3 with the said key indexed. Here is a simple example of an automatically maintained hash key.

 if {[llength $argv] == 0} {
     puts "Usage: people.tcl NAME"
     puts "   searches for NAME in the people.mk database"
     exit 1
 }
 
 package require Mk4tcl
 
 catch { file delete people.mk }
 
 mk::file open db people.mk -nocommit
 mk::view layout db.person { name state }
 mk::view open db.person data
 mk::view layout db.person_map {_H:I _R:I}
 mk::view open db.person_map map
 rename [data view hash map 1] people
 
 people insert end name John state OH
 people insert end name Jim  state WV
 people insert end name Jack state PA
 people insert end name Jeff state IN
 
 mk::file commit db
 
 set searchName [lindex $argv 0]
 
 if {[catch {people find name $searchName} row]} {
     puts "'$searchName' not found"
     puts "    hint: try John, Jim, Jack or Jeff"
 } else {
     puts [people get $row name state]
 }
 
 mk::file close db