<!-- 
/*
Copyright 2020 apHarmony

This file is part of jsHarmony.

jsHarmony is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

jsHarmony is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with this package.  If not, see <http://www.gnu.org/licenses/>.
*/
-->
<script type="text/x-tutorial-info">
{
  "Title": "Tasks",
  "ID": "reference_tasks",
  "Menu": ["Language Reference"]
}
</script>

<h3 class="tutorials_intro">Tasks</h3>

<pre>
model := {
  //Same top-level settings as [html]<i><a href="/tutorials/reference_forms">Forms</a></i>[/html]
  "layout": "exec",
  "title": "Task Title",
  "actions": "U",
  "roles": { "ADMIN": "U" },
  "fields": [
    {"name":"cust_id","type":"bigint","validate":["Required"]}
  ],

  //Tasks have the following additional properties
  "task": {
    "commands": [
      //Can use @parameters in the following properties: sql, path, dest, data, email, jsharmony_txt, cmd
      //Can use "js:" prefix to execute javascript in the following properties: sql, path, dest, data, email, jsharmony_txt, cmd
      //sql, js can be multiline array
      //Format { "exec": "...", "param1": "value1", "param2": "value2" }
      //Paths can be absolute, or relative to datadir (except for shell.path - path can be set via cwd)
      /*
      sql (sql, db, into, foreach_row, fields, batch)
      sqltrans(db, for)
      delete_folder (path, recursive)
      create_folder (path)
      move_folder (path, dest)
      list_files (path, matching, into, foreach_file) *** matching can be exact match, wildcard, or /regex/
      delete_file (path)
      copy_file (path, dest, overwrite)
      move_file (path, dest, overwrite)
      write_file (path, text, overwrite)
      append_file (path, text)
      read_file (path, into, foreach_line)
      write_csv (path, db, data, sql, fields, headers, csv_options)
      append_csv (path, db, data, sql, fields, headers, csv_options)
      read_csv (path, into, foreach_row, fields, headers, pipe, csv_options)
      js (js, into, foreach) --> update parameters, custom validation, return an array foreach - can return promise for async operations
      shell (path, params, cwd, into, foreach_stdio, foreach_stdio_line, foreach_stderr, foreach_stderr_line)
      log (path, level, text)  //path can contain %YYYY%MM%DD
      email ( email: {to, cc, bcc, subject, text, html, attachments} ) //Attachments = { path: ... }
      email ( jsharmony_txt: {txt_attrib, to, cc, bcc, attachments} )  //Attachments = { path: ... }
      */
      //Examples
      { "exec": "sql", "sql": "insert into cust(cust_name, cust_sts) values ('New customer', 'ACTIVE');" },
      { "exec": "delete_folder", "path": "sample_task", "recursive": true },
      { "exec": "create_folder", "path": "sample_task" },
      { "exec": "sqltrans", "for": [
        { "exec": "sql", "sql": "select cust_id, cust_name from cust", "into": "src",
          "fields":[
            {"name":"cust_id","type":"bigint"},
            {"name":"cust_name","type":"varchar","length":255,"validate":["Required"]},
          ],
          "foreach_row":[
            { "exec": "sql", "sql":"update cust set cust_sts = 'HOLD' where cust_id=@src.cust_id", "batch": 100 }, //@parameters - input parameters, fields from each parent row
          ]
        },
      ] },
      { "exec": "list_files", "path": "sample_folder", "matching": ["*.csv"], "into": "csvfile",
        "foreach_file": [
          { "exec": "read_csv", "path": "@csvfile.path", "into": "csvdata", "headers": false, "pipe": "require('zlib').createGunzip()", "csv_options": { "delimiter": "\t" },
            "fields": [
              {"name":"country"},
              {"name":"id"},
            ],
            "foreach_row": [
              { "exec": "sql", "sql": "insert into cust(cust_name, cust_sts) values (@csvdata.id, 'ACTIVE');" },
              { "exec": "write_file", "path": "sample_task\\@csvdata.id.tmp", "text": "TMP File" },
              { "exec": "write_file", "path": "sample_task\\@csvdata.id.txt", "text": "Country: @csvdata.country\n" },
              { "exec": "append_file", "path": "sample_task\\@csvdata.id.txt", "text": "Complete" },
              { "exec": "delete_file", "path": "sample_task\\@csvdata.id.tmp" },
            ]
          },
        ]
      },
      { "exec": "write_csv", "path": "sample_task\\cust.csv", "sql": "select cust_id,cust_name from cust order by cust_id asc", "headers": true },
      { "exec": "append_csv", "path": "sample_task\\cust.csv", "sql": "select cust_id,cust_name from cust order by cust_id desc" },

      { "exec": "write_csv", "path": "sample_task\\numbers.csv", "data": [{"Number": 2.7}], "headers": true },
      { "exec": "append_csv", "path": "sample_task\\numbers.csv", "data": [9.8] },
      { "exec": "append_csv", "path": "sample_task\\numbers.csv", "data": [[1.4],[2]] },
      { "exec": "append_csv", "path": "sample_task\\numbers.csv", "data": {"Number": 3} },
      { "exec": "read_file", "path": "sample_folder\\Numbers.txt", "into": "number",
        "foreach_line": [
          { "exec": "append_csv", "path": "sample_task\\numbers.csv", "data": {"Number": "@number.text"} },
          { "exec": "js", "js": "params['number.text'].value = 'Again'+params['number.text'].value;" },
          { "exec": "append_csv", "path": "sample_task\\numbers.csv", "data": {"Number": "@number.text"} },
        ]
      },
      { "exec": "copy_file", "path": "sample_task\\numbers.csv", "dest": "sample_task\\numbers2.csv", "overwrite": true },
      { "exec": "move_file", "path": "sample_task\\numbers2.csv", "dest": "sample_task\\numbers3.csv", "overwrite": true },
      { "exec": "create_folder", "path": "sample_task\\test_folder" },
      { "exec": "move_folder", "path": "sample_task\\test_folder", "dest": "sample_task\\test_folder2" },
      { "exec": "js", "js": "return [{ key: 1 },{ key: 2 },{ key: 4 }]", "into": "jsdata", "foreach": [
        { "exec": "append_file", "path": "sample_task\\jsoutput.txt", "text": "Key: @jsdata.key\n" },
      ] },
      { "exec": "js", "js": "return new Promise(function(resolve,reject){ resolve([{ rslt: 'success'}]); });", "into": "jspromise", "foreach": [
        { "exec": "append_file", "path": "sample_task\\jspromise.txt", "text": "Rslt: @jspromise.rslt\n" },
      ] },
      { "exec": "shell", "path": "cmd", "params": ["/c", "echo abc > sample_task\\a.a"] },
      { "exec": "shell", "path": "cmd", "params": ["/c", "dir"], "into": "dir_output",
        "foreach_stdio_line": [
          { "exec": "js", "js": "console.log(params['dir_output.stdio'].value);" },
        ],
        "foreach_stderr_line": [
          { "exec": "log", "level": "error", "text": "@dir_output.stderr" },
        ],
      },
      { "exec": "email", "email": { "to": "test@test.com", "subject": "Task Complete", "text": "The task is complete: @cust_id", "attachments": [ { "path": "sample_task\\numbers.csv" } ] } },
      { "exec": "email", "jsharmony_txt": { "txt_attrib": "SAMPLE_EMAIL", "to": "test@test.com", "attachments": [ { "path": "sample_task\\numbers.csv" } ] } },
    ],
    //Log paths can be absolute or relative to logdir
    "log": [
      {
        "path": "sample-task-%YYYY%MM%DD.log",
        "events": ["debug","info","warning","error"],
      }
    ],
    "onerror": [
      { "email": { "to": "test@test.com", "subject": "Error exporting data" } }
    ]
  }
}
</pre>