├── .circleci ├── check-external-links.sh └── config.yml ├── .editorconfig ├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── _redirects ├── build-deprecation-notice.sh ├── build-netlify.sh ├── build.sh ├── deprecation-notice ├── images │ ├── marketing-background.jpg │ ├── qlik-core-banner.jpg │ └── qlik-logo-color.svg ├── index.html ├── package.json └── styling.css ├── docs ├── .lint-condo.yaml ├── .markdownlintrc ├── .proselintrc ├── conventions │ ├── api-strategy.md │ ├── introduction.md │ ├── logging.md │ └── metrics.md ├── downloads.md ├── eula.md ├── get-started.md ├── images │ ├── Icon_Global_Services_green.png │ ├── Icon_Information_green.png │ ├── Icon_Laptop_green.png │ ├── Icon_Megaphone_green.png │ ├── Icon_Qlik_Branch.png │ ├── Icon_Repository_Service_green.png │ ├── african-urbanization-screenshot.png │ ├── assisted-prescription-screenshot.png │ ├── catwalk-circular-reference.png │ ├── catwalk-default-websocket.png │ ├── catwalk-export-hypercube.png │ ├── catwalk-field-info.png │ ├── catwalk-field-select-one-value.gif │ ├── catwalk-hypercube-tabs.png │ ├── catwalk-loading.gif │ ├── catwalk-numeric-right.png │ ├── catwalk-resize-tables.gif │ ├── catwalk-scrolling-headers.gif │ ├── catwalk-top-bar.png │ ├── catwalk-walk-through.png │ ├── corectl-bash-completion.gif │ ├── corectl-powershell.gif │ ├── corectl-traffic-log.png │ ├── corectl-unbuild.gif │ ├── corectl.png │ ├── favicon.ico │ ├── hello-viz.png │ ├── marketing-background.jpg │ ├── modal-state.gif │ ├── qix-service │ │ ├── cpu_high_average.png │ │ ├── cpu_peak.png │ │ ├── frequency_noworries.png │ │ ├── frequency_over_time.png │ │ ├── frequency_worries.png │ │ ├── monitoring_ram.png │ │ ├── qix_allocation_multiple_docs.png │ │ └── qix_allocation_single_doc.png │ ├── qlik-core-banner.jpg │ ├── qlik-core-logo-color.svg │ ├── qlik-core-logo-white.svg │ ├── qlik-logo-color.svg │ ├── qlik-sense-catwalk-extension.gif │ ├── qlik-sense-catwalk-extension.png │ ├── select-excluded.gif │ ├── urbanization_autoscaling.png │ └── urbanization_connection_of_one_session.png ├── index.md ├── javascripts │ ├── downloads.js │ ├── extra.js │ ├── star-rating.js │ └── submit-textbox.js ├── licensing.md ├── services │ ├── licenses.md │ ├── mira.md │ ├── qix-engine │ │ ├── access-control.md │ │ ├── apis │ │ │ ├── data-loading │ │ │ │ ├── data-connector-api.md │ │ │ │ ├── data-connector-api.proto │ │ │ │ ├── data-connector.png │ │ │ │ └── introduction.md │ │ │ ├── file-loading │ │ │ │ ├── file-connector-api.md │ │ │ │ ├── file-connector-api.proto │ │ │ │ └── introduction.md │ │ │ ├── qix │ │ │ │ ├── definitions.md │ │ │ │ ├── doc.md │ │ │ │ ├── field.md │ │ │ │ ├── genericbookmark.md │ │ │ │ ├── genericdimension.md │ │ │ │ ├── genericmeasure.md │ │ │ │ ├── genericobject.md │ │ │ │ ├── genericvariable.md │ │ │ │ ├── global.md │ │ │ │ ├── introduction.md │ │ │ │ └── variable.md │ │ │ ├── rest │ │ │ │ ├── qlik-associative-engine-api.json │ │ │ │ └── qlik-associative-engine-api.md │ │ │ └── server-side-extension │ │ │ │ ├── analytical-connector-api.md │ │ │ │ ├── analytical-connector-api.proto │ │ │ │ └── introduction.md │ │ ├── doc-synchronization.md │ │ ├── introduction.md │ │ ├── logging.md │ │ ├── resource-management.md │ │ └── script_reference │ │ │ ├── NULL_functions.md │ │ │ ├── Script_regular_statements.md │ │ │ ├── basic_aggregation_functions.md │ │ │ ├── color_functions.md │ │ │ ├── conditional_functions.md │ │ │ ├── counter_aggregation_functions.md │ │ │ ├── counter_functions.md │ │ │ ├── data_modelling_information.wip │ │ │ ├── date_and_time_functions.md │ │ │ ├── error.md │ │ │ ├── exponential_and_logarithmic_functions.md │ │ │ ├── file_functions.md │ │ │ ├── financial_aggregation_functions.md │ │ │ ├── financial_functions.md │ │ │ ├── formatting_functions.md │ │ │ ├── general_numeric_functions.md │ │ │ ├── geospatial_functions.md │ │ │ ├── inter-record_functions.md │ │ │ ├── interpretation_functions.md │ │ │ ├── introduction.md │ │ │ ├── logical_functions.md │ │ │ ├── mapping_functions.md │ │ │ ├── mathematical_functions.md │ │ │ ├── number_variables.md │ │ │ ├── operators.md │ │ │ ├── range_functions.md │ │ │ ├── script_control.md │ │ │ ├── script_prefix.md │ │ │ ├── statistical_aggregation_functions.md │ │ │ ├── statistical_distribution_functions.md │ │ │ ├── statistical_test_functions.md │ │ │ ├── string_aggregation_functions.md │ │ │ ├── string_functions.md │ │ │ ├── system_functions.md │ │ │ ├── system_variables.wip │ │ │ ├── table_functions.md │ │ │ ├── trigonometric_and_hyperbolic_functions.md │ │ │ ├── value_handling_variables.md │ │ │ └── variables.md │ └── services.md ├── stylesheets │ ├── custom-style.css │ ├── downloads.css │ ├── pricing.css │ └── star-rating.css ├── third-party-licenses.md ├── tooling │ ├── catwalk.md │ ├── corectl.md │ └── overview.md ├── tutorials │ ├── authorization.md │ ├── data-loading │ │ ├── databases.md │ │ ├── local-files.md │ │ └── remote-files.md │ ├── hello-data.md │ ├── hello-engine.md │ ├── hello-visualization.md │ └── orchestration.md ├── use-cases.md └── why-qlik-core.md ├── generate-eula-page.sh ├── lint.sh ├── mkdocs.yml ├── qlik-core-eula.docx ├── runtime.txt ├── serve.sh └── theme ├── 404.html ├── LICENSE ├── main.html └── partials ├── footer.html ├── header.html ├── language └── en.html ├── nav.html ├── tabs-item.html └── tabs.html /.circleci/check-external-links.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd "$(dirname "$0")" 4 | 5 | set -e 6 | STATUS=0 7 | # Select the diff from the branch. Grep the changes indicated with the '+' sign. Use grep with extended regex syntax to identify weblinks. Trim text with sed. 8 | #URLS=$(curl -s -L "https://github.com/qlik-oss/core-website/compare/$CIRCLE_BRANCH.diff" | grep '+' | grep -Eo '\(https?://[^ ]+\)' | sed 's/^.\(.*\).$/\1/' | sed 's/)//g' | uniq) 9 | # Grep all "" references in all HTML/css pages, then remove leading "" from grep, sort it, and make the list unique 10 | URLS=$(grep -Eroih '=\"(http|https)://[^ "]+' --include '*.html' --include '*.css' ../site/ | cut -f 2 -d '"' | sort | uniq) 11 | # echo "Following URLS found: $URLS" 12 | 13 | for url in $URLS 14 | do 15 | sleep 0.1 # Short delay between checks to avoid 429 Too many requests responses 16 | if [[ $url == *"localhost"* || $url == *"gstatic"* || $url == *"google-analytics"* || $url == *"googletagmanager"* || $url == *"zlib.net"* || $url == *"ampl.com"* ]]; then 17 | echo "# Skipping: $url" 18 | elif curl -s -L -f -I -k -o /dev/null "$url"; then 19 | echo " Working: $url" 20 | else 21 | echo "! Broken: $url" 22 | STATUS=1 23 | fi 24 | done 25 | 26 | if [ "$STATUS" -eq "1" ]; then 27 | exit $STATUS; 28 | fi 29 | -------------------------------------------------------------------------------- /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2.1 2 | jobs: 3 | build: 4 | docker: 5 | - image: circleci/node:lts 6 | working_directory: ~/info 7 | steps: 8 | - checkout 9 | - run: 10 | name: Build the site 11 | command: ./build-deprecation-notice.sh 12 | - store_artifacts: 13 | path: ./site 14 | - run: 15 | name: Check if external links are broken 16 | command: .circleci/check-external-links.sh 17 | - run: 18 | name: Sync documentation to S3 bucket 19 | command: | 20 | if [ "${CIRCLE_BRANCH}" == "master" ] && [ "${TARGET_USER}" != "" ]; then 21 | sudo apt-get install awscli 22 | aws configure set preview.cloudfront true 23 | aws s3 sync site/ s3://qlikcoresite/ --delete 24 | aws cloudfront create-invalidation --distribution-id $DISTRIBUTION_ID --paths '/*' 25 | fi 26 | 27 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: http://EditorConfig.org 2 | 3 | # Top-most EditorConfig file 4 | root = true 5 | 6 | # Source files 7 | [*] 8 | charset = utf-8 9 | indent_style = space 10 | indent_size = 2 11 | end_of_line = lf 12 | insert_final_newline = true 13 | 14 | # Markdown files 15 | [*.md] 16 | indent_size = 4 17 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Set the default behavior, in case people don't have core.autocrlf set. 2 | * text=auto 3 | 4 | # Unix line endings in all text files. 5 | * text eol=lf 6 | 7 | # Binary files 8 | *.docx binary 9 | *.jpg binary 10 | *.png binary 11 | *.gif binary 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # VS Code folder 2 | .vscode/ 3 | # WebStorm Code folder 4 | .idea/ 5 | # Merge files (BC, KDiff3 etc.) 6 | *.orig 7 | # Site generation folder 8 | site/ 9 | .DS_Store 10 | 11 | *.new 12 | mkdocs.yml.old -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2017-present QlikTech International AB 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Qlik Core Website 2 | 3 | [![CircleCI](https://circleci.com/gh/qlik-oss/core-website.svg?style=svg)](https://circleci.com/gh/qlik-oss/core-website) 4 | 5 | This repo contains sources to the Qlik Core end-user documentation. 6 | 7 | Documentation is primarily represented as markdown files and images. 8 | Markdown files are organized in the same way as the generated site is organized. 9 | 10 | [MkDocs](http://www.mkdocs.org) is used to generate and build the site. 11 | Currently the [mkdocs-material](https://github.com/squidfunk/mkdocs-material) theme is used but this shall be changes 12 | to a theme matches Qlik branding. 13 | 14 | For the generated site, visit [core.qlik.com](https://core.qlik.com). 15 | 16 | ## Prerequisites 17 | 18 | To develop and contribute to the Qlik Core documentation, the following must be available on the local machine: 19 | 20 | - Docker - [Docker for Windows](https://www.docker.com/docker-windows) or [Docker for Mac](https://www.docker.com/docker-mac) 21 | - Bash - On Windows, Git Bash included in [Git for Windows](https://git-for-windows.github.io/) is recommended 22 | 23 | ## Serving the Site Locally 24 | 25 | To generate and serve the site locally on a developer machine, use the [serve.sh](./serve.sh) Bash script, 26 | in the repository root: 27 | 28 | ```sh 29 | ./serve.sh 30 | ``` 31 | 32 | This makes the generated site available [locally](http://localhost:8000). 33 | 34 | Once the site is running locally, modifications to sources can be made and the local web server automatically updates. 35 | No re-build step is needed. 36 | 37 | ## Building the Site 38 | 39 | To build the site for deployment to some external web server, use the [build.sh](./build.sh) Bash script, 40 | in the repository root: 41 | 42 | ```sh 43 | ./build.sh 44 | ``` 45 | 46 | This builds the site contents in the `site/` folder in the repository root. 47 | This folder is an entry in `.gitignore` to avoid undesired pending repo changes. 48 | 49 | ## Linting the Documentation 50 | 51 | For linting the documentation in this repository we use [lint-condo](https://github.com/singapore/lint-condo), 52 | which contains a set of linters for linting a markdown file. 53 | The linting is part of the Circle CI pipeline, but can also be run locally 54 | 55 | ```sh 56 | ./lint.sh 57 | ``` 58 | 59 | The linters that are enabled is configured in [.lint-condo.yaml](./docs/.lint-condo.yaml). 60 | -------------------------------------------------------------------------------- /_redirects: -------------------------------------------------------------------------------- 1 | # Redirect default Netlify subdomain to primary domain 2 | https://core-website.netlify.com/* https://core.qlik.com/:splat 301! 3 | -------------------------------------------------------------------------------- /build-deprecation-notice.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | cd "$(dirname "$0")" 4 | 5 | echo "Building site into `pwd`/site/ folder." 6 | 7 | npm install --prefix ./deprecation-notice 8 | npm run build --prefix ./deprecation-notice 9 | -------------------------------------------------------------------------------- /build-netlify.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ./build-deprecation-notice.sh 4 | cp _redirects ./site 5 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | cd "$(dirname "$0")" 4 | 5 | echo "Building site into `pwd`/site/ folder." 6 | 7 | docker_cmd=docker 8 | pwd=$(pwd) 9 | 10 | if [[ "$OS" == "Windows_NT" ]]; then 11 | docker_cmd="winpty docker" 12 | pwd=/$(pwd -W) 13 | fi 14 | 15 | $docker_cmd run --rm -it -v $pwd:/docs squidfunk/mkdocs-material:4.1.1 build 16 | -------------------------------------------------------------------------------- /deprecation-notice/images/marketing-background.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlik-oss/core-website/0b356d166309e06f82f8faccd6109b37d7370125/deprecation-notice/images/marketing-background.jpg -------------------------------------------------------------------------------- /deprecation-notice/images/qlik-core-banner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlik-oss/core-website/0b356d166309e06f82f8faccd6109b37d7370125/deprecation-notice/images/qlik-core-banner.jpg -------------------------------------------------------------------------------- /deprecation-notice/images/qlik-logo-color.svg: -------------------------------------------------------------------------------- 1 | 2 | image/svg+xml -------------------------------------------------------------------------------- /deprecation-notice/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Qlik Core 6 | 7 | 8 | 9 | 11 | 12 | 13 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 28 |
29 |
30 |
31 |
32 |

Qlik Core®

33 |
34 |
As of 1 July 2020, Qlik Core is no longer available to new customers.
35 |

To learn more about Qlik 36 | Sense, click here.
37 |
38 | 39 |
40 | 41 |
42 |

Documentation for existing Qlik Core customers

43 |

44 | All Qlik Core documentation is in the 45 | Qlik Core repository on GitHub. 46 |

47 | A couple of shortcuts: 48 | 65 | 66 |

67 | To learn more about Qlik Sense, 68 | click here. 69 |

70 |
71 | 72 | 128 | 129 | 139 | 140 | 141 | 142 | 143 | 144 | -------------------------------------------------------------------------------- /deprecation-notice/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "core-website-lite", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.html", 6 | "scripts": { 7 | "start": "parcel index.html", 8 | "build": "parcel build index.html -d ../site" 9 | }, 10 | "author": "QlikTech International AB", 11 | "license": "MIT", 12 | "devDependencies": { 13 | "cssnano": "4.1.10", 14 | "parcel-bundler": "1.12.4" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /deprecation-notice/styling.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | font-size: .5rem; 3 | font-family: "Source Sans Pro","Helvetica Neue",Helvetica,Arial,sans-serif; 4 | width: 100%; 5 | margin: 0px; 6 | color: #444; 7 | overflow-x: hidden; 8 | } 9 | 10 | .md-header-home { 11 | display: flex; 12 | width: 100%; 13 | height: 120px; 14 | padding-left: 60px; 15 | } 16 | 17 | .md-logo { 18 | margin-top: auto; 19 | margin-bottom: auto; 20 | } 21 | 22 | .md-logo img { 23 | width: 180px; 24 | } 25 | 26 | .md-header-hero { 27 | height: 500px; 28 | position: relative; 29 | display: flex; 30 | background-position: bottom; 31 | background-repeat: no-repeat; 32 | background-size: cover; 33 | background-color: #2D4A59; 34 | background-image: url("images/marketing-background.jpg"); 35 | -webkit-animation: fadein 1s; 36 | /* Safari, Chrome and Opera > 12.1 */ 37 | -moz-animation: fadein 1s; 38 | /* Firefox < 16 */ 39 | -ms-animation: fadein 1s; 40 | /* Internet Explorer */ 41 | -o-animation: fadein 1s; 42 | /* Opera < 12.1 */ 43 | animation: fadein 1s; 44 | } 45 | 46 | .md-header-info h2 { 47 | font-size: 70px; 48 | color: #fff; 49 | line-height: normal; 50 | } 51 | 52 | .md-header-info { 53 | letter-spacing: 3px; 54 | font-size: 24px; 55 | line-height: 35px; 56 | color: #fff; 57 | font-weight: 400; 58 | text-shadow: 2px 2px 4px #000; 59 | padding-left: 60px; 60 | } 61 | 62 | .red-banner { 63 | margin-left: 60px; 64 | margin-right: 60px; 65 | margin-top: 30px; 66 | padding: 10px; 67 | text-align: center; 68 | position: relative; 69 | font-size: 24px; 70 | background-color: rgba(255, 0, 0, .6); 71 | color: white; 72 | } 73 | 74 | .content { 75 | margin-left: 60px; 76 | margin-right: 60px; 77 | font-size: 20px; 78 | line-height: 1.6; 79 | margin-bottom: 40px; 80 | } 81 | 82 | .content h3 { 83 | margin: 2rem 0 0.8rem; 84 | font-size: 30px; 85 | line-height: 1.4; 86 | } 87 | 88 | 89 | @media only screen and (min-width: 730px) and (max-width: 76.1875em) { 90 | .md-header-hero { 91 | height: 350px; 92 | } 93 | 94 | 95 | .md-tagline { 96 | display: none; 97 | } 98 | 99 | 100 | } 101 | 102 | @media only screen and (min-width: 0) and (max-width: 730px) { 103 | 104 | .md-header-hero { 105 | height: 280px; 106 | overflow: hidden; 107 | } 108 | 109 | .md-header-info h2 { 110 | font-size: 40px; 111 | } 112 | 113 | .md-tagline { 114 | display: none; 115 | } 116 | 117 | .footer-logo-right { 118 | display: none; 119 | } 120 | } 121 | 122 | @media (max-width: 76.1875em) { 123 | 124 | .md-header-home { 125 | height: 60px; 126 | } 127 | 128 | .md-header { 129 | color: #444; 130 | } 131 | 132 | .md-logo img { 133 | height: auto; 134 | width: 100px; 135 | } 136 | 137 | .md-column-icons { 138 | min-width: 333px; 139 | } 140 | 141 | } 142 | 143 | @media (min-width: 76.1875em) { 144 | .md-header-home { 145 | height: 120px; 146 | } 147 | 148 | .md-header-hero { 149 | height: 380px; 150 | 151 | } 152 | 153 | .md-logo img { 154 | height: auto; 155 | width: 180px; 156 | } 157 | } 158 | 159 | @keyframes fadein { 160 | from { 161 | opacity: 0; 162 | } 163 | 164 | to { 165 | opacity: 1; 166 | } 167 | } 168 | 169 | /* Firefox < 16 */ 170 | @-moz-keyframes fadein { 171 | from { 172 | opacity: 0; 173 | } 174 | 175 | to { 176 | opacity: 1; 177 | } 178 | } 179 | 180 | /* Safari, Chrome and Opera > 12.1 */ 181 | @-webkit-keyframes fadein { 182 | from { 183 | opacity: 0; 184 | } 185 | 186 | to { 187 | opacity: 1; 188 | } 189 | } 190 | 191 | /* Internet Explorer */ 192 | @-ms-keyframes fadein { 193 | from { 194 | opacity: 0; 195 | } 196 | 197 | to { 198 | opacity: 1; 199 | } 200 | } 201 | 202 | /* Opera < 12.1 */ 203 | @-o-keyframes fadein { 204 | from { 205 | opacity: 0; 206 | } 207 | 208 | to { 209 | opacity: 1; 210 | } 211 | } 212 | 213 | .md-footer-legal { 214 | border-top: 1px solid rgba(255, 255, 255, 0.3); 215 | width: 100%; 216 | overflow: auto; 217 | } 218 | 219 | .md-footer-legal-text { 220 | float: left; 221 | padding-top: 30px; 222 | padding-bottom: 30px; 223 | font-size: 14px; 224 | color: #c2c2c2; 225 | line-height: 24px; 226 | letter-spacing: .1em; 227 | text-transform: uppercase; 228 | } 229 | 230 | .footer-nav { 231 | background-color: #e1e1e1; 232 | padding: 45px 0; 233 | } 234 | 235 | .footer-nav ul { 236 | display: block; 237 | list-style-type: disc; 238 | -webkit-margin-before: 1em; 239 | -webkit-margin-after: 1em; 240 | -webkit-margin-start: 0px; 241 | -webkit-margin-end: 0px; 242 | -webkit-padding-start: 0px; 243 | list-style: none; 244 | } 245 | 246 | .wrapper { 247 | position: relative; 248 | box-sizing: border-box; 249 | width: 100%; 250 | 251 | margin: auto; 252 | margin-top: 0px; 253 | padding: 0px 60px; 254 | font-size: 18px; 255 | } 256 | 257 | .footer-nav-wrapper { 258 | width: 75%; 259 | display: flex; 260 | } 261 | 262 | .footer-left { 263 | padding-right: 10px; 264 | display: flex; 265 | flex-wrap: wrap; 266 | } 267 | 268 | .footer-logo-right { 269 | position: absolute; 270 | width: 100px; 271 | bottom: 16px; 272 | right: 100px; 273 | } 274 | 275 | .footer-nav-menu { 276 | width: 100%; 277 | max-width: 800px; 278 | display: flex; 279 | flex-wrap: wrap; 280 | justify-content: space-between; 281 | padding-top: 0px; 282 | } 283 | 284 | .footer-nav-menu .footer-menu-item { 285 | padding: 0px 10px; 286 | 287 | } 288 | 289 | .footer-nav-menu ul { 290 | padding-top: 20px; 291 | } 292 | 293 | li { 294 | display: list-item; 295 | text-align: -webkit-match-parent; 296 | } 297 | 298 | .footer-nav-menu ul li { 299 | line-height: 45px; 300 | color: #63666a; 301 | } 302 | 303 | .footer-nav-menu .footer-menu-item .footer-menu-title { 304 | font-weight: 600; 305 | letter-spacing: .05em; 306 | text-transform: uppercase; 307 | color:black; 308 | } 309 | 310 | .md-footer-last { 311 | background-color: #424346; 312 | color: #e1e1e1; 313 | } -------------------------------------------------------------------------------- /docs/.lint-condo.yaml: -------------------------------------------------------------------------------- 1 | linters: 2 | - markdownlint . # Markdown syntax linting 3 | # The magic parameter filters out all files that has 'proselint-disable' in them 4 | - proselint $(grep -L "proselint-disable" -r . | grep .md) # English prose linting 5 | -------------------------------------------------------------------------------- /docs/.markdownlintrc: -------------------------------------------------------------------------------- 1 | { 2 | "MD007": { 3 | "indent": 4 // For MkDoc to generate nested lists corrrectly 4 | }, 5 | "MD013": { 6 | "line_length": 120, 7 | "tables": false, // Allow long lines in a table 8 | "code_blocks": false // Allow long lines in a code block 9 | }, 10 | "MD024": false, // Allow multiple headers with the same content 11 | "MD026": { 12 | "punctuation": ".,;:" // Allow headers ending with question mark or exclamation mark 13 | }, 14 | "MD033": false, // Allow inline html 15 | "MD036": false // Allow using emphasis as a form of header 16 | } 17 | -------------------------------------------------------------------------------- /docs/.proselintrc: -------------------------------------------------------------------------------- 1 | { 2 | "checks": { 3 | "typography.symbols": false, 4 | "misc.but": false, 5 | "hyperbole.misc": false, 6 | "typography.exclamation": false, 7 | "dates_times.dates": false 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /docs/conventions/api-strategy.md: -------------------------------------------------------------------------------- 1 | # API Strategy 2 | 3 | We take our relationship with our partners and customers seriously. This is why we have a transparent 4 | and reliable API Strategy to support you and your investments that rely on our APIs. 5 | 6 | ## Elements of our API Strategy 7 | 8 | The API Governance Policy consists of five areas: 9 | 10 | * Versioning 11 | * Visibility Index 12 | * Stability Index 13 | * Deprecation Policy 14 | * Breaking Change Definition 15 | 16 | ### Versioning 17 | 18 | Our versioning policy describes a simple set of rules and requirements for an API, that dictate how the version 19 | numbers should be assigned and incremented. 20 | 21 | We follow industry standard [Semantic Versioning](https://semver.org/). A version number must take the form 22 | X.Y.Z, where X is the major version, Y is the minor version, and Z is the patch version. 23 | 24 | The advantage of using this method of versioning is that by comparing two versions, you can 25 | determine the compatibility differences. 26 | 27 | * Backwards-compatible bug fixes (Z is incremented) 28 | * New backwards-compatible features (Y is incremented) 29 | * Backwards-incompatible changes (X is incremented) 30 | 31 | Major version zero (0.Y.Z) is for initial development, so our API Governance Policy does not apply. Our 32 | public APIs will always be at major version one (1.Y.Z) or higher. 33 | 34 | ### Visibility Index 35 | 36 | The Visibility Index defines who is the intended user of the API. We currently have two types of 37 | APIs: private and public. 38 | 39 | Public APIs are officially supported, and they are documented in the 40 | [Qlik Core documentation](/index.md). 41 | To avoid the risk that your solution might break with any new version of our products, 42 | you should always use public APIs for custom solutions built on top of our APIs. 43 | 44 | ### Stability Index 45 | 46 | The Stability Index indicates how stable or mature an API is. 47 | We currently have three levels: 48 | 49 | * **Experimental** 50 | 51 | Experimental APIs are under development and might change with every new release, as 52 | there is no need to deprecate before removing. 53 | We want to expose new APIs to our partners and customers as soon as possible. 54 | This lets customers and partners develop early prototypes with experimental APIs and 55 | provides us with important feedback in the early stage of the API. Experimental APIs 56 | are not subject to the Versioning policy. 57 | 58 | * **Stable** 59 | 60 | Stable APIs are reliable and breaking changes are unlikely. The deprecation period for stable 61 | APIs is set to 6 months. 62 | 63 | * **Locked** 64 | 65 | Locked APIs are extremely reliable and will not be broken unless necessary. The 66 | deprecation period for locked APIs is set to 12 months. 67 | 68 | The stability index can be assigned to the whole API or part of the API. 69 | Different areas of an API can have different Stability Index levels. 70 | 71 | !!! Note 72 | APIs can only be promoted and move to a more reliable Stability Index. 73 | 74 | ### Deprecation Policy 75 | 76 | The Deprecation Policy defines when and how an API is considered to be deprecated. 77 | 78 | We aim to minimize the changes to our APIs, but it is sometimes necessary due to 79 | architectural changes and with the introduction of new functionality. 80 | 81 | The deprecation period starts when the deprecation has been communicated, which means that it has 82 | been officially documented in the 83 | [Qlik Core documentation](/index.md). 84 | A replacement must be announced at the same time as the deprecation period starts. This gives 85 | you a period in which you can start adapting your custom solution to the API replacement 86 | and prepare for the API change. 87 | 88 | The deprecation period varies depending on the maturity of the API, which is set as the stability index. 89 | The deprecation period lasts until the removal has been officially communicated to the API consumer. 90 | 91 | The API governance policy applies to both our public and private APIs, 92 | but private APIs are treated differently for deprecations. 93 | 94 | ### Breaking Change Definition 95 | 96 | The Breaking Change Definition is a set of rules that defines if a change is considered to be a backward or 97 | non-backward compatible change. 98 | 99 | ## Bringing our API Strategy to life 100 | 101 | In December 2016, we established the API Governance Policy within Qlik's R&D organization. 102 | This policy ensures that we meet the high standards of our API strategy. 103 | 104 | ### Qlik Help 105 | 106 | We have started to introduce the Stability Index in our Qlik Core 107 | documentation. 108 | This is an ongoing effort and we will continue with future 109 | [Qlik Core documentation](/index.md) 110 | updates. 111 | 112 | ### Qlik API Insights 113 | 114 | Our intention is to be fully transparent to our partners and customers. 115 | Therefore, we have launched 116 | [Qlik API Insights](https://api-insights.qlik.com/?_ga=2.240450371.1316921484.1517254575-1425872494.1511967817#/start-page). 117 | This is a tool that lets you see API changes over time. 118 | With this tool, you can see when something has been added, updated, deprecated, or removed, from an API. 119 | -------------------------------------------------------------------------------- /docs/conventions/introduction.md: -------------------------------------------------------------------------------- 1 | # Conventions 2 | 3 | Service conventions are common concepts and features that are shared among 4 | all services in Qlik Core. 5 | 6 | We currently have the following conventions: 7 | 8 | Convention | Description 9 | ----------------------------------- | ----------- 10 | [API Strategy](./api-strategy.md) | API versioning and deprecation. 11 | [Logging](./logging.md) | Service event logging. 12 | [Metrics](./metrics.md) | Run-time metadata and how to expose it. 13 | -------------------------------------------------------------------------------- /docs/conventions/logging.md: -------------------------------------------------------------------------------- 1 | # Logging 2 | 3 | Service logs provide visibility into the behavior of the service. 4 | Services must log enough information for a developer to be able to debug and fix an issue using the information 5 | available in the logs. In general, developers will not have access to production environments to debug services. 6 | They instead rely on real-time historical logs for analysis. 7 | 8 | A service should write its logs to `stdout`. A service should also ensure that it writes sufficient content to the log 9 | for monitoring and troubleshooting issues. A service should _not_ manage the routing, storage, or aggregation of its logs. 10 | 11 | ## Logging conventions 12 | 13 | 1. Write events only on `stdout`. Do not write events to files. 14 | * Events _must_ be on `stdout` and not `stderr`. 15 | * It is _not_ the job of the service to store, transmit, or buffer log events. 16 | * During local development, the developer will view the service's event stream in their terminal or console, 17 | or manually redirect (with a pipe or similar) to a local file. 18 | * When the service is deployed, 19 | it is the responsibility of the execution environment to capture and direct logs for later analysis. 20 | 1. Events must be written as valid JSON, with the following minimum standard fields: 21 | 22 | | Field | Description | Requirements | 23 | | ----- | ----------- | ------------ | 24 | | `timestamp` | The date/time at which the event occurred. | | 25 | | `message` | A message that describes the event. | | 26 | | `logseverity` | String value indicating the level of importance of the log message. | | 27 | 28 | 1. Some contexts require additional fields. 29 | Fields should be coordinated between services so analysis is correctly aggregated across services. 30 | For example, if two services track session IDs, then both services should track the common field name 31 | that is case and style specific. 32 | We recommend that you use snake case `session_id` rather than Pascal case `SessionId`. 33 | 34 | ## Logging level definitions 35 | 36 | * `TRACE` 37 | * Fine-grained debug message, typically used to capture a flow of events. 38 | * `DEBUG` 39 | * Mostly used for debugging purposes. 40 | * Typically not enabled by default in production. 41 | * `INFO` 42 | * Normal operations of the service that should be logged. 43 | * Indicates some important operation or state in the service. 44 | * `WARN` 45 | * Indicates an event or state that was not part of common operations, but was handled. 46 | * An event that potentially can become an error. 47 | * An event that does not prevent correct operation of the system from an end-user perspective. 48 | * `ERROR` 49 | * An error that was not handled and was unexpected to the service. 50 | * Service can continue normal operation after error recovery. 51 | * `FATAL` 52 | * Non-recoverable error that forces the service to terminate. 53 | -------------------------------------------------------------------------------- /docs/conventions/metrics.md: -------------------------------------------------------------------------------- 1 | # Metrics 2 | 3 | A service must expose enough run-time metadata to provide metrics about the health of the service, 4 | and to support public features. 5 | We recommend that you follow the [Prometheus metrics](https://prometheus.io/docs/introduction/overview/) 6 | _format_ to collect metrics details about your services. 7 | 8 | The service should follow these conventions: 9 | 10 | * Expose metrics on a `/metrics` endpoint. 11 | * Support protobuf and plain text representations, based on the `Content-Type` that is passed in. 12 | * Follow the [Prometheus best practices](https://prometheus.io/docs/introduction/overview/). 13 | -------------------------------------------------------------------------------- /docs/downloads.md: -------------------------------------------------------------------------------- 1 | # Downloads 2 | 3 | ## Components 4 | 5 | Qlik Core consists of a core set of supported components, including the Qlik Associative Engine: 6 | 7 |
8 | 9 | | Service | Feature | Links | Latest Version | 10 | | ---------- | ------- | ------| -------------- | 11 | | [Qlik Associative Engine](./services/qix-engine/introduction.md) | The powerful associative indexing engine from Qlik and the foundation of Qlik Core. | [qlikcore/engine](https://hub.docker.com/r/qlikcore/engine) | N/A | 12 | | [License](./services/licenses.md) | Service required to run Qlik Associative Engine with a paid license. | [qlikcore/licenses](https://hub.docker.com/r/qlikcore/licenses) | N/A | 13 | | [Mira](./services/mira.md) | Qlik Associative Engine discovery service. | [qlikcore/mira](https://hub.docker.com/r/qlikcore/mira)
(source code: [GitHub](https://github.com/qlik-oss/mira)) | N/A | 14 | | [enigma.js](https://www.npmjs.com/package/enigma.js) | Communication with the Qlik Associative Engine. | [GitHub](https://github.com/qlik-oss/enigma.js/) | N/A | 15 | | [halyard.js](https://www.npmjs.com/package/halyard.js) | Simple data loading into the Qlik Associative Engine. | [GitHub](https://github.com/qlik-oss/halyard.js) | N/A | 16 | 17 | Qlik Core comes with a developer edition that may be used to evaluate, 18 | develop, or test solutions. Note that it cannot be used for commercial purposes. 19 | For more information about the license of Qlik Core visit 20 | [Licensing](licensing.md). 21 | 22 | ## Other Components 23 | 24 | In addition, there are several unsupported open source libraries that you will find useful when working 25 | with Qlik Core. 26 | 27 | | Library | Feature | Source Code | 28 | | ------- | ------- | ----------- | 29 | | [after-work.js](https://www.npmjs.com/package/@after-work.js/aw) | Unified testing framework for different test levels. | [GitHub](https://github.com/qlik-oss/after-work.js) | 30 | | [picasso.js](https://www.npmjs.com/package/picasso.js) | Visualization library on top of the Qlik Associative Engine. | [GitHub](https://github.com/qlik-oss/picasso.js/) | 31 | | enigma-go | Go library for consuming Qlik's Associative Engine | [GitHub](https://github.com/qlik-oss/enigma-go/) | 32 | -------------------------------------------------------------------------------- /docs/get-started.md: -------------------------------------------------------------------------------- 1 | # Get Started 2 | 3 | To get started with Qlik Core and Qlik Associative Engine, and to learn the basic concepts, 4 | we provide a number of tools, examples and tutorials. 5 | 6 | You can explore and play around with the 7 | [core-experimenter](https://experimenter.qlik.dev/), a tool which showcases the Qlik Associative Engine's selection 8 | model and how this affects the data model. For a more in depth walkthrough of the Qlik Associative Engine, take a look 9 | at the [engine tutorial]( https://developer.qlik.com/knowledge/tutorial/engineTutorial) on 10 | [Qlik Branch](https://developer.qlik.com). 11 | 12 | We created three learning paths to introduce different concepts step by step. 13 | 14 | Many of the tutorials contain runnable examples. 15 | The source code is available in separate open source repositories on GitHub. 16 | 17 | Before you run these examples, make sure you read the [Licensing](./licensing.md) page. 18 | 19 | ## Hello Qlik Core! 20 | 21 | Start here if you are new to Qlik products and Qlik Associative Engine. 22 | 23 | The first set of examples introduce basic operations and usage of the Qlik Associative Engine. Think of 24 | it as the "Hello World" of the engine and the next steps after that. 25 | The Hello Qlik Core examples are divided into three separate parts: 26 | 27 | !!! Note 28 | In the following tutorials, you accept the EULA by defining the `ACCEPT_EULA` environment variable.
29 | ```bash 30 | ACCEPT_EULA=yes docker-compose up -d 31 | ``` 32 | 33 | - [Hello Engine](./tutorials/hello-engine.md) - Running Qlik Associative Engine as a Docker container and using 34 | [enigma.js](https://github.com/qlik-oss/enigma.js/) to communicate with it. 35 | - [Hello Data](./tutorials/hello-data.md) - Loading user data into Qlik Associative Engine using 36 | load script and [halyard.js](https://github.com/qlik-oss/halyard.js). 37 | - [Hello Visualization](./tutorials/hello-visualization.md) - Building visualizations using [picasso.js](https://picassojs.com/). 38 | 39 | Once you have completed these tutorials, you should be presented with a result similar to the screenshot below. 40 | 41 | ![screenshot](./images/hello-viz.png) 42 | 43 | ## Orchestration 44 | 45 | Start here if you have some knowledge about Qlik Associative Engine, its supporting libraries, 46 | and Qlik products, but you are new to container technologies such as Docker: 47 | 48 | - [Orchestration](./tutorials/orchestration.md) 49 | 50 | This tutorial covers aspects such as: 51 | 52 | - Configuring and using a license for Qlik Associative Engine 53 | - Using Qlik Associative Engine in different container orchestration tools 54 | - Using Mira - the Qlik Associative Engine discovery service - when running multiple 55 | instances of Qlik Associative Engine in a cluster 56 | 57 | ## In-Depth Tutorials 58 | 59 | Start here if you want to cover in-depth tutorials that provide detailed examples of how to work with more specific 60 | aspects of Qlik Core. We recommend that you explore these tutorials in order: 61 | 62 | 1. [Data loading](./tutorials/data-loading/local-files.md) 63 | - Loading user data from files into Qlik Associative Engine 64 | 1. [Authorization](./tutorials/authorization.md) 65 | - Using JWTs and JWT validation in Qlik Associative Engine 66 | - Making sure users only see the data they are supposed to see 67 | 68 | ## Use Cases 69 | 70 | Complementary to our tutorials are the use case examples. These provide complete solutions using Qlik Core that cover 71 | typical problems of production deployments, such as monitoring, logging, scaling, and scheduling strategies. 72 | 73 | More information can be found in the [Use Cases](./use-cases.md) section. 74 | -------------------------------------------------------------------------------- /docs/images/Icon_Global_Services_green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlik-oss/core-website/0b356d166309e06f82f8faccd6109b37d7370125/docs/images/Icon_Global_Services_green.png -------------------------------------------------------------------------------- /docs/images/Icon_Information_green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlik-oss/core-website/0b356d166309e06f82f8faccd6109b37d7370125/docs/images/Icon_Information_green.png -------------------------------------------------------------------------------- /docs/images/Icon_Laptop_green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlik-oss/core-website/0b356d166309e06f82f8faccd6109b37d7370125/docs/images/Icon_Laptop_green.png -------------------------------------------------------------------------------- /docs/images/Icon_Megaphone_green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlik-oss/core-website/0b356d166309e06f82f8faccd6109b37d7370125/docs/images/Icon_Megaphone_green.png -------------------------------------------------------------------------------- /docs/images/Icon_Qlik_Branch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlik-oss/core-website/0b356d166309e06f82f8faccd6109b37d7370125/docs/images/Icon_Qlik_Branch.png -------------------------------------------------------------------------------- /docs/images/Icon_Repository_Service_green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlik-oss/core-website/0b356d166309e06f82f8faccd6109b37d7370125/docs/images/Icon_Repository_Service_green.png -------------------------------------------------------------------------------- /docs/images/african-urbanization-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlik-oss/core-website/0b356d166309e06f82f8faccd6109b37d7370125/docs/images/african-urbanization-screenshot.png -------------------------------------------------------------------------------- /docs/images/assisted-prescription-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlik-oss/core-website/0b356d166309e06f82f8faccd6109b37d7370125/docs/images/assisted-prescription-screenshot.png -------------------------------------------------------------------------------- /docs/images/catwalk-circular-reference.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlik-oss/core-website/0b356d166309e06f82f8faccd6109b37d7370125/docs/images/catwalk-circular-reference.png -------------------------------------------------------------------------------- /docs/images/catwalk-default-websocket.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlik-oss/core-website/0b356d166309e06f82f8faccd6109b37d7370125/docs/images/catwalk-default-websocket.png -------------------------------------------------------------------------------- /docs/images/catwalk-export-hypercube.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlik-oss/core-website/0b356d166309e06f82f8faccd6109b37d7370125/docs/images/catwalk-export-hypercube.png -------------------------------------------------------------------------------- /docs/images/catwalk-field-info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlik-oss/core-website/0b356d166309e06f82f8faccd6109b37d7370125/docs/images/catwalk-field-info.png -------------------------------------------------------------------------------- /docs/images/catwalk-field-select-one-value.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlik-oss/core-website/0b356d166309e06f82f8faccd6109b37d7370125/docs/images/catwalk-field-select-one-value.gif -------------------------------------------------------------------------------- /docs/images/catwalk-hypercube-tabs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlik-oss/core-website/0b356d166309e06f82f8faccd6109b37d7370125/docs/images/catwalk-hypercube-tabs.png -------------------------------------------------------------------------------- /docs/images/catwalk-loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlik-oss/core-website/0b356d166309e06f82f8faccd6109b37d7370125/docs/images/catwalk-loading.gif -------------------------------------------------------------------------------- /docs/images/catwalk-numeric-right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlik-oss/core-website/0b356d166309e06f82f8faccd6109b37d7370125/docs/images/catwalk-numeric-right.png -------------------------------------------------------------------------------- /docs/images/catwalk-resize-tables.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlik-oss/core-website/0b356d166309e06f82f8faccd6109b37d7370125/docs/images/catwalk-resize-tables.gif -------------------------------------------------------------------------------- /docs/images/catwalk-scrolling-headers.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlik-oss/core-website/0b356d166309e06f82f8faccd6109b37d7370125/docs/images/catwalk-scrolling-headers.gif -------------------------------------------------------------------------------- /docs/images/catwalk-top-bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlik-oss/core-website/0b356d166309e06f82f8faccd6109b37d7370125/docs/images/catwalk-top-bar.png -------------------------------------------------------------------------------- /docs/images/catwalk-walk-through.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlik-oss/core-website/0b356d166309e06f82f8faccd6109b37d7370125/docs/images/catwalk-walk-through.png -------------------------------------------------------------------------------- /docs/images/corectl-bash-completion.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlik-oss/core-website/0b356d166309e06f82f8faccd6109b37d7370125/docs/images/corectl-bash-completion.gif -------------------------------------------------------------------------------- /docs/images/corectl-powershell.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlik-oss/core-website/0b356d166309e06f82f8faccd6109b37d7370125/docs/images/corectl-powershell.gif -------------------------------------------------------------------------------- /docs/images/corectl-traffic-log.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlik-oss/core-website/0b356d166309e06f82f8faccd6109b37d7370125/docs/images/corectl-traffic-log.png -------------------------------------------------------------------------------- /docs/images/corectl-unbuild.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlik-oss/core-website/0b356d166309e06f82f8faccd6109b37d7370125/docs/images/corectl-unbuild.gif -------------------------------------------------------------------------------- /docs/images/corectl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlik-oss/core-website/0b356d166309e06f82f8faccd6109b37d7370125/docs/images/corectl.png -------------------------------------------------------------------------------- /docs/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlik-oss/core-website/0b356d166309e06f82f8faccd6109b37d7370125/docs/images/favicon.ico -------------------------------------------------------------------------------- /docs/images/hello-viz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlik-oss/core-website/0b356d166309e06f82f8faccd6109b37d7370125/docs/images/hello-viz.png -------------------------------------------------------------------------------- /docs/images/marketing-background.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlik-oss/core-website/0b356d166309e06f82f8faccd6109b37d7370125/docs/images/marketing-background.jpg -------------------------------------------------------------------------------- /docs/images/modal-state.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlik-oss/core-website/0b356d166309e06f82f8faccd6109b37d7370125/docs/images/modal-state.gif -------------------------------------------------------------------------------- /docs/images/qix-service/cpu_high_average.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlik-oss/core-website/0b356d166309e06f82f8faccd6109b37d7370125/docs/images/qix-service/cpu_high_average.png -------------------------------------------------------------------------------- /docs/images/qix-service/cpu_peak.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlik-oss/core-website/0b356d166309e06f82f8faccd6109b37d7370125/docs/images/qix-service/cpu_peak.png -------------------------------------------------------------------------------- /docs/images/qix-service/frequency_noworries.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlik-oss/core-website/0b356d166309e06f82f8faccd6109b37d7370125/docs/images/qix-service/frequency_noworries.png -------------------------------------------------------------------------------- /docs/images/qix-service/frequency_over_time.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlik-oss/core-website/0b356d166309e06f82f8faccd6109b37d7370125/docs/images/qix-service/frequency_over_time.png -------------------------------------------------------------------------------- /docs/images/qix-service/frequency_worries.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlik-oss/core-website/0b356d166309e06f82f8faccd6109b37d7370125/docs/images/qix-service/frequency_worries.png -------------------------------------------------------------------------------- /docs/images/qix-service/monitoring_ram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlik-oss/core-website/0b356d166309e06f82f8faccd6109b37d7370125/docs/images/qix-service/monitoring_ram.png -------------------------------------------------------------------------------- /docs/images/qix-service/qix_allocation_multiple_docs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlik-oss/core-website/0b356d166309e06f82f8faccd6109b37d7370125/docs/images/qix-service/qix_allocation_multiple_docs.png -------------------------------------------------------------------------------- /docs/images/qix-service/qix_allocation_single_doc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlik-oss/core-website/0b356d166309e06f82f8faccd6109b37d7370125/docs/images/qix-service/qix_allocation_single_doc.png -------------------------------------------------------------------------------- /docs/images/qlik-core-banner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlik-oss/core-website/0b356d166309e06f82f8faccd6109b37d7370125/docs/images/qlik-core-banner.jpg -------------------------------------------------------------------------------- /docs/images/qlik-core-logo-color.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/images/qlik-core-logo-white.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/images/qlik-logo-color.svg: -------------------------------------------------------------------------------- 1 | 2 | image/svg+xml -------------------------------------------------------------------------------- /docs/images/qlik-sense-catwalk-extension.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlik-oss/core-website/0b356d166309e06f82f8faccd6109b37d7370125/docs/images/qlik-sense-catwalk-extension.gif -------------------------------------------------------------------------------- /docs/images/qlik-sense-catwalk-extension.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlik-oss/core-website/0b356d166309e06f82f8faccd6109b37d7370125/docs/images/qlik-sense-catwalk-extension.png -------------------------------------------------------------------------------- /docs/images/select-excluded.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlik-oss/core-website/0b356d166309e06f82f8faccd6109b37d7370125/docs/images/select-excluded.gif -------------------------------------------------------------------------------- /docs/images/urbanization_autoscaling.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlik-oss/core-website/0b356d166309e06f82f8faccd6109b37d7370125/docs/images/urbanization_autoscaling.png -------------------------------------------------------------------------------- /docs/images/urbanization_connection_of_one_session.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlik-oss/core-website/0b356d166309e06f82f8faccd6109b37d7370125/docs/images/urbanization_connection_of_one_session.png -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | # Home 2 | -------------------------------------------------------------------------------- /docs/javascripts/downloads.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | const downloadsTableIdentifier = document.getElementById('downloads-table-identifier'); 3 | 4 | if (!downloadsTableIdentifier) { return; } 5 | 6 | const cellTitle = (version, date) => ` 7 |
8 | 9 | ${version} 10 | 11 | 12 | (${date}) 13 | 14 |
15 | `; 16 | const apiLink = (name, version, prevVersion, visibility) => ` 17 | 22 | `; 23 | const getCircleClass = (name) => { 24 | switch (name.toLowerCase()) { 25 | case 'added': 26 | return 'changes__circle--added'; 27 | case 'updated': 28 | return 'changes__circle--updated'; 29 | case 'removed': 30 | return 'changes__circle--removed'; 31 | case 'deprecated': 32 | return 'changes__circle--deprecated'; 33 | default: 34 | return ''; 35 | } 36 | }; 37 | const changesCircle = (changes, name) => { 38 | if ( 39 | !changes 40 | || parseFloat(changes) === 0 41 | ) { return ''; } 42 | 43 | return ` 44 |
45 | ${changes} 46 |
47 | ${changes} API method(s) ${name.toLowerCase()} 48 |
49 |
50 | `; 51 | }; 52 | 53 | const services = [ 54 | { 55 | service: 'Qlik Associative Engine', 56 | apis: [ 57 | 'EngineAPI', 58 | 'EngineRestAPI', 59 | 'ScriptLanguageAPI', 60 | ], 61 | }, { 62 | service: 'Licenses', 63 | apis: [ 64 | 'LicensesAPI', 65 | ], 66 | }, { 67 | service: 'Mira', 68 | apis: [ 69 | 'MiraAPI', 70 | ], 71 | }, { 72 | service: 'enigma.js', 73 | apis: [ 74 | 'enigma.js', 75 | ], 76 | }, { 77 | service: 'halyard.js', 78 | apis: [ 79 | 'halyard.js', 80 | ], 81 | }, 82 | ]; 83 | 84 | const loader = document.createElement('div'); 85 | loader.className = 'dots'; 86 | for (let i = 0; i < 7; i++) { 87 | const dot = document.createElement('div'); 88 | dot.className = 'dots__dot'; 89 | loader.appendChild(dot); 90 | } 91 | 92 | const table = document.getElementsByTagName('table')[0]; 93 | const lastBodyColumn = table.querySelectorAll('tr td:last-child'); 94 | lastBodyColumn.forEach(cell => { 95 | cell.innerText = ''; 96 | cell.appendChild(loader.cloneNode(true)); 97 | }); 98 | 99 | const schema = { 100 | "structs": { 101 | "Global": { 102 | "OpenDoc": { 103 | "In": [{ "Name": "qDocName", "DefaultValue": "" }, { "Name": "qUserName", "DefaultValue": "", "Optional": true }, { "Name": "qPassword", "DefaultValue": "", "Optional": true }, { "Name": "qSerial", "DefaultValue": "", "Optional": true }, { "Name": "qNoData", "DefaultValue": false, "Optional": true }], 104 | "Out": [] 105 | } 106 | }, 107 | "Doc": { 108 | "CreateSessionObject": { 109 | "In": [{ "Name": "qProp", "DefaultValue": { "qInfo": { "qId": "", "qType": "" }, "qExtendsId": "", "qMetaDef": {} } }], 110 | "Out": [] 111 | }, 112 | }, 113 | "GenericObject": { 114 | "GetLayout": { 115 | "In": [], 116 | "Out": [{ "Name": "qLayout" }] 117 | } 118 | } 119 | }, 120 | }; 121 | const appId = '52e3297d-ceeb-45c9-bbe4-6069fe920760'; 122 | const session = enigma.create({ 123 | schema, 124 | url: `wss://branch-sense.qlik.com/anon/app/${appId}`, 125 | }); 126 | 127 | session.open() 128 | .then(global => global.openDoc(appId)) 129 | .then(doc => doc.createSessionObject({ 130 | qInfo: { qType: 'my-obj' }, 131 | qHyperCubeDef: { 132 | qInitialDataFetch: [{ qLeft: 0, qTop: 0, qWidth: 10, qHeight: 100 }], 133 | qDimensions: [ 134 | "APIName", "APIVersion", "PrevAPIVersion", "ReleaseDate", 135 | "Added", "Updated", "Removed", "Deprecated", "Visibility" 136 | ].map(field => ({ qDef: { qFieldDefs: [field] } })) 137 | } 138 | }) 139 | .then(obj => obj.getLayout()) 140 | .then(({ qHyperCube: { qDataPages: [{ qMatrix: rawDataApis }] }}) => { 141 | const apis = rawDataApis.map(([ 142 | { qText: apiName }, 143 | { qText: apiVersion }, 144 | { qText: prevAPIVersion }, 145 | { qText: releaseDate }, 146 | { qText: added }, 147 | { qText: updated }, 148 | { qText: removed }, 149 | { qText: deprecated }, 150 | { qText: visibility }, 151 | ]) => ({ 152 | apiName, 153 | apiVersion, 154 | prevAPIVersion, 155 | releaseDate, 156 | added, 157 | updated, 158 | removed, 159 | deprecated, 160 | visibility, 161 | })); 162 | 163 | lastBodyColumn.forEach((cell, index) => { 164 | const service = services[index]; 165 | const serviceApis = apis.filter(({ apiName }) => service.apis.indexOf(apiName) >= 0); 166 | const publicApis = serviceApis.filter(({ visibility }) => visibility === 'public'); 167 | 168 | const [{ 169 | apiVersion: componentVersion, 170 | releaseDate: componentDate, 171 | }] = serviceApis; 172 | 173 | cell.innerText = ''; 174 | cell.insertAdjacentHTML('beforeend', cellTitle(componentVersion, componentDate)); 175 | 176 | publicApis.forEach(({ 177 | apiName, 178 | apiVersion, 179 | prevAPIVersion, 180 | added, 181 | updated, 182 | removed, 183 | deprecated, 184 | }) => { 185 | cell.insertAdjacentHTML('beforeend', apiLink(apiName, apiVersion, prevAPIVersion)); 186 | cell.insertAdjacentHTML('beforeend', ` 187 |
188 | ${changesCircle(added, 'added')} 189 | ${changesCircle(updated, 'updated')} 190 | ${changesCircle(removed, 'removed')} 191 | ${changesCircle(deprecated, 'deprecated')} 192 |
193 | `); 194 | }); 195 | }) 196 | }) 197 | ) 198 | .then(() => session.close()) 199 | .catch(err => console.log); 200 | })(); 201 | -------------------------------------------------------------------------------- /docs/javascripts/extra.js: -------------------------------------------------------------------------------- 1 | function cookiePopup() { 2 | if (document.getElementById("cookieModal")){ 3 | document.getElementsByClassName("accept-cookies")[0].className += 4 | " hidden";} 5 | } 6 | 7 | (function() { 8 | var h1 = document.getElementsByTagName("h1"); 9 | for (i = 0; i < h1.length; i++) { 10 | h1[i].insertAdjacentHTML('afterbegin', '/ '); 11 | } 12 | })(); 13 | 14 | window.onload = function(){ 15 | var anchors = document.querySelectorAll('a.md-footer-social__link'); 16 | for (var i=0; i { 36 | star.classList.toggle('full', i <= index); 37 | }); 38 | } 39 | 40 | constructor() { 41 | super(); 42 | this.number = this.number; 43 | 44 | this.addEventListener('mousemove', e => { 45 | let box = this.getBoundingClientRect(), 46 | starIndex = Math.floor((e.pageX - box.left) / box.width * this.stars.length); 47 | this.highlight(starIndex); 48 | }); 49 | 50 | this.addEventListener('mouseout', () => { 51 | this.value = this.value; 52 | }); 53 | 54 | this.addEventListener('click', e => { 55 | document.getElementsByClassName("submitform")[0].style.display = 'block'; 56 | document.getElementsByClassName("submitform")[0].classList.toggle("show") 57 | let box = this.getBoundingClientRect(), 58 | starIndex = Math.floor((e.pageX - box.left) / box.width * this.stars.length); 59 | this.value = starIndex + 1; 60 | let rateEvent = new Event('rate'); 61 | this.dispatchEvent(rateEvent); 62 | }); 63 | } 64 | } 65 | 66 | customElements.define('x-star-rating', StarRating); 67 | -------------------------------------------------------------------------------- /docs/javascripts/submit-textbox.js: -------------------------------------------------------------------------------- 1 | var box = document.querySelector("#submitform"); 2 | 3 | document.addEventListener("mousedown", function (event) { 4 | if (document.getElementsByClassName("submitform")[0].classList[1] != "show") return; 5 | if (event.target.closest("#container")) return; 6 | document.getElementsByClassName("submitform")[0].classList.toggle("show") 7 | }); 8 | 9 | function submitForm() { 10 | 11 | if (document.activeElement.form === undefined) { 12 | if (ev.keyCode === 70 || ev.keyCode === 83) { 13 | query.focus() 14 | ev.preventDefault() 15 | } 16 | } 17 | 18 | document.getElementsByClassName("submitform")[0].classList.toggle("show") 19 | } 20 | -------------------------------------------------------------------------------- /docs/licensing.md: -------------------------------------------------------------------------------- 1 |

Pricing

2 |

There are currently two options for using Qlik Core — one for evaluation and one for production. 3 | These are outlined below.

4 | 5 |
6 | 7 |
8 |
9 |

DEVELOPER EDITION

10 |

FREE

11 |
12 |
13 |
    14 |
  • 5 concurrent session limit
  • 15 |
  • 60-day expiration
  • 16 |
  • Use to quickly evaluate, develop or test solutions for testing (and not commercial) purposes
  • 17 |
18 |
19 |
20 |

GET STARTED »

21 |
22 |
23 | 24 |
25 |
26 |

PRODUCTION EDITION

27 |

CONTACT US FOR PRICE

28 |
29 |
30 |
    31 |
  • Enables an agreed amount of minutes (resets at the end of each applicable period)
  • 32 |
  • Based on a subscription agreement
  • 33 |
  • Use to fully unleash Qlik Core in your production projects
  • 34 |
35 |

Based on your application and usage patterns, our team can help you build the right model for your implementation.

36 |
37 | 41 |
42 |
43 |
44 | 45 | # Licensing Model 46 | 47 | Please see our License Metrics for Qlik Core. 48 | 49 | Qlik Core includes a suite of APIs, License Service and the Qlik Associative Engine (Engine). 50 | Applications may be built using these APIs. The function of the License Service is to unlock the 51 | Engine and collect usage metrics. 52 | 53 | For more details on the licensing and pricing model please 54 | 55 | contact us. 56 | 57 | # Third Party Licenses 58 | 59 | Click [here](./third-party-licenses.md) for information about our third-party licenses used in our closed source components. 60 | 61 | !!! Note "Disclaimer" 62 | The information published herein is for informational purposes only and is subject to change at Qlik’s discretion. 63 | Qlik shall not be liable for errors or omissions with respect to this publication and makes no representation or 64 | warranty of any kind, other than any express warranties set forth in any applicable agreement. 65 | Nothing herein should be construed as constituting an additional warranty. -------------------------------------------------------------------------------- /docs/services/licenses.md: -------------------------------------------------------------------------------- 1 | # License 2 | 3 | To run Qlik Associative Engine with a paid license, you are required to run this service. 4 | Make sure that you have read and understood how [licensing](../licensing.md) in Qlik Core works. 5 | 6 | ## Distribution 7 | 8 | The License service is available on Docker Hub as a Docker image: [qlikcore/licenses](https://hub.docker.com/r/qlikcore/licenses). 9 | 10 | It is developed by Qlik as closed source. 11 | 12 | ## Configuration 13 | 14 | You need to configure the License service with an environment variable `LICENSE_KEY` 15 | containing your signed license key. 16 | 17 | You also need to configure [Qlik Associative Engine](./qix-engine/introduction.md) 18 | where to find it. You can do this by passing the following command line argument to the Qlik 19 | Associative Engine. 20 | 21 | ```sh 22 | -S LicenseServiceUrl= 23 | ``` 24 | 25 | ## Examples 26 | 27 | To see an example of a license configuration, see the 28 | [core-using-licenses](https://github.com/qlik-oss/core-using-licenses) repository. 29 | 30 | ## Deployment 31 | 32 | In most Qlik Core deployments, you will only need to deploy a single instance of this service. This is because 33 | traffic between Qlik Associative Engine instances and the License service is relatively low. It does however 34 | support multiple instances if needed. 35 | 36 | ### Health check 37 | 38 | For health checking, the service exposes `/health` on port 9200, and it always responds with http status code `200 OK`. 39 | 40 | ### Metrics 41 | 42 | For Prometheus metrics scraping, the service exposes `/metrics` on port 9200. It provides the following 43 | metrics associated with your license: 44 | 45 | | Name | Type | Description | 46 | | ---- | ---- | ----------- | 47 | | license_time_consumption | GAUGE | Number of license minutes consumed this month. This metrics is only showed if any minutes have been consumed. | 48 | | license_time_total | GAUGE | The total amount of license minutes per month your license gives you. | 49 | 50 | To see an example of how you can use these metrics to create dashboards of your license consumption, 51 | see the [core-using-licenses](https://github.com/qlik-oss/core-using-licenses) repository. 52 | 53 | ### Logging 54 | 55 | This service complies with the [Logging](../conventions/logging.md) conventions. 56 | By default, the minimum log level is `info`. 57 | 58 | You can override the minimum logging level by providing the `LICENSES_LOG_LEVEL` environment variable. 59 | 60 | ### License Events 61 | 62 | If no valid license exists or all license minutes are already consumed and the Qlik Associative Engine 63 | is configured to run in licensed mode without overreach it will send a `SESSION_ERROR_NO_LICENSE` 64 | push event on the websocket and then close it. 65 | 66 | If during a license renewal there are no more license minutes and your license is without overreach a `SESSION_ERROR_LICENSE_RENEW` 67 | push event will be sent from the Qlik Associative Engine and afterwards the websocket will be closed. 68 | -------------------------------------------------------------------------------- /docs/services/qix-engine/apis/data-loading/data-connector.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlik-oss/core-website/0b356d166309e06f82f8faccd6109b37d7370125/docs/services/qix-engine/apis/data-loading/data-connector.png -------------------------------------------------------------------------------- /docs/services/qix-engine/apis/data-loading/introduction.md: -------------------------------------------------------------------------------- 1 | # Data Connector API 2 | 3 | !!! warning "Experimental feature" 4 | This feature is in an experimental state. Use with caution 5 | since this feature may change in the future. 6 | 7 | The Data Connector API in Qlik Associative Engine is based on gRPC. If you are new 8 | to gRPC we recommend that you [read their documentation](https://grpc.io/docs/) as well 9 | as check our [examples](#examples) how they are used when loading data into the engine. 10 | 11 | In Qlik Core, a connector is typically implemented as a stateless Docker container that 12 | sits between the engine and the data source, as shown in the diagram below. 13 | 14 | ![connector](./data-connector.png) 15 | 16 | ## API Specification 17 | 18 | The Data Connector API is documented [here](./data-connector-api.md). 19 | 20 | ## Examples 21 | 22 | We recommend that you have a look at the respective example projects below to 23 | see a full working connector. 24 | There is also a tutorial available describing step-by-step on how to start using a gRPC connector 25 | and fetch data from a database [here](../../../../tutorials/data-loading/databases.md). 26 | 27 | !!! Tip 28 | For large data sets, it is important to choose a language that meets your performance requirements. 29 | Although gRPC is a fast protocol, it still comes with some computational overhead, especially in 30 | managed/interpreted languages like JavaScript. 31 | Go seems to be fast enough to saturate a gigabit line, which covers most requirements. 32 | 33 | ### JDBC connector built with Java 34 | 35 | [github.com/qlik-oss/core-grpc-jdbc-connector](https://github.com/qlik-oss/core-grpc-jdbc-connector) 36 | 37 | ### PostgreSQL connector built with Go 38 | 39 | [github.com/qlik-oss/core-grpc-postgres-connector](https://github.com/qlik-oss/core-grpc-postgres-connector) 40 | 41 | ### MongoDB connector built with JavaScript 42 | 43 | [github.com/qlik-oss/core-grpc-mongodb-connector](https://github.com/qlik-oss/core-grpc-mongodb-connector) 44 | 45 | ### Prometheus connector built with Python 46 | 47 | [github.com/qlik-oss/core-grpc-prometheus-connector](https://github.com/qlik-oss/core-grpc-prometheus-connector) 48 | -------------------------------------------------------------------------------- /docs/services/qix-engine/apis/file-loading/introduction.md: -------------------------------------------------------------------------------- 1 | # File Connector API 2 | 3 | !!! warning "Experimental feature" 4 | This feature is in an experimental state. Use with caution 5 | since this feature may change in the future. 6 | 7 | The File Connector API in Qlik Associative Engine is based on gRPC. 8 | If you are new to gRPC we recommend that you [read their documentation](https://grpc.io/docs/) 9 | as well as check our [examples](#examples). 10 | 11 | ## Description 12 | 13 | The gRPC File Connector feature in Qlik Associative Engine can be used to download and upload files 14 | to and/or from a remote storage. 15 | Functionality-wise the feature is similar to that of the `folder` connector which is used for accessing locally stored files. 16 | The feature is intended to enable a user to load or store files from external sources 17 | such as an S3 bucket, Dropbox or other remote storage services. 18 | 19 | ## Configuration 20 | 21 | The gRPC File Connector feature is enabled by passing `-S EnableGrpcFileStreamConnector=1` 22 | to Qlik Associative Engine as a startup parameter. 23 | 24 | When the feature is enabled it is also possible to define your own custom gRPC File Connectors e.g. `-S GrpcCustomConnectorPlugins=s3connector,s3connector:50051,fs`. 25 | 26 | Multiple connectors can also be configured using a `;` as delimiter e.g. `-S GrpcCustomConnectorPlugins=s3-grpc-file-connector,s3connector:50051,fs;dropbox-grpc-file-connector,dropboxconnector:50052,fs`. 27 | 28 | An example on how it can be configured in a `docker-compose` file: 29 | 30 | ```yaml 31 | qix-engine: 32 | image: qlikcore/engine:12.792.0 33 | ports: 34 | - 9076:9076 35 | command: -S AcceptEULA=${ACCEPT_EULA} -S EnableGrpcFileStreamConnector=1 -S GrpcConnectorPlugins="s3-grpc-file-connector,s3-grpc-file-connector:50051,fs" 36 | ``` 37 | 38 | There is also a full example of a implemented gRPC File Connector for an S3 bucket [here](https://github.com/qlik-oss/core-grpc-s3-file-connector). 39 | 40 | ## API Specification 41 | 42 | The File Connector API is documented [here](./file-connector-api.md). 43 | 44 | ## Examples 45 | 46 | The example below is a connector written in Node.js 47 | that showcases how this feature can be implemented and used against an S3 Bucket in AWS. 48 | If you want to go through the example step-by-step take a look at the [tutorial](../../../../tutorials/data-loading/remote-files.md). 49 | 50 | ### S3 file connector built with Node.js 51 | 52 | [github.com/qlik-oss/core-grpc-s3-file-connector](https://github.com/qlik-oss/core-grpc-s3-file-connector) 53 | -------------------------------------------------------------------------------- /docs/services/qix-engine/apis/qix/genericbookmark.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # GenericBookmark 5 | 6 | _QIX methods for version 12.887.0._ 7 | 8 | ## `Apply` 9 | 10 | Applies a bookmark.

The operation is successful if **qSuccess** is set to true. 11 | 12 | 13 | _No parameters._ 14 | 15 | **Returns:** 16 | 17 | | Name | Type | Description | 18 | | ---- | ---- | ----------- | 19 | | `qSuccess` | boolean | <true or false> | 20 | 21 | ## `ApplyPatches` 22 | 23 | Applies a patch to the properties of an object. Allows an update to some of the properties.
Applying a patch takes less time than resetting all the properties. 24 | 25 | Required permissions: [`update`](https://core.qlik.com/services/qix-engine/access-control/#actions) 26 | 27 | **Parameters:** 28 | 29 | | Name | Type | Mandatory | Description | 30 | | ---- | ---- | --------- | ----------- | 31 | | `qPatches` | [`NxPatch`](./definitions.md#nxpatch) | Yes | Array of patches. | 32 | 33 | _No return values._ 34 | 35 | ## `Approve` 36 | 37 | Adds the generic bookmark to the list of approved objects
This operation is possible only in Qlik Sense Enterprise. 38 | 39 | Required permissions: [`approve`](https://core.qlik.com/services/qix-engine/access-control/#actions) 40 | 41 | _No parameters._ 42 | 43 | _No return values._ 44 | 45 | ## `GetFieldValues` 46 | 47 | Retrieves the values of a field. 48 | 49 | 50 | **Parameters:** 51 | 52 | | Name | Type | Mandatory | Description | 53 | | ---- | ---- | --------- | ----------- | 54 | | `qField` | string | Yes | Name of the field. | 55 | | `qGetExcludedValues` | boolean | Yes | If set to true, only excluded values are returned. | 56 | | `qDataPage` | [`BookmarkFieldPage`](./definitions.md#bookmarkfieldpage) | Yes | [`Range`](./definitions.md#range) of returned values. | 57 | 58 | **Returns:** 59 | 60 | | Name | Type | Description | 61 | | ---- | ---- | ----------- | 62 | | `qFieldValues` | array<[`FieldValue`](./definitions.md#fieldvalue)> | The field values from a defined range. | 63 | 64 | ## `GetInfo` 65 | 66 | Returns:
- The type of the object.
- The identifier of the object. 67 | 68 | 69 | _No parameters._ 70 | 71 | **Returns:** 72 | 73 | | Name | Type | Description | 74 | | ---- | ---- | ----------- | 75 | | `qInfo` | [`NxInfo`](./definitions.md#nxinfo) | `{"qId":"","qType":""}` | 76 | 77 | ## `GetLayout` 78 | 79 | Evaluates an object and displays its properties including the dynamic properties.
If the member _delta_ is set to true in the request object, only the delta is evaluated. 80 | 81 | 82 | _No parameters._ 83 | 84 | **Returns:** 85 | 86 | | Name | Type | Description | 87 | | ---- | ---- | ----------- | 88 | | `qLayout` | [`GenericBookmarkLayout`](./definitions.md#genericbookmarklayout) | Information on the object. | 89 | 90 | ## `GetProperties` 91 | 92 | Shows the properties of an object.
If the member delta is set to true in the request object, only the delta is retrieved.
The following is always returned in the output: 93 | 94 | 95 | _No parameters._ 96 | 97 | **Returns:** 98 | 99 | | Name | Type | Description | 100 | | ---- | ---- | ----------- | 101 | | `qProp` | [`GenericBookmarkProperties`](./definitions.md#genericbookmarkproperties) | Information about the generic object. | 102 | 103 | ## `Publish` 104 | 105 | Publishes a bookmark.
This operation is not applicable for Qlik Sense Desktop. 106 | 107 | Required permissions: [`publish`](https://core.qlik.com/services/qix-engine/access-control/#actions) 108 | 109 | _No parameters._ 110 | 111 | _No return values._ 112 | 113 | ## `SetProperties` 114 | 115 | Sets some properties for a bookmark. 116 | 117 | Required permissions: [`update`](https://core.qlik.com/services/qix-engine/access-control/#actions) 118 | 119 | **Parameters:** 120 | 121 | | Name | Type | Mandatory | Description | 122 | | ---- | ---- | --------- | ----------- | 123 | | `qProp` | [`GenericBookmarkProperties`](./definitions.md#genericbookmarkproperties) | Yes | Information about the bookmark. | 124 | 125 | _No return values._ 126 | 127 | ## `UnApprove` 128 | 129 | Removes the generic bookmark from the list of approved objects
This operation is possible only in Qlik Sense Enterprise. 130 | 131 | Required permissions: [`approve`](https://core.qlik.com/services/qix-engine/access-control/#actions) 132 | 133 | _No parameters._ 134 | 135 | _No return values._ 136 | 137 | ## `UnPublish` 138 | 139 | Unpublishes a bookmark.
This operation is not applicable for Qlik Sense Desktop. 140 | 141 | Required permissions: [`publish`](https://core.qlik.com/services/qix-engine/access-control/#actions) 142 | 143 | _No parameters._ 144 | 145 | _No return values._ 146 | -------------------------------------------------------------------------------- /docs/services/qix-engine/apis/qix/genericdimension.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # GenericDimension 5 | 6 | _QIX methods for version 12.887.0._ 7 | 8 | ## `ApplyPatches` 9 | 10 | Applies a patch to the properties of an object. Allows an update to some of the properties.
Applying a patch takes less time than resetting all the properties. 11 | 12 | Required permissions: [`update`](https://core.qlik.com/services/qix-engine/access-control/#actions) 13 | 14 | **Parameters:** 15 | 16 | | Name | Type | Mandatory | Description | 17 | | ---- | ---- | --------- | ----------- | 18 | | `qPatches` | [`NxPatch`](./definitions.md#nxpatch) | Yes | Array of patches. | 19 | 20 | _No return values._ 21 | 22 | ## `Approve` 23 | 24 | Adds the generic dimension to the list of approved objects
This operation is possible only in Qlik Sense Enterprise. 25 | 26 | Required permissions: [`approve`](https://core.qlik.com/services/qix-engine/access-control/#actions) 27 | 28 | _No parameters._ 29 | 30 | _No return values._ 31 | 32 | ## `GetDimension` 33 | 34 | Returns the definition of a dimension.

The definition of the dimension is returned. 35 | 36 | 37 | _No parameters._ 38 | 39 | **Returns:** 40 | 41 | | Name | Type | Description | 42 | | ---- | ---- | ----------- | 43 | | `qDim` | [`NxLibraryDimensionDef`](./definitions.md#nxlibrarydimensiondef) | `{"qGrouping":"...","qFieldDefs":["..."],"qFieldLabels":["..."]}` | 44 | 45 | ## `GetInfo` 46 | 47 | Returns the type and identifier of the object. 48 | 49 | 50 | _No parameters._ 51 | 52 | **Returns:** 53 | 54 | | Name | Type | Description | 55 | | ---- | ---- | ----------- | 56 | | `qInfo` | [`NxInfo`](./definitions.md#nxinfo) | `{"qId":"","qType":""}` | 57 | 58 | ## `GetLayout` 59 | 60 | Evaluates a dimension and displays its properties, including the dynamic properties. 61 | 62 | 63 | _No parameters._ 64 | 65 | **Returns:** 66 | 67 | | Name | Type | Description | 68 | | ---- | ---- | ----------- | 69 | | `qLayout` | [`GenericDimensionLayout`](./definitions.md#genericdimensionlayout) | Information on the object. | 70 | 71 | ## `GetLinkedObjects` 72 | 73 | Lists the linked objects to a generic object, a dimension or a measure. 74 | 75 | 76 | _No parameters._ 77 | 78 | **Returns:** 79 | 80 | | Name | Type | Description | 81 | | ---- | ---- | ----------- | 82 | | `qItems` | array<[`NxLinkedObjectInfo`](./definitions.md#nxlinkedobjectinfo)> | List of the linked objects. | 83 | 84 | ## `GetProperties` 85 | 86 | Shows the properties of an object.
Returns the identifier and the definition of the dimension.
If the member delta is set to true in the request object, only the delta is retrieved. 87 | 88 | 89 | _No parameters._ 90 | 91 | **Returns:** 92 | 93 | | Name | Type | Description | 94 | | ---- | ---- | ----------- | 95 | | `qProp` | [`GenericDimensionProperties`](./definitions.md#genericdimensionproperties) | Information about the generic object. | 96 | 97 | ## `Publish` 98 | 99 | Publishes a dimension.
This operation is not applicable for Qlik Sense Desktop. 100 | 101 | Required permissions: [`publish`](https://core.qlik.com/services/qix-engine/access-control/#actions) 102 | 103 | _No parameters._ 104 | 105 | _No return values._ 106 | 107 | ## `SetProperties` 108 | 109 | Sets some properties for a dimension. 110 | 111 | Required permissions: [`update`](https://core.qlik.com/services/qix-engine/access-control/#actions) 112 | 113 | **Parameters:** 114 | 115 | | Name | Type | Mandatory | Description | 116 | | ---- | ---- | --------- | ----------- | 117 | | `qProp` | [`GenericDimensionProperties`](./definitions.md#genericdimensionproperties) | Yes | Information about the dimension. | 118 | 119 | _No return values._ 120 | 121 | ## `UnApprove` 122 | 123 | Removes the generic dimension from the list of approved objects
This operation is possible only in Qlik Sense Enterprise. 124 | 125 | Required permissions: [`approve`](https://core.qlik.com/services/qix-engine/access-control/#actions) 126 | 127 | _No parameters._ 128 | 129 | _No return values._ 130 | 131 | ## `UnPublish` 132 | 133 | Unpublishes a dimension.
This operation is not applicable for Qlik Sense Desktop. 134 | 135 | Required permissions: [`publish`](https://core.qlik.com/services/qix-engine/access-control/#actions) 136 | 137 | _No parameters._ 138 | 139 | _No return values._ 140 | -------------------------------------------------------------------------------- /docs/services/qix-engine/apis/qix/genericmeasure.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # GenericMeasure 5 | 6 | _QIX methods for version 12.887.0._ 7 | 8 | ## `ApplyPatches` 9 | 10 | Applies a patch to the properties of an object. Allows an update to some of the properties.
Applying a patch takes less time than resetting all the properties. 11 | 12 | Required permissions: [`update`](https://core.qlik.com/services/qix-engine/access-control/#actions) 13 | 14 | **Parameters:** 15 | 16 | | Name | Type | Mandatory | Description | 17 | | ---- | ---- | --------- | ----------- | 18 | | `qPatches` | [`NxPatch`](./definitions.md#nxpatch) | Yes | Array of patches. | 19 | 20 | _No return values._ 21 | 22 | ## `Approve` 23 | 24 | Adds the generic measure to the list of approved objects
This operation is possible only in Qlik Sense Enterprise. 25 | 26 | Required permissions: [`approve`](https://core.qlik.com/services/qix-engine/access-control/#actions) 27 | 28 | _No parameters._ 29 | 30 | _No return values._ 31 | 32 | ## `GetInfo` 33 | 34 | Returns the type and identifier of the object. 35 | 36 | 37 | _No parameters._ 38 | 39 | **Returns:** 40 | 41 | | Name | Type | Description | 42 | | ---- | ---- | ----------- | 43 | | `qInfo` | [`NxInfo`](./definitions.md#nxinfo) | `{"qId":"","qType":""}` | 44 | 45 | ## `GetLayout` 46 | 47 | Evaluates a measure and displays its properties, including the dynamic properties. 48 | 49 | 50 | _No parameters._ 51 | 52 | **Returns:** 53 | 54 | | Name | Type | Description | 55 | | ---- | ---- | ----------- | 56 | | `qLayout` | [`GenericMeasureLayout`](./definitions.md#genericmeasurelayout) | Information on the object. | 57 | 58 | ## `GetLinkedObjects` 59 | 60 | Lists the linked objects to a generic object, a dimension or a measure. 61 | 62 | 63 | _No parameters._ 64 | 65 | **Returns:** 66 | 67 | | Name | Type | Description | 68 | | ---- | ---- | ----------- | 69 | | `qItems` | array<[`NxLinkedObjectInfo`](./definitions.md#nxlinkedobjectinfo)> | List of the linked objects. | 70 | 71 | ## `GetMeasure` 72 | 73 | Returns the definition of a measure. 74 | 75 | 76 | _No parameters._ 77 | 78 | **Returns:** 79 | 80 | | Name | Type | Description | 81 | | ---- | ---- | ----------- | 82 | | `qMeasure` | [`NxLibraryMeasureDef`](./definitions.md#nxlibrarymeasuredef) | Information about the measure. | 83 | 84 | ## `GetProperties` 85 | 86 | Shows the properties of an object.
Returns the identifier and the definition of the measure.
If the member delta is set to true in the request object, only the delta is retrieved.
The following is always returned in the output: 87 | 88 | 89 | _No parameters._ 90 | 91 | **Returns:** 92 | 93 | | Name | Type | Description | 94 | | ---- | ---- | ----------- | 95 | | `qProp` | [`GenericMeasureProperties`](./definitions.md#genericmeasureproperties) | Information about the generic object. | 96 | 97 | ## `Publish` 98 | 99 | Publishes a measure.
This operation is not applicable for Qlik Sense Desktop. 100 | 101 | Required permissions: [`publish`](https://core.qlik.com/services/qix-engine/access-control/#actions) 102 | 103 | _No parameters._ 104 | 105 | _No return values._ 106 | 107 | ## `SetProperties` 108 | 109 | Sets some properties for a measure. 110 | 111 | Required permissions: [`update`](https://core.qlik.com/services/qix-engine/access-control/#actions) 112 | 113 | **Parameters:** 114 | 115 | | Name | Type | Mandatory | Description | 116 | | ---- | ---- | --------- | ----------- | 117 | | `qProp` | [`GenericMeasureProperties`](./definitions.md#genericmeasureproperties) | Yes | Information about the measure. | 118 | 119 | _No return values._ 120 | 121 | ## `UnApprove` 122 | 123 | Removes the generic measure from the list of approved objects
This operation is possible only in Qlik Sense Enterprise. 124 | 125 | Required permissions: [`approve`](https://core.qlik.com/services/qix-engine/access-control/#actions) 126 | 127 | _No parameters._ 128 | 129 | _No return values._ 130 | 131 | ## `UnPublish` 132 | 133 | Unpublishes a measure.
This operation is not applicable for Qlik Sense Desktop. 134 | 135 | Required permissions: [`publish`](https://core.qlik.com/services/qix-engine/access-control/#actions) 136 | 137 | _No parameters._ 138 | 139 | _No return values._ 140 | -------------------------------------------------------------------------------- /docs/services/qix-engine/apis/qix/genericvariable.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # GenericVariable 5 | 6 | _QIX methods for version 12.887.0._ 7 | 8 | ## `ApplyPatches` 9 | 10 | Applies a patch to the properties of a variable. Allows an update to some of the properties.
Applying a patch takes less time than resetting all the properties. 11 | 12 | Required permissions: [`update`](https://core.qlik.com/services/qix-engine/access-control/#actions) 13 | 14 | **Parameters:** 15 | 16 | | Name | Type | Mandatory | Description | 17 | | ---- | ---- | --------- | ----------- | 18 | | `qPatches` | [`NxPatch`](./definitions.md#nxpatch) | Yes | Array of patches. | 19 | 20 | _No return values._ 21 | 22 | ## `GetInfo` 23 | 24 | Returns the type and identifier of the object. 25 | 26 | 27 | _No parameters._ 28 | 29 | **Returns:** 30 | 31 | | Name | Type | Description | 32 | | ---- | ---- | ----------- | 33 | | `qInfo` | [`NxInfo`](./definitions.md#nxinfo) | `{"qId":"","qType":""}` | 34 | 35 | ## `GetLayout` 36 | 37 | Evaluates an object and displays its properties including the dynamic properties.
If the member _delta_ is set to true in the request object, only the delta is evaluated. 38 | 39 | 40 | _No parameters._ 41 | 42 | **Returns:** 43 | 44 | | Name | Type | Description | 45 | | ---- | ---- | ----------- | 46 | | `qLayout` | [`GenericVariableLayout`](./definitions.md#genericvariablelayout) | Information on the object | 47 | 48 | ## `GetProperties` 49 | 50 | Shows the properties of an object.
If the member **delta** is set to true in the request, only the delta is retrieved.
The following is always returned in the output: 51 | 52 | 53 | _No parameters._ 54 | 55 | **Returns:** 56 | 57 | | Name | Type | Description | 58 | | ---- | ---- | ----------- | 59 | | `qProp` | [`GenericVariableProperties`](./definitions.md#genericvariableproperties) | Information about the generic object | 60 | 61 | ## `GetRawContent` 62 | 63 | Returns the raw value of a variable. 64 | 65 | 66 | _No parameters._ 67 | 68 | **Returns:** 69 | 70 | | Name | Type | Description | 71 | | ---- | ---- | ----------- | 72 | | `qReturn` | string | <Definition of the variable> | 73 | 74 | ## `SetDualValue` 75 | 76 | Sets the value of a dual variable.
These changes are not persistent. They only last the duration of the engine session. 77 | 78 | 79 | **Parameters:** 80 | 81 | | Name | Type | Mandatory | Description | 82 | | ---- | ---- | --------- | ----------- | 83 | | `qText` | string | Yes | String representation of a dual value. Set this parameter to "", if the string representation is to be Null. | 84 | | `qNum` | number | Yes | Numeric representation of a dual value. | 85 | 86 | _No return values._ 87 | 88 | ## `SetNumValue` 89 | 90 | Sets a numerical value to a variable.
These changes are not persistent. They only last the duration of the engine session. 91 | 92 | 93 | **Parameters:** 94 | 95 | | Name | Type | Mandatory | Description | 96 | | ---- | ---- | --------- | ----------- | 97 | | `qVal` | number | Yes | Value of the variable. | 98 | 99 | _No return values._ 100 | 101 | ## `SetProperties` 102 | 103 | Sets some properties for a variable.
The identifier of a variable cannot be modified. You cannot update the properties of a script-defined variable using the [`SetProperties`](#setproperties) method. 104 | 105 | Required permissions: [`update`](https://core.qlik.com/services/qix-engine/access-control/#actions) 106 | 107 | **Parameters:** 108 | 109 | | Name | Type | Mandatory | Description | 110 | | ---- | ---- | --------- | ----------- | 111 | | `qProp` | [`GenericVariableProperties`](./definitions.md#genericvariableproperties) | Yes | Information about the variable. | 112 | 113 | _No return values._ 114 | 115 | ## `SetStringValue` 116 | 117 | Sets a string value to a variable.
These changes are not persistent. They only last the duration of the engine session. 118 | 119 | 120 | **Parameters:** 121 | 122 | | Name | Type | Mandatory | Description | 123 | | ---- | ---- | --------- | ----------- | 124 | | `qVal` | string | Yes | Value of the variable. The string can contain an expression. | 125 | 126 | _No return values._ 127 | -------------------------------------------------------------------------------- /docs/services/qix-engine/apis/qix/introduction.md: -------------------------------------------------------------------------------- 1 | # QIX API 2 | 3 | The QIX API is the primary API used for consuming QIX documents. It is based on the WebSocket protocol and requires some 4 | specific parameters to work correctly. 5 | 6 | ## WebSockets 7 | 8 | Any websocket client implementation that follows the [RFC specification](https://tools.ietf.org/html/rfc6455) 9 | should be supported. The URL format is: 10 | 11 | ```raw 12 | ws://:/app/ 13 | ``` 14 | 15 | `` can be anything that would identify the document for the user making the request. 16 | 17 | JavaScript example: 18 | 19 | ```js 20 | const websocket = new WebSocket('ws://localhost:9076/app/my-document.qvf'); 21 | ``` 22 | 23 | ### Headers 24 | 25 | In a non-browser environment, most websocket client implementations support to add headers. 26 | 27 | Header | Description 28 | ------ | ----------- 29 | `X-Qlik-Session: ` | Defines the session id, regardless of the user. If you use this header, the websocket URL could simply be `ws://hostname:9076/app/`. 30 | `Authorization: Bearer ` | If the [JWT feature](../../../../tutorials/authorization.md) is enabled, this header will identify the user and its attributes. 31 | 32 | ### Session Sharing 33 | 34 | Qlik Associative Engine uses the concept of _sessions_ to identify the state of connections to the QIX API. When making 35 | a new connection either a new unique session is created, or the connection gets attached to an existing session. This 36 | makes it possible to share state, like selections, between several connections. 37 | 38 | Session sharing can be achieved in two ways depending on whether the 39 | [JWT feature](../../../../tutorials/authorization.md) is enabled or not: 40 | 41 | 1. If enabled, a second connection will share session if the same user connects by setting the `X-Qlik-Session` header 42 | to the same value as an existing session. 43 | 1. If disabled, a second connection will share session if connecting to the same document omitting the `X-Qlik-Session` 44 | header or setting it to the same value as an existing session. 45 | 46 | Note that `X-Qlik-Session` can be set to a new unique identifier to delibarately force creation of a new session. 47 | 48 | ### Session Time-to-Live 49 | 50 | It can be useful to be able to reconnect to an existing session even after the last connection to the session has been 51 | closed. Qlik Associative Engine supports setting TTL on sessions which keeps them alive for the duration specified. 52 | 53 | These command line switches can be used to control TTL: 54 | 55 | Switch | Default | Description 56 | ------ | ------- | ------------ 57 | `SessionTTL` | `0` | Global TTL in seconds for all sessions. Set to `-1` for infinite TTL (requires `MaxSessionTTL=-1`). | 58 | `MaxSessionTTL` | `1800` | Maximum TTL in seconds. TTL is always capped to this value. Set to `-1` to allow infinite TTL. | 59 | 60 | The TTL can also be provided per connection by passing the TTL value in the URL, as in 61 | 62 | ```raw 63 | ws://:/.../ttl/ 64 | ``` 65 | 66 | This overrides the global TTL set with `SessionTTL` and is still capped by `MaxSessionTTL`. Since different TTL values 67 | for the same session could potentially be set, it is the latest TTL provided that is effective. 68 | 69 | ## JSONRPC Protocol 70 | 71 | Once a session has been established using websockets, you may start interacting 72 | using the QIX API. All requests sent from the client should contain the following: 73 | 74 | ```json 75 | { 76 | // Protocol descriptor: 77 | "jsonrpc": "2.0", 78 | // Session-unique numeric id, referred to in the response 79 | // to connect the request and response: 80 | "id": 6, 81 | // The handle for the object to interact with: 82 | "handle": 2, 83 | // The object type of the handle above decides 84 | // which API methods you may invoke: 85 | "method": "ApiMethodName", 86 | // Parameters for the invoked API method: 87 | "params": { 88 | } 89 | } 90 | ``` 91 | 92 | ### Request and response 93 | 94 | Here is an example request/response pair. Note that there is only _one_ static handle in 95 | the QIX API, and that is `-1`. This handle refers to the [Global](./global.md) API. 96 | 97 | In this example request, we will open a document using [`OpenDoc`](./global.md#opendoc). 98 | If successful, the response will contain a reference to the document handle, which can 99 | be used to do further requests towards the [Document](./doc.md) API, and so forth. 100 | 101 | ```json 102 | { 103 | "jsonrpc": "2.0", 104 | "id": 1, 105 | "handle": -1, 106 | "method": "OpenDoc", 107 | "params": { 108 | "qDocName": "my-document.qvf" 109 | } 110 | } 111 | ``` 112 | 113 | If that document exist, the response would look similar to this: 114 | 115 | ```json 116 | { 117 | "jsonrpc": "2.0", 118 | "id": 1, 119 | "result": { 120 | "qReturn": { 121 | "qType": "Doc", 122 | "qHandle": 1, 123 | "qGenericId": "my-document.qvf" 124 | } 125 | }, 126 | "change":[1] 127 | } 128 | ``` 129 | 130 | Note that `qHandle` contains the handle we may use to make additional 131 | requests to invoke API methods towards the document. We also get a 132 | property on the response called `change`, this array can be added by QIX 133 | Engine on any responses and contains all open handles in your session 134 | that may have been invalidated and you should refetch data to ensure 135 | your application in a valid state. 136 | 137 | ## API references 138 | 139 | For the API references, see the different classes listed in the left-side menu. 140 | -------------------------------------------------------------------------------- /docs/services/qix-engine/apis/qix/variable.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # Variable 5 | 6 | _QIX methods for version 12.887.0._ 7 | 8 | ## `ForceContent` 9 | 10 | !!! warning "Deprecated" 11 | Use [`GenericVariable::SetProperties`](./genericvariable.md#genericvariable::setproperties) method instead 12 | 13 | Sets the value of a dual variable overriding any input constraints. 14 | 15 | 16 | **Parameters:** 17 | 18 | | Name | Type | Mandatory | Description | 19 | | ---- | ---- | --------- | ----------- | 20 | | `qs` | string | Yes | String representation of a dual value.
Set this parameter to "", if the string representation is to be Null. | 21 | | `qd` | number | Yes | Numeric representation of a dual value. | 22 | 23 | _No return values._ 24 | 25 | ## `GetContent` 26 | 27 | !!! warning "Deprecated" 28 | Use [`GenericVariable::GetProperties`](./genericvariable.md#genericvariable::getproperties) method instead 29 | 30 | Returns the calculated value of a variable. 31 | 32 | 33 | _No parameters._ 34 | 35 | **Returns:** 36 | 37 | | Name | Type | Description | 38 | | ---- | ---- | ----------- | 39 | | `qContent` | [`AlfaNumString`](./definitions.md#alfanumstring) | Information about the calculated value. | 40 | 41 | ## `GetNxProperties` 42 | 43 | !!! warning "Deprecated" 44 | Use [`GetProperties`](./genericvariable.md#getproperties) method instead 45 | 46 | Gets the properties of a variable. 47 | 48 | 49 | _No parameters._ 50 | 51 | **Returns:** 52 | 53 | | Name | Type | Description | 54 | | ---- | ---- | ----------- | 55 | | `qProperties` | [`NxVariableProperties`](./definitions.md#nxvariableproperties) | Information about the properties of the variable. | 56 | 57 | ## `GetRawContent` 58 | 59 | !!! warning "Deprecated" 60 | Use [`GenericVariable::GetProperties`](./genericvariable.md#genericvariable::getproperties) method instead 61 | 62 | Returns the raw value of a variable. 63 | 64 | 65 | _No parameters._ 66 | 67 | **Returns:** 68 | 69 | | Name | Type | Description | 70 | | ---- | ---- | ----------- | 71 | | `qReturn` | string | <Definition of the variable> | 72 | 73 | ## `SetContent` 74 | 75 | !!! warning "Deprecated" 76 | Use [`GenericVariable::SetProperties`](./genericvariable.md#genericvariable::setproperties) method instead 77 | 78 | Sets a value to a variable. 79 | 80 | 81 | **Parameters:** 82 | 83 | | Name | Type | Mandatory | Description | 84 | | ---- | ---- | --------- | ----------- | 85 | | `qContent` | string | Yes | Value of the variable. | 86 | | `qUpdateMRU` | boolean | Yes | If set to true, the value is added to the Most Recently Used (MRU) list. | 87 | 88 | **Returns:** 89 | 90 | | Name | Type | Description | 91 | | ---- | ---- | ----------- | 92 | | `qReturn` | boolean | true/false
The operation is successful if qReturn is set to true. | 93 | 94 | ## `SetNxProperties` 95 | 96 | !!! warning "Deprecated" 97 | Use [`SetProperties`](./genericvariable.md#setproperties) method instead 98 | 99 | Sets some properties to a variable. 100 | 101 | Required permissions: [`update`](https://core.qlik.com/services/qix-engine/access-control/#actions) 102 | 103 | **Parameters:** 104 | 105 | | Name | Type | Mandatory | Description | 106 | | ---- | ---- | --------- | ----------- | 107 | | `qProperties` | [`NxVariableProperties`](./definitions.md#nxvariableproperties) | Yes | Information about the properties of the variable | 108 | 109 | _No return values._ 110 | -------------------------------------------------------------------------------- /docs/services/qix-engine/apis/server-side-extension/analytical-connector-api.proto: -------------------------------------------------------------------------------- 1 | syntax="proto3"; 2 | 3 | /** 4 | * A gRPC definition for the Qlik engine extension protocol. 5 | */ 6 | package qlik.sse; 7 | 8 | /** 9 | * Enable protobuf arena allocations in C++. 10 | * Using an arena can boost performance by reducing the overhead for heap allocations. 11 | */ 12 | option cc_enable_arenas = true; 13 | 14 | /** 15 | * Data types of the parameters and return values. 16 | */ 17 | enum DataType { 18 | STRING = 0; /// Contains only string. 19 | NUMERIC = 1; /// Contains only double. 20 | DUAL = 2; /// Contains both a string and a double. 21 | } 22 | 23 | /** 24 | * Types of functions (determined by their return values). 25 | */ 26 | enum FunctionType { 27 | SCALAR = 0; /// The return value is a scalar per row. 28 | AGGREGATION = 1; /// All rows are aggregated into a single scalar. 29 | TENSOR = 2; /// Multiple rows in, multiple rows out. 30 | } 31 | 32 | /** 33 | * An empty message used when nothing is to be passed in a call. 34 | */ 35 | message Empty {} 36 | 37 | /** 38 | * Parameter definition for functions and script calls. 39 | */ 40 | message Parameter { 41 | DataType dataType = 1; /// The data type of the parameter. 42 | string name = 2; /// The name of the parameter. 43 | } 44 | 45 | /** 46 | * Field definition for function and script calls. 47 | */ 48 | message FieldDescription { 49 | DataType dataType = 1; /// The data type of the field. 50 | string name = 2; /// The name of the field. 51 | repeated string tags = 3; /// The tags of the field. 52 | } 53 | 54 | /** 55 | * The definition of a function, which informs the Qlik engine how to use it. 56 | */ 57 | message FunctionDefinition { 58 | string name = 1; /// The name of the function. 59 | FunctionType functionType = 2; /// The type of the function. 60 | DataType returnType = 3; /// The return type of the function. 61 | repeated Parameter params = 4; /// The parameters the function takes. 62 | int32 functionId = 5; /// A unique ID number for the function, set by the plugin, to be used in calls from the Qlik engine to the plugin. 63 | } 64 | 65 | /** 66 | * A full description of the plugin, sent to the Qlik engine, listing all functions available and indicating whether script evaluation is allowed. 67 | */ 68 | message Capabilities { 69 | bool allowScript = 1; /// When true, the Qlik engine allows scripts to be sent to the plugin. 70 | repeated FunctionDefinition functions = 2; /// The definitions of all available functions. 71 | string pluginIdentifier = 3; /// The ID or name of the plugin. 72 | string pluginVersion = 4; /// The version of the plugin. 73 | } 74 | 75 | /** 76 | * The basic data type for the data stream. Can contain double, string, or both. 77 | */ 78 | message Dual { 79 | double numData = 1; /// Numeric value as double. 80 | string strData = 2; /// String. 81 | } 82 | 83 | /** 84 | * A row of duals. 85 | */ 86 | message Row { 87 | repeated Dual duals = 1; /// Row of duals. 88 | } 89 | 90 | /** 91 | * A number of rows collected in one message. The actual number will depend on the size of each row and is adjusted to optimize throughput. 92 | */ 93 | message BundledRows { 94 | repeated Row rows = 1; 95 | } 96 | 97 | /** 98 | * A header sent at the start of an EvaluateScript request under the key "qlik-scriptrequestheader-bin". 99 | */ 100 | message ScriptRequestHeader { 101 | string script = 1; /// The script to be executed. 102 | FunctionType functionType = 2; /// The function type of the script evaluation: scalar, aggregation or tensor. 103 | DataType returnType = 3; /// The return type from the script evaluation: numeric, string or both. 104 | repeated Parameter params = 4; /// The parameters names and types passed to the script. 105 | } 106 | 107 | /** 108 | * A header sent at the start of an ExecuteFunction request under the key "qlik-functionrequestheader-bin". 109 | */ 110 | message FunctionRequestHeader { 111 | int32 functionId = 1; /// The ID of the function to be executed. 112 | string version = 2; /// A dummy variable as a workaround for an issue. 113 | } 114 | 115 | /** 116 | * A header sent at the start of both an EvaluateScript request and an ExecuteFunction request under the key "qlik-commonrequestheader-bin". 117 | */ 118 | message CommonRequestHeader { 119 | string appId = 1; /// The ID of the app the request was executed in. 120 | string userId = 2; /// The ID of the user the request was executed by. 121 | int64 cardinality = 3; /// The cardinality of the parameters. 122 | } 123 | 124 | /** 125 | * A header sent before returning data to Qlik, under the key "qlik-tabledescription-bin". 126 | */ 127 | message TableDescription { 128 | repeated FieldDescription fields = 1; /// The fields of the table. 129 | string name = 2; /// The name of the table. 130 | int64 numberOfRows = 3; /// Number of rows in table. 131 | } 132 | 133 | /** 134 | * The communication service provided between the Qlik engine and the plugin. 135 | */ 136 | service Connector 137 | { 138 | /// A handshake call for the Qlik engine to retrieve the capability of the plugin. 139 | rpc GetCapabilities (Empty) returns (Capabilities) {} 140 | 141 | /// Requests a function to be executed as specified in the header. 142 | rpc ExecuteFunction (stream BundledRows) returns (stream BundledRows) {} 143 | 144 | /// Requests a script to be evaluated as specified in the header. 145 | rpc EvaluateScript (stream BundledRows) returns (stream BundledRows) {} 146 | } 147 | -------------------------------------------------------------------------------- /docs/services/qix-engine/apis/server-side-extension/introduction.md: -------------------------------------------------------------------------------- 1 | # Analytical Connector API 2 | 3 | The Analytical Connector API in Qlik Associative Engine is based on gRPC. If you are new 4 | to gRPC we recommend that you [read their documentation](https://grpc.io/docs/). 5 | 6 | With analytic connections you are able to integrate external analysis with your business discovery. 7 | An analytic connection extends the expressions you can use in load scripts and charts 8 | by calling an external calculation engine (when you do this, the calculation engine acts as a server-side extension (SSE)). 9 | For example, you could create an analytic connection to R, and use statistical expressions when you load the data. 10 | 11 | An overview of the protocol and more details can be found in the Github repository for [Server Side Extension](https://github.com/qlik-oss/server-side-extension/blob/master/docs/README.md). 12 | 13 | ## API Specification 14 | 15 | The Analytical Connector API is documented [here](./analytical-connector-api.md). 16 | 17 | ## Analytical Connector Examples 18 | 19 | There are a number of examples created for different programming languages available [here](https://github.com/qlik-oss/server-side-extension/tree/master/examples). 20 | 21 | ## How to configure an Analytical Connector in Qlik Core 22 | 23 | An Analytical Connector is configured by providing command line parameters to the Qlik Associative Engine 24 | using the `SSEPlugin` parameter. 25 | How to provide a command line parameter to Qlik Associative Engine is described [here](../../introduction.md#command-line-parameters). 26 | 27 | The `SSEPlugin` parameter takes a comma-separated list of configuration elements in the format `,
[,,,]`. 28 | The elements within the brackets are optional. 29 | 30 | - **PluginName** Mapping/alias to the plugin that will be used from within the expressions in the app using the plugin functions, 31 | for example, SSEPython for a Python plugin. 32 | - **Address** colon-separated list with two elements `:`. 33 | - **Host** DNS name (or IP-adress) of the plugin. 34 | If the plugin is running in a container this will typically be the service name. 35 | Please note that _localhost_ will not be accessible for a Qlik Associative Engine running as a docker container. 36 | If you want to use an Analytical Connector running on the host e.g for development purpose, 37 | please see these [instructions](https://docs.docker.com/docker-for-mac/networking/#i-want-to-connect-from-a-container-to-a-service-on-the-host). 38 | - **Port** Port on which the plugin listens. 39 | - **PathToCertFile** File system path to folder containing client certificates required for secure communication 40 | with the plugin. Optional. If omitted, insecure communication will be invoked. 41 | This path just points to the folder where the certificates are located. 42 | You have to make sure that they are actually copied to that folder. 43 | The names of the three certificate files must be the following: root_cert.pem, sse_client_cert.pem, sse_client_key.pem. 44 | Only mutual authentication (server and client authentication) is allowed. 45 | - **RequestTimeout** Integer (seconds). Optional. Default value is 0 (infinite). Timeout for message duration. 46 | - **ReconnectTimeout** Integer (seconds). Optional. Default value is 20 (seconds). 47 | Time before the client tries to reconnect to the plugin after the connection to the plugin was lost. 48 | 49 | ### Configuration Examples 50 | 51 | - Example where one SSE plugin server is defined: `SSEPlugin=SSEPython,sse-python:50051` 52 | - Example where two SSE plugin servers are defined: `SSEPlugin=SSEPython,sse-python:50051;R,sse-r:50053` 53 | - Example where one SSE plugin server is defined without certificate path but with timeouts set: `SSEPlugin=SSEPython,sse-python:50051,,0,20` 54 | -------------------------------------------------------------------------------- /docs/services/qix-engine/doc-synchronization.md: -------------------------------------------------------------------------------- 1 | # Document Synchronization 2 | 3 | !!! warning "Experimental feature" 4 | This feature is in an experimental state. Use with caution 5 | since this feature may change in the future. 6 | 7 | ## Description 8 | 9 | For sharing documents between multiple instances the Qlik Associative Engine uses file polling to detect document changes. 10 | This feature support changes based on creation, editing, and deletion of generic objects, as well as reload of the data. 11 | If there are for example changes to the data blob or objects in a document, 12 | this would trigger a notification to other engine instances sharing the same document. 13 | The file polling interval for checking for document changes is every 10 seconds. 14 | 15 | When a document change has been detected the client in the other session will receive invalidations on the affected objects, 16 | and can act on it as preferred. 17 | There is an example in `enigma.js` for how to subscribe on these events [here](https://github.com/qlik-oss/enigma.js/blob/master/docs/api.md#event-changed). 18 | 19 | With this feature the Qlik Associative Engine instances running in a cluster, regardless of orchestration, 20 | will assume that the cluster uses a shared persistence layer. 21 | What type of shared persistence volume that should be used is configurable by the end-user, 22 | as long as the volume is based on a block file system. 23 | 24 | ## Example 25 | 26 | To show how two Qlik Associative Engine instances are sharing the same document using the file polling feature, 27 | we have implemented a basic example in `Kubernetes` using `Persisted Volumes`. 28 | You can find the example in the repository [core-document-synchronization](https://github.com/qlik-oss/core-document-synchronization). 29 | -------------------------------------------------------------------------------- /docs/services/qix-engine/script_reference/NULL_functions.md: -------------------------------------------------------------------------------- 1 | # NULL functions 2 | 3 | ## IsNull 4 | 5 | The IsNull function tests if the value of an expression is NULL and if 6 | so, returns -1 (True), otherwise 0 (False). 7 | 8 | `IsNull( expr )` 9 | 10 | !!! Tip 11 | A string with length zero is not considered as a NULL and will cause 12 | IsNull to return False. 13 | 14 | In this example, an inline table with four rows is loaded, where the 15 | first three lines contain either nothing, - or 'NULL' in the Value 16 | column. We convert these values to true NULL value representations with 17 | the middle preceding **LOAD** using the **Null** function. 18 | 19 | The first preceding **LOAD** adds a field checking if the value is NULL,using the 20 | **IsNull** function. 21 | 22 | ```qlik 23 | NullsDetectedAndConverted: 24 | LOAD *, 25 | If(IsNull(ValueNullConv), 'T', 'F') as IsItNull; 26 | 27 | LOAD *, 28 | If(len(trim(Value))= 0 or Value='NULL' or Value='-', Null(), Value ) as ValueNullConv; 29 | 30 | LOAD * Inline 31 | [ID, Value 32 | 0, 33 | 1,NULL 34 | 2,- 35 | 3,Value]; 36 | ``` 37 | 38 | This is the resulting table. In the ValueNullConv column, the NULL 39 | values are represented by -. 40 | 41 | | ID | Value | ValueNullConv | IsItNull | 42 | | -- | ----- | ------------- | -------- | 43 | | 0 | | \- | T | 44 | | 1 | NULL | \- | T | 45 | | 2 | \- | \- | T | 46 | | 3 | Value | Value | F | 47 | 48 | ## NULL 49 | 50 | The **Null** function returns a NULL value. 51 | 52 | `Null( )` 53 | 54 | In this example, an inline table with four rows is loaded, where the 55 | first three lines contain either nothing, - or 'NULL' in the Value 56 | column. We want to convert these values to true NULL value 57 | representations. 58 | 59 | The middle preceding **LOAD** performs the conversion using the 60 | **Null** function. 61 | 62 | The first preceding **LOAD** adds a field checking if the value is NULL, just for illustration 63 | purposes in this 64 | example. 65 | 66 | ```qlik 67 | NullsDetectedAndConverted: 68 | LOAD *, 69 | If(IsNull(ValueNullConv), 'T', 'F') as IsItNull; 70 | 71 | LOAD *, If(len(trim(Value))= 0 or Value='NULL' or Value='-', Null(), Value ) as ValueNullConv; 72 | 73 | LOAD * Inline 74 | [ID, Value 75 | 0, 76 | 1,NULL 77 | 2,- 78 | 3,Value]; 79 | ``` 80 | 81 | This is the resulting table. In the ValueNullConv column, the NULL 82 | values are represented by -. 83 | 84 | | ID | Value | ValueNullConv | IsItNull | 85 | | -- | ----- | ------------- | -------- | 86 | | 0 | | \- | T | 87 | | 1 | NULL | \- | T | 88 | | 2 | \- | \- | T | 89 | | 3 | Value | Value | F | 90 | -------------------------------------------------------------------------------- /docs/services/qix-engine/script_reference/color_functions.md: -------------------------------------------------------------------------------- 1 | # Color functions 2 | 3 | ## Pre-defined color functions 4 | 5 | The following functions can be used in expressions for pre-defined colors. Each function returns an RGB color representation. 6 | 7 | Optionally a parameter for alpha factor can be given, in which case an ARGB color representation is returned. An alpha 8 | factor of 0 corresponds to full transparency, and an alpha factor of 255 corresponds to full opacity. If a value for 9 | alpha is not entered, it is assumed to be 255. 10 | 11 | | Color function | RGB value | 12 | | ------------------- -| ------------ | 13 | | black ([alpha]) | (0,0,0) | 14 | | blue([alpha]) | (0,0,128) | 15 | | brown([alpha]) | (128,128,0) | 16 | | cyan([alpha]) | (0,128,128) | 17 | | darkgray([alpha]) | (128,128,128)| 18 | | green([alpha]) | (0,128,0) | 19 | | lightblue([alpha]) | (0,0,255) | 20 | | lightcyan([alpha]) | (0,255,255) | 21 | | lightgray([alpha]) | (192,192,192)| 22 | | lightgreen([alpha]) | (0,255,0) | 23 | | lightmagenta([alpha])| (255,0,255) | 24 | | lightred([alpha]) | (255,0,0) | 25 | | magenta([alpha]) | (128,0,128) | 26 | | red([alpha]) | (128,0,0) | 27 | | white([alpha]) | (255,255,255)| 28 | | yellow([alpha]) | (255,255,0) | 29 | 30 | | Examples | Results | 31 | | --------- | ----------------- | 32 | | Blue() | RGB(0,0,128) | 33 | | Blue(128) | ARGB(128,0,0,128) | 34 | 35 | These functions can be used in expressions associated with setting and evaluating the color properties. 36 | 37 | ## ARGB 38 | 39 | ARGB() is used in expressions to set or evaluate the color properties of a chart object, where the color is defined by 40 | a red component **r**, a green component **g**, and a blue component **b**, with an alpha factor (opacity) of alpha. 41 | 42 | `ARGB(alpha, r, g, b)` 43 | 44 | **Return data type:** dual 45 | 46 | | Argument | Description | 47 | | --------------- | ---------------------------- | 48 | | alpha | Transparency value in the range 0 - 255. 0 corresponds to full transparency and 255 corresponds to full opacity.| 49 | | r, g, b | Red, green, and blue component values. A color component of 0 corresponds to no contribution and one of 255 to full contribution.| 50 | 51 | !!! Note 52 | All arguments must be expressions that resolve to integers in the range 0 to 255. 53 | 54 | If interpreting the numeric component and formatting it in hexadecimal notation, the values of the color components are 55 | easier to see.For example, light green has the number 4 278 255 360, which in hexadecimal notation is FF00FF00. The 56 | first two positions ‘FF’ (255) denote the alpha factor.The next two positions ‘00’ denote the amount of red, the next 57 | two positions ‘FF’ denote the amount of green and the final two positions ‘00’ denote the amount of blue. 58 | 59 | ## RGB 60 | 61 | RGB() is used in expressions to set or evaluate the color properties of a chart object, where the color is defined by a 62 | red component **r**, a green component **g**, and a blue component **b** with values between 0 and 255. 63 | 64 | `RGB (r, g, b)` 65 | 66 | **Return data type:** dual 67 | 68 | | Argument | Description | 69 | | --------------- | ---------------------------- | 70 | | r, g, b | Red, green, and blue component values. A color component of 0 corresponds to no contribution and one of 255 to full contribution.| 71 | 72 | !!! Note 73 | All arguments must be expressions that resolve to integers in the range 0 to 255. 74 | 75 | If interpreting the numeric component and formatting it in hexadecimal notation, the values of the color components are 76 | easier to see. For example, light green has the number 4 278 255 360, which in hexadecimal notation is FF00FF00. The 77 | first two positions ‘FF’ (255) denote the alpha factor.In the functions RGB and HSL, this is always ‘FF’ (opaque). The 78 | next two positions ‘00’ denote the amount of red, the next two positions ‘FF’ denote the amount of green and the final 79 | two positions ‘00’ denote the amount of blue. 80 | 81 | ## HSL 82 | 83 | HSL() is used in expressions to set or evaluate the color properties of a chart object, where the color is defined by 84 | values of hue, saturation, and luminosity between 0 and 1. 85 | 86 | `HSL (hue, saturation, luminosity)` 87 | 88 | **Return data type:** dual 89 | 90 | | Argument | Description | 91 | | --------------------------- | ---------------------------- | 92 | | hue, saturation, luminosity | hue, saturation, and luminosity component values ranging between 0 and 1.| 93 | 94 | All arguments must be expressions that resolve to integers in the range 0 to 1. 95 | 96 | If interpreting the numeric component and formatting it in hexadecimal notation, the RGB values of the color components 97 | are easier to see. For example, light green has the number 4 278 255 360, which in hexadecimal notation is FF00FF00 and 98 | RGB (0,255,0). This is equivalent to HSL (80/240, 240/240, 120/240) - a HSL value of (0.33, 1, 0.5). 99 | -------------------------------------------------------------------------------- /docs/services/qix-engine/script_reference/error.md: -------------------------------------------------------------------------------- 1 | # Error variables 2 | 3 | ## ErrorMode 4 | 5 | The error variable determines what action is to be taken when an error is encountered during script execution. 6 | 7 | `ErrorMode` 8 | 9 | | Argument | Description | 10 | | ----------- | ----------- | 11 | | ErrorMode=1 | The default setting. The script execution will halt and the user will be prompted for action (non-batch mode).| 12 | | ErrorMode=0 | The engine will simply ignore the failure and continue script execution at the next script statement. | 13 | | ErrorMode=2 | The engine will trigger an "Execution of script failed..." error, without prompting the user for action beforehand. | 14 | 15 | ## ScriptError 16 | 17 | This error variable returns the error code of the last executed script statement. 18 | 19 | `ScriptError` 20 | 21 | This variable will be reset to 0 after each successfully executed script statement. If an error occurs it will be set to 22 | an internal error code. Error codes are dual values with a numeric and a text component. The following error codes 23 | exist: 24 | 25 | | Error code | Description | 26 | | ---------- | ------------------------------ | 27 | | 0 | No error | 28 | | 1 | General error | 29 | | 2 | Syntax error | 30 | | 3 | General ODBC error | 31 | | 4 | General OLE DB error | 32 | | 5 | General custom database error | 33 | | 6 | General XML error | 34 | | 7 | General HTML error | 35 | | 8 | File not found | 36 | | 9 | Database not found | 37 | | 10 | Table not found | 38 | | 11 | Field not found | 39 | | 12 | File has wrong format | 40 | | 13 | BIFF error | 41 | | 14 | BIFF error encrypted | 42 | | 15 | BIFF error unsupported version | 43 | | 16 | Semantic error | 44 | 45 | **Example**: 46 | 47 | ```qlik 48 | set ErrorMode=0; 49 | LOAD * from abc.qvf; 50 | if ScriptError=8 then 51 | exit script; 52 | //no file; 53 | end if 54 | ``` 55 | 56 | ## ScriptErrorCount 57 | 58 | This error variable returns the total number of statements that have caused errors during the current script execution. 59 | This variable is always reset to 0 at the start of script execution. 60 | 61 | ## ScriptErrorList 62 | 63 | This error variable will contain a concatenated list of all script errors that have occurred during the last script 64 | execution. Each error is separated by a line feed. 65 | -------------------------------------------------------------------------------- /docs/services/qix-engine/script_reference/exponential_and_logarithmic_functions.md: -------------------------------------------------------------------------------- 1 | # Exponential and Logarithmic functions 2 | 3 | ## exp 4 | 5 | The natural exponential function, e^x, using the natural logarithm e as base. 6 | 7 | `exp(x)` 8 | 9 | **Return data type:** positive number 10 | 11 | ## log 12 | 13 | The natural logarithm of x. 14 | The function is only defined if x > 0. 15 | 16 | `log(x)` 17 | 18 | **Return data type:** number 19 | 20 | ## log10 21 | 22 | The common logarithm (base 10) of x. 23 | The function is only defined if x > 0. 24 | 25 | `log10(x)` 26 | 27 | **Return data type:** number 28 | 29 | ## pow 30 | 31 | Returns x to the power of y. 32 | 33 | `pow(x,y)` 34 | 35 | **Return data type:** number 36 | 37 | ## sqr 38 | 39 | x squared (x to the power of 2). 40 | 41 | `sqr(x)` 42 | 43 | **Return data type:** number 44 | 45 | ## sqrt 46 | 47 | Square root of x. 48 | The function is only defined if x >= 0. 49 | number. 50 | 51 | `sqrt(x)` 52 | 53 | **Return data type:** positive number 54 | -------------------------------------------------------------------------------- /docs/services/qix-engine/script_reference/introduction.md: -------------------------------------------------------------------------------- 1 | # Load Script Reference 2 | 3 | The engine uses a data load script to connect to and retrieve data from various data sources. In the script, the 4 | fields and tables to load are specified and it is possible to manipulate the data structure and the associations by 5 | using script statements and expressions. These statements and expressions are described in this chapter. 6 | 7 | !!! warning 8 | This section is under review and might contain errors. If you find any inconsistencies, please 9 | contact us on [Slack](https://qlikbranch-slack-invite.herokuapp.com/) or create an issue on 10 | [Github](https://github.com/qlik-oss/core-website). 11 | -------------------------------------------------------------------------------- /docs/services/qix-engine/script_reference/logical_functions.md: -------------------------------------------------------------------------------- 1 | # Logical functions 2 | 3 | !!! Tip 4 | Both IsNum and IsText return 0 if the expression is NULL. 5 | 6 | Example: 7 | 8 | ```qlik 9 | Load *, IsNum(Value), IsText(Value) 10 | Inline [ 11 | Value 12 | 23 13 | Green 14 | Blue 15 | 12 16 | 33Red]; 17 | ``` 18 | 19 | The resulting table looks like this: 20 | 21 | | Value | IsNum(Value) | IsText(Value) | 22 | | ----- | ------------ | ------------- | 23 | | 23 | \-1 | 0 | 24 | | Green | 0 | \-1 | 25 | | Blue | 0 | \-1 | 26 | | 12 | \-1 | 0 | 27 | | 33Red | 0 | \-1 | 28 | 29 | ## IsNum 30 | 31 | Returns -1 (True) if the expression can be interpreted as a number, 32 | otherwise 0 (False). Returns 0 if the expression is NULL. 33 | 34 | `IsNum(expr)` 35 | 36 | ## IsText 37 | 38 | Returns -1 (True) if the expression has a text representation, otherwise 39 | 0 (False). Returns 0 if the expression is NULL. 40 | 41 | `IsText(expr)` 42 | -------------------------------------------------------------------------------- /docs/services/qix-engine/script_reference/mapping_functions.md: -------------------------------------------------------------------------------- 1 | # Mapping functions 2 | 3 | Functions for handling mapping tables. A mapping table can be used to replace field values or 4 | field names during script execution. 5 | 6 | ## ApplyMap 7 | 8 | The ApplyMap script function is used for mapping the output of an expression to a 9 | previously loaded mapping table. 10 | 11 | `ApplyMap('map_name', expression [, default_mapping])` 12 | 13 | **Return data type:** dual 14 | 15 | | Argument | Description | 16 | | - | - | 17 | | map_name | The name of a mapping table that has previously been created through the **mapping load** or the **mapping select** statement. Its name must be enclosed by single, straight quotation marks. Note that if you use this function in a macro expanded variable and refer to a mapping table that does not exist, the function call fails and a field is not created.| 18 | | expression | The expression, the result of which should be mapped. | 19 | | default_mapping | If stated, this value will be used as a default value if the mapping table does not contain a matching value for expression. If not stated, the value of expression will be returned as is. | 20 | 21 | In this example we load a list of salespersons with a country code 22 | representing their country of residence. We use a table mapping a 23 | country code to a country to replace the country code with the country 24 | name. Only three countries are defined in the mapping table, other 25 | country codes are mapped to 'Rest of the 26 | world'. 27 | 28 | ```qlik 29 | // Load mapping table of country codes: 30 | map1: mapping LOAD * 31 | Inline [ 32 | CCode, Country 33 | Sw, Sweden 34 | Dk, Denmark 35 | No, Norway 36 | ]; 37 | // Load list of salesmen, mapping country code to country 38 | // If the country code is not in the mapping table, put Rest of the world 39 | Salespersons: LOAD *, 40 | ApplyMap('map1', CCode,'Rest of the world') As Country 41 | Inline [ 42 | CCode, Salesperson 43 | Sw, John 44 | Sw, Mary 45 | ``` 46 | 47 | ```qlik 48 | Sw, Per 49 | Dk, Preben 50 | Dk, Olle 51 | No, Ole 52 | Sf, Risttu 53 | ]; 54 | // We don't need the CCode anymore 55 | Drop Field 'CCode'; 56 | ``` 57 | 58 | The resulting table looks like this: 59 | 60 | | Salesperson | Country | 61 | | ----------- | ----------------- | 62 | | John | Sweden | 63 | | Mary | Sweden | 64 | | Per | Sweden | 65 | | Preben | Denmark | 66 | | Olle | Denmark | 67 | | Ole | Norway | 68 | | Risttu | Rest of the world | 69 | 70 | ## MapSubstring 71 | 72 | The MapSubstring script function is used to map parts of any expression to a previously 73 | loaded mapping table. The mapping is case sensitive and non-iterative, 74 | and substrings are mapped from left to right. 75 | 76 | `MapSubstring('map_name', expression)` 77 | 78 | **Return data type:** string 79 | 80 | | Argument | Description | 81 | | - | - | 82 | | map_name | The name of a mapping table previously read by a **mapping load** or a **mapping select** statement. The name must be enclosed by single straight quotation marks. Note that if you use this function in a macro expanded variable and refer to a mapping table that does not exist, the function call fails and a field is not created. | 83 | | expression | The expression whose result is to be mapped by substrings. | 84 | 85 | In this example we load a list of product models. Each model has a set 86 | of attributes that are described by a composite code. Using the mapping 87 | table with MapSubstring, we can expand the attribute codes to a 88 | description. 89 | 90 | ```qlik 91 | map2: 92 | mapping LOAD * 93 | Inline [ 94 | AttCode, Attribute 95 | R, Red 96 | Y, Yellow 97 | B, Blue 98 | C, Cotton 99 | P, Polyester 100 | S, Small 101 | M, Medium 102 | L, Large 103 | ]; 104 | 105 | Productmodels: 106 | LOAD *, 107 | MapSubString('map2', AttCode) as Description 108 | Inline [ 109 | Model, AttCode 110 | Twixie, R C S 111 | Boomer, B P L 112 | Raven, Y P M 113 | Seedling, R C L 114 | SeedlingPlus, R C L with hood 115 | Younger, B C with patch 116 | MultiStripe, R Y B C S/M/L 117 | ]; 118 | // We don't need the AttCode anymore 119 | Drop Field 'AttCode'; 120 | ```` 121 | 122 | The resulting table looks like this: 123 | 124 | | Model | Description | 125 | | ------------ | ----------------------------------------- | 126 | | Twixie | Red Cotton Small | 127 | | Boomer | Blue Polyester Large | 128 | | Raven | Yellow Polyester Medium | 129 | | Seedling | Red Cotton Large | 130 | | SeedlingPlus | Red Cotton Large with hood | 131 | | Younger | Blue Cotton with patch | 132 | | MultiStripe | Red Yellow Blue Cotton Small/Medium/Large | 133 | -------------------------------------------------------------------------------- /docs/services/qix-engine/script_reference/mathematical_functions.md: -------------------------------------------------------------------------------- 1 | # Mathematical functions 2 | 3 | ## e 4 | 5 | The function returns the base of the natural logarithms, 6 | **e** (2.71828…). 7 | 8 | `e()` 9 | 10 | ## false 11 | 12 | The function returns a dual value with text value 'False' and numeric 13 | value 0, which can be used as logical false in expressions. 14 | 15 | `false()` 16 | 17 | ## pi 18 | 19 | The function returns the value of π (3.14159…). 20 | 21 | `pi()` 22 | 23 | ## rand 24 | 25 | The function returns a random number between 0 and 1. This can be used 26 | to create sample data. 27 | 28 | `rand()` 29 | 30 | This example script creates a table of 1000 records with randomly 31 | selected upper case characters, that is, characters in the range 65 to 32 | 91 33 | (65+26). 34 | 35 | ```qlik 36 | Load Chr(Floor(rand() * 26) + 65) as UCaseChar, RecNo() as ID 37 | Autogenerate 1000; 38 | ``` 39 | 40 | ## true 41 | 42 | The function returns a dual value with text value 'True' and numeric 43 | value -1, which can be used as logical true in 44 | expressions. 45 | 46 | `true()` 47 | -------------------------------------------------------------------------------- /docs/services/qix-engine/script_reference/operators.md: -------------------------------------------------------------------------------- 1 | # Operators 2 | 3 | ## Bit operators 4 | 5 | All bit operators convert (truncate) the operands to signed integers (32bit) and return the result in the same way. All 6 | operations are performed bit by bit. If an operand cannot be interpreted as a number, the operation will return NULL. 7 | 8 | | | | | 9 | | ------ | ----------- | --- | 10 | | bitnot | Bit inverse | Unary operator. The operation returns the logical inverse of the operand performed bit by bit.
bitnot 17 returns -18| 11 | | bitand | Bit and | The operation returns the logical AND of the operands performed bit by bit.
17 bitand 7 returns 1| 12 | | bitor | Bit or | The operation returns the logical OR of the operands performed bit by bit.
17 bitor 7 returns 23| 13 | | bitxor | Bit exclusive or | The operation returns the logical exclusive or of the operands performed bit by bit.
17 bitxor 7 returns 22| 14 | | >> | Bit right shift | The operation returns the first operand shifted to the right. The number of steps is defined in the second operand.
8 >> 2 returns 2| 15 | | << | Bit left shift | The operation returns the first operand shifted to the left. The number of steps is defined in the second operand.
8 << 2 returns 32 | 16 | 17 | ## Logical operators 18 | 19 | All logical operators interpret the operands logically and return True (-1) or False (0) as result. 20 | 21 | | | | 22 | | --- | --- | 23 | | not | Logical inverse. One of the few unary operators. The operation returns the logical inverse of the operand.| 24 | | and | Logical and. The operation returns the logical and of the operands. | 25 | | or | Logical or. The operation returns the logical or of the operands. | 26 | | Xor | Logical exclusive or. The operation returns the logical exclusive or of the operands. I.e. like logical or, but with the difference that the result is False if both operands are True. | 27 | 28 | ## Numeric operators 29 | 30 | All numeric operators use the numeric values of the operands and return 31 | a numeric value as 32 | result. 33 | 34 | | | | 35 | | - | --- | 36 | | + | Sign for positive number (unary operator) or arithmetic addition. The binary operation returns the sum of the two operands. | 37 | | - | Sign for negative number (unary operator) or arithmetic subtraction. The unary operation returns the operand multiplied by -1, and the binary the difference between the two operands.| 38 | | * | Arithmetic multiplication. The operation returns the product of the two operands. | 39 | | / | Arithmetic division. The operation returns the ratio between the two operands. | 40 | 41 | ## Relational operators 42 | 43 | All relational operators compare the values of the operands and return True (-1) or False (0) as the result. All 44 | relational operators are binary. 45 | 46 | 47 | 48 | 49 | 50 | 51 | 53 | 54 | 55 | 56 | 57 | 59 | 60 | 61 | 62 | 63 | 65 | 66 | 67 | 68 | 69 | 71 | 72 | 73 | 74 | 75 | 77 | 78 | 79 | 80 | 81 | 83 | 84 | 85 | 86 | 87 | 101 | 102 | 103 | 104 | 105 | 120 | 121 | 122 |
<Less thanA numeric comparison is made if both operands can be interpreted numerically. The operation returns the logical 52 | value of the evaluation of the comparison.
<=Less than or equalA numeric comparison is made if both operands can be interpreted numerically. The operation returns the logical 58 | value of the evaluation of the comparison.
>Greater thanA numeric comparison is made if both operands can be interpreted numerically. The operation returns the logical 64 | value of the evaluation of the comparison.
>=Greater than or equalA numeric comparison is made if both operands can be interpreted numerically. The operation returns the logical 70 | value of the evaluation of the comparison.
=EqualsA numeric comparison is made if both operands can be interpreted numerically. The operation returns the logical 76 | value of the evaluation of the comparison.
<>Not equivalent toA numeric comparison is made if both operands can be interpreted numerically. The operation returns the logical 82 | value of the evaluation of the comparison.
precedes Unlike the < operator no attempt is made to make a numeric interpretation of the argument values before the 88 | comparison. The operation returns true if the value to the left of the operator has a text representation which, in 89 | string comparison, comes before the text representation of the value on the right. 90 |
91 | '1 ' precedes ' 2' returns FALSE
92 | whilst
93 | ' 1' precedes ' 2' returns TRUE
94 | as the ASCII value of a space (' ') is of less value than the ASCII value of a number. 95 |

96 | Compare this to:
97 | '1 ' < ' 2' returns TRUE
98 | and
99 | ' 1' < ' 2' returns TRUE
100 |

follows Unlike the > operator no attempt is made to make a numeric interpretation of the argument values before the 106 | comparison. The operation returns true if the value to the left of the operator has a text representation which, in 107 | string comparison, comes after the text representation of the value on the right. 108 |
109 | ' 2' follows '1 ' returns FALSE
110 | whilst
111 | ' 2' follows ' 1' returns TRUE
112 | as the ASCII value of a space (' ') is of less value than the ASCII value of a number. 113 |

114 | Compare this to:
115 | ' 2' > ' 1' returns TRUE
116 | and
117 | ' 2' > '1 ' returns TRUE
118 |

119 |
123 | 124 | ## String operators 125 | 126 | There are two string operators. One uses the string values of the operands and return a string as result. The other one 127 | compares the operands and returns a boolean value to indicate match. 128 | 129 | | Operator | Description | Example | 130 | | -------- | -------------| ------- | 131 | | & | String concatenation. The operation returns a text string, that consists of the two operand strings, one after another.| 'abc' & 'xyz' returns 'abcxyz'| 132 | | like | String comparison with wildcard characters. The operation returns a boolean True (-1) if the string before the operator is matched by the string after the operator. The second string may contain the wildcard characters * (any number of arbitrary characters) or ? (one arbitrary character). | 'abc' lie 'a*' returns True (-1)
'abcd' like 'a?c*' returns True (-1)
'abc' like 'a??bc' returns False (0)| -------------------------------------------------------------------------------- /docs/services/qix-engine/script_reference/statistical_test_functions.md: -------------------------------------------------------------------------------- 1 | # Statistical Test functions 2 | 3 | ## Chi2Test_chi2 4 | 5 | Chi2Test_chi2() returns the aggregated chi2-test value for one or two series of values. The values are iterated over a 6 | number of records as defined by a group by clause. 7 | 8 | `Chi2Test_chi2(col, row, actual_value[, expected_value])` 9 | 10 | **Return data type:** numeric 11 | 12 | | Argument | Description | 13 | | -------------- | --------------------------------------------------------------------- | 14 | | col, row | The specified column and row in the matrix of values being tested. | 15 | | actual_value | The observed value of the data at the specified col and row. | 16 | | expected_value | The expected value for the distribution at the specified col and row. | 17 | 18 | Text values, NULL values and missing values in the expression value will result in the function returning NULL. 19 | 20 | ## Chi2Test_df 21 | 22 | Chi2Test_df() returns the aggregated chi2-test df value (degrees of freedom) for one or two series of values. The values 23 | are iterated over a number of records as defined by a group by clause. 24 | 25 | `Chi2Test_df(col, row, actual_value[, expected_value])` 26 | 27 | **Return data type:** numeric 28 | 29 | | Argument | Description | 30 | | -------------- | --------------------------------------------------------------------- | 31 | | col, row | The specified column and row in the matrix of values being tested. | 32 | | actual_value | The observed value of the data at the specified col and row. | 33 | | expected_value | The expected value for the distribution at the specified col and row. | 34 | 35 | Text values, NULL values and missing values in the expression value will result in the function returning NULL 36 | 37 | ## Chi2Test_p 38 | 39 | **Chi2Test_p()** returns the aggregated chi2-test p value (significance) for one or two series of values. The test can 40 | be done either on the values in **actual_value**, testing for variations within the specified col and row matrix, or by 41 | comparing values in actual_value with corresponding values in expected_value, if specified. The values are iterated over 42 | a number of records as defined by a group by clause. 43 | 44 | `Chi2Test_p( col, row, actual_value[, expected_value] )` 45 | 46 | **Return data type:** numeric 47 | 48 | | Argument | Description | 49 | | -------------- | --------------------------------------------------------------------- | 50 | | col, row | The specified column and row in the matrix of values being tested. | 51 | | actual_value | The observed value of the data at the specified col and row. | 52 | | expected_value | The expected value for the distribution at the specified col and row. | 53 | 54 | Text values, NULL values and missing values in the expression value will result in the function returning NULL. 55 | -------------------------------------------------------------------------------- /docs/services/qix-engine/script_reference/system_functions.md: -------------------------------------------------------------------------------- 1 | # System functions 2 | 3 | ## EngineVersion 4 | 5 | This function returns the full engine version as a string. 6 | 7 | `EngineVersion()` 8 | 9 | ## IsPartialReload 10 | 11 | This function returns - 1 (True) if the current reload is partial, otherwise 0 (False). 12 | 13 | `IsPartialReload()` 14 | -------------------------------------------------------------------------------- /docs/services/qix-engine/script_reference/table_functions.md: -------------------------------------------------------------------------------- 1 | # Table functions 2 | 3 | The table functions return information about the data table which is currently being read. 4 | If no table name is specified and the function is used within a LOAD statement, the current table 5 | is assumed. 6 | 7 | ## FieldName 8 | 9 | The **FieldName** script function returns the name of the field with the specified number 10 | within a previously loaded table. If the function is used within a 11 | **LOAD** statement, it must not reference the table currently being loaded. 12 | 13 | `FieldName(field_number, table_name)` 14 | 15 | | Argument | Description | 16 | | ------------- | ----------------------------------------------------- | 17 | | field_number | The field number of the field you want to reference. | 18 | | table_name | The table containing the field you want to reference. | 19 | 20 | **Example:** 21 | 22 | `LET a = FieldName(4,'tab1');` 23 | 24 | ## FieldNumber 25 | 26 | The **FieldNumber** script function returns the number of a specified field within a 27 | previously loaded table. If the function is used within a 28 | **LOAD** statement, it must not reference the table currently being loaded. 29 | 30 | `FieldNumber(field_name, table_name)` 31 | 32 | | Argument | Description | 33 | | ----------- | ------------------------------------------- | 34 | | field_name | The name of the field. | 35 | | table_name | The name of the table containing the field. | 36 | 37 | If the field field_name does not exist in table_name, or table_name 38 | does not exist, the function returns 0. 39 | **Example:** 40 | 41 | `LET a = FieldNumber('Customer','tab1');` 42 | 43 | ## NoOfFields 44 | 45 | The **NoOfFields** script function returns the number of fields in a previously loaded 46 | table. If the function is used within a **LOAD** statement, it must not reference the table currently being loaded. 47 | 48 | `NoOfFields(table_name)` 49 | 50 | | Argument | Description | 51 | | ----------- | ---------------------- | 52 | | table_name | The name of the table. | 53 | 54 | **Example:** 55 | 56 | `LET a = NoOfFields('tab1');` 57 | 58 | ## NoOfRows 59 | 60 | The **NoOfRows** function returns the number of rows (records) in a previously loaded 61 | table. If the function is used within a 62 | **LOAD** statement, it must not reference the table currently being loaded. 63 | 64 | `NoOfRows(table_name)` 65 | 66 | | Argument | Description | 67 | | ----------- | ---------------------- | 68 | | table_name | The name of the table. | 69 | 70 | **Example!:** 71 | 72 | `LET a = NoOfRows('tab1');` 73 | 74 | ## NoOfTables 75 | 76 | This script function returns the number of tables previously loaded. 77 | 78 | `NoOfTables()` 79 | 80 | ## TableName 81 | 82 | This script function returns the name of the table with the specified 83 | number. 84 | 85 | `TableName(table_number)` 86 | 87 | ## TableNumber 88 | 89 | This script function returns the number of the specified table. The 90 | first table has number 0. 91 | 92 | If table_name does not exist, NULL is returned. 93 | 94 | `TableNumber(table_name)` 95 | 96 | In this example, we want to create a table with information about the 97 | tables and fields that have been loaded. 98 | 99 | First we load some sample data. This creates the two tables that will be 100 | used to illustrate the table functions described in this 101 | section. 102 | 103 | ```qlik 104 | Characters: 105 | Load Chr(RecNo()+Ord('A')-1) as Alpha, RecNo() as Num 106 | autogenerate 26; 107 | 108 | ASCII: 109 | Load if(RecNo()>=65 and 110 | RecNo()<=90,RecNo()-64) as Num, 111 | Chr(RecNo()) as AsciiAlpha, 112 | RecNo() as AsciiNum 113 | autogenerate 255 114 | Where (RecNo()>=32 and RecNo()<=126) or RecNo()>=160; 115 | ``` 116 | 117 | Next, we iterate through the tables that have been loaded, using the 118 | **NoOfTables** function, and then through the fields of each table, using the 119 | **NoOfFields** function, and load information using the table 120 | functions. 121 | 122 | ```qlik 123 | // Iterate through the loaded tables 124 | For t = 0 to NoOfTables() - 1 125 | 126 | // Iterate through the fields of table 127 | For f = 1 to NoOfFields(TableName($(t))) 128 | Tables: 129 | Load 130 | TableName($(t)) as Table, 131 | TableNumber(TableName($(t))) as TableNo, 132 | NoOfRows(TableName($(t))) as TableRows, 133 | FieldName($(f),TableName($(t))) as Field, 134 | FieldNumber(FieldName($(f), TableName($(t))), TableName($(t))) as FieldNo 135 | Autogenerate 1; 136 | Next f 137 | Next t; 138 | ``` 139 | 140 | The resulting table Tables will look like this: 141 | 142 | | Table | TableNo | TableRows | Field | FieldNo | 143 | | ---------- | ------- | --------- | ---------- | ------- | 144 | | Characters | 0 | 26 | Alpha | 1 | 145 | | Characters | 0 | 26 | Num | 2 | 146 | | ASCII | 1 | 191 | Num | 1 | 147 | | ASCII | 1 | 191 | AsciiAlpha | 2 | 148 | | ASCII | 1 | 191 | AsciiNum | 3 | 149 | -------------------------------------------------------------------------------- /docs/services/qix-engine/script_reference/trigonometric_and_hyperbolic_functions.md: -------------------------------------------------------------------------------- 1 | # Trigonometric and Hyperbolic functions 2 | 3 | ## cos 4 | 5 | Cosine of **x**. 6 | The result is a number between -1 and 1. 7 | 8 | `cos( x )` 9 | 10 | ## acos 11 | 12 | Inverse cosine of **x**. 13 | The function is only defined if -1≤ **x** ≤1. 14 | The result is a number between 0 and 15 | p. 16 | 17 | `acos( x )` 18 | 19 | ## sin 20 | 21 | Sine of **x**. 22 | The result is a number between -1 and 1. 23 | 24 | `sin( x )` 25 | 26 | ## asin 27 | 28 | Inverse sine of **x**. 29 | The function is only defined if 30 | -1≤ **x** ≤1. 31 | The result is a number between - 32 | p/2 33 | and 34 | p/2. 35 | 36 | `asin( x )` 37 | 38 | ## tan 39 | 40 | Tangent of **x**. 41 | The result is a real number. 42 | 43 | `tan( x )` 44 | 45 | ## atan 46 | 47 | Inverse tangent of **x**. 48 | The result is a number between - 49 | p/2 50 | and 51 | p/2. 52 | 53 | `atan( x )` 54 | 55 | ## atan2 56 | 57 | Two-dimensional generalization of the inverse tangent function. Returns 58 | the angle between the origin and the point represented by the 59 | coordinates **x** and **y**. 60 | The result is a number between - 61 | p 62 | and + 63 | p. 64 | 65 | `atan2( y,x )` 66 | 67 | ## cosh 68 | 69 | Hyperbolic cosine of **x**. 70 | The result is a positive real number. 71 | 72 | `cosh( x )` 73 | 74 | ## sinh 75 | 76 | Hyperbolic sine of **x**. 77 | The result is a real number. 78 | 79 | `sinh( x )` 80 | 81 | ## tanh 82 | 83 | Hyperbolic tangent of **x** . 84 | The result is a real number. 85 | 86 | `tanh( x )` 87 | 88 | The following script code loads a sample table, and then loads a table 89 | containing the calculated trigonometric and hyperbolic operations on the 90 | values. 91 | 92 | ```qlik 93 | SampleData: 94 | LOAD * Inline [Value -1 0 1]; 95 | 96 | Results: 97 | Load *, 98 | cos(Value), 99 | acos(Value), 100 | sin(Value), 101 | asin(Value), 102 | tan(Value), 103 | atan(Value), 104 | atan2(Value, Value), 105 | cosh(Value), 106 | sinh(Value), 107 | tanh(Value) 108 | RESIDENT SampleData; 109 | 110 | Drop Table SampleData; 111 | ``` 112 | -------------------------------------------------------------------------------- /docs/services/qix-engine/script_reference/value_handling_variables.md: -------------------------------------------------------------------------------- 1 | # Value Handling Variables 2 | 3 | This section describes variables that are used for handling NULL and other values. 4 | 5 | ## NullDisplay 6 | 7 | The defined symbol will substitute all NULL values from ODBC, and connectors, on the lowest level of data. This is a 8 | user-defined variable. 9 | 10 | `NullDisplay` 11 | 12 | **Example:** 13 | 14 | `set NullDisplay='';` 15 | 16 | ## NullInterpret 17 | 18 | The defined symbol will be interpreted as NULL when it occurs in a text file, Excel file or an inline statement. This is 19 | a user-defined variable. 20 | 21 | `NullInterpret` 22 | 23 | **Examples:** 24 | 25 | ```qlik 26 | set NullInterpret=' '; 27 | set NullInterpret =; 28 | ``` 29 | 30 | will not return NULL values for blank values in Excel, but it will for a CSV text file. 31 | 32 | `set NullInterpret ='';` 33 | 34 | will return NULL values for blank values in Excel. 35 | 36 | ## NullValue 37 | 38 | If the **NullAsValue** statement is used, the defined symbol will substitute all NULL values in the **NullAsValue** 39 | specified fields with the specified string. 40 | 41 | `NullValue` 42 | 43 | **Example:** 44 | 45 | ```qlik 46 | NullAsValue Field1, Field2; 47 | set NullValue=''; 48 | ``` 49 | 50 | ## OtherSymbol 51 | 52 | Defines a symbol to be treated as 'all other values' before a **LOAD/SELECT** statement. This is a user-defined 53 | variable. 54 | 55 | `OtherSymbol` 56 | 57 | ```qlik 58 | set OtherSymbol='+'; 59 | LOAD inline 60 | [X, Y 61 | a, a 62 | b, b]; 63 | LOAD inline 64 | [X, Z 65 | a, a 66 | +, c]; 67 | ``` 68 | 69 | The field value Y=’b’ will now link to Z=’c’ through the other symbol. 70 | -------------------------------------------------------------------------------- /docs/services/qix-engine/script_reference/variables.md: -------------------------------------------------------------------------------- 1 | # Variables 2 | 3 | A variable in the engineis a container storing a static value or a calculation, for example a numeric or alphanumeric 4 | value. When you use the variable in the app, any change made to the variable is applied everywhere the variable is used. 5 | You set the value of a variable using Let or Set statements in the data load script. 6 | 7 | When used, the variable is substituted by its value. Variables can be used in the script for dollar sign expansion and 8 | in various control statements. This is useful if the same string is repeated many times in the script, for example, 9 | a path. 10 | 11 | Some special system variables will be set at the start of the script execution regardless of their previous values. 12 | 13 | ## Defining a variable 14 | 15 | When defining a variable, the syntax: 16 | 17 | `set variablename = string` 18 | 19 | or 20 | 21 | `let variable = expression` 22 | 23 | is used. The **Set** command assigns the text to the right of the equal sign to the variable, whereas the **Let** 24 | command evaluates the expression. 25 | 26 | Variables are case sensitive. 27 | 28 | !!! Note 29 | It is not recommended to name a variable identically to a field or a function. 30 | 31 | **Examples:** 32 | 33 | ```qlik 34 | set HidePrefix = $ ; // the variable will get the character '$' as value. 35 | let vToday = Num(Today()); // returns the date serial number of today. 36 | ``` 37 | 38 | ## Deleting a variable 39 | 40 | If you remove a variable from the script and reload the data, the variable stays in the app. If you want to fully 41 | remove the variable from the app, you must also delete the variable using the 42 | [destroyvariablebyname](../apis/qix/doc/#destroyvariablebyname) or 43 | [destroyvariablebyid](../apis/qix/doc/destroyvariablebyid) functions. 44 | 45 | ## Loading a variable value as a field value 46 | 47 | If you want to load a variable value as a field value in a **LOAD** statement and the result of the dollar expansion is 48 | text rather than numeric or an expression then you need to enclose the expanded variable in single quotes. 49 | 50 | **Example:** 51 | 52 | This example loads the system variable containing the list of script errors to a table. You can note that the expansion 53 | of ScriptErrorCount in the If clause does not require quotes, while the expansion of ScriptErrorList requires quotes. 54 | 55 | ```qlik 56 | IF $(ScriptErrorCount) >= 1 THEN 57 | LOAD '$(ScriptErrorList)' AS Error AutoGenerate 1; 58 | END IF 59 | ``` 60 | 61 | ## Variable calculation 62 | 63 | There are several ways to use variables with calculated values, and the result depends on how you define it and how you 64 | call it in an expression. 65 | 66 | In this example we load some inline data: 67 | 68 | ```qlik 69 | LOAD * INLINE [ 70 | Dim, Sales 71 | A, 150 72 | A, 200 73 | B, 240 74 | B, 230 75 | C, 410 76 | C, 330 77 | ]; 78 | ``` 79 | 80 | Let's define two variables: 81 | 82 | ```qlik 83 | Let vSales = 'Sum(Sales)' ; 84 | Let vSales2 = '=Sum(Sales)' ; 85 | ``` 86 | 87 | In the second variable, we add an equal sign before the expression. This will cause the variable to be calculated before 88 | it is expanded and the expression is evaluated. 89 | 90 | If you use the vSales variable as it is, for example in a measure, the result will be the string Sum(Sales), that is, no 91 | calculation is performed. 92 | 93 | If you add a dollar-sign expansion and call $(vSales) in the expression, the variable is expanded, and the sum of Sales 94 | is displayed. 95 | 96 | Finally, if you call $(vSales2), the variable will be calculated before it is expanded. This means that the result 97 | displayed is the total sum of Sales. The difference between using =$(vSales) and =$(vSales2) as measure expressions is 98 | seen in this table showing the results: 99 | 100 | | Dim | $(vSales) | $(vSales2) | 101 | | --- | --------- | ---------- | 102 | | A | 350 | 1560 | 103 | | B | 470 | 1560 | 104 | | C | 740 | 1560 | 105 | 106 | As you can see, $(vSales) results in the partial sum for a dimension value, while $(vSales2) results in the total sum. -------------------------------------------------------------------------------- /docs/services/services.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | 3 | Qlik Core consists of a core set of supported services: 4 | 5 | | Service | Description | 6 | | ---------- | ------- | 7 | | [Qlik Associative Engine](./qix-engine/introduction.md) | The powerful associative indexing engine from Qlik and the foundation of Qlik Core. | 8 | | [License](./licenses.md) | Service required to run Qlik Associative Engine with a paid license. | 9 | | [Mira](./mira.md) | Qlik Associative Engine discovery service. | 10 | 11 | Qlik Core comes with a developer edition that may be used to evaluate, 12 | develop, or test solutions. Note that it cannot be used for commercial purposes. 13 | For more information about the license of Qlik Core visit 14 | [Licensing](/licensing/). 15 | 16 | For more information on how to retreive the services visit [Downloads](/downloads/). -------------------------------------------------------------------------------- /docs/stylesheets/downloads.css: -------------------------------------------------------------------------------- 1 | .dots { 2 | --timer: 1s; 3 | --delay: calc(var(--timer) * .4); 4 | --delay-coefficient: calc(var(--delay) * .25); 5 | 6 | height: 50px; 7 | display: flex; 8 | align-items: center; 9 | justify-content: space-evenly; 10 | flex-direction: row; 11 | } 12 | 13 | .dots__dot { 14 | background-color: #fff; 15 | width: calc(80% / 7); 16 | animation: bounce var(--timer) alternate infinite; 17 | transform: scale(.3); 18 | flex-shrink: 0; 19 | animation-delay: var(--delay); 20 | } 21 | 22 | .dots__dot::before { 23 | content: ''; 24 | display: block; 25 | padding-bottom: 100%; 26 | } 27 | 28 | .dots__dot:nth-child(1) { 29 | animation-delay: calc(var(--delay) + (1 * var(--delay-coefficient))); 30 | } 31 | .dots__dot:nth-child(2) { 32 | animation-delay: calc(var(--delay) + (2 * var(--delay-coefficient))); 33 | } 34 | .dots__dot:nth-child(3) { 35 | animation-delay: calc(var(--delay) + (3 * var(--delay-coefficient))); 36 | } 37 | .dots__dot:nth-child(4) { 38 | animation-delay: calc(var(--delay) + (4 * var(--delay-coefficient))); 39 | } 40 | .dots__dot:nth-child(5) { 41 | animation-delay: calc(var(--delay) + (5 * var(--delay-coefficient))); 42 | } 43 | .dots__dot:nth-child(6) { 44 | animation-delay: calc(var(--delay) + (6 * var(--delay-coefficient))); 45 | } 46 | .dots__dot:nth-child(7) { 47 | animation-delay: calc(var(--delay) + (7 * var(--delay-coefficient))); 48 | } 49 | 50 | @keyframes bounce { 51 | 0% { 52 | transform: scale(1); 53 | background-color: var(--custom-grey, grey); 54 | } 55 | } 56 | 57 | .title__version { 58 | font-weight: bold; 59 | display: block; 60 | } 61 | 62 | .title__release-date { 63 | font-style: italic; 64 | display: block; 65 | } 66 | 67 | .changes__circle { 68 | --size: 24px; 69 | --backgroundColor: #000; 70 | 71 | position: relative; 72 | cursor: pointer; 73 | background-color: var(--backgroundColor); 74 | display: inline-block; 75 | width: var(--size); 76 | height: var(--size); 77 | text-align: center; 78 | line-height: var(--size); 79 | border-radius: 50%; 80 | color: #fff; 81 | font-size: .8em; 82 | font-weight: bold; 83 | -webkit-font-smoothing: antialiased; 84 | margin: 0.2rem; 85 | } 86 | 87 | .changes__circle:hover .tooltip { 88 | opacity: 1; 89 | visibility: visible; 90 | } 91 | 92 | .changes__circle--added { 93 | --backgroundColor: var(--custom-green, green); 94 | } 95 | 96 | .changes__circle--updated { 97 | --backgroundColor: orange; 98 | } 99 | 100 | .changes__circle--removed { 101 | --backgroundColor: var(--custom-grey, grey); 102 | } 103 | 104 | .changes__circle--deprecated { 105 | --backgroundColor: red; 106 | } 107 | -------------------------------------------------------------------------------- /docs/stylesheets/pricing.css: -------------------------------------------------------------------------------- 1 | .md-sidebar--secondary { 2 | display: none; 3 | } 4 | .md-content { 5 | margin-right: unset; 6 | } 7 | .md-content__icon { 8 | display: none; 9 | } 10 | .cards-pricing { 11 | border: 2px; 12 | border-style: solid; 13 | margin-top: 10px; 14 | margin-right: 10px; 15 | float: left; 16 | width: calc(33% - 20px); 17 | min-width: 300px; 18 | box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2); 19 | } 20 | .cards-pricing-free { 21 | border-color: var(--custom-pricing-color-3); 22 | } 23 | .cards-pricing-trial { 24 | border-color: var(--custom-pricing-color-2); 25 | } 26 | .cards-pricing-enterprise { 27 | border-color: var(--custom-pricing-color-1); 28 | } 29 | .cards-pricing h2 { 30 | padding-top: 30px; 31 | margin-top: 0px; 32 | text-align: center; 33 | } 34 | .cards-pricing p { 35 | margin-bottom: 0px; 36 | padding-bottom: 20px; 37 | } 38 | .md-column > ul li { 39 | list-style-type: none; 40 | } 41 | .md-column > ul li::before { 42 | content: "\2022"; 43 | color: var(--custom-pricing-color-1); 44 | font-weight: bold; 45 | display: inline-block; 46 | width: 1em; 47 | margin-left: -1em; 48 | } 49 | .cards-middle { 50 | height: 19rem; 51 | padding: 10px; 52 | background-color: var(--custom-pricing-color-4); 53 | } 54 | .cards-bottom { 55 | color: #fff; 56 | font-weight: bold; 57 | text-align: center; 58 | transition: 0.3s; 59 | } 60 | .cards-bottom p { 61 | margin-top: 0px; 62 | padding-top: 20px; 63 | } 64 | .cards-header { 65 | text-align: center; 66 | color: #fff; 67 | } 68 | .card-free { 69 | background-color: var(--custom-pricing-color-3); 70 | } 71 | .card-trial { 72 | background-color: var(--custom-pricing-color-2); 73 | } 74 | .card-enterprise { 75 | background-color: var(--custom-pricing-color-1); 76 | } 77 | .cards-middle p { 78 | padding-left: 1.4rem; 79 | } 80 | .pricing a, .pricing a:hover { 81 | text-decoration: none; 82 | color: #fff; 83 | } 84 | .pricing:hover { 85 | text-decoration: none; 86 | border-bottom: 2px solid #fff; 87 | cursor: pointer; 88 | } -------------------------------------------------------------------------------- /docs/stylesheets/star-rating.css: -------------------------------------------------------------------------------- 1 | @import url(//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css); 2 | 3 | 4 | #leave-feedback { 5 | margin-top: 8px; 6 | } 7 | 8 | #starbox { 9 | margin-top: -3px; 10 | } 11 | 12 | #stars { 13 | display: block; 14 | width: 100%; 15 | } 16 | 17 | .submitform { 18 | border-radius: 4px; 19 | display: none; 20 | -webkit-animation: fadeOut 0.5s; 21 | animation: fadeOut 0.5s; 22 | position: absolute; 23 | align-content: right; 24 | width: 328px; 25 | right: 0; 26 | text-align: center; 27 | background: white; 28 | border: 1px solid rgba(131, 131, 131, 0.555); 29 | z-index: 1; 30 | opacity: 0; 31 | } 32 | 33 | .show { 34 | opacity: 1; 35 | -webkit-animation: fadeIn 0.5s; 36 | animation: fadeIn 0.5s; 37 | } 38 | 39 | /* Add animation (fade in the popup) */ 40 | @-webkit-keyframes fadeIn { 41 | from { 42 | opacity: 0; 43 | } 44 | 45 | to { 46 | opacity: 1; 47 | } 48 | } 49 | 50 | @keyframes fadeIn { 51 | from { 52 | opacity: 0; 53 | } 54 | 55 | to { 56 | opacity: 1; 57 | } 58 | } 59 | 60 | @-webkit-keyframes fadeOut { 61 | from { 62 | opacity: 1; 63 | } 64 | 65 | to { 66 | opacity: 0; 67 | } 68 | } 69 | 70 | @keyframes fadeOut { 71 | from { 72 | opacity: 1; 73 | } 74 | 75 | to { 76 | opacity: 0; 77 | } 78 | } 79 | 80 | x-star-rating { 81 | font-family: FontAwesome; 82 | font-size: 28px; 83 | display: inline-flex; 84 | cursor: pointer; 85 | content: "★"; 86 | } 87 | 88 | x-star-rating>.star::after { 89 | content: "★"; 90 | color: rgb(150, 150, 150); 91 | } 92 | 93 | x-star-rating>.star.full::after { 94 | content: "★"; 95 | color: #fd0; 96 | } 97 | 98 | textarea { 99 | margin-top: 5px; 100 | width: 97%; 101 | padding: 12px; 102 | border: 1px solid #ccc; 103 | border-radius: 4px; 104 | resize: vertical; 105 | margin-bottom: 2px; 106 | box-sizing: border-box; 107 | background-color: #f8f8f8; 108 | resize: none; 109 | height: 100px; 110 | } 111 | 112 | button[type=submit] { 113 | background-color: #009845; 114 | color: white; 115 | padding: 3px 12px; 116 | border: none; 117 | border-radius: 4px; 118 | cursor: pointer; 119 | float: right; 120 | margin-bottom: 4px; 121 | margin-right: 7px; 122 | font-size: 15px; 123 | } 124 | 125 | button[type=submit]:hover { 126 | background-color: #006937; 127 | } 128 | 129 | @media screen and (max-width: 600px) { 130 | 131 | .col-25, 132 | .col-75, 133 | input[type=submit] { 134 | width: 100%; 135 | margin-top: 0; 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /docs/tooling/catwalk.md: -------------------------------------------------------------------------------- 1 | # catwalk 2 | 3 | ![catwalk](https://github.com/qlik-oss/catwalk/raw/master/src/assets/catwalk.svg?sanitize=true) 4 | 5 | After you have created the initial load script, chances are that you experience data modeling problems. In such cases, 6 | you may need help finding out how the data is associated and how interactions with the data impacts the model. 7 | 8 | Catwalk provides you with a view of all your tables, fields, their associations as well as information about the data 9 | within. 10 | 11 | ![screenshot](https://github.com/qlik-oss/catwalk/raw/master/images/screenshot.png) 12 | 13 | ## Usage 14 | 15 | You can use catwalk in the following ways: 16 | 17 | * provide a link to an engine websocket at [catwalk](https://catwalk.core.qlik.com/) 18 | * open an application from corectl by `corectl catwalk --app my-app.qvf` 19 | * clone the [catwalk repo](https://github.com/qlik-oss/catwalk) and run the tool locally 20 | 21 | If no websocket configuration is provided, catwalk defaults to localhost:9076. 22 | 23 | !!! Note 24 | The Qlik application's content is transferred directly from the engine to the web browser through a websocket. I.e. 25 | no data is sent to Qlik or any 3:rd party. Beside this Qlik collects anonymous usage data through Google Analytics 26 | such as browser version and catwalk exceptions. 27 | 28 | ## Best practices and techniques 29 | 30 | Catwalk provides an alternative view of the Qlik application's data model compared to existing products. However best 31 | practices and data modelling techniques are the same and can be found on the 32 | [Qlik help page](https://help.qlik.com/en-US/sense/Subsystems/Hub/Content/Sense_Hub/DataModeling/best-practices-data-modeling.htm). 33 | -------------------------------------------------------------------------------- /docs/tooling/corectl.md: -------------------------------------------------------------------------------- 1 | # Corectl 2 | 3 | Qlik Core Control (corectl) is a tool that delivers a command line interface (CLI) for the Qlik Associative Engine. With 4 | corectl you can interact with your apps, objects, and data. 5 | 6 | ![screenshot](../images/corectl.png) 7 | 8 | The main use cases are: 9 | 10 | * View: list applications, view and query data, and evaluate expressions 11 | * Develop: create, update and model a Qlik application 12 | * Script: support scripting and automation of common tasks 13 | 14 | Download instructions for corectl can be found [here](https://github.com/qlik-oss/corectl#download). 15 | -------------------------------------------------------------------------------- /docs/tooling/overview.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | 3 | Qlik Core comes with a set of tools for designing, developing and viewing artifacts within the Qlik Associative Engine. 4 | The following tools are not required when building a Qlik Core solution but can be used to support you when developing: 5 | 6 | Tool | Description 7 | ------------------------- | ----------- 8 | [corectl](./corectl.md) | A command line interface where you can interact with a Qlik Core app, for example reload data, fetch metadata and evaluate expressions. 9 | [catwalk](./catwalk.md) | A data modeling tool where you get a graphical representation of the data model within an application. -------------------------------------------------------------------------------- /docs/tutorials/authorization.md: -------------------------------------------------------------------------------- 1 | # Authorization 2 | 3 | In this tutorial, learn how to configure JSON Web Tokens (JWT) and how to use Qlik Associative Engine 4 | to manage and authenticate users. 5 | 6 | ## JSON Web Token 7 | 8 | JWT is an open standard for creating access tokens. To learn more about JWT, 9 | see the [JWT documentation](https://jwt.io/) and the [JWT Standard](https://tools.ietf.org/html/rfc7519). 10 | 11 | The Qlik Associative Engine uses JWTs for the following tasks: 12 | 13 | - Ensuring that only authenticated users are allowed to connect. 14 | - Connecting users to the same sessions. 15 | - Applying data security (for example, section access). 16 | - Enforcing document level access control. 17 | 18 | ### JWT format 19 | 20 | A typical JWT consists of three parts. 21 | 22 | `{header}.{payload}.{signature}` 23 | 24 | !!! Note 25 | Each part of the JWT is base64url-encoded and separated by a dot. 26 | To learn more about JWT encoding, see [Base 64 Encoding with URL and Filename Safe Alphabet](https://tools.ietf.org/html/rfc4648#section-5). 27 | 28 | #### Header 29 | 30 | The header describes the type of token, 31 | and the hashing algorithm that is used to sign the token. For example: 32 | 33 | ```json 34 | { 35 | "typ": "JWT", 36 | "alg": "none" 37 | } 38 | ``` 39 | 40 | #### Payload 41 | 42 | The payload contains the claims of the JWT. 43 | The relevant claims that are evaluated by the Qlik Associative Engine are the subject and the expiration date. 44 | 45 | | Field | Mandatory | Description | 46 | | -------- | --------- | ----------- | 47 | | `sub` | Yes | The subject is a unique identifier for a user. | 48 | | `exp` | No | The numerical expiration date. If omitted it never expires. | 49 | | `groups` | No | Array of user groups. If present the GROUP column can be used in section access | 50 | | `kid` | No | Reserved field for JWKS in the future. | 51 | 52 | For example: 53 | 54 | ```json 55 | { 56 | "sub": "jdoe", 57 | "exp": "1541173994" 58 | } 59 | ``` 60 | 61 | #### Signature 62 | 63 | The signature is used to verify the authenticity of the token. 64 | The Qlik Associative Engine supports the following JWT signing algorithms: 65 | 66 | | Encryption type | Algorithms | 67 | | ---- | --------- | 68 | | HMAC | HS256, HS384, HS512 | 69 | | Elliptic curve | ES256, ES384, ES512 | 70 | | RSA | RS256, RS384, RS512 | 71 | 72 | To learn more about JWT signatures, see [Signature](https://jwt.io/introduction/#signature). 73 | 74 | ### Qlik Associative Engine configuration 75 | 76 | To validate JWTs, you must configure the Qlik Associative Engine by specifying 77 | the JWT enforcement type and the JWT secret in the `docker-compose.yml` file. 78 | 79 | The enforcement type is defined as: 80 | 81 | `-S ValidateJsonWebTokens=` 82 | 83 | where `enforcement type` is one of the following values: 84 | 85 | | Value | Description | 86 | |---|---| 87 | | 0 | Not enforced (default) | 88 | | 1 | Enforce JWT validation (JWT can be either signed or unsigned) | 89 | | 2 | Enforce JWT validation (JWT must be signed) | 90 | 91 | HMAC secrets are injected through the command line parameter: 92 | 93 | `-S JsonWebTokenSecret=` 94 | 95 | Elliptic curve and RSA secrets are retrieved from a public key, 96 | stored on a `pem` file. 97 | 98 | `-S JsonWebTokenPath=` 99 | 100 | Example: 101 | 102 | ```yaml 103 | version: "3.1" 104 | 105 | services: 106 | engine: 107 | image: qlikcore/engine 108 | command: -S ValidateJsonWebTokens=2 -S JsonWebTokenSecret=passw0rd 109 | ... 110 | ``` 111 | 112 | ### Validation 113 | 114 | The JWT is passed to the Qlik Associative Engine in the `Authorization` header using 115 | the `Bearer` schema, and is validated once the websocket connection is established. 116 | 117 | `Authorization: Bearer ` 118 | 119 | In order for validation to be successful, two 120 | conditions must be met: 121 | 122 | 1. The signature must be valid. 123 | 1. If the `exp` field exists, then the expiry date must not have passed. 124 | 125 | If validation fails, the request is rejected and a `401 Unauthorized` HTTP response code is returned. 126 | 127 | ## Section access 128 | 129 | You can use section access to segment application data so specific 130 | sections are available only to certain users or groups. 131 | To learn more about section access, see [Managing security with section access](https://help.qlik.com/en-US/sense/Subsystems/Hub/Content/Sense_Hub/Scripting/Security/manage-security-with-section-access.htm). 132 | 133 | !!! Note 134 | Qlik Associative Engine has to be started with `-S ValidateJsonWebTokens=< 1 or 2 >` otherwise the error 135 | `Section access detected when opening an app in QlikView Personal.` will be shown. 136 | 137 | ### Managing access control 138 | 139 | Access control is managed through one or several security tables loaded 140 | in the same way that the Qlik Associative Engine normally loads data. 141 | 142 | In the example below, the load script grants regional 143 | users access to their respective country data 144 | while the admin user has access to all data. 145 | 146 | ```none 147 | section access; 148 | LOAD * inline [ 149 | ACCESS, USERID, COUNTRY, OMIT 150 | ADMIN, admin,, 151 | USER, us-user,US, 152 | USER, uk-user,UK, 153 | USER, de-user,DE, 154 | ]; 155 | 156 | section Application; 157 | Sales: 158 | LOAD * INLINE [ 159 | COUNTRY, PRODUCT, SALES_AMOUNT 160 | US, Electronics, 101 161 | US, Furniture, 102 162 | US, Other, 103 163 | UK, Electronics, 201 164 | UK, Furniture, 202 165 | UK, Other, 203 166 | DE, Electronics, 301 167 | DE, Furniture, 302 168 | DE, Other, 303 169 | ]; 170 | ``` 171 | 172 | The Qlik Associative Engine maps the `sub` field from the JWT to the user names 173 | that are specified in the section access table. 174 | In the example above, the section access table is linked to the `Sales` table 175 | through the `COUNTRY` field value, 176 | which allows the visibility of row data to be controlled by section access. 177 | 178 | If the JWT contains the `groups` field it will be mapped to the 'GROUP' column in the section access table. 179 | -------------------------------------------------------------------------------- /docs/tutorials/hello-data.md: -------------------------------------------------------------------------------- 1 | # Hello Data 2 | 3 | Load data into and retrieve data from the Qlik Associative Engine running in a Docker container. 4 | 5 | ## Prerequisites 6 | 7 | Clone the 8 | [Get Started](https://github.com/qlik-oss/core-get-started) 9 | Git repository to your local machine. The *Hello* tutorials are located here, 10 | and all commands should be executed from this Git repository. 11 | 12 | You must have [Node.js](https://nodejs.org/en/) and npm 13 | installed on your local machine. 14 | 15 | !!! Note 16 | Make sure the Qlik Associative Engine is running. Run `docker-compose up -d` 17 | command in a command shell to start the engine in a Docker container. 18 | If you are unfamiliar with starting the Qlik Associative Engine in a Docker container, we 19 | recommend that you begin with the [Hello Engine](./hello-engine.md) tutorial. 20 | 21 | ## Loading and retrieving data 22 | 23 | To load and retrieve data, you will run a small Node.js application 24 | that loads data into, and then retrieves that data from the Qlik Associative Engine. 25 | 26 | The application consists of the `hello-data.js` file and the `package.json` 27 | file, which is also shared among the Hello Data and 28 | Hello Visualization tutorials. 29 | 30 | 1. Install dependencies. 31 | 32 | !!! Note 33 | If you already installed the dependencies in the previous tutorial, go to step 2. 34 | 35 | Run the following command from a command shell: 36 | 37 | ```bash 38 | npm install 39 | ``` 40 | 41 | This command installs all of the dependent packages 42 | in the `package.json` file. 43 | 44 | 1. Run the application. 45 | 46 | Run the following command in a command shell: 47 | 48 | ```bash 49 | npm run hello-data 50 | ``` 51 | 52 | This command runs the application, which creates a representation 53 | of the data and loads it into Qlik Associative Engine as a part of opening a session. 54 | 55 | ### What is happening 56 | 57 | When you start Qlik Associative Engine, the `docker-compose.yml` file makes the `movies.csv` file 58 | available to Qlik Associative Engine, and the data location is specified in the volumes section. 59 | 60 | ```yml 61 | volumes: 62 | - ./data:/data 63 | ``` 64 | 65 | !!! Tip 66 | To learn more about volumes, see 67 | [Use volumes](https://docs.docker.com/engine/admin/volumes/volumes/). 68 | 69 | To load data, the `hello-data` application executes a _load script_ in Qlik Associative Engine that loads data 70 | from a `movies.csv` file available to the engine on the local file system. enigma.js is used to open a session and 71 | create a session object that holds the first 10 movie titles. The application then retrieves the movie titles from the 72 | dataset, prints the results, and closes the session. 73 | 74 | If the application runs successfully, you will see the list of 10 movies from the dataset. 75 | 76 | ```bash 77 | $ npm run hello-data 78 | 79 | Creating table data representation. 80 | Creating and opening session using mixin. 81 | Creating session object with movie titles. 82 | Listing the 10 first movies: 83 | 2012 84 | Armageddon 85 | Avatar 86 | Battleship 87 | Cars 2 88 | Cleopatra 89 | Evan Almighty 90 | Green Lantern 91 | Harry Potter and the Half-Blood Prince 92 | Indiana Jones and the Kingdom of the Crystal Skull 93 | Session closed. 94 | ``` 95 | 96 | !!! Tip 97 | Open the [`hello-data.js`](https://github.com/qlik-oss/core-get-started/blob/master/src/hello-data/hello-data.js) 98 | file to inspect how the load script and enigma.js are used to load and retrieve data from the 99 | Qlik Associative Engine. 100 | 101 | !!! Note 102 | You might see some unfamiliar details of the Qlik Associative Engine in the source code. 103 | For example, the `properties` object that is used to create the session object contains a field called 104 | `qHyperCubeDef`. This relates to the central concept of _hypercubes_ in the Qlik Associative Engine. 105 | To learn more about hypercubes, see 106 | [Hypercubes](https://help.qlik.com/en-US/sense-developer/Subsystems/Platform/Content/Sense_PlatformOverview/Concepts/Hypercubes.htm). 107 | 108 | ## Using halyard.js 109 | 110 | In the example above, the _hello-data_ application executes a load script that specifies how data from a CSV file is 111 | loaded into Qlik Associative Engine. 112 | 113 | Rather than directly using a load script, you can use the [halyard.js](https://github.com/qlik-oss/halyard.js) library, 114 | which provides a convenient way to do similar data loading tasks without the need to write load scripts because 115 | halyard.js generates them for you. 116 | 117 | Here is an equivalent implementation of the _hello data_ example, but now using halyard.js instead. 118 | 119 | Run the following command: 120 | 121 | ```bash 122 | npm run hello-data-halyard 123 | ``` 124 | 125 | You should see output similar to the previous example, with the 10 first movie titles printed. 126 | 127 | ### What is happening 128 | 129 | In this example, the load script is now replaced by a halyard.js table representation of the data, which is used to load 130 | data into the Qlik Associative Engine as part of opening a session. Then, it uses enigma.js _mixin_ support to create a 131 | session object that holds the first 10 movie titles from the `movies.csv` dataset. The application then retrieves the 132 | movie titles from the dataset, prints the results, and closes the session, just as in the previous example. 133 | 134 | !!! Tip 135 | Open the 136 | [`hello-data-halyard.js`](https://github.com/qlik-oss/core-get-started/blob/master/src/hello-data/hello-data-halyard.js) 137 | file to inspect how halyard.js and enigma.js are used to load and retrieve data from the Qlik Associative Engine. 138 | 139 | ## Next steps 140 | 141 | Continue with the [Hello Visualization](./hello-visualization.md) tutorial 142 | to learn how to display the data that you loaded in this tutorial as a scatter plot. 143 | 144 | !!! Tip 145 | To learn more about the libraries that are used in this tutorial, 146 | we recommend that you take a look at [enigma.js](https://github.com/qlik-oss/enigma.js) and 147 | [halyard.js](https://github.com/qlik-oss/halyard.js) to learn about their many features. 148 | -------------------------------------------------------------------------------- /docs/tutorials/hello-engine.md: -------------------------------------------------------------------------------- 1 | # Hello Engine 2 | 3 | Get started by running the Qlik Associative Engine in a Docker container on your local machine and 4 | communicating with it using [enigma.js](https://github.com/qlik-oss/enigma.js). 5 | 6 | ## Prerequisites 7 | 8 | Clone the 9 | [Get Started](https://github.com/qlik-oss/core-get-started) 10 | Git repository to your local machine. The *Hello* tutorials are located here, 11 | and all commands should be executed from this Git repository. 12 | 13 | You must have [Node.js](https://nodejs.org/en/) and npm installed on your local machine. 14 | 15 | ## Starting the Qlik Associative Engine service 16 | 17 | 1. Start the Qlik Associative Engine in a Docker container. 18 | Run the following command in a command shell: 19 | 20 | !!! Note 21 | Before you deploy, you need to set the `ACCEPT_EULA` environment variable, 22 | otherwise the Qlik Associative Engine won't start. 23 | 24 | ```bash 25 | ACCEPT_EULA=yes docker-compose up -d 26 | ``` 27 | 28 | When you run this command, Docker builds the container and leaves it running in the background. 29 | If successful, you will see a message that creating the container is done. 30 | 31 | 1. Verify that the dockerized Qlik Associative Engine is running. 32 | 33 | Run the following command in a command shell: 34 | 35 | ```bash 36 | docker ps -a 37 | ``` 38 | 39 | The `docker ps` command lists the containers that are running. 40 | The `-a` option lists all containers, even those that are not running. 41 | 42 | !!! Note 43 | You can access the logs for a functional container by running the following command: 44 | 45 | ```bash 46 | docker logs 47 | ``` 48 | 49 | ### What is happening 50 | 51 | When you execute the `docker-compose up` command, 52 | Docker builds and starts a Docker container with the services configured in the `docker-compose.yml` file. 53 | The `-d` option keeps the container running in the background. 54 | In this example, Docker builds the container from the `docker-compose.yml` file. 55 | This file is located in the root folder of the Getting Started with Web Platform Git repository. 56 | Open the [docker-compose.yml](https://github.com/qlik-oss/core-get-started/blob/master/docker-compose.yml) 57 | file to see what the compose file looks like. 58 | It specifies how the Qlik Associative Engine runs as a Docker container, using the `qlikcore/engine` Docker image. 59 | 60 | !!! Tip 61 | To learn more about Docker compose files, see [Compose file](https://docs.docker.com/compose/compose-file/). 62 | 63 | ## Communicating with the Qlik Associative Engine 64 | 65 | To communicate with the Qlik Associative Engine in a Docker container, we use a small node.js application that uses 66 | [enigma.js](https://github.com/qlik-oss/enigma.js) to retrieve the Qlik Associative Engine version number. 67 | 68 | The application consists of the hello-engine.js file and the package-json file, 69 | which is also shared among the Hello Data and Hello Visualization tutorials. 70 | 71 | 1. Install dependencies. 72 | 73 | Run the following command in a command shell: 74 | 75 | ```bash 76 | npm install 77 | ``` 78 | 79 | This command installs all of the dependent packages listed in the package.json file. 80 | 81 | 1. Run the application. 82 | 83 | Run the following command in a command shell: 84 | 85 | ```bash 86 | npm run hello-engine 87 | ``` 88 | 89 | This command runs the application, which communicates with Qlik Associative Engine and retrieves the 90 | Qlik Associative Engine semantic version. 91 | If successful, you will see a response like the following: 92 | 93 | ```bash 94 | npm run hello-engine 95 | Creating and opening session. 96 | Engine version retrieved: 12.91.0 97 | Session closed. 98 | ``` 99 | 100 | !!! Tip 101 | Open the [hello-engine.js](https://github.com/qlik-oss/core-get-started/blob/master/src/hello-engine/hello-engine.js) 102 | file to see how enigma.js is configured to communicate with the Qlik Associative Engine. 103 | 104 | 1. Stop and remove the Docker container. 105 | 106 | !!! Note 107 | To continue with the next tutorial, leave the Docker container running. 108 | 109 | Run the following command from a command shell: 110 | 111 | ```bash 112 | docker-compose down 113 | ``` 114 | 115 | This command stops the container and removes it. 116 | 117 | ## Next steps 118 | 119 | Continue with the [Hello Data](./hello-data.md) tutorial to learn how to load data into the Qlik Associative Engine. 120 | Hello Data is a continuation of this tutorial. 121 | 122 | !!! Tip 123 | We recommended that you take a look at [enigma.js](https://github.com/qlik-oss/enigma.js) to learn about its many features. 124 | -------------------------------------------------------------------------------- /docs/tutorials/hello-visualization.md: -------------------------------------------------------------------------------- 1 | # Hello Visualization 2 | 3 | Build a data visualization from data loaded into a Qlik Associative Engine running inside a Docker container. 4 | 5 | ## Prerequisites 6 | 7 | Clone the [Get Started](https://github.com/qlik-oss/core-get-started) Git repository 8 | to your local machine. The *Hello* tutorials are located here, and all commands should be executed from this Git repository. 9 | 10 | You must have [Node.js](https://nodejs.org/en/) and npm installed on your local machine. 11 | 12 | !!! Note 13 | Make sure the Qlik Associative Engine is running and that you have loaded data into the Qlik Associative Engine. 14 | If you are unfamiliar with starting the Qlik Associative Engine in a Docker container and loading data, 15 | we recommend that you begin with the [Hello Engine](./hello-engine.md) tutorial followed by the 16 | [Hello Data](./hello-data.md) tutorial. 17 | 18 | ## Building a visualization 19 | 20 | This example contains a small Node.js application that creates two visualizations 21 | from the data loaded into your dockerized Qlik Associative Engine. 22 | 23 | 1. Install dependencies. 24 | 25 | !!! Note 26 | If you already installed the dependencies in the previous tutorial, go to step 2. 27 | 28 | Run the following command from a command shell: 29 | 30 | ```bash 31 | npm install 32 | ``` 33 | 34 | This command installs all of the dependent packages in the `package.json` file. 35 | 36 | 1. Run the application. 37 | 38 | Run the following command from a command shell: 39 | 40 | ```bash 41 | npm run hello-visualization 42 | ``` 43 | 44 | This command runs the application, which contains information on where to fetch the data and which data to load. 45 | This information is then used to create and populate a session app. 46 | 47 | 1. Open the visualization in a browser. 48 | 49 | Open a browse and navigate to [http://localhost:8080](http://localhost:8080) to view the data in a visualization. 50 | 51 | If the application runs successfully, 52 | you will see that the visualization is deployed to localhost:8080 53 | and you will receive a message that the webpack has compiled successfully. 54 | 55 | ### What is happening 56 | 57 | When you run a visualization, app.js creates and populates a session app 58 | from the data that is available to the Qlik Associative Engine using enigma.js 59 | to communicate with the engine and halyard.js to manage the data. 60 | A session app only lives while the session is alive. 61 | 62 | !!! Tip 63 | We recommend that you take a look at [picasso.js](https://github.com/qlik-oss/picasso.js), 64 | a charting library that is streamlined for building visualizations with Qlik Core. 65 | You can also open the `app.js` file to see how enigma.js and halyard.js are used 66 | to load and retrieve the movies data from the engine. 67 | 68 | ## Next steps 69 | 70 | Now that you have seen how to start the Qlik Associative Engine in a Docker container, 71 | load data, and build a visualization from that data, 72 | we recommend that you explore the [Orchestration](./orchestration.md) tutorial, 73 | which shows how to run all core services of Qlik Core together. 74 | This will cover important topics such as how to run several Qlik Associative Engine instances using 75 | different container orchestration platforms. 76 | -------------------------------------------------------------------------------- /docs/use-cases.md: -------------------------------------------------------------------------------- 1 | # Use Cases 2 | 3 | ## Assisted Prescription 4 | 5 | Assisted Prescription provides an interactive application to assist doctors with drug prescriptions. Data is served 6 | from the Qlik Core backend using a single document. Variance in user load is limited and any scaling of the application 7 | can be manually managed. 8 | 9 | A live demo is available at [ap.core.qlik.com](https://ap.core.qlik.com/). You need a GitHub account to log in. 10 | 11 | ![screenshot](./images/assisted-prescription-screenshot.png) 12 | 13 | This use case is good to check out if you want to explore the following aspects of Qlik Core: 14 | 15 | * Building a custom UI on top of Qlik Core, using [picasso.js](https://github.com/qlik-oss/picasso.js) and 16 | [enigma.js](https://github.com/qlik-oss/enigma.js). 17 | * Building a backend using Qlik Core to serve multiple users with a single document used by 18 | [Qlik Associative Engine](./services/qix-engine/introduction.md). 19 | * Managing load from multiple users by scheduling sessions to different engines using a least-load strategy. 20 | * Running [Mira](./services/mira.md) with Kubernetes as container orchestrator. 21 | 22 | More info and source code of the Assisted Prescription can be found in the 23 | [core-assisted-prescription-ui](https://github.com/qlik-oss/core-assisted-prescription-ui) and 24 | [core-scaling](https://github.com/qlik-oss/core-scaling) GitHub repositories. 25 | 26 | This use case was earlier deployed on a Docker Swarm cluster. You can still find the code used here: 27 | [core-assisted-prescription](https://github.com/qlik-oss/core-assisted-prescription) GitHub repository. 28 | 29 | ## African Urbanization 30 | 31 | African Urbanization provides a captivating experience in an infographic inspired UI which tells the story about the 32 | urbanization in Africa from 1960 til today. Data is served from the Qlik Core backend using a single document. Large 33 | variance in user load is anticipated which is handled by horizontal pod auto-scaling and infrastructure auto-scaling. 34 | An overview of the flows is described in [autoscaling](./images/urbanization_autoscaling.png) and 35 | [connection of a session](./images/urbanization_connection_of_one_session.png). 36 | 37 | A live demo is available at [urbanization.core.qlik.com](https://urbanization.core.qlik.com/). 38 | 39 | ![screenshot](./images/african-urbanization-screenshot.png) 40 | 41 | Look at this solution using Qlik Core if you are interested in: 42 | 43 | * Sharing a document between multiple [Qlik Associative Engine](./services/qix-engine/introduction.md) instances using 44 | volumes. 45 | * Horizontal auto-scaling of Qlik Associative Engine pods in Kubernetes using Prometheus metrics. 46 | * Deploying a Qlik Core application on Google Kubernetes Engine (GKE) on Google Cloud. 47 | * Automatic scaling of infrastructure with GKE. 48 | * Running [Mira](./services/mira.md) with Kubernetes as container orchestrator. 49 | 50 | More info and source code of the African Urbanization can be found in the 51 | [core-scaling](https://github.com/qlik-oss/core-scaling) and 52 | [core-scaling-ui](https://github.com/qlik-oss/core-scaling-ui) GitHub repositories. 53 | -------------------------------------------------------------------------------- /docs/why-qlik-core.md: -------------------------------------------------------------------------------- 1 | # An analytics development platform by Qlik 2 | 3 | Qlik Core is built around the Qlik Associative Engine and Qlik-authored open source libraries. 4 | Who’s Qlik you might ask? We’ve been around for 25 years and our specialty is analytics. 5 | Our platform has powerful features like responsive and intelligent visualizations, 6 | collaboration and storytelling functionality, robust data control and role-based data security. 7 | Underneath those features is our "secret sauce" that we call the Qlik Associative Engine. 8 | This in-memory inference and calculation engine is what’s responsible for the magic — 9 | dynamically indexing and associating data without needing to rely on query-based analyses 10 | which are restricted to linear exploration within a partial view of the data. 11 | 12 | With Qlik Core, you can take advantage of this powerful associative engine to build, 13 | extend and quickly deploy custom interactive data-driven solutions that are highly scalable 14 | and cloud-ready. Supported by a backbone of Linux and Docker, Qlik Core applications can 15 | easily be embedded into any stack, IoT device, application, web page, etc. And with the 16 | associative engine, all data points are associated within a virtual data layer over your 17 | front-end and back-end systems. These associations exist even across tables, allowing you 18 | to change, model and visualize complex relationships between various data sources and tables. 19 | 20 | **With Qlik Core, you also get...** 21 | 22 | - **Easy data aggregation during run time** – save development time by combining disparate data sources, 23 | no matter how large, and letting our engine take care of the data computation 24 | 25 | - **Flexibility when changes happen** – gain flexibility with the virtual data layer that updates 26 | the front and back-end system at the same time when data changes 27 | 28 | - **Rapid searching & filtering** – search on any set of terms or apply filters and the engine 29 | automatically manages the relationships in the data to rapidly return related items from across 30 | the model, no more of those pesky left-joins 31 | 32 | - **No querying** – added flexibility with automatic calculations across the data set by our engine, 33 | even working across tables to produce results without requiring any joins 34 | 35 | - **Simplified state management** – objects/elements tied to a single data model will be automatically 36 | synched and maintained in the same state, without having to introduce specific code since the 37 | engine manages and stores the state of functions and objects 38 | 39 | **So, how do you get it? Licensing info [here](./services/licenses.md) but let’s talk components** 40 | 41 | - **Linux-based Associative Engine**  – provided as a Docker image with built-in support for 42 | Amazon Web Services, Microsoft Azure and Google Cloud Platform 43 | 44 | - **Supporting APIs**  – these ingest your data into the Qlik Associative Engine through connectors 45 | 46 | - **Supporting Open Source Libraries**  – these various libraries by Qlik expose the engine to help 47 | you build solutions faster 48 | 49 | It’s all language agnostic but JavaScript lovers will find it easier to work with given the number of 50 | our open source tools available in JavaScript. Other top languages and tools used include R, Go, Shell, 51 | C#, Python, Java and D3. Qlik Core can also be managed with the orchestration tool of your choice for 52 | implementing, scaling and managing containerized applications. 53 | 54 | 62 | -------------------------------------------------------------------------------- /generate-eula-page.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | cd "$(dirname "$0")" 4 | 5 | echo "Generating eula markdown page..." 6 | 7 | docker_cmd=docker 8 | pwd=$(pwd) 9 | 10 | if [[ "$OS" == "Windows_NT" ]]; then 11 | docker_cmd="winpty docker" 12 | pwd=/$(pwd -W) 13 | fi 14 | 15 | $docker_cmd run --rm -it -v $pwd:/pandoc dalibo/pandocker:latest \ 16 | -s qlik-core-eula.docx \ 17 | -t markdown_strict \ 18 | -o docs/eula.md 19 | 20 | content=$(cat docs/eula.md) 21 | echo -e "\n\n$content" > docs/eula.md 22 | -------------------------------------------------------------------------------- /lint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | cd "$(dirname "$0")" 4 | 5 | docker_cmd=docker 6 | pwd=$(pwd) 7 | 8 | if [[ "$OS" == "Windows_NT" ]]; then 9 | docker_cmd="winpty docker" 10 | pwd=/$(pwd -W) 11 | fi 12 | 13 | $docker_cmd run --rm -v $pwd/docs/:/src/ -v $pwd/docs/.proselintrc:/root/.proselintrc -it singapore/lint-condo:0.18.0 14 | -------------------------------------------------------------------------------- /qlik-core-eula.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qlik-oss/core-website/0b356d166309e06f82f8faccd6109b37d7370125/qlik-core-eula.docx -------------------------------------------------------------------------------- /runtime.txt: -------------------------------------------------------------------------------- 1 | 3.6 2 | -------------------------------------------------------------------------------- /serve.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | cd "$(dirname "$0")" 4 | 5 | docker_cmd=docker 6 | pwd=$(pwd) 7 | 8 | if [[ "$OS" == "Windows_NT" ]]; then 9 | docker_cmd="winpty docker" 10 | pwd=/$(pwd -W) 11 | fi 12 | 13 | $docker_cmd run --rm -it -p 8000:8000 -v $pwd:/docs squidfunk/mkdocs-material:4.1.1 14 | -------------------------------------------------------------------------------- /theme/404.html: -------------------------------------------------------------------------------- 1 | 19 | 20 | {% extends "base.html" %} 21 | 22 | 23 | {% block content %} 24 |

404 - Seems like you got a broken link

25 | Don't fear though, if you do not find what you are searching for in the table of 26 | content you can always send us a Slack message 27 | or create an issue on our repo. 28 | 29 | {% endblock %} -------------------------------------------------------------------------------- /theme/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016-2018 Martin Donath 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to 5 | deal in the Software without restriction, including without limitation the 6 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | sell copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 | IN THE SOFTWARE. -------------------------------------------------------------------------------- /theme/main.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block site_meta %} 4 | 5 | 6 | 7 | 8 | {% if page and page.meta and page.meta.title %} 9 | 10 | {% elif page and page.title and not page.is_homepage %} 11 | 12 | {% else %} 13 | 14 | {% endif %} 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | {% if page and page.meta and page.meta.title %} 24 | 25 | {% elif page and page.title and not page.is_homepage %} 26 | 27 | {% else %} 28 | 29 | {% endif %} 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | {% endblock %} 46 | 47 | {% block extrahead %} 48 | 64 | {% endblock %} 65 | 66 | {% block content %} 67 | 71 | 72 | {% if page.edit_url %} 73 |  74 | 75 | 76 | 77 | 78 | 79 | 80 |
81 |
82 |
83 | 84 |
85 |
86 | 87 |
88 |
89 | 91 | 92 |
93 |
94 | 95 |
96 |
97 | {% endif %} 98 | 99 | {% if page.title == "Home" %} 100 | 106 | {% endif %} 107 | {% if page.title == "Pricing" %} 108 | 109 | {% endif %} 110 | 111 | {{ page.content }} 112 | 113 | {% if page.title == "License Registration" %} 114 |
115 | 116 |
117 | 121 | 122 |
123 | {% endif %} 124 | 125 | {% endblock %} 126 | 127 | {% block analytics %} 128 | {% endblock %} 129 | -------------------------------------------------------------------------------- /theme/partials/footer.html: -------------------------------------------------------------------------------- 1 | {% import "partials/language.html" as lang with context %} 2 | 3 | 66 | 67 |
68 |
69 |
70 | 80 |
81 |
82 |
83 | -------------------------------------------------------------------------------- /theme/partials/language/en.html: -------------------------------------------------------------------------------- 1 | {% macro t(key) %}{{ { 2 | "language": "en", 3 | "direction": "ltr", 4 | "clipboard.copy": "Copy to clipboard", 5 | "clipboard.copied": "Copied to clipboard", 6 | "edit.link.title": "Edit this page", 7 | "footer.previous": "Previous", 8 | "footer.next": "Next", 9 | "meta.comments": "Comments", 10 | "meta.source": "Source", 11 | "search.language": "en", 12 | "search.pipeline.stopwords": true, 13 | "search.pipeline.trimmer": true, 14 | "search.placeholder": "Search", 15 | "search.result.placeholder": "Type to start searching", 16 | "search.result.none": "No matching documents", 17 | "search.result.one": "1 matching document", 18 | "search.result.other": "# matching documents", 19 | "search.tokenizer": "[\s\-]+", 20 | "skip.link.title": "Skip to content", 21 | "source.link.title": "Go to repository", 22 | "toc.title": "On this page" 23 | }[key] }}{% endmacro %} -------------------------------------------------------------------------------- /theme/partials/nav.html: -------------------------------------------------------------------------------- 1 | {% if page.title != "EULA" %} 2 |