Email - see below - the web site is currently at an advanced stage of unreadiness. Living in the most beautiful part of the UK (opinions vary): Dedham Vale, Suffolk [http://www.countryside.gov.uk/aonb/9_dedh.htm], with Sue (libraries) [http://www.essexcc.gov.uk/libraries/] and sometimes student offspring Sam (digital cinema) [http://www.polaris-digital.com] and Jo (TV and radio production). Programming since 1970 {![[clock seconds]]!}, still not rich nor famous, but no plans to stop. Tcl user since 7.6, no plans to stop that either. Serious long-term lurker at this wiki, the best resource a language could have - thanks to all for all the free help. Currently (April 2003) working as a long term freelancer for British Telecommunications Laboratories, Martlesham Heath on network monitoring and management [http://www.labs.bt.com/research/researchthemes], for the British Home Office on monitoring Rehabilitation Programmes [http://www.probation.homeoffice.gov.uk/output/Page1.asp], and for the Alcohol Education and Research Council [http://www.aerc.org.uk/] on paperwork reduction - you have to have at least two jobs in the UK these days. Also rapidly becoming very interested indeed in 802.11 combined community networking and broadband provision, and involved through local pressure group SSBB. [http://www.ssbb.co.uk] Technically mainly trying to continue working in design and Oracle SQL, C, C++, Tcl and (whisper it) VB, mainly succeeding so far. Occasionally worrying about not knowing any of the above properly, nor Java, Perl, Python, Ruby, Scheme, C#, .Net... even slightly, yet. Always happy to be paid to learn though :) Claiming one minuscule right to Tcl fame, having invented ''ClarifyScript'', a C++ bolt-on for Tcl to let it talk to a Clarify CRM (oops, now Nortel, oops, now Amdocs [http://www.amdocs.com/product_tree.asp?ID=22]) object database - the audience is currently three projects at BT Exact, who have kindly allowed it to become public, and their several hundred users at BT network operation units. Now also claiming proud authorship of a 10-line Tcl program to set your PC's clock from an NTP server: see the ''TIME Protocol Client'' [http://mini.net/tcl/3391.html] elsewhere in this wiki. Reminiscing for a moment: anyone involved with Acorn ''BBC Micro'' home computing (6502@2MHz) in the early 1980s may remember me as one quarter of SoftMachinery, fabulous furry ''Prestel'' pioneers whose bits went 75 per second in one direction and 1200 in the other. Prestel was a quite brilliant precursor to the web, invented by Sam Fedida at BT Labs when BT was still the Post Office [http://iml.jou.ufl.edu/carlson/professional/new_media/History/Prestel.htm], much beloved by UK travel agents, and completely eclipsed as soon as HTTP arrived. But we did get to be Essex MUD wizards [http://www.mud.co.uk/] and to love a beautiful witch [http://www.mud.co.uk/richard/microadv.htm] along the way [http://www.qtq.org/mud2/dhbook/appendixA.html]. We were our own digital publishers and journalists at the gnotorious Home Of The Gnome [http://www.mud.co.uk/richard/opublish.htm], both on Prestel (*258192# - error: gno carrier), and as a Prestel-like 6-line community bulletin board. Along with our collaborators, we invented a few quite amazing things that never made any money whatsoever. One of the partners' previous companies was called ''Belder'', which in hindsight probably explains a lot. Speaking of which, we invented Danny O'Brien too [http://www.ntk.net/]. Scattered to the winds in the 90s by recession and the rising price of Nike trainers, SoftMachinery is pursuing rather more stable employment these days, although none of us has stopped inventing so far as I can tell. ---- '''ClarifyScript''' This will only make any sense to dedicated Clarifiers (if them :). Possibly this could be a model for other object database packages, but really, SQL is still the best way to access a database. ClarifyScript is a shell for the Clarify Low-Level C API (LLAPI). proc SubcaseStateTransition {id_number newstate} { #### sets subcase state to newstate (a valid Open global string) with all the trimmings global env transaction { set now [sysdate] set subcase [find subcase id_number $id_number] ;# default [find the ...] for exactly one object, or error set user [find user login_name $env(CLARIFY_USER1)] ;# current user's login_name set oldstatus [find via $subcase subc_casests2gbst_elm] ;# follow a relation to find current status string object set newstatus [find string Open $newstate] ;# find the global string $newstatus in the "Open" global list set transit "from status [$oldstatus get title] to status [$newstatus get title]" ;# informative message $subcase set subc_casests2gbst_elm $newstatus ;# relate the subcase to its new status string object transaction { ;# a separate transaction is necessary here set chgst [find string "Activity Name" "Chg Status"];# another global string, from the "Activity Name" list set user2 [find user objid [$user get objid]] ;# must re-find these objects because there is ... set subc2 [find subcase objid [$subcase get objid]] ;# ... no relating between transactions (LLAPI issue) set actent [find new act_entry] ;# [find new ...] to create a new act_entry object $actent set act_code 300 \ entry_time $now \ addnl_info $transit \ proxy $env(CLARIFY_USER1) \ entry_name2gbst_elm $chgst \ act_entry2user $user2 \ act_entry2subcase $subc2 commit ;# commit in inner transaction to establish new objid set aeobjid [$actent get objid] ;# remember objid, because all objects [found] in this ... } ;# ... transaction are discarded when it ends (LLAPI issue) set actent [find act_entry objid $aeobjid] ;# re-find the new act_entry using its objid set stchg [find new status_chg] ;# create and populate a new status_chg object $stchg set creation_time $now \ notes $transit \ status_chg2act_entry $actent \ subc_stat_chg2subcase $subcase \ c_status_chg2gbst_elm $newstatus \ p_status_chg2gbst_elm $oldstatus \ status_chger2user $user set timeb [find new time_bomb] ;# and all because time_bomb has objid pointers not relations :( $timeb set end_time $now \ focus_lowid [$subcase get objid] \ focus_type 24 \ time_period [$actent get objid] \ flags 65538 \ left_repeat 0 \ cmit_creator2employee $user commit ;# commit in outer transaction to update the database if {$env(CLARIFYSCRIPT_DEBUG)} { ;# notifier example $user notify "DEBUG: SubcaseStateTransition $id_number: $transit" commit } } ;# discard outer transaction and object memory } The [[find ...]] command locates zero, one or more Clarify objects in the database as a named set, and creates a new Tcl command ''setname'' through which to access that set, in classic Tcl style, using subcommands to control the type of query, and trailing field name and value pairs to filter the results (always ANDed). [[find]] always creates a new ''setname'' command accessing a set of zero, one or more Clarify objects, always all of the same ''objtype'', always distinct with no duplicates, and [[find]] always returns the name of the new command ''setname'', or fails with an error. A -sort option allows the object set to be pre-sorted in the database before being fetched. [[find ?the? ''objtype'' ?''field'' ''value'' ...?]] finds a set of exactly one object by field lookup, or fails. [[find every ''objtype'' ?''field'' ''value'' ...?]] finds a set of zero, one or more objects by field lookup. [[find new ''objtype'' ?''field'' ''value'' ...?]] creates a new Clarify object, or optionally finds exactly one existing object with matching field values, or creates and sets field values if none found, or fails if many found. [[find index ''setname'' ''index'']] isolates a set of one object from another set of one or more by index number, or fails if index out of range 0..[[''setname'' count]]-1. [[find via ''setname'' ''relation'' ?''field'' ''value'' ...?]] follows a relation from a set of one object, to a set of zero, one or more objects, optionally also filtered by field values. [[find string ''listtitle'' ''stringtitle'']] finds a Clarify global string object from a global list object by their titles, as a set of one object. [[find union ''setname'' ''setname1'' ?...?]], [[find minus ''setname'' ''setname1'' ?...?]] and [[find intersect ''setname'' ''setname1'' ?...?]] perform standard set operations pretty fast (using Tcl hash tables), resulting in a set of zero, one or more objects. [[find empty ''objtype'']] returns an empty set, nominally of ''objtype''. Having [[found]] a set of Clarify objects, use its ''setname'' command to manipulate it: [[''setname'' count]] returns the number of objects in ''setname''. [[''setname'' objtype]] returns the objtype of the objects in ''setname'', had you forgotten. [[''setname'' foreach ''var'' ''script'']] iterates through ''setname'', via a set of one object at a time, whose command name is placed in ''var'' each time ''script'' is evaluated. [[''setname'' get ''field'' ?...?]] gets a list of field values, from a set of exactly one object. [[''setname'' list ''field'' ?...?]] gets a list of a list of field values, from a set of zero, one or more objects - there is one outer list element per object or row, one inner list element per field value. [[''setname'' report ''field'' ?...?]] gets a list of a list of field values, from a set of zero, one or more objects, then returns the results padded into aligned rows and columns. [[''setname'' set ''field'' ''value'' ?...?]] sets fields or relations, in a set of one or more objects. [[''setname'' delete]] deletes a set of one or more objects from the database. [[''setname'' in ''othersetname'']], [[''setname'' has ''othersetname'']], [[''setname'' is ''othersetname'']] do fast set comparisons (using Tcl hash tables) - [[''setname'' has ...]] also recognises none|one|some|many as meaningful ''othersetname''s representing 0|1|>=1|>1 objects of the appropriate objtype. Get, list, report and set include syntax to get or set fields in related objects on the fly, and list and report have a -sort option for Tcl-based post-fetch sorting. [[''caseorsubcasesetname'' log ''string'']] correctly adds an entry to case or subcase objects' history log. [[''usersetname'' notify ''string'' ?...?]] uses the Clarify Notifier subsystem to notify users of an event, or can call a Clarify Basic procedure in an online users' GUI. [[sysdate ...]] gets the time now in Clarify datestring style, or converts between Clarify datestring and Tcl [[clock seconds]]. [[transaction]], [[commit ...]] and [[rollback]] are for optional transaction and object memory management, otherwise a default transaction is provided which must be ''commit''ted to update the database. For memory management, each ''setname'' belongs to the transaction in which it was created, and the command and its object set memory are discarded when that transaction ends or is rolled back. Explicit transactions are seldom but occasionally required, as in the sample above. ClarifyScript is about 4 years old, currently an untidy but reliable pile of Sun Forte 4.2 vintage C++ classes, linked with Tcl 8.3 and the Clarify High- and Low-Level APIs up to 10.1, running on Solaris up to 8, and definitely not a standard Tcl plug-in package in any way at all. There is an executable ClarifyScript Shell cssh, and three classes to allow embedded ClarifyScript in C++ programs. It has so far only been used with Clarify ClearSupport, buts looks ready for the other Clarify applications. ClarifyScript is database-independent, because it is based on the Clarify APIs, although we have only used it with Oracle (up to 8.1.7.3), and in fact currently build Oratcl into it too - thanks guys, it's good to be able to drop into SQL when the devil drives. ClarifyScript was written while Tcl 8.0 was still in alpha, so it uses the Ousterhout 7.6 string-based internal model. There is a manual. 2004-05-27 No more email. Bob died of a heart attack at his home in that most beautiful part of England. A most beautiful man, loving father and husband and a good friend. He will be sorely missed. Goodbye, Bob. ---- [Category Person]