SlideShare a Scribd company logo
DivConq Framework’s MUMPS API
DivConq Database
About DivConq

          http://www.divconq.com/about/

     Getting Started With DivConq

          http://www.divconq.com/home/getting-started/


This presentation is part of a sequence of presentations on DivConq’s database
features. Visit the Getting Started page at our website to see the suggested order
for our presentations.
Coding and Testing in MUMPS
In the previous presentations we focused on how stored procedures worked
within Java. Things like the request-response flow, request objects, callbacks,
schema and JSON-Like data structures.

In the coming slides the focus is going to be on MUMPS development for stored
procedures. We’ll use some examples that ship with DivConq Framework so you
can follow along.
D:devdivconqtemplate>.binrun.bat testdb
      Command testdb
      Starting Hub
      ...




You should recall how to run TestDb from previous presentations in Getting
Started. If not then you may wish to review those presentations.
Select option 4 “Load stored proc results (testProc1)”. The output we see will be
JSON, but keep in mind the database result uses DivConq’s Struct classes
(JSON-Like API). Your output should be:

      testProc1 Response:
       {
              "Name": "Sally",
              "Age": 5,
              "Toys": [
                      "Legos",
                      "Puzzle"
               ] ,
              "Friends": [
                        {
                                 "Name": "Chad",
                                 "Age": 5
                       } ,
                       {
                                 "Name": "Ginger",
                                 "Age": 6
                       }
              ]
       }
D:devdivconqtemplatepackagesdcTestmdctTest.m



Open the MUMPS code file dctTest.m ni a text editor to follow within the real
source code.
testProc1 n data,tnum,fnum
       ;
       s data("Name")="Sally"
       s data("Age")=5
       s data("Toys",1)="Legos"
       s data("Toys",2)="Puzzle"
       s data("Friends",1,"Name")="Chad"
       s data("Friends",1,"Age")=5
       s data("Friends",2,"Name")="Ginger"
       s data("Friends",2,"Age")=6
       ;

      [continued]




This first and simplest example starts by populating a local MUMPS data
structure.
[continued]

        w   StartRec
        w   Field_"Name"_ScalarStr_data("Name")
        w   Field_"Age"_ScalarInt_data("Age")
        ;
        w   Field_"Toys"_StartList
        f    s tnum=$o(data("Toys",tnum)) q:tnum=""   d
        .   w ScalarStr_data("Toys",tnum)
        w   EndList
        ;

       [continued]

       Java output from this part:

        { "Name": "Sally", "Age": 5, "Toys":      [ "Legos", "Puzzle" ] ,


Then the result is started by using MUMPS’ “write” commands. The start of a
record or list begins with StartRec or StartList. The start of a field name starts
with Field. The start of a field value or item is always ScalarNNN.
[continued]

        w   Field_"Friends"_StartList
        f    s fnum=$o(data("Friends",fnum)) q:fnum="" d
        .   w StartRec
        .   w Field_"Name"_ScalarStr_data("Friends",fnum,"Name")
        .   w Field_"Age"_ScalarInt_data("Friends",fnum,"Age")
        .   w EndRec
        w   EndList

       [continued]

       Java output from this part:

       "Friends":    [ { "Name": "Chad", "Age": 5 } ,
                       { "Name": "Ginger", "Age": 6 } ]



“Friends” is a field. The field value is a list of records where each record has two
fields. Note how EndRecord and EndList are paired, you must have an EndNNN
for every StartNNN. Field and ScalarNNN do not need an ending delineator.
[continued]

       ;
       w EndRec
       ;
       quit


      Java output from this part:

      }




Stored procedures will always return a record or a list. So the last “write”
command in a stored proc should always be EndRec or EndList – to match the
first write.
$ sudo su gtmuser

      $ cd ~

      $ ./gtmcon

      GTM>d local^dcConn("QUERY testProc1")

      Data:
      { , Name: Sally, Age: 5, Toys[ : Legos: Puzzle] , Friends[ { ,
      Name: Chad, Age: 5} { , Name: Ginger, Age: 6} ] } !
      Messages:
      [ ] !


Stored procedures are used by Java, but if you want to test your procedure in
MUMPS you may emulate a Java call. Bring up the MUMPS prompt, something
like above, and then call local^dcConn to run the procedure. When calling
procedures this way you’ll want to use “UPDATE” or “QUERY” – only use
“UPDATE” if the call will change data in the database.
{ , Name: Sally, Age: 5, Toys[ : Legos: Puzzle] , Friends[ { ,
      Name: Chad, Age: 5} { , Name: Ginger, Age: 6} ] } !




The results returned to Java from stored procedures are not in JSON format.
Likewise, when we run the procedure within MUMPS we aren’t getting pure JSON
but we do get something similar.

Once you get used to ", " preceding every field (e.g. “, Name” and ": " preceding
every scalar (e.g. “: Legos”) then it is not too bad to read.
QueryRequest tp1 = new QueryRequest("testProc1");

      ObjectCallback callback = new ObjectCallback() {
               @Override
               public void process(ObjectResult res) {
                         if (res.hasErrors()) {
                                  System.out.println(" Error:");
                                  TestDb.printPretty(res.getMessages());
                         }
                         else {
                                  System.out.println(" Response:");
                                  TestDb.printPretty(res.getResult());
                         }
               }
      };

      Hub.instance.getDatabase().submit(tp1, callback);


A quick look back at how to call from Java, note the “Query” in QueryRequest and
the use of the name “testProc1”. Also note no parameters are used.
GTM>s Params(0)="gun"

      GTM>s Params(1)="candy"

      GTM>d local^dcConn("QUERY testProc2")

      Data:
      !
      Messages:
      [ { , Level: Error, Code: 1, Message: Gun not allowed in toy list}
      { , Level: Error, Code: 1, Message: Candy not allowed in toy list}
      ] !




Lets run the next test procedure, testProc2. This one will show us how to return
messages from a stored proc. Messages are not result data, but rather
information for tracing, info, warnings or errors. Only a few messages should be
returned from a procedure, do not try to return hundreds or more. Note you can
add a message anytime during the output generation – in the middle of a Field is
fine. Also we see how to pass Params from the M command line.
testProc2 n tnum,toy
    ;
    ; validate your inputs, if toy list is not there do not continue
    i $d(Params)<10 d errMsg^dcConn("Missing toy list") quit
    ;
    ; continue input validation, check for undesirable toys
    f s tnum=$o(Params(tnum)) q:tnum="" d
    . s toy=Params(tnum)
    . s toy=$$toUpper^dcStrUtil(toy)
    . i toy["GUN" d errMsg^dcConn("Gun not allowed in toy list") q
    . i toy["CANDY" d errMsg^dcConn("Candy not allowed in toy list") q
    . i toy["HAMMER" d warnMsg^dcConn("A hammer may not be safe for this age") q



We expect a list of toys for our parameters. A check with $d tells us if the list is
missing. If so, then we need to add an error message and quit the routine.
Calling errMsg or warnMsg in dcConn is one way to do this, we’ll see another way
soon. Note that it is ok to “quit” before any output if there is an error. In Java
always check for errors in the result (ObjectResult) before processing the data.
Ignore the result data if an error occurred.
testProc2 n tnum,toy
    ;
    ; validate your inputs, if toy list is not there do not continue
    i $d(Params)<10 d errMsg^dcConn("Missing toy list") quit
    ;
    ; continue input validation, check for undesirable toys
    f s tnum=$o(Params(tnum)) q:tnum="" d
    . s toy=Params(tnum)
    . s toy=$$toUpper^dcStrUtil(toy)
    . i toy["GUN" d errMsg^dcConn("Gun not allowed in toy list") q
    . i toy["CANDY" d errMsg^dcConn("Candy not allowed in toy list") q
    . i toy["HAMMER" d warnMsg^dcConn("A hammer may not be safe for this age") q



Loop the list of toys in our parameters. Check if the toy matches some key word,
if so create an error and continue in the loop. Every toy that fails will generate a
message. This should be capped, do not return more than a hundred messages
this way.
i Errors quit
    ;
    ; if only warnings or no validation messages then proceed
    w StartList
    f s tnum=$o(Params(tnum)) q:tnum="" d
    . s toy=Params(tnum)
    . s toy=$$toUpper^dcStrUtil(toy)
    . w ScalarStr_toy
    w EndList
    ;
    quit




Before we do the output, which just echoes the list back, first check for any error
messages. Remember the validation loops all toys and may generate one or
more warning or error. Doing “i Errors quit” ensures that we don’t bother with
output if an error was created in a previous step.
ListStruct toys = new ListStruct("gun", "candy");

      QueryRequest tp2 = new QueryRequest("testProc2", toys);

      ... Submit ...

      // in your callback be sure to check for errors

      if (res.hasErrors()) {
               System.out.println(" Error:");
               TestDb.printPretty(res.getMessages());
      }




A glance back at calls from Java. Note passing the List of toys as parameters.
Coding and Testing in MUMPS
DivConq Name     MUMPS Write Type
     String           ScalarStr
     Integer          ScalarInt
     BigInteger       ScalarBigInt
     Decimal          ScalarDec
     BigDecimal       ScalarBigDec
     Boolean          ScalarFalse, ScalarTrue or ScalarBool_”true|false”
     Null             ScalarNull
     Binary           ScalarBin
     DateTime         ScalarDateTime
     BigDateTime      ScalarBigDateTime



Above is a list of most the ScalarNNN types as they relate to the types in
Schema/Java. To refresh yourself on the data types, see the “Data Types in
DivConq” presentation.
Java
      ListStruct toys = new ListStruct("gun", "candy");

          // as used with
          QueryRequest tp2 = new QueryRequest("testProc2", toys);


      MUMPS
      Params(0)="gun"
      Params(1)="candy"



Lists in Java become numerical keys in MUMPS, starting at 0.
Java
     RecordStruct params = new RecordStruct(
              new FieldStruct("MinAge", 30),
              new FieldStruct("MaxAge", 48)
     );

     MUMPS
     Params("MinAge")=30
     Params("MaxAge")=48




Records in Java become keyed by field name in MUMPS.
Java
      ListStruct toys = new ListStruct(
               new RecordStruct(
                         new FieldStruct("Name", "Mike"),
                         new FieldStruct("Age", 44)
               ),
               new RecordStruct(
                         new FieldStruct("Name", "Mary"),
                         new FieldStruct("Age", 38)
               )
      );

      MUMPS
      Params(0,"Name")="Mike"
      Params(0,"Age")=44
      Params(1,"Name")="Mary"
      Params(1,"Age")=38


Lists of Records become numerical keys with field name sub-keys.
Java
      RecordStruct   params = new RecordStruct(
               new   FieldStruct("Name", "Mike"),
               new   FieldStruct("Age", 14),
               new   FieldStruct(“Toys",
                           new ListStruct( "Bike", "Soccer Ball" )
               )
      );

      MUMPS
      Params("Name")="Mike"
      Params("Age")=14
      Params("Toys",0)="Bike"
      Params("Toys",1)="Soccer Ball"




Records with lists become field name keys with numerical sub-keys.
Java
RecordStruct   params = new RecordStruct(
         new   FieldStruct("Name", "Mike Jr."),
         new   FieldStruct("Age", 14),
         new   FieldStruct("Dad",
                     new RecordStruct(
                              new FieldStruct("Name", "Mike Sr."),
                              new FieldStruct("Age", 44)
                     )
         )
);

MUMPS
Params("Name")="Mike Jr."
Params("Age")=14
Params("Dad","Name")="Bike Sr."
Params("Dad","Age")=44
Java
ListStruct params = new ListStruct(
         new ListStruct( "Bike", "Soccer Ball" ),
         new ListStruct( "Bat", "Soft Ball" )
);

MUMPS
Params(0,0)="Bike"
Params(0,1)="Soccer Ball"
Params(1,0)="Bat"
Params(1,1)="Soft Ball"
MUMPS has some limits to how big your keys and your values can get, but within
reason you can send very complex JSON-Like structures. There is more than
just the examples above. You can have a list of records that have fields with lists
of records.

Params([numerical],[field name],[numerical],[field name])=NNN

Or any combination of lists and records as long as it follows MUMPS limitations
(or specifically GT.M’s limitations – though if you used DivConq with Cache you’d
have to watch the limitations for Cache).
Globalizing in MUMPS
testProc3 n tnum,toy,utoy
    ;
    ; validate your inputs, if toy list is not there do not continue
    i $d(Params)<10 d err^dcConn(90000) quit
    ;
    ; continue input validation, check for undesirable toys
    f s tnum=$o(Params(tnum)) q:tnum="" d
    . s toy=Params(tnum)
    . s utoy=$$toUpper^dcStrUtil(toy)
    . i (utoy["GUN")!(utoy["CANDY") d err^dcConn(90001,toy) q
    . i utoy["HAMMER" d warn^dcConn(90002,toy) q
    ;
    i Errors quit
    ...

The preferred way to send a message is to use a message code. Message
codes can be used to translate a message to the user’s locale. Note the calls to
“err” and “warn” in dcConn. Pass the code and, optionally, up to 6 parameters.
There is also an “info” and a “trace” function. For now you may use the 80,000 –
89,999 code range in your projects.
D:devdivconqtemplatepackagesdcTestalldictionarydictionary.xml
   D:devdivconqtemplatepackagesdcTestalldictionaryx-pig-latin.xml




Every DivConq package should have a dictionary file (or many). The name of the
file doesn’t matter, though we can see that one file in dcTest contains Pig Latin.
What does matter is that you have an entry for every code in every supported
language.
<Dictionary>
      <Locale Id="en">
            <Entry Token="_code_90000"   Value="Missing   toy list" />
            <Entry Token="_code_90001"   Value="Toy not   allowed: {$1}" />
            <Entry Token="_code_90002"   Value="Toy may   not be safe: {$1}" />
            <Entry Token="_code_90010"   Value="Missing   required fields" />
      </Locale>
   </Dictionary>



The first file contains only English (see Id attribute of Locale element). In
testProc3 the call to “d err^dcConn(90000)” produces “Missing toy list” when
using the English locale.

The call to “d warn^dcConn(90002,toy)” on the other hand has a parameter, the
toy’s name. The first parameter replaces {$1} in the message, so for a Hammer
the message becomes “Toy may not be safe: Hammer”.
<Dictionary>
   <Locale Id="x-pig-latin">
      <Entry Token="_code_90000"   Value="Issingmay oytay istlay" />
      <Entry Token="_code_90001"   Value="Oytay otnay allowedway: {$1}" />
      <Entry Token="_code_90002"   Value="Oytay aymay otnay ebay afesay: {$1}" />
      <Entry Token="_code_90010"   Value="Issingmay equiredray ieldsfay" />
   </Locale>
   </Dictionary>



The second file contains only Pig Latin, though technically both translations could
be in the same file. The call to “d err^dcConn(90000)” produces “Issingmay oytay
istlay” when using the Pig Latin locale.

The call to “d warn^dcConn(90002,toy)” with a Hammer produces “Oytay aymay
otnay ebay afesay: Hammer”.
We now have a better idea of how to pass data to a stored procedure and how to
return data from a stored procedure. We also learned that we can pass status or
debugging messages from our stored procedure – and that those messages can
be localized.

More Related Content

What's hot

Java 8 Puzzlers [as presented at OSCON 2016]
Java 8 Puzzlers [as presented at  OSCON 2016]Java 8 Puzzlers [as presented at  OSCON 2016]
Java 8 Puzzlers [as presented at OSCON 2016]
Baruch Sadogursky
 
The Groovy Puzzlers – The Complete 01 and 02 Seasons
The Groovy Puzzlers – The Complete 01 and 02 SeasonsThe Groovy Puzzlers – The Complete 01 and 02 Seasons
The Groovy Puzzlers – The Complete 01 and 02 Seasons
Baruch Sadogursky
 
What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)
Pavlo Baron
 
NetBeans Plugin Development: JRebel Experience Report
NetBeans Plugin Development: JRebel Experience ReportNetBeans Plugin Development: JRebel Experience Report
NetBeans Plugin Development: JRebel Experience ReportAnton Arhipov
 
The Ring programming language version 1.10 book - Part 94 of 212
The Ring programming language version 1.10 book - Part 94 of 212The Ring programming language version 1.10 book - Part 94 of 212
The Ring programming language version 1.10 book - Part 94 of 212
Mahmoud Samir Fayed
 
mobl presentation @ IHomer
mobl presentation @ IHomermobl presentation @ IHomer
mobl presentation @ IHomerzefhemel
 
Parsing with Perl6 Grammars
Parsing with Perl6 GrammarsParsing with Perl6 Grammars
Parsing with Perl6 Grammars
abrummett
 
Google guava
Google guavaGoogle guava
dotSwift 2016 : Beyond Crusty - Real-World Protocols
dotSwift 2016 : Beyond Crusty - Real-World ProtocolsdotSwift 2016 : Beyond Crusty - Real-World Protocols
dotSwift 2016 : Beyond Crusty - Real-World Protocols
Rob Napier
 
Predictably
PredictablyPredictably
Predictablyztellman
 
Functional Programming with Groovy
Functional Programming with GroovyFunctional Programming with Groovy
Functional Programming with Groovy
Arturo Herrero
 
RxSwift 시작하기
RxSwift 시작하기RxSwift 시작하기
RxSwift 시작하기
Suyeol Jeon
 
Introduction to Python
Introduction to PythonIntroduction to Python
Introduction to Python
UC San Diego
 
Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor
Programming Java - Lection 07 - Puzzlers - Lavrentyev FedorProgramming Java - Lection 07 - Puzzlers - Lavrentyev Fedor
Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor
Fedor Lavrentyev
 
Google Guava - Core libraries for Java & Android
Google Guava - Core libraries for Java & AndroidGoogle Guava - Core libraries for Java & Android
Google Guava - Core libraries for Java & Android
Jordi Gerona
 
concurrency with GPars
concurrency with GParsconcurrency with GPars
concurrency with GPars
Paul King
 
Alternate JVM Languages
Alternate JVM LanguagesAlternate JVM Languages
Alternate JVM Languages
Saltmarch Media
 
Testing a 2D Platformer with Spock
Testing a 2D Platformer with SpockTesting a 2D Platformer with Spock
Testing a 2D Platformer with Spock
Alexander Tarlinder
 
Benefits of Kotlin
Benefits of KotlinBenefits of Kotlin
Benefits of Kotlin
Benjamin Waye
 

What's hot (20)

Java 8 Puzzlers [as presented at OSCON 2016]
Java 8 Puzzlers [as presented at  OSCON 2016]Java 8 Puzzlers [as presented at  OSCON 2016]
Java 8 Puzzlers [as presented at OSCON 2016]
 
The Groovy Puzzlers – The Complete 01 and 02 Seasons
The Groovy Puzzlers – The Complete 01 and 02 SeasonsThe Groovy Puzzlers – The Complete 01 and 02 Seasons
The Groovy Puzzlers – The Complete 01 and 02 Seasons
 
What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)
 
NetBeans Plugin Development: JRebel Experience Report
NetBeans Plugin Development: JRebel Experience ReportNetBeans Plugin Development: JRebel Experience Report
NetBeans Plugin Development: JRebel Experience Report
 
The Ring programming language version 1.10 book - Part 94 of 212
The Ring programming language version 1.10 book - Part 94 of 212The Ring programming language version 1.10 book - Part 94 of 212
The Ring programming language version 1.10 book - Part 94 of 212
 
mobl presentation @ IHomer
mobl presentation @ IHomermobl presentation @ IHomer
mobl presentation @ IHomer
 
Parsing with Perl6 Grammars
Parsing with Perl6 GrammarsParsing with Perl6 Grammars
Parsing with Perl6 Grammars
 
Google guava
Google guavaGoogle guava
Google guava
 
dotSwift 2016 : Beyond Crusty - Real-World Protocols
dotSwift 2016 : Beyond Crusty - Real-World ProtocolsdotSwift 2016 : Beyond Crusty - Real-World Protocols
dotSwift 2016 : Beyond Crusty - Real-World Protocols
 
Predictably
PredictablyPredictably
Predictably
 
Functional Programming with Groovy
Functional Programming with GroovyFunctional Programming with Groovy
Functional Programming with Groovy
 
RxSwift 시작하기
RxSwift 시작하기RxSwift 시작하기
RxSwift 시작하기
 
Introduction to Python
Introduction to PythonIntroduction to Python
Introduction to Python
 
Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor
Programming Java - Lection 07 - Puzzlers - Lavrentyev FedorProgramming Java - Lection 07 - Puzzlers - Lavrentyev Fedor
Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor
 
Google Guava - Core libraries for Java & Android
Google Guava - Core libraries for Java & AndroidGoogle Guava - Core libraries for Java & Android
Google Guava - Core libraries for Java & Android
 
Spock and Geb
Spock and GebSpock and Geb
Spock and Geb
 
concurrency with GPars
concurrency with GParsconcurrency with GPars
concurrency with GPars
 
Alternate JVM Languages
Alternate JVM LanguagesAlternate JVM Languages
Alternate JVM Languages
 
Testing a 2D Platformer with Spock
Testing a 2D Platformer with SpockTesting a 2D Platformer with Spock
Testing a 2D Platformer with Spock
 
Benefits of Kotlin
Benefits of KotlinBenefits of Kotlin
Benefits of Kotlin
 

Similar to Stored Procedures and MUMPS for DivConq

Go testdeep
Go testdeepGo testdeep
Go testdeep
Maxime Soulé
 
Java Programming - 03 java control flow
Java Programming - 03 java control flowJava Programming - 03 java control flow
Java Programming - 03 java control flow
Danairat Thanabodithammachari
 
02 - Prepcode
02 - Prepcode02 - Prepcode
02 - Prepcode
thewhiteafrican
 
Real life-coffeescript
Real life-coffeescriptReal life-coffeescript
Real life-coffeescript
David Furber
 
An Introduction to Scala (2014)
An Introduction to Scala (2014)An Introduction to Scala (2014)
An Introduction to Scala (2014)
William Narmontas
 
Reason - introduction to language and its ecosystem | Łukasz Strączyński
Reason - introduction to language and its ecosystem | Łukasz StrączyńskiReason - introduction to language and its ecosystem | Łukasz Strączyński
Reason - introduction to language and its ecosystem | Łukasz Strączyński
Grand Parade Poland
 
Groovy Basics
Groovy BasicsGroovy Basics
Groovy Basics
Wes Williams
 
Einführung in TypeScript
Einführung in TypeScriptEinführung in TypeScript
Einführung in TypeScript
Demian Holderegger
 
Dealing with combinatorial explosions and boring tests
Dealing with combinatorial explosions and boring testsDealing with combinatorial explosions and boring tests
Dealing with combinatorial explosions and boring tests
Alexander Tarlinder
 
Not your father's tests
Not your father's testsNot your father's tests
Not your father's tests
Sean P. Floyd
 
Spock Framework
Spock FrameworkSpock Framework
Spock Framework
Daniel Kolman
 
Spock Framework - Slidecast
Spock Framework - SlidecastSpock Framework - Slidecast
Spock Framework - Slidecast
Daniel Kolman
 
The Future of JVM Languages
The Future of JVM Languages The Future of JVM Languages
The Future of JVM Languages
VictorSzoltysek
 
Code as data as code.
Code as data as code.Code as data as code.
Code as data as code.Mike Fogus
 
Game Design and Development Workshop Day 1
Game Design and Development Workshop Day 1Game Design and Development Workshop Day 1
Game Design and Development Workshop Day 1
Troy Miles
 
TDAD
TDADTDAD
Java 8 Lambda Expressions
Java 8 Lambda ExpressionsJava 8 Lambda Expressions
Java 8 Lambda Expressions
Scott Leberknight
 
Testing and validating distributed systems with Apache Spark and Apache Beam ...
Testing and validating distributed systems with Apache Spark and Apache Beam ...Testing and validating distributed systems with Apache Spark and Apache Beam ...
Testing and validating distributed systems with Apache Spark and Apache Beam ...
Holden Karau
 
2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests
Tomek Kaczanowski
 

Similar to Stored Procedures and MUMPS for DivConq (20)

Go testdeep
Go testdeepGo testdeep
Go testdeep
 
Java Programming - 03 java control flow
Java Programming - 03 java control flowJava Programming - 03 java control flow
Java Programming - 03 java control flow
 
02 - Prepcode
02 - Prepcode02 - Prepcode
02 - Prepcode
 
Real life-coffeescript
Real life-coffeescriptReal life-coffeescript
Real life-coffeescript
 
An Introduction to Scala (2014)
An Introduction to Scala (2014)An Introduction to Scala (2014)
An Introduction to Scala (2014)
 
Reason - introduction to language and its ecosystem | Łukasz Strączyński
Reason - introduction to language and its ecosystem | Łukasz StrączyńskiReason - introduction to language and its ecosystem | Łukasz Strączyński
Reason - introduction to language and its ecosystem | Łukasz Strączyński
 
Scala introduction
Scala introductionScala introduction
Scala introduction
 
Groovy Basics
Groovy BasicsGroovy Basics
Groovy Basics
 
Einführung in TypeScript
Einführung in TypeScriptEinführung in TypeScript
Einführung in TypeScript
 
Dealing with combinatorial explosions and boring tests
Dealing with combinatorial explosions and boring testsDealing with combinatorial explosions and boring tests
Dealing with combinatorial explosions and boring tests
 
Not your father's tests
Not your father's testsNot your father's tests
Not your father's tests
 
Spock Framework
Spock FrameworkSpock Framework
Spock Framework
 
Spock Framework - Slidecast
Spock Framework - SlidecastSpock Framework - Slidecast
Spock Framework - Slidecast
 
The Future of JVM Languages
The Future of JVM Languages The Future of JVM Languages
The Future of JVM Languages
 
Code as data as code.
Code as data as code.Code as data as code.
Code as data as code.
 
Game Design and Development Workshop Day 1
Game Design and Development Workshop Day 1Game Design and Development Workshop Day 1
Game Design and Development Workshop Day 1
 
TDAD
TDADTDAD
TDAD
 
Java 8 Lambda Expressions
Java 8 Lambda ExpressionsJava 8 Lambda Expressions
Java 8 Lambda Expressions
 
Testing and validating distributed systems with Apache Spark and Apache Beam ...
Testing and validating distributed systems with Apache Spark and Apache Beam ...Testing and validating distributed systems with Apache Spark and Apache Beam ...
Testing and validating distributed systems with Apache Spark and Apache Beam ...
 
2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests
 

Recently uploaded

From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
Product School
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Product School
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
Paul Groth
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
Jemma Hussein Allen
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
Ana-Maria Mihalceanu
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
Product School
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Ramesh Iyer
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Tobias Schneck
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
Laura Byrne
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
Kari Kakkonen
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
Safe Software
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
ControlCase
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
DanBrown980551
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Product School
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Product School
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
Cheryl Hung
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
DianaGray10
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
91mobiles
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance
 

Recently uploaded (20)

From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
 

Stored Procedures and MUMPS for DivConq

  • 3. About DivConq http://www.divconq.com/about/ Getting Started With DivConq http://www.divconq.com/home/getting-started/ This presentation is part of a sequence of presentations on DivConq’s database features. Visit the Getting Started page at our website to see the suggested order for our presentations.
  • 5. In the previous presentations we focused on how stored procedures worked within Java. Things like the request-response flow, request objects, callbacks, schema and JSON-Like data structures. In the coming slides the focus is going to be on MUMPS development for stored procedures. We’ll use some examples that ship with DivConq Framework so you can follow along.
  • 6. D:devdivconqtemplate>.binrun.bat testdb Command testdb Starting Hub ... You should recall how to run TestDb from previous presentations in Getting Started. If not then you may wish to review those presentations.
  • 7. Select option 4 “Load stored proc results (testProc1)”. The output we see will be JSON, but keep in mind the database result uses DivConq’s Struct classes (JSON-Like API). Your output should be: testProc1 Response: { "Name": "Sally", "Age": 5, "Toys": [ "Legos", "Puzzle" ] , "Friends": [ { "Name": "Chad", "Age": 5 } , { "Name": "Ginger", "Age": 6 } ] }
  • 8. D:devdivconqtemplatepackagesdcTestmdctTest.m Open the MUMPS code file dctTest.m ni a text editor to follow within the real source code.
  • 9. testProc1 n data,tnum,fnum ; s data("Name")="Sally" s data("Age")=5 s data("Toys",1)="Legos" s data("Toys",2)="Puzzle" s data("Friends",1,"Name")="Chad" s data("Friends",1,"Age")=5 s data("Friends",2,"Name")="Ginger" s data("Friends",2,"Age")=6 ; [continued] This first and simplest example starts by populating a local MUMPS data structure.
  • 10. [continued] w StartRec w Field_"Name"_ScalarStr_data("Name") w Field_"Age"_ScalarInt_data("Age") ; w Field_"Toys"_StartList f s tnum=$o(data("Toys",tnum)) q:tnum="" d . w ScalarStr_data("Toys",tnum) w EndList ; [continued] Java output from this part: { "Name": "Sally", "Age": 5, "Toys": [ "Legos", "Puzzle" ] , Then the result is started by using MUMPS’ “write” commands. The start of a record or list begins with StartRec or StartList. The start of a field name starts with Field. The start of a field value or item is always ScalarNNN.
  • 11. [continued] w Field_"Friends"_StartList f s fnum=$o(data("Friends",fnum)) q:fnum="" d . w StartRec . w Field_"Name"_ScalarStr_data("Friends",fnum,"Name") . w Field_"Age"_ScalarInt_data("Friends",fnum,"Age") . w EndRec w EndList [continued] Java output from this part: "Friends": [ { "Name": "Chad", "Age": 5 } , { "Name": "Ginger", "Age": 6 } ] “Friends” is a field. The field value is a list of records where each record has two fields. Note how EndRecord and EndList are paired, you must have an EndNNN for every StartNNN. Field and ScalarNNN do not need an ending delineator.
  • 12. [continued] ; w EndRec ; quit Java output from this part: } Stored procedures will always return a record or a list. So the last “write” command in a stored proc should always be EndRec or EndList – to match the first write.
  • 13. $ sudo su gtmuser $ cd ~ $ ./gtmcon GTM>d local^dcConn("QUERY testProc1") Data: { , Name: Sally, Age: 5, Toys[ : Legos: Puzzle] , Friends[ { , Name: Chad, Age: 5} { , Name: Ginger, Age: 6} ] } ! Messages: [ ] ! Stored procedures are used by Java, but if you want to test your procedure in MUMPS you may emulate a Java call. Bring up the MUMPS prompt, something like above, and then call local^dcConn to run the procedure. When calling procedures this way you’ll want to use “UPDATE” or “QUERY” – only use “UPDATE” if the call will change data in the database.
  • 14. { , Name: Sally, Age: 5, Toys[ : Legos: Puzzle] , Friends[ { , Name: Chad, Age: 5} { , Name: Ginger, Age: 6} ] } ! The results returned to Java from stored procedures are not in JSON format. Likewise, when we run the procedure within MUMPS we aren’t getting pure JSON but we do get something similar. Once you get used to ", " preceding every field (e.g. “, Name” and ": " preceding every scalar (e.g. “: Legos”) then it is not too bad to read.
  • 15. QueryRequest tp1 = new QueryRequest("testProc1"); ObjectCallback callback = new ObjectCallback() { @Override public void process(ObjectResult res) { if (res.hasErrors()) { System.out.println(" Error:"); TestDb.printPretty(res.getMessages()); } else { System.out.println(" Response:"); TestDb.printPretty(res.getResult()); } } }; Hub.instance.getDatabase().submit(tp1, callback); A quick look back at how to call from Java, note the “Query” in QueryRequest and the use of the name “testProc1”. Also note no parameters are used.
  • 16. GTM>s Params(0)="gun" GTM>s Params(1)="candy" GTM>d local^dcConn("QUERY testProc2") Data: ! Messages: [ { , Level: Error, Code: 1, Message: Gun not allowed in toy list} { , Level: Error, Code: 1, Message: Candy not allowed in toy list} ] ! Lets run the next test procedure, testProc2. This one will show us how to return messages from a stored proc. Messages are not result data, but rather information for tracing, info, warnings or errors. Only a few messages should be returned from a procedure, do not try to return hundreds or more. Note you can add a message anytime during the output generation – in the middle of a Field is fine. Also we see how to pass Params from the M command line.
  • 17. testProc2 n tnum,toy ; ; validate your inputs, if toy list is not there do not continue i $d(Params)<10 d errMsg^dcConn("Missing toy list") quit ; ; continue input validation, check for undesirable toys f s tnum=$o(Params(tnum)) q:tnum="" d . s toy=Params(tnum) . s toy=$$toUpper^dcStrUtil(toy) . i toy["GUN" d errMsg^dcConn("Gun not allowed in toy list") q . i toy["CANDY" d errMsg^dcConn("Candy not allowed in toy list") q . i toy["HAMMER" d warnMsg^dcConn("A hammer may not be safe for this age") q We expect a list of toys for our parameters. A check with $d tells us if the list is missing. If so, then we need to add an error message and quit the routine. Calling errMsg or warnMsg in dcConn is one way to do this, we’ll see another way soon. Note that it is ok to “quit” before any output if there is an error. In Java always check for errors in the result (ObjectResult) before processing the data. Ignore the result data if an error occurred.
  • 18. testProc2 n tnum,toy ; ; validate your inputs, if toy list is not there do not continue i $d(Params)<10 d errMsg^dcConn("Missing toy list") quit ; ; continue input validation, check for undesirable toys f s tnum=$o(Params(tnum)) q:tnum="" d . s toy=Params(tnum) . s toy=$$toUpper^dcStrUtil(toy) . i toy["GUN" d errMsg^dcConn("Gun not allowed in toy list") q . i toy["CANDY" d errMsg^dcConn("Candy not allowed in toy list") q . i toy["HAMMER" d warnMsg^dcConn("A hammer may not be safe for this age") q Loop the list of toys in our parameters. Check if the toy matches some key word, if so create an error and continue in the loop. Every toy that fails will generate a message. This should be capped, do not return more than a hundred messages this way.
  • 19. i Errors quit ; ; if only warnings or no validation messages then proceed w StartList f s tnum=$o(Params(tnum)) q:tnum="" d . s toy=Params(tnum) . s toy=$$toUpper^dcStrUtil(toy) . w ScalarStr_toy w EndList ; quit Before we do the output, which just echoes the list back, first check for any error messages. Remember the validation loops all toys and may generate one or more warning or error. Doing “i Errors quit” ensures that we don’t bother with output if an error was created in a previous step.
  • 20. ListStruct toys = new ListStruct("gun", "candy"); QueryRequest tp2 = new QueryRequest("testProc2", toys); ... Submit ... // in your callback be sure to check for errors if (res.hasErrors()) { System.out.println(" Error:"); TestDb.printPretty(res.getMessages()); } A glance back at calls from Java. Note passing the List of toys as parameters.
  • 21. Coding and Testing in MUMPS
  • 22. DivConq Name MUMPS Write Type String ScalarStr Integer ScalarInt BigInteger ScalarBigInt Decimal ScalarDec BigDecimal ScalarBigDec Boolean ScalarFalse, ScalarTrue or ScalarBool_”true|false” Null ScalarNull Binary ScalarBin DateTime ScalarDateTime BigDateTime ScalarBigDateTime Above is a list of most the ScalarNNN types as they relate to the types in Schema/Java. To refresh yourself on the data types, see the “Data Types in DivConq” presentation.
  • 23. Java ListStruct toys = new ListStruct("gun", "candy"); // as used with QueryRequest tp2 = new QueryRequest("testProc2", toys); MUMPS Params(0)="gun" Params(1)="candy" Lists in Java become numerical keys in MUMPS, starting at 0.
  • 24. Java RecordStruct params = new RecordStruct( new FieldStruct("MinAge", 30), new FieldStruct("MaxAge", 48) ); MUMPS Params("MinAge")=30 Params("MaxAge")=48 Records in Java become keyed by field name in MUMPS.
  • 25. Java ListStruct toys = new ListStruct( new RecordStruct( new FieldStruct("Name", "Mike"), new FieldStruct("Age", 44) ), new RecordStruct( new FieldStruct("Name", "Mary"), new FieldStruct("Age", 38) ) ); MUMPS Params(0,"Name")="Mike" Params(0,"Age")=44 Params(1,"Name")="Mary" Params(1,"Age")=38 Lists of Records become numerical keys with field name sub-keys.
  • 26. Java RecordStruct params = new RecordStruct( new FieldStruct("Name", "Mike"), new FieldStruct("Age", 14), new FieldStruct(“Toys", new ListStruct( "Bike", "Soccer Ball" ) ) ); MUMPS Params("Name")="Mike" Params("Age")=14 Params("Toys",0)="Bike" Params("Toys",1)="Soccer Ball" Records with lists become field name keys with numerical sub-keys.
  • 27. Java RecordStruct params = new RecordStruct( new FieldStruct("Name", "Mike Jr."), new FieldStruct("Age", 14), new FieldStruct("Dad", new RecordStruct( new FieldStruct("Name", "Mike Sr."), new FieldStruct("Age", 44) ) ) ); MUMPS Params("Name")="Mike Jr." Params("Age")=14 Params("Dad","Name")="Bike Sr." Params("Dad","Age")=44
  • 28. Java ListStruct params = new ListStruct( new ListStruct( "Bike", "Soccer Ball" ), new ListStruct( "Bat", "Soft Ball" ) ); MUMPS Params(0,0)="Bike" Params(0,1)="Soccer Ball" Params(1,0)="Bat" Params(1,1)="Soft Ball"
  • 29. MUMPS has some limits to how big your keys and your values can get, but within reason you can send very complex JSON-Like structures. There is more than just the examples above. You can have a list of records that have fields with lists of records. Params([numerical],[field name],[numerical],[field name])=NNN Or any combination of lists and records as long as it follows MUMPS limitations (or specifically GT.M’s limitations – though if you used DivConq with Cache you’d have to watch the limitations for Cache).
  • 31. testProc3 n tnum,toy,utoy ; ; validate your inputs, if toy list is not there do not continue i $d(Params)<10 d err^dcConn(90000) quit ; ; continue input validation, check for undesirable toys f s tnum=$o(Params(tnum)) q:tnum="" d . s toy=Params(tnum) . s utoy=$$toUpper^dcStrUtil(toy) . i (utoy["GUN")!(utoy["CANDY") d err^dcConn(90001,toy) q . i utoy["HAMMER" d warn^dcConn(90002,toy) q ; i Errors quit ... The preferred way to send a message is to use a message code. Message codes can be used to translate a message to the user’s locale. Note the calls to “err” and “warn” in dcConn. Pass the code and, optionally, up to 6 parameters. There is also an “info” and a “trace” function. For now you may use the 80,000 – 89,999 code range in your projects.
  • 32. D:devdivconqtemplatepackagesdcTestalldictionarydictionary.xml D:devdivconqtemplatepackagesdcTestalldictionaryx-pig-latin.xml Every DivConq package should have a dictionary file (or many). The name of the file doesn’t matter, though we can see that one file in dcTest contains Pig Latin. What does matter is that you have an entry for every code in every supported language.
  • 33. <Dictionary> <Locale Id="en"> <Entry Token="_code_90000" Value="Missing toy list" /> <Entry Token="_code_90001" Value="Toy not allowed: {$1}" /> <Entry Token="_code_90002" Value="Toy may not be safe: {$1}" /> <Entry Token="_code_90010" Value="Missing required fields" /> </Locale> </Dictionary> The first file contains only English (see Id attribute of Locale element). In testProc3 the call to “d err^dcConn(90000)” produces “Missing toy list” when using the English locale. The call to “d warn^dcConn(90002,toy)” on the other hand has a parameter, the toy’s name. The first parameter replaces {$1} in the message, so for a Hammer the message becomes “Toy may not be safe: Hammer”.
  • 34. <Dictionary> <Locale Id="x-pig-latin"> <Entry Token="_code_90000" Value="Issingmay oytay istlay" /> <Entry Token="_code_90001" Value="Oytay otnay allowedway: {$1}" /> <Entry Token="_code_90002" Value="Oytay aymay otnay ebay afesay: {$1}" /> <Entry Token="_code_90010" Value="Issingmay equiredray ieldsfay" /> </Locale> </Dictionary> The second file contains only Pig Latin, though technically both translations could be in the same file. The call to “d err^dcConn(90000)” produces “Issingmay oytay istlay” when using the Pig Latin locale. The call to “d warn^dcConn(90002,toy)” with a Hammer produces “Oytay aymay otnay ebay afesay: Hammer”.
  • 35. We now have a better idea of how to pass data to a stored procedure and how to return data from a stored procedure. We also learned that we can pass status or debugging messages from our stored procedure – and that those messages can be localized.