Skip to main content
Previous section

Exercise 7: Third Lookup Class

Click here to return to the exercise description in the main part of the tutorial.

  1. Using Atelier, edit the Store() method of ObjectScript.DataEntry4. Add a TStart just before storing the user's answers in the ^PersonD global.

        // change all globals inside a transaction
        tstart
        set ^PersonD(id) = answers  // store the answers
    
    Copy code to clipboard

    Add a TCommit just after updating the indexes in the ^PersonI global.

        set $bit(^PersonI("Bitmap-ID", chunk), position) = 1
        tcommit
        write "...stored"    
    
    Copy code to clipboard

    Normally, only statements that set or kill globals should be between TStart and TCommit, but you'll leave Store() otherwise unchanged.

  2. Click the Save and Compile buttons.

  3. Change the top line of ObjectScript.Lookup2 to ObjectScript.Lookup3, and save it as ObjectScript.Lookup3.

  4. Add this code to TakeAction() to give the user the option of deleting the record.

        // ask if user wants to delete
        read !, "Delete? (y/n): ", yn
        if ((yn = "y") || (yn = "Y")) {
            do ..Delete(id, record)
            quit
        }
    
    Copy code to clipboard
  5. Write the new Delete() method.

    Class ObjectScript.Lookup3
    {
    
    /// delete chosen record (lock, start a txn, kill global nodes, commit txn, unlock)
    ClassMethod Delete(id as %Integer, record as %String)
    {
        // try to lock the record for 5 seconds
        lock +^PersonD(id):5
        if '$test {
            write "...someone else is editing this person. Try again later."
            quit
        }
        // retrieve data
        set $listbuild(name, phone, intdob) = record
        set last = $piece(name, ",", 1), first = $piece(name, ",", 2)
        set chunk = (id\64000) + 1, position = (id#64000) + 1
        
        // change all globals inside a transaction
        tstart
        kill ^PersonD(id)
        kill ^PersonI("Name", last, first, id)
        kill ^PersonI("Phone", phone)
        kill ^PersonI("DOB", intdob, id)
        set $bit(^PersonI("Bitmap-ID", chunk), position) = 0
        tcommit
        write "...deleted"
        lock -^PersonD(id)
    }
    }
    Copy code to clipboard
  6. Click the Save and Compile buttons.

  7. Start the Terminal, and run your method to test the new deletion option, by typing do ##class(ObjectScript.Lookup3).Main().

  8. Add this code to TakeAction() to give the user the option of editing the record.

        // ask if user wants to edit
        read !, "Edit? (y/n): ", yn
        if ((yn = "y") || (yn = "Y")) {
            do ..Edit(id, record)
            quit
        }
    
    Copy code to clipboard
  9. Write the new Edit() method.

    Class ObjectScript.Lookup3
    {
    
    /// edit chosen record (lock, reprompt, compare, update globals, unlock)
    ClassMethod Edit(id as %Integer, record as %String)
    {
        // try to lock the record for 5 seconds
        lock +^PersonD(id):5
        if '$test {
            write "...someone else is editing this person. Try again later."
            quit
        }
        // show current data and prompt for updates
        do ..Reprompt(record, .newanswers)
        // if changes were made, update the record
        if '$listsame(record, newanswers) {do ..Update(id, record, newanswers)}
        lock -^PersonD(id)
    }
    }
    Copy code to clipboard
  10. Write the new Reprompt() method.

    Class ObjectScript.Lookup3
    {
    
    /// prompt for updates - similar to ##class(ObjectScript.DataEntry4).Prompt()
    ClassMethod Reprompt(currentdata as %String, ByRef newanswers as %String)
    {   
        // get current name, phone, intdob so that they can be displayed within prompts
        set $listbuild(currentname, currentphone, currentintdob) = currentdata
        do {
            write !, "Name: ", currentname, " => "
            read newname
            // enter nothing to keep current value
            if (newname = "") {
                set newname = currentname
                quit
            }
         }
        while '##class(ObjectScript.DataEntry4).ValidName(newname)
        
        do {
            write !, "Phone: ", currentphone, " => "
            read "(617): ", newphone
            // enter nothing to keep current value
            if (newphone = "") {
                set newphone = currentphone
                quit
            }
        }
        while '##class(ObjectScript.DataEntry4).ValidPhone(.newphone)
    
        do {
            write !, "DOB: ", $zdate(currentintdob, 2), "=> "
            read newdob
            // enter nothing to keep current value
            if (newdob = "") {
                set newintdob = currentintdob
                quit
            }
        }
        while '##class(ObjectScript.DataEntry4).ValidDOB(newdob, .newintdob)
    
        set newanswers = $listbuild(newname, newphone, newintdob)
    }
    }
    Copy code to clipboard
  11. Write the new Update() method.

    Class ObjectScript.Lookup3
    {
    
    /// save the updated record (start a txn, updating data and index globals using set and kill, commit txn)
    ClassMethod Update(id as %Integer, currentdata as %String, ByRef newanswers as %String)
    {
        read !, "Store updates? (y/n): ", yn  // ask if user wants to store
        // only go on if user says yes
        if ((yn '= "y") && (yn '= "Y")) {
            write "...not stored."
            quit
        }
        
        // get current and new data for comparisons
        set $listbuild(currentname, currentphone, currentintdob) = currentdata
        set currentlast = $piece(currentname, ",", 1), currentfirst = $piece(currentname, ",", 2)
        set $listbuild(newname, newphone, newintdob) = newanswers
        set newlast = $piece(newname, ",", 1), newfirst = $piece(newname, ",", 2)    
    
        // update all globals inside a transaction
        // only update indexes if the data was changed    
        tstart
        set ^PersonD(id) = newanswers
        if (newname '= currentname) {
            // kill old name and add new name to index
            kill ^PersonI("Name", currentlast, currentfirst, id)
            set ^PersonI("Name", newlast, newfirst, id) = ""
        }
        if (newphone '= currentphone) {
            // kill old phone and add new phone to index
            kill ^PersonI("Phone", currentphone)
            set ^PersonI("Phone", newphone) = id
        }
        if (newintdob '= currentintdob) {
            // kill old dob and add new dob to index
            kill ^PersonI("DOB", currentintdob, id)
            set ^PersonI("DOB", newintdob, id) = ""
        }
        tcommit  // commit the transaction
        write "...updated."    
    }
    }
    Copy code to clipboard
  12. Click the Save and Compile buttons.

  13. Start the Terminal, and run your method to test the new editing option, by typing do ##class(ObjectScript.Lookup3).Main().