import { JsonQLExpr, JsonQLQuery } from "@mwater/jsonql"; /** * Localized string. The base string is usually the English string. The rest are translations. * language is the language code (e.g. "en", "fr", "sw"). * string[string._base] is the base string, usually English. * string[language] is the translation of the base string to the language. */ export interface LocalizedString { _base: string; [language: string]: string; } export interface Row { [alias: string]: any; } /** Expression. Can be null */ export type Expr = LiteralExpr | FieldExpr | OpExpr | IdExpr | ScalarExpr | CaseExpr | ScoreExpr | BuildEnumsetExpr | VariableExpr | SubqueryExpr | ExtensionExpr | LegacyExpr | null; export interface LiteralExpr { type: "literal"; valueType: LiteralType; idTable?: string; value: any; } export interface IdExpr { type: "id"; table: string; } export interface FieldExpr { type: "field"; table: string; column: string; } export interface OpExpr { type: "op"; table?: string; op: string; exprs: Expr[]; } export interface CaseExprCase { when: Expr; then: Expr; } export interface CaseExpr { type: "case"; /** Table id of table */ table?: string; /** when is a boolean expr */ cases: CaseExprCase[]; /** optional else if no cases match */ else: Expr; } /** Scores an enum or enumset by assigning and summing the scores for each value. */ export interface ScoreExpr { type: "score"; /** Table id of table */ table?: string; /** enum or enumset expression */ input: Expr; /** map of enum/enumset id to score expression */ scores: { [id: string]: Expr; }; } /** Creates an enumset from a set of boolean expressions for each value */ export interface BuildEnumsetExpr { type: "build enumset"; /** Table id of table */ table?: string; /** map of enumset id to boolean expression. If true, will be included */ values: { [id: string]: Expr; }; } /** Expression that references a variable */ export interface VariableExpr { type: "variable"; /** Table of expression that variable references (if relevant) */ table?: string; variableId: string; } /** Expression that runs a correlated subquery */ export interface SubqueryExpr { type: "subquery"; /** Table of expression (table of the outer query, not the inner subquery) */ table?: string; /** Expression to evaluate in subquery */ select: Expr; /** * Table of subquery. Initially undefined to auto-open the * modal to edit the subquery. */ from?: string; /** Where clause of subquery */ where: Expr; /** Order bys of subquery */ orderBys: SubqueryExprOrderBy[]; /** Expressions that are exposed from the outer query to the inner subquery as variables */ outerRefs: SubqueryExprOuterRef[]; } export interface SubqueryExprOrderBy { expr: Expr; dir: "asc" | "desc"; } export interface SubqueryExprOuterRef { /** Unique id of the variable */ id: string; /** Expression from the outer query that is exposed to the inner subquery as a variable */ expr: Expr; } /** Expression which is implemented by an extension to the standard * mWater expressions */ export interface ExtensionExpr { type: "extension"; /** Extension to use */ extension: string; /** Table to which expression applies (if any) */ table?: string; } /** Variable that is referenced in an expression. The value is another expression */ export interface Variable { /** Unique id of the variable */ id: string; /** Localized name of the variable */ name: LocalizedString; /** Localized description of the variable */ desc?: LocalizedString; /** Type of the value of the variable */ type: LiteralType; /** Table that variable expression is for. If present, value is an expression for the table. Note: must be non-aggregate */ table?: string; /** For enum and enumset variables */ enumValues?: EnumValue[]; /** table for id, id[] fields */ idTable?: string; } /** Expression that reaches through a join to then evaluate on the table reached */ export interface ScalarExpr { type: "scalar"; /** Table id of start table */ table: string; /** @deprecated */ aggr?: string; /** @deprecated */ where?: Expr; /** Array of join columns to follow to get to table of expr. All must be `join` type */ joins: string[]; /** Expression from final table to get value */ expr: Expr; } /** @deprecated */ export type LegacyExpr = LegacyComparisonExpr | LegacyLogicalExpr | LegacyCountExpr; /** @deprecated */ export interface LegacyComparisonExpr { type: "comparison"; op: string; table: string; lhs: Expr; rhs: Expr; } /** @deprecated */ export interface LegacyLogicalExpr { type: "logical"; op: string; table: string; exprs: Expr[]; } /** @deprecated */ export interface LegacyCountExpr { type: "count"; table: string; } export type AggrStatus = "individual" | "literal" | "aggregate"; /** Row is a plain object that has the following functions as properties */ export interface ExprEvaluatorRow { /** gets primary key of row. callback is called with (error, value) */ getPrimaryKey(callback: (error: any, value?: any) => void): void; /** gets the value of a column. callback is called with (error, value) * For joins, getField will get array of rows for 1-n and n-n joins and a row for n-1 and 1-1 joins */ getField(columnId: string, callback: (error: any, value?: any) => void): void; } /** Context to evaluate an expression using the PromiseExprEvalutator */ export interface ExprEvaluatorContext { /** current row. Optional for aggr expressions */ row?: ExprEvaluatorRow; /** array of rows (for aggregate expressions) */ rows?: ExprEvaluatorRow[]; } /** Single table in a schema */ export interface Table { id: string; /** localized name of table */ name: LocalizedString; /** localized description of table (optional) */ desc?: LocalizedString; /** non-localized short code for a table (optional) */ code?: string; /** column of database (not schema column) with primary key (optional). * Note: used to allow JsonQL but removed now. */ primaryKey?: string; /** column in schema with natural ordering (optional). */ ordering?: string; /** table with "ancestor" and "descendant". Faster than ancestry and ancestryText */ ancestryTable?: string; /** DEPRECATED: column with jsonb array of primary keys, including self. Makes table hierarchical. */ ancestry?: string; /** DEPRECATED: column with jsonb array of primary keys as JSON text, including self. Required if non-text primary keys for optimization purposes. */ ancestryText?: string; /** column with label when choosing a single row. Can be JsonQL expression with `{alias}` for table alias */ label?: string | JsonQLExpr; /** array of content items (columns, sections and joins) of the table */ contents: Array; /** true if table is deprecated. Do not show unless already selected */ deprecated?: boolean; /** Optional custom JsonQL expression. This allows a simple table to be translated to an arbitrarily complex JsonQL expression before being sent to the server. * @deprecated This is not enforced everywhere as some queries don't use compileTable */ jsonql?: JsonQLQuery; /** sql expression that gets the table. Usually just name of the table. *Note*: this is only for when using a schema file for Water.org's visualization server */ sql?: string; } export interface EnumValue { id: string; name: LocalizedString; /** Optional code of enum value e.g. A1 */ code?: string; /** Optional description of enum value */ desc?: LocalizedString; } /** * Detailed descriptions for various specialized content types: * - text: Strings, e.g., "apple" * - number: Numeric values, e.g., 1.34, 2, 5 * - enum: A fixed set of values with localized names * - enumset: An unordered set of enum values, stored as `text[]` or `jsonb` * - boolean: Boolean values, true or false * - date: A date stored as ISO 8601, e.g., "2015-12-31" * - datetime: A timestamp stored as ISO 8601, e.g., "2015-12-31T02:04:31Z" * - id: An ID column, requires `idTable` * - id[]: An array of primary keys from another table, include `idTable` field. Suggested storage as `integer[]`, `text[]`, or `jsonb` * - text[]: An ordered array of text values, stored as `text[]` or `jsonb` * - image: Object containing { id: id of image, caption: optional caption } * - imagelist: An array of images, where each image object adheres to the structure defined for `image` * - json: Arbitrary JSON data * - dataurl: A file stored as a data URL in text format, beginning with "data:" * - file: Object representing a file, structured as { id: id of file, filename: name of file, size: size in bytes, mimetype: mime type }. Stored as JSON and conforms to the FileValue interface * - filelist: An array of files, with each file object following the structure defined for `file` and adhering to the FilelistValue interface when stored as JSON * - geometry: A geometry column, database-specific but should be GeoJSON when queried as JSON. Must be stored in webmercator (3857) */ export type LiteralType = "text" | "number" | "enum" | "enumset" | "boolean" | "date" | "datetime" | "id" | "id[]" | "geometry" | "text[]" | "image" | "imagelist" | "json" | "dataurl" | "file" | "filelist"; /** Value for file fields */ export interface FileValue { /** Unique id of the file contents. UUID v4 without dashes */ id: string; /** Name of the file for downloading */ filename: string; /** Size of the file in bytes */ size: number; /** Mime type of the file */ mimetype: string; } /** Value for filelist fields */ export type FilelistValue = FileValue[]; export interface Column { /** table-unique id of item */ id: string; /** localized name of item */ name: LocalizedString; /** localized description of item */ desc?: LocalizedString; /** optional non-localized code of item */ code?: string; /** type of content item. Literal type or `join`, `expr`. `expr` is deprecated! * "join" is not a column per se, but link to one or N rows in another table. As an value, it evaluates to id or id[]. */ type: LiteralType | "join" | "expr"; /** Values for enum. Array of { id, name, code }. For type `enum` or `enumset` only. `id` is the string value of the enum. `code` is optional non-localized code for enum value */ enumValues?: EnumValue[]; /** table for id, id[] fields */ idTable?: string; /** Details of the join. See below. For type `join` only. */ join?: Join; /** true if column is deprecated. Do not show unless already selected */ deprecated?: boolean; /** set to expression if the column is an mwater-expression to be evaluated */ expr?: Expr; /** true if column contains confidential data and should be not displayed by default */ confidential?: boolean; /** true if column is redacted and might be blank or scrambled */ redacted?: boolean; /** Optional custom JsonQL expression. This allows a simple column to be translated to an arbitrarily complex JsonQL expresion before being sent to the server. It will have any fields with tableAlias = `{alias}` replaced by the appropriate alias. For all except `join`, `section` and `expr` */ jsonql?: JsonQLExpr; /** sql expression that gets the column value. Uses `{alias}` which will be substituted with the table alias. Usually just `{alias}.some_column_name`. *Note*: this is only for when using a schema file for Water.org's visualization server */ sql?: string; /** sql expression for saving back to database. Uses `{value}` which will be substituted with the value to be written *Note*: this is only for when using a schema file for Water.org's visualization server */ reverseSql?: string; /** True if column is required and cannot be null */ required?: boolean; } export interface Join { /** Type of join. 1-n and n-1 are the most common */ type: "1-n" | "n-1" | "n-n" | "1-1"; /** Table which join is to */ toTable: string; /** Inverse join column id in the case of 1-n joins (but optionally for all joins) */ inverse?: string; /** jsonql expression with aliases {from} and {to} */ jsonql?: JsonQLExpr; /** table column to start join from or jsonql with alias {alias} */ fromColumn?: string | JsonQLExpr; /** table column to end join at or jsonql with alias {alias}. */ toColumn?: string | JsonQLExpr; } /** Grouping of columns */ export interface Section { id?: string; type: "section"; name: LocalizedString; /** localized description of section */ desc?: LocalizedString; contents: Array
; } export interface SchemaJson { tables: Table[]; } /** Image value */ export interface Image { /** UUID of image */ id: string; /** Optional clockwise rotation (0, 90, 180, 270) */ rotation?: number; /** Optional caption */ caption?: string; /** If part of an image set, true if cover image */ cover?: boolean; }