26. The miraj-cli console
miraj-cli is the MIRAJ interactive SQL console: it opens a data folder (or connects to a running server, see 26.7), executes SQL statements and displays the results. It is used both for interactive exploration (REPL) and for running .sql scripts in batch mode (scheduled tasks, migrations, deployments).
26.1 General syntax#
miraj-cli [--root <folder>] [--config <file.xml>] [-d <database>] [-e "<SQL>"]
[--lang en|fr|zh|hi|es|ar|pt|ru|de|ja] [--json] [--timing] [--no-history]
[<file.sql>]
miraj-cli --host <host> [--port <port>] [--user <account>] [--password]
[--protocol auto|miraj|postgresql] [TLS options] [-d <database>] [-e "<SQL>"]
[--json] [--timing] [--no-history] [<file.sql>]The option names of the embedded console are case-insensitive (--ROOT is equivalent to --root); the connection options (26.7) are written in lowercase.
Exit codes:
| Code | Meaning |
|---|---|
0 | Success (all statements succeeded) |
1 | At least one statement failed, or a .sql file given as an argument was not found |
2 | Error while opening the embedded server (root folder, configuration file, folder already opened by another MIRAJ process), invalid connection option or connection to the server impossible |
26.2 Command-line options#
| Option | Description | Example |
|---|---|---|
--root <folder> | Root folder of the data to open (default: data, created if missing). Each database it contains is loaded on first use. | miraj-cli --root C:\donnees\miraj |
--config <file.xml> | XML engine configuration file to use, instead of <root folder>\miraj_config.xml. If the file does not exist, a commented template is created at that location; miraj_default.xml, the reference list of all variables with their default value, is regenerated at each startup next to it (it is never read). | miraj-cli --config C:\conf\miraj-prod.xml |
-d <database> | Database to select after opening (equivalent to typing USE <database>; as the first statement). | miraj-cli -d shop |
-e "<SQL>" | Executes the given SQL statement (or script) then exits, without entering the REPL. Disables the history. | miraj-cli -d shop -e "SELECT COUNT(*) FROM articles" |
--lang <code> | Language of error and warning messages: en (default), fr, zh, hi, es, ar, pt, ru, de, ja. | miraj-cli --lang fr |
--json | Displays results as JSON instead of a text table. Can also be enabled during a session with \json. | miraj-cli --json -e "SELECT * FROM articles" |
--timing | Displays the execution time of each statement. Can also be enabled during a session with \timing. | miraj-cli --timing |
--no-history | Disables reading and writing of the persistent statement history. | miraj-cli --no-history |
<file.sql> | Executes this file in batch mode then exits (recognized by its .sql extension, without being the value of -e). The last .sql argument on the command line is the one retained. | miraj-cli migration.sql |
--help, -h, /? | Displays the syntax summary and exits. | miraj-cli --help |
Notes:
-eand<file.sql>take precedence over the REPL, in that order: if-eis present, it is executed and the console exits without reading any file or opening a REPL; otherwise, if there is a.sqlargument, that file is executed; otherwise, the REPL starts.-d <database>can be combined with-eor with a.sqlfile: the database is selected before execution.- The executed
.sqlfile may begin with a UTF-8 BOM, which is ignored automatically. On a data folder opened by the console, it is executed as a single batch of statements separated by;, up to the first error (exit code1); theDELIMITERcommand is not recognized there (error 1064): a script that contains it, like those ofmiraj-dump, is reloaded withmiraj-dump restoreor with the console connected to a server (26.7). - The console embeds the engine: it opens the data folder itself and takes its exclusive lock (
miraj.lck). As long as amiraj-serverholds that folder, it cannot open it (exit code2): connect to the server with the connection options (26.7).
26.3 Internal REPL commands#
In the REPL, an SQL statement can span several lines; it is sent to the engine as soon as a line ends with ;. The following commands, most of them prefixed with \, are not SQL and run immediately, without a semicolon:
| Command | Purpose | Example |
|---|---|---|
\help, \h, help | Displays the list of commands. | \help |
\timing | Toggles the display of execution time (on/off). | \timing |
\json | Toggles the result display format between table and JSON. | \json |
\d | Lists the tables of the current database (SHOW TABLES). | \d |
\d <table> | Describes the columns of the given table (DESCRIBE <table>). | \d articles |
\l | Lists the databases of the server (SHOW DATABASES). | \l |
\history [n] | Displays the last n statements of the history (20 by default). A negative number displays nothing. | \history 50 |
\!n | Re-executes statement number n of the history (number shown by \history). | \!12 |
source <file.sql>, \. <file.sql> | Executes a .sql file without leaving the REPL. | source migration.sql |
\q, exit, quit | Exits the console. | \q |
| up / down arrows | Recall of previously typed lines (Windows console). | — |
| Ctrl-C | While a statement is running (data folder opened by the console): interrupts the statement, which returns error 1317, without leaving the console. Outside execution, Ctrl-C keeps its usual effect. | — |
Example of interrupting a query that runs too long:
miraj> SET cte_max_recursion_depth = 4294967295;
OK, 0 ligne(s) affectée(s)
miraj> WITH RECURSIVE s(n) AS (SELECT 1 UNION ALL SELECT n+1 FROM s WHERE n < 1000000000) SELECT COUNT(*) FROM s;
ERREUR 1317 (70100) : Query execution was interrupted
miraj> SELECT 2;
+---+
| 2 |
+---+
| 2 |
+---+
1 ligne(s)26.4 Typical interactive use#
> miraj-cli --root C:\donnees\miraj --timing
MIRAJ 1.0.0 Entreprise - tapez \help pour l'aide, \q pour quitter.
miraj> \l
+--------------------+
| Database |
+--------------------+
| information_schema |
| miraj |
| performance_schema |
| shop |
| sys |
+--------------------+
5 ligne(s) (60.08 ms)
miraj> USE shop;
OK, 0 ligne(s) affectée(s) (56.24 ms)
shop> \d
+----------------+
| Tables_in_shop |
+----------------+
| articles |
+----------------+
1 ligne(s) (60.12 ms)
shop> \d articles
+-------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| nom | varchar(50) | NO | | NULL | |
| prix | decimal(10,2) | YES | | NULL | |
| stock | int(11) | YES | | 0 | |
+-------+---------------+------+-----+---------+----------------+
4 ligne(s) (52.23 ms)
shop> SELECT nom, prix
-> FROM articles
-> WHERE prix > 10;
+--------+-------+
| nom | prix |
+--------+-------+
| Cahier | 12.90 |
+--------+-------+
1 ligne(s) (53.49 ms)
shop> \json
Résultats au format JSON
shop> SELECT nom, prix FROM articles WHERE prix > 10;
[
{"nom": "Cahier", "prix": 12.90}
]
1 ligne(s) (58.58 ms)
shop> \qThe prompt shows the current database (shop>) or miraj> if no database is selected; it becomes -> while continuing an unfinished multi-line statement.
26.5 Running SQL scripts in batch mode#
Three ways to run a script without going through the interactive REPL:
# File given as an argument: executed, then the console exits
miraj-cli --root C:\donnees\miraj -d shop migration.sql
# Inline statement or script with -e (several statements separated by ;)
miraj-cli --root C:\donnees\miraj -e "USE shop; DELETE FROM articles WHERE stock = 0;"
# From the REPL, without leaving the current session
miraj> source migration.sqlA non-zero exit code signals a failed script; combined with --json, the output of a script executed with -e can be consumed directly by another program:
miraj-cli --root C:\donnees\miraj -d shop --json -e "SELECT id, nom FROM articles" > articles.json
if ($LASTEXITCODE -ne 0) { Write-Error "Échec du script" }26.6 Practical tips#
- Persistent history: each statement submitted in the REPL is appended to
%APPDATA%\MIRAJ\cli-history.sql(or~/.config/MIRAJ/cli-history.sqloutside Windows), with up to 1000 entries kept. This history is reloaded at the next startup and feeds\historyand\!n.--no-history(or-e, which disables it automatically) ignores it, which is useful for scripts called in a loop from a scheduled task. - Timing:
--timing(or\timingduring a session) is useful for quickly comparing two formulations of the same query without instrumenting a client. - JSON format:
--json(or\json) makes it easy to pass results to another command-line tool (ConvertFrom-Jsonin PowerShell,jq, etc.) without writing a dedicated client. - Configuration file: at the first startup,
miraj-cliwrites a commented templatemiraj_config.xmlin the root folder (or at the path given by--config) and regeneratesmiraj_default.xml, the reference of all engine variables. Editingmiraj_config.xmlthen restarting the console applies the settings; an invalid or unreadable file makes the console exit with code2. Unlikemiraj-server, the console does not look for amiraj_config.xmlnext to its executable. - Passwords: a statement that contains a password or an encryption key (
CREATE USER … IDENTIFIED BY,SET PASSWORD, etc.) can still be replayed with\!nin the session but is never written to the history file. - Errors: a failing statement displays
ERREUR <code> (<SQLSTATE>) : <message>, followed byposition : ligne L, colonne Cwhen the parser knows it. - Warnings: session warnings (truncations, default values applied, etc.) are displayed after the result of each statement that produced any.
26.7 Console on a running server#
With a connection option (--host, --port, --user, --password, --protocol, --ssl, --ssl-ca, --ssl-insecure, --no-ssl), the console connects to the server instead of opening a data folder (--root, --config and --lang then have no effect; the message language is the server's).
| Option | Default | Description |
|---|---|---|
--host <host> | 127.0.0.1 | Server to reach. |
--port <port> | 7007 | Server port. |
--user <account> | root | Connection account. |
--password (or --ask-password) | — | Password asked at the keyboard, without echo. Without this option, the MIRAJ_PASSWORD environment variable is read if it exists. |
--password=<password> | — | Not recommended: visible in the process list; the console prints a warning. |
| (no TLS option) | TLS offered | Encrypted connection if the server offers TLS, certificate not verified. |
--ssl | — | TLS required, server certificate verified (host name included). |
--ssl-ca <file.pem> | — | Authority that signed the server certificate (implies --ssl). |
--ssl-insecure | — | TLS required, certificate accepted without verification. |
--no-ssl | — | Clear-text connection. |
--protocol auto|miraj|postgresql | auto | Language of the instance: recognized at connection time, or forced. |
miraj-cli --port 7007 -d shop
miraj-cli --host 10.0.0.5 --user admin --password --ssl-ca ca.pem migration.sql> miraj-cli --port 7007 -d essai
MIRAJ 1.0.0 - connecté (langage MIRAJ) - tapez \help pour l'aide, \q pour quitter.
essai> SELECT 1 = 1 AS vrai;
+------+
| vrai |
+------+
| 1 |
+------+
1 ligne(s)
essai> SELECT * FROM absente;
ERREUR 1146 (42S02) : Table 'essai.absente' doesn't exist
essai> SELECT CAST('abc' AS SIGNED) AS n;
+---+
| n |
+---+
| 0 |
+---+
1 ligne(s)
Avertissement : Truncated incorrect INTEGER value: 'abc'
essai> \qThe same session on an instance in PostgreSQL language:
MIRAJ 1.0.0 - connecté (langage PostgreSQL) - tapez \help pour l'aide, \q pour quitter.
miraj=> SELECT 1 = 1 AS vrai;
+------+
| vrai |
+------+
| t |
+------+
1 ligne(s)
miraj=> SELECT * FROM absente;
ERREUR 42P01 : relation "absente" does not exist
miraj=> \q- Instance language: recognized at connection time (
--protocol auto, the default;mirajorpostgresqlforce it, see 30.12). Statements are written in that language; the prompt shows it:database>in the MIRAJ language,database=>in the PostgreSQL language (miraj>/miraj=>with no current database). - Errors:
ERREUR 1146 (42S02) : …in the MIRAJ language,ERREUR 42P01 : …(SQLSTATE) in the PostgreSQL language; warnings and notices follow the result. Only those raised by the statement itself are displayed, once: an error is not repeated as a warning, nor after the following statements. -d <database>: the database is selected without displaying anything (the banner comes first); an unknown database displays the error, and the console returns exit code1when it exits..sqlfile: split into statements in the instance's language (strings, comments,DELIMITERin the MIRAJ language; standard strings,E'…',$$…$$in the PostgreSQL language), read as it goes and executed up to the first error (exit code1), likemiraj-dump restore, indicating the line of the faulty statement. Amiraj-dumpexport can be reloaded this way.> miraj-cli --port 7007 e.sql OK, 0 ligne(s) affectée(s) ERREUR 1146 (42S02) : Table 'shop.absente' doesn't exist e.sql, ligne 2- The
\d,\l,\json,\timingcommands, the history andsourcework the same way; a boolean result is displayed ast/fin the PostgreSQL language. - Exit code
2: connection impossible.