演習 7 : 3 番目の Lookup クラス
チュートリアル本編の演習の説明に戻るには、ここをクリックします。
-
VS Code - ObjectScript を使用して、ObjectScript.DataEntry4 の Store() メソッドを編集します。ユーザの回答を ^PersonD グローバルに格納する処理の直前に、TStart を追加します。
// change all globals inside a transaction tstart set ^PersonD(id) = answers // store the answers
^PersonI グローバルのインデックスを更新する処理の直後に、TCommit を追加します。
set $bit(^PersonI("Bitmap-ID", chunk), position) = 1 tcommit write "...stored"
通常、TStart と TCommit の間にはグローバルを設定または削除する文だけを配置し、それ以外は Store() を変更しないでおきます。
-
[保存]ボタン、[コンパイル] ボタンをクリックします。
-
ObjectScript.Lookup2 の先頭行を ObjectScript.Lookup3 に変更し、ObjectScript.Lookup3 という名前で保存します。
-
このコードを TakeAction() に追加し、レコードを削除するオプションをユーザに表示するようにします。
// ask if user wants to delete read !, "Delete? (y/n): ", yn if ((yn = "y") || (yn = "Y")) { do ..Delete(id, record) quit }
-
新しい Delete() メソッドを記述します。
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) } }
-
[保存] ボタン、[コンパイル] ボタンをクリックします。
-
ターミナルを開始し、do ##class(ObjectScript.Lookup3).Main() と入力してメソッドを実行し、新しい削除オプションをテストします。
-
このコードを TakeAction() に追加し、レコードを編集するオプションをユーザに表示するようにします。
// ask if user wants to edit read !, "Edit? (y/n): ", yn if ((yn = "y") || (yn = "Y")) { do ..Edit(id, record) quit }
-
新しい Edit() メソッドを記述します。
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) } }
-
新しい Reprompt() メソッドを記述します。
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) } }
-
新しい Update() メソッドを記述します。
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." } }
-
[保存] ボタン、[コンパイル] ボタンをクリックします。
-
ターミナルを開始し、do ##class(ObjectScript.Lookup3).Main() と入力してメソッドを実行し、新しい編集オプションをテストします。