Skip to main content

1E SDK

Basic syntax

Simple method execution

A Tachyon instruction is composed of one or more sequential statements in the Agent language, separated by a semi-colon. At its simplest, this might be a single method invocation:

Example - query all active network connections

Network.GetConnections();

This example executes the GetConnections method on the Network module.

The set of data returned from this instruction might look as follows:

233276248.png

Implicit in this statement is the "return" of the output data from this method call as the result of the instruction. Each Tachyon instruction returns a single set of data (in the form of a table), and it is this data that is sent back to the Tachyon Server and ultimately displayed in Tachyon Explorer. The data returned from an instruction is based on the last set of data the instruction produces.

For example, the following instruction:

Example - query network connections, then logged on users

Network.GetConnections();
Users.GetLoggedOnUsers();

… will retrieve the active network connections, but then immediately discard the output. It will then query the logged-on users, and return that output as the result of the instruction (as that is the set of data produced).

The output of this instruction might look as follows:

233276247.png

Although the Agent language permits this type of construct, it is clearly not useful in this context – two methods are executed, but only the data from the last is available. Things start to come together when the data from multiple method executions are combined using SQL. This is discussed in detail later.

Use of white-space

Although this example shows the two method statements on separate lines for readability, whitespace within the language is not treated as significant. The two statements could appear on the same line.

Case sensitivity

The Agent Language is case-sensitive with respect to names of modules, methods and parameters.

Although some aspects of the Agent Language are more permissive in terms of character case, it is recommended that you treat the entire language as case sensitive.

Strings and Escaping

String literals should be enclosed in double-quotes (").

Warning

Single-quotes (') are deprecated. Despite being permitted in SQLite, they should not be used. They are acceptable in the current version of Tachyon but this may change in the future due to potential difficulties with escaping.

The escape character is a backslash (\).

If a literal double-quote is required in a string then use the escape character (\").

If a literal escape character is required in a string then use backslash-backslash (\\).

The following is an example of both uses.

Example - String escaping

// Result: The Tachyon Agent log is found in "C:\ProgramData\1E\Tachyon\" by default.
 
SELECT "The Tachyon Agent log is found in \"C:\\ProgramData\\1E\\Tachyon\\\" by default." AS Tip;

The following examples are different ways of achieving the same thing, depending on your preference for readability.

Example - String concatenation

// Result: James says "I would like sausages today" every morning.

@breakfast = SELECT "sausages" AS choice;

SELECT "James says \"I would like " || choice || " today\" every morning." AS greeting FROM @breakfast;

SELECT "James says " || CHAR(34) || "I would like " || choice || " today" || CHAR(34) || " every morning." AS greeting FROM @breakfast;

SELECT PRINTF("James says \"I would like %s today\" every morning.", choice) AS greeting FROM @breakfast;

SELECT PRINTF("James says %sI would like %s today%s every morning.", CHAR(34), choice, "\"") AS greeting FROM @breakfast;
Passing method parameters

Now we’ll consider passing parameters to a method. Parameters are passed by specifying their name and value within the parentheses following a method name. Some examples:

Example - passing simple parameters

/* Pass a string parameter */
Users.GetLocalGroupMembers(GroupName: "Administrators");
/* Pass an integer parameter */
Agent.Sleep(Seconds: 5);
/* Pass a string parameter and a boolean parameter */
FileSystem.GetFilesInFolder(Folder: "D:\\MyData\\MyPictures", Recursive: true);

Note the following about parameters:

  • Parameter names are case-sensitive

  • Parameters can be supplied in any order

  • Parameters can be omitted if they are optional

  • Parameter values have datatypes – strings are enclosed in double-quotes (and use the backslash character to escape either a literal double quote or a backslash itself); numbers and Booleans should not be enclosed in double-quotes

    • For Tachyon Agent versions 3.2 and onwards, a boolean can also be supplied as an sqlite3 integer. In such a case, zero will be interpreted as false, and any non-zero integer will be interpreted as true. A real will not be accepted. For example:

      v3.3+

      // Recursion on
      FileSystem.GetFilesInFolder(Folder:"c:\\potato", Recursive: true)
      FileSystem.GetFilesInFolder(Folder:"c:\\potato", Recursive: -15)
      FileSystem.GetFilesInFolder(Folder:"c:\\potato", Recursive: 65535)
      // Recursion off
      FileSystem.GetFilesInFolder(Folder:"c:\\potato", Recursive: false)
      FileSystem.GetFilesInFolder(Folder:"c:\\potato", Recursive: 0)
  • Parameter values can be supplied using @table – this is an advanced topic discussed in Passing @tables as method parameters

@tables

@tables have the following properties:

  • they are used to store the output of Agent methods and SQL queries, and must be considered as SQLite tables, and as such can have multiple rows and columns, as well as empty tables with no rows.

  • their names must be alphanumeric, and start with a letter, and are case-sensitive

  • they can be used as parameters for Agent methods

  • they can be re-created and re-used multiple times within an instruction

Example - @tables

@device = Device.GetSummary();
@device = SELECT Manufacturer, Model FROM @device;

You can also store a numeric or string value, without the need for a full SELECT statement. The column name is Value.

Example - @tables

@table = 99;
SELECT Value FROM @table;

You can create your own @tables. One method is:

@colors = 
  SELECT
    column1 AS ColorName, column2 AS ColorCode
  FROM
  ( VALUES 
    ("Green","#008000"),
    ("Blue", "#0000FF"),      
    ("Yellow", "#FFFF00"),
    ("Cyan", "#00FFFF"),
    ("Red", "#FF0000"),  
    ("Purple", "#800080")
   );

@tables are deleted and memory freed when an instruction exits.

SQLite tables have a built-in autoincremented key rowid which is not included in output, unless specified in a SELECT statement. An example of where rowid is useful is when using SplitLines in methods, for example in NativeServices.RunCommand and Utilities.SplitLines.

The Tachyon built-in function IsUndefined is used to determine whether a table is real and full of values or whether it is the result of an operation that produced nothing, which is different to producing an empty table.

SQL queries

Having executed a method, the data can be returned directly from the instruction, or can be assigned to a @table for further processing.

In the following example, we capture all the active network connections, assign them to a @table, and then run a SQL SELECT query to count them, grouped by the process name (i.e. count number of network connections per process):

Example - count network connections by process

@connections = Network.GetConnections();

@connections = SELECT   COUNT(1) AS ConnectionCount
,        ProcessName
FROM     @connections
GROUP BY ProcessName;

Since the last statement of this instruction is our SQL query, the output of this query becomes the result of the instruction. The example shows the results of the SQL query are saved in a table called @connections which could be used by further methods or queries.

See SQL section above for useful references on the SQLite website.

Reserved keywords

The following are keywords, which are reserved, and should not be used as names of @tables or columns. Potential future keywords should also be avoided because any instructions that use these words may be invalidated, so do not use them.)

1.0

v3.0.0

v3.3

Potential future

  • EVALUATE

  • FALSE

  • TRUE

  • DO

  • DONE

  • FOREACH

  • IN

  • IF

  • ELSE

  • ENDIF

  • ERROR

  • NOCONTENT

  • NOTIMPLEMENTED

  • RETURN

  • ANY

  • BREAK

  • EMPTY

  • NONE

  • THEN

  • WHILE

Comments

Comments can either be multi-line or single-line.

Outside of SQL statements the Agent language supports C-style comments.

Agent language examples

/* This is a comment
   which spans
   multiple lines */

@connections = Network.GetConnections(); // This comment continues until the next line break

Within SQL statements, comments are are subject to what is supported by SQLite (see http://www.sqlite.org/lang_comment.html).

SQL examples

/* This is a comment
   which spans
   multiple lines */

@flag = SELECT 1 AS value; -- This comment continues until the next line break

Multi-line comments are supported in all cases, and can also be used for single-line, provided you remember to terminate the comment.

General example

@flag = SELECT 1 AS value; /* This is a comment that has been correctly terminated */

Known issue

Comments within SQL statements should not include an unterminated quote, single or double. This is not a problem outside of a SQL statement.

Use of comments

Although comments are useful to annotate code, they do not serve any functional purpose. As such, you may wish to consider removing comments from your instructions, otherwise you will be sending comments to each Agent over the network only for them to be ignored when they are processed. At large scales, making small savings on payload sizes (e.g. by removing comments or reducing whitespace) can help to reduce network traffic.