Module:Cargo/doc

From Star Trek Online Wiki
Jump to: navigation, search

This is the documentation page for Module:Cargo


declare[edit source]

This assembles a #cargo_declare call for the given Cargo table, provided its definition is in the defs at the top of the module. This is used in a <noinclude section of a template to permit creating the table. The template in question is almost always going to be the same one making #cargo_store calls in a <includeonly> section to insert values into the table.

Usage is simple:

{{#invoke:cargo|declare|_table=}}

store[edit source]

#cargo_store has to be used directly due to technical issues of framing and when Lua processing happens in the page save, so there is no store function in the module.

query[edit source]

The query function of this module is an alternative to #cargo_query with format=template. It should not be used as an alternative to #cargo_query for any other format.

The latter is subject to an intermittent bug that causes output to appear as unrendered HTML requiring a purge to correct. The query function avoids the bug by processing the template transclusion in Lua after running the query through Cargo, rather than having Cargo perform both steps.

Usage is similar to a #cargo_query call:

{{#invoke:Cargo|query
  |tables=
  |fields=
  |where=
  |join=
  |groupBy=
  |having=
  |orderBy=
  |template=
  |intro=
  |outro=
  |default=
  |limit=
  |offset=
}}

See Extension:Cargo/Querying data for more information, as the parameters here have the same usage as in #cargo_query with the following exceptions:

  • table cannot be used as an alternative to tables
  • join is used instead of join on
  • groupBy is used instead of group by
  • orderBy is used instead of order by
  • This function always behaves as if named args is yes
  • Very important: this module provides important special parameterization features where and having. Using these features allow a number of workarounds for certain Cargo bugs and limitations to be used automatically. In addition, it also handles certain escaping automatically. It is strongly recommended that the parameterization features be used on every query to prevent a number of avoidable errors and complications.

where and having parameterization[edit source]

The parameterization features are similar to Parameterized queries used in many programming languages to avoid the security risks of SQL injection. They have different purposes here, but the way they are used in this module is similar in some ways.

This involves using "placeholders" in the where and having clauses where numeric or quoted values would usually go, and then supplying values for those placeholders in special arguments in the #invoke call. In the clauses, the placeholders are identified by a name in between two question marks, such as ?$value? or ?$value?.

  • The name should begin with # for placeholders used where numeric values should go.
  • The name should begin with $ for placeholders used where quoted values should go.

As an example, suppose you wanted to get all escorts with over 5000 hull strength. Without using parameterization. Using a basic #cargo_query call, it'd look something like this:

{{#cargo_query:
   tables=Ships
  |fields=_pageName
  |where=Ships.type HOLDS "Escort" AND Ships.hull > 5000
  |format=template
  |template=SomeTemplate
}}

Using the query function of this module, the recommended way to write this would instead be something like this:

{{#invoke:Cargo|query
  |tables=Ships
  |fields=_pageName
  |where=Ships.type HOLDS ?$type? AND Ships.hull > ?#hull?
  |$type=Escort
  |#hull=5000
  |template=SomeTemplate
}}

It's true that this simple case doesn't gain anything from it, but it would come in useful if:

  • Any of the values happened to contain text that matched the field names of one of the tables, as this triggers a known Cargo bug. This module automatically detects that as long as the defs table at the top of this module is up to date and applies a workaround.
  • If any quoted value has quotes that are part of the value. This automatically escapes those quotes so they are handled correctly. Otherwise, if you were building a template to use arbitrary values, you'd have to use a #replace to escape them yourself.
  • This often comes in most useful in templates where the values aren't known in advance.

There is a more advanced parameterization feature used to work around limitations with using HOLDS or HOLDS NOT on list fields in Cargo tables. As a general rule, you can only get away with using HOLDS or HOLDS NOT once in a query, though it may work if you don't have to use them on different fields.

For example, say you were looking for all Escorts with Pilot Maneuvers. The way to write this would seem to be:

{{#invoke:Cargo|query
  |tables=Ships
  |fields=_pageName
  |where=Ships.type HOLDS ?$type? AND Ships.abilities HOLDS ?$ability?
  |$type=Escort
  |$ability=Pilot Maneuvers
}}

But this will probably fail, as Cargo will probably not be able to construct a valid SQL query out of this.

This module has a workaround, and this workaround is recommended instead of using HOLDS or HOLDS NOT at all. Instead, you'd write it something like this:

{{#invoke:Cargo|query
  |tables=Ships
  |fields=_pageName
  |where=?%Ships.type.holds? AND ?%Ships.abilities.holds?
  |%Ships.type.holds=Escort
  |%Ships.abilities.holds=Pilot Maneuvers
}}

The module will construct a comparison for each that doesn't actually use HOLDS or HOLDS NOT, though usually give the same result, and can be used multiple times in a single query.

In more detail, the HOLDS or HOLDS NOT workarounds are used like this:

  • Start the name with % to simulate HOLDS and ! to simulate HOLDS NOT
  • Follow with the table name the field to check belongs to and follow that with a .
  • Add the field name and then another . (this with the table name allows the module to look up the correct delimiter from its defs table), which it needs to know.
  • After the last dot, it isn't actually necessary to add anything. Anything more just makes it a unique name, which is useful if you need to do multiple HOLDS checks on the same field. For example ?%Ships.abilities.holds1? AND ?%Ships.abilities.holds2? would let you check for ships that have two specific abilities by passing those abilities through the arguments %Ships.abilities.holds1 and %Ships.abilities.holds2.
    • Using holds or holdsnot here is recommended for readability.