Skip to main content

TQL programming rules and best practices

This section covers the rules you must follow when writing TQL applications as well as best practices that will make development easier and more efficient. Refer to the Striim concepts or Glossary if you are unfamiliar with any of the terminology.

Namespaces

Namespaces are logical domains within the Striim environment that contain applications, flows, their components such as sources, streams, and so on, and dashboards.

Every user account has a personal namespace with the same name. For example, the admin user has the admin namespace.

Every Striim application exists in a namespace. For example, if you install an evaluation version using the installer, the PosApp application is in the Samples namespace.

See Using namespaces for more information.

Connections

A Striim application consists of a set of components and the connections between them. Some components may be connected directly, others must use an intermediate stream, as follows:

  • source (OUTPUT TO) > stream > CQ (SELECT FROM)

  • source (OUTPUT TO) > stream > window (OVER)

  • source (OUTPUT TO) > stream > target (INPUT FROM)

  • cache > CQ (SELECT FROM)

  • WActionStore > CQ (SELECT FROM)

  • window > CQ (SELECT FROM)

  • window > CQ (SELECT FROM window, INSERT INTO stream) > stream > window (OVER)

  • CQ (INSERT INTO) > WActionStore

  • CQ (INSERT INTO) > stream > target (INPUT FROM)

Note

The output from a cache or window must be processed by a CQ's SELECT statement before it can be passed to a target. In other words, cache > stream > target and window > stream > target are invalid sequences.

Joins

Inner joins may be performed implicitly by specifying multiple sources in the FROM clause. For example:

FROM PosData5Minutes p, HourlyAveLookup l

Other joins must be explicitly declared. See CREATE CQ (query).

A join must include bound data, in other words, at least one cache, event table, WActionStore, or window. For example, assuming that

StoreOrders is a stream that originated from a source and ZipCodeLookup is a cache, the following is valid:

SELECT s.storeId, z.latVal, z.longVal
FROM StoreOrders s, ZipCodeLookup z
WHERE s.zip = z.zip

When joining events from multiple streams, the CQ's SELECT FROM should reference windows rather than streams. See the LargeRTCheck and ZeroContentCheck flows in the MultiLogApp sample application for examples. Define the windows so that they are large enough to include the events to be joined. If necessary, use the GRACE PERIOD option (see CREATE STREAM) and/or a sorter (see CREATE SORTER) to ensure that the events' timestamps are in sync.

Dependencies

You must create a component before you can reference it in the CREATE statement for another component.

component type

create after

create before

application

any other component

flow*

its containing application

the components it contains

source

  • any window for which its output stream is an input (OVER)

  • any query for which its output stream is an input (SELECT FROM)

type

  • any stream for which it is the type (OF)**

  • any cache for which it is the type (OF)

  • referencing it in a WActionStore's CONTEXT OF or EVENT TYPES clause

stream

its type**

  • any source for which it is the output (OUTPUT TO)

  • any window for which it is the input (OVER)

  • any query for which it is an input (SELECT FROM)

  • any targets for which it is the input (INPUT FROM)

cache

any query for which it is an input (SELECT FROM)

window

its input stream (OVER)

any query for which it is an input (SELECT FROM)

WActionStore

its types (CONTEXT OF and EVENT TYPES)

  • any query for which it is an input (SELECT FROM)

  • any query for which it is the output (INSERT INTO)

CQ (query)

  • all input streams (SELECT FROM)

  • all input caches (SELECT FROM)

  • all input windows (SELECT FROM)

  • its output stream (INSERT INTO)

referencing its output stream in a target

target

its input stream (INPUT FROM)

*When an application contains only one flow, it does not need to be explicitly declared by a CREATE FLOW statement. See PosApp for an example of an application with a single flow and MultiLogApp for an example with multiple flows.

**When a stream is created automatically by referencing it in a source's OUTPUT TO clause, it will use the built-in type associated with the source's adapter, so it is not necessary to manually create the type first.

Component names

Names of applications, flows, sources, and so on:

  • must contain only alphanumeric characters and underscores

  • may not start with a numeric character

  • must be unique within the namespace

  • must not be reserved keywords (see List of reserved keywords)List of reserved keywords

Components cannot be renamed. In the Flow Designer, you can copy a component and give it a new name.

Grouping statements and commenting

TQL supports SQL-style comments. For example:

-- The PosApp sample application demonstrates how a credit card
-- payment processor might use Striim to generate reports on current
-- transaction activity by merchant and send alerts when transaction
-- counts for a merchant are higher or lower than average for the time
-- of day.

CREATE APPLICATION PosApp; ...

To make your TQL easier to read, we recommend grouping statements by CQ or flow and preceding each group with explanatory comments as necessary. See the TQL source code for the Sample applications for programmers for examples.

Including one TQL file in another

You can include one TQL file in another by reference. For example, if part of PosApp were in another file, you could include it in the main file using:

@Samples/PosApp/PosApp_part_2.tql;

You must specify the path relative to the Striim program directory or from root. If you do not, the include will fail with a "file not found" error.