      * ILE RPG example of a REST provider with multiple parameters
      *
      * This gets it's input parameters from the URL, in a format
      * like this:
      *
      *    http://whatever/rest/invoice/495/20100901/20100930
      *
      * It will then look up all invoices for the customer number
      * in the provided date range, and output them all in a
      * list like this one:
      *
      *     { "success": true,
      *       "errmsg": "",
      *       "list": [{
      *          "invno": "xyz",
      *           "date": "2012-01-23",
      *           "name": "Acme Industries, Inc.",
      *         "amount": 123.45,
      *         "weight": 123.45,
      *       },
      *       { same fields again },
      *       { same fields again },
      *       { etc }
      *     ]}
      *
      *
      *  To compile:
      *> CHGCURLIB SKWEBSRV
      *> CRTSQLRPGI INVOICE SRCFILE(QRPGLESRC) DBGVIEW(*SOURCE) -
      *>            OBJTYPE(*MODULE)
      *> CRTPGM INVOICE BNDSRVPGM(QHTTPSVR/QZHBCGI) ACTGRP(RESTFUL)

     H OPTION(*SRCSTMT: *NODEBUGIO) PGMINFO(*PCML:*MODULE)

     D getenv          PR              *   extproc('getenv')
     D   var                           *   value options(*string)

     D QtmhWrStout     PR                  extproc('QtmhWrStout')
     D   DtaVar                   65535a   options(*varsize) const
     D   DtaVarLen                   10I 0 const
     D   ErrorCode                 8000A   options(*varsize)

     D err             ds                  qualified
     D   bytesProv                   10i 0 inz(0)
     D   bytesAvail                  10i 0 inz(0)

     D xml             pr          5000a   varying
     D   inp                       5000a   varying const

     D row             ds                  qualified
     D   inv                          5a
     D   date                         8s 0
     D   name                        25a
     D   amount                       9p 2
     D   weight                       9p 1

     D CRLF            C                   x'0d25'
     D data            s           5000a   varying
     D uri             s           5000a   varying
     D cust            s              4s 0
     D sdate           s              8s 0
     D edate           s              8s 0
     d custpos         s             10i 0
     d sdatepos        s             10i 0
     d edatepos        s             10i 0
     D jsonName        s             25a
     D jsonDate        s             10a

      * Unicode versions of {, }, [ and ], respectively.
     D LBRACE          C                   u'007b'
     D RBRACE          C                   u'007d'
     D RSQB            C                   u'005d'
     D LSQB            C                   u'005b'

      /free
          exec SQL set option naming=*SYS;

          *inlr = *on;
          uri = %str(getenv('REQUEST_URI'));

          monitor;
             custpos = %scan('/invoice/': uri) + %len('/invoice/');
             sdatepos = %scan('/': uri: custpos) + 1;
             edatepos = %scan('/': uri: sdatepos) + 1;
             cust  = %int(%subst(uri: custpos: (sdatepos-custpos-1)));
             sdate = %int(%subst(uri: sdatepos: (edatepos-sdatepos-1)));
             edate = %int(%subst(uri: edatepos));
          on-error;
             data = 'Status: 500 Invalid URI' + CRLF
                  + 'Content-type: text/plain' + CRLF
                  + CRLF
                  + %char(LBRACE) + CRLF
                  + '"success": "false",' + CRLF
                  + '"errmsg": "An unknown URI format was given"' + CRLF
                  + %char(RBRACE) + CRLF;
             QtmhWrStout(data: %len(data): err);
             return;
          endmon;

          exec SQL declare C1 cursor for
              select aiOrdn, aiIDat, aiSNme, aiDamt, aiLbs
                from ARSHIST
               where aiCust = :cust
                 and aiIDat between :sdate
                                and :edate;

          exec SQL open C1;
          exec SQL fetch next from C1 into :row;

          if sqlstt<>'00000'
             and %subst(sqlstt:1:2) <> '01'
             and %subst(sqlstt:1:2) <> '02';
             data = 'Status: 500 Query Failed' + CRLF
                  + 'Content-type: text/plain' + CRLF
                  + CRLF
                  + %char(LBRACE) + CRLF
                  + '"success": "false",' + CRLF
                  + '"errmsg": "SQL Failed with SQLSTT='+SQLSTT+'"' + CRLF
                  + %char(RBRACE) + CRLF;
             QtmhWrStout(data: %len(data): err);
             return;
          endif;

          data = 'Status: 200 OK' + CRLF
               + 'Content-type: text/plain' + CRLF
               + CRLF
               + %char(LBRACE) + CRLF
               + '"success": "true",' + CRLF
               + '"errmsg": "",' + CRLF
               + '"list": ' + %char(LSQB);
          QtmhWrStout(data: %len(data): err);

          dow %subst(sqlstt:1:2)='00' or %subst(sqlstt:1:2)='01';
             jsonName = %scanrpl( '"': '\"': row.name );
             jsonDate = %char( %date( row.date: *iso ): *iso );
             data = %char(LBRACE) + CRLF
                  + '   "invno": "' + row.inv           + '",' + CRLF
                  + '    "date": "' + jsonDate          + '",' + CRLF
                  + '    "name": "' + %trim(jsonName)   + '",' + CRLF
                  + '  "amount": "' + %char(row.amount) + '",' + CRLF
                  + '  "weight": "' + %char(row.weight) + '"'  + CRLF
                  + %char(RBRACE);
             QtmhWrStout(data: %len(data): err);

             exec SQL fetch next from C1 into :row;
             if %subst(sqlstt:1:2)='00' or %subst(sqlstt:1:2)='01';
                data = ',' + CRLF;
             else;
                data = CRLF;
             endif;
             QtmhWrStout(data: %len(data): err);
          enddo;

          exec SQL close C1;

          data = %char(RSQB) + %char(RBRACE) + CRLF;
          QtmhWrStout(data: %len(data): err);
          return;
      /end-free
