Mirajv1.0
FR

29. Pilote ODBC

MIRAJ ODBC Driver est le pilote ODBC natif de MIRAJ. Il parle à miraj-server (port 7007 par défaut) le protocole de l'instance : protocole hérité sur une instance en langage MIRAJ, protocole PostgreSQL v3 sur une instance en langage PostgreSQL (chapitre 30), reconnu à la connexion (29.5). Il n'a besoin d'aucun autre composant (aucune bibliothèque cliente tierce). Il vise le niveau Core et le niveau 1 de l'API ODBC 3.8 (fonctions en 29.8), en 64 bits, pour les applications qui lisent MIRAJ par ODBC : Excel, Power BI, Access (tables liées), LibreOffice Base, pyodbc, FireDAC (Delphi), DBeaver.

SystèmeBibliothèqueInstallée par
Windows 64 bitsmiraj_odbc.dlll'assistant d'installation (dossier du programme) ou le zip
macOS (Apple silicon)/usr/local/miraj-express/lib/libmiraj_odbc.dylible paquet .pkg
Linux 64 bitslibmiraj_odbc.sole zip Linux

Le nom du pilote, à écrire tel quel dans les chaînes de connexion, est MIRAJ ODBC Driver. Le serveur n'a rien à régler pour lui : un compte MIRAJ ordinaire suffit (chapitre 15).

29.1 Installation#

Windows#

L'assistant d'installation (2.2) copie miraj_odbc.dll à côté de miraj-server.exe et déclare le pilote à Windows, dans la vue 64 bits du registre :

  • la clé HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\MIRAJ ODBC Driver, avec les valeurs Driver et Setup (chemin de la DLL), APILevel = 1, ConnectFunctions = YYY, DriverODBCVer = 03.80, SQLLevel = 1 et FileUsage = 0 ;
  • la valeur MIRAJ ODBC Driver = Installed dans la clé ...\ODBCINST.INI\ODBC Drivers.

Le pilote apparaît alors dans l'onglet Pilotes de l'administrateur de sources de données ODBC 64 bits (odbcad32.exe du dossier System32). Il n'existe pas en 32 bits : une application 32 bits (Access ou Excel 32 bits, ancien Delphi 32) ne le voit pas, et il faut une édition 64 bits de l'application. Les éditions Express et Entreprise déclarent le même nom ; si les deux sont installées, c'est la dernière installée qui l'emporte.

Sans l'assistant (zip) : décompresser le dossier où l'on veut, puis lancer, dans un PowerShell 64 bits ouvert en administrateur :

.\Declarer-ODBC.ps1                              # miraj_odbc.dll à côté du script
.\Declarer-ODBC.ps1 -Dll C:\MIRAJ\miraj_odbc.dll

Le dossier de la DLL ne doit plus être déplacé après la déclaration (le registre en garde le chemin) ; pour le déplacer, relancer le script.

macOS#

Le paquet MIRAJ-<version>-Express-macos-<arch>.pkg (2.2, 21.14) dépose /usr/local/miraj-express/lib/libmiraj_odbc.dylib, et son script de fin d'installation ajoute la section [MIRAJ ODBC Driver] à /Library/ODBC/odbcinst.ini (fichier créé au besoin), ainsi qu'à /usr/local/etc/odbcinst.ini et /opt/homebrew/etc/odbcinst.ini s'ils existent (unixODBC installé par Homebrew). Les autres pilotes de ces fichiers ne sont pas modifiés ; une réinstallation remplace seulement la section de MIRAJ.

[MIRAJ ODBC Driver]
Description=MIRAJ ODBC Driver (vers miraj-server)
Driver=/usr/local/miraj-express/lib/libmiraj_odbc.dylib
Setup=/usr/local/miraj-express/lib/libmiraj_odbc.dylib

macOS ne fournit pas de Driver Manager : installer unixODBC (brew install unixodbc) ou utiliser celui d'une application (Excel pour Mac embarque iODBC, qui lit le même odbcinst.ini). Vérification :

odbcinst -q -d                  # liste les pilotes : « MIRAJ ODBC Driver » doit y figurer

Linux#

Le zip MIRAJ-<version>-Express-linux-x64.zip contient libmiraj_odbc.so et, dans odbc/, deux scripts. Il faut unixODBC (unixodbc sous Debian et Ubuntu, unixODBC sous Fedora et RHEL). Après décompression, par exemple dans /opt/miraj :

sudo /opt/miraj/odbc/register.sh                 # déclare le pilote dans odbcinst.ini
sudo /opt/miraj/odbc/register.sh --lib /opt/miraj/libmiraj_odbc.so   # chemin explicite

Le script cherche le fichier indiqué par odbcinst -j (ligne DRIVERS, en général /etc/odbcinst.ini), retire une ancienne section [MIRAJ ODBC Driver] puis écrit la nouvelle, en laissant le reste intact. Il est répétable. --ini <fichier> vise un autre fichier (plusieurs fois possible), par exemple un odbcinst.ini d'essai ou celui d'un ODBCSYSINI particulier. La même section peut aussi s'écrire à la main, ou se déclarer par odbcinst -i -d -f modèle.ini avec un fichier contenant la section ci-dessus.

29.2 Chaîne de connexion#

Une chaîne ODBC est une suite de MOT=valeur;MOT=valeur. Les mots sont insensibles à la casse, un mot répété garde sa première valeur, et un mot inconnu est ignoré (les outils en ajoutent). Une valeur qui contient ; s'écrit entre accolades : PWD={a;b} ; une } s'y écrit }}. Une accolade non fermée, un texte après }, un mot vide ou un caractère de contrôle dans un nom d'hôte, de base ou de source sont refusés (HY000), sans que le message cite la valeur.

DRIVER={MIRAJ ODBC Driver};SERVER=127.0.0.1;PORT=7007;UID=root;PWD=mot de passe;DATABASE=ventes
MotRôleDéfaut
DRIVERnom du pilote ({MIRAJ ODBC Driver}) ; choisit le pilote auprès du Driver Manager
DSNnom d'une source de données (29.3) ; les mots de la chaîne l'emportent sur ceux de la source
SERVER (ou HOST, SERVERNAME)nom ou adresse du serveur ; localhost est ramené à 127.0.0.1127.0.0.1
PORTport TCP, de 1 à 655357007
UID (ou USER, USERNAME)compte MIRAJ
PWD (ou PASSWORD)mot de passe ; jamais écrit dans un message d'erreur, un journal ni dans la chaîne rendue à l'application
DATABASE (ou DB, INITIALCATALOG)base courante à la connexionaucune
SSLMODETLS : disabled, preferred, required, verify-ca, verify-full (casse ignorée ; disable, prefer, require, verify-identity acceptés)preferred
SSLCAfichier d'autorités de certification (PEM ou DER) pour verify-ca et verify-fullautorités publiques
SSLCERT, SSLKEYcertificat et clé privée du client (PEM ou DER), ensemble, clé non chiffréeaucun
COMPRESS (ou COMPRESSION)protocole compressé (1, yes, true, on, y ; 0, no, false, off, n)0
PREPONCLIENT1 : les paramètres ? sont substitués dans le texte SQL par le pilote ; 0 : requêtes préparées par le serveur0
CONNECTTIMEOUTdélai de connexion, en secondes : connexion TCP, poignée de main TLS et authentification ensemble ; sans lui, SQL_ATTR_LOGIN_TIMEOUT ; 0 vaut le défaut30
READTIMEOUT, WRITETIMEOUTdélais de lecture et d'écriture de la session, en secondes ; sans eux, SQL_ATTR_CONNECTION_TIMEOUTaucun
INITSTMTinstruction exécutée après la connexionaucune
LOGchemin d'un journal du pilote (ou variable d'environnement MIRAJ_ODBC_LOG) ; sans mot de passe ni valeurs, fichier en 0600, limité à 64 Miodésactivé
PROTOCOLprotocole de l'instance : auto (reconnu à la connexion), miraj (langage MIRAJ) ou postgresql (langage PostgreSQL, 29.5)auto

TLS. disabled n'utilise jamais TLS. preferred chiffre si le serveur le propose et retombe sinon en clair, sans vérifier le certificat : il ne protège pas d'un attaquant actif. required exige TLS (la connexion échoue avant l'envoi du mot de passe si le serveur ne le propose pas) sans vérifier le certificat. verify-ca et verify-full vérifient la chaîne avec SSLCA et que le nom du serveur figure dans le certificat (limite de la bibliothèque cliente : verify-ca ne peut pas ignorer le nom, il est donc aussi strict que verify-full). Sans SSLCA, seules les autorités publiques sont crues : un certificat auto-signé exige SSLCA. Pour un réseau qui n'est pas de confiance, utiliser verify-full avec le certificat de l'autorité du serveur :

DRIVER={MIRAJ ODBC Driver};SERVER=miraj.exemple.fr;UID=app;PWD=...;SSLMODE=verify-full;SSLCA=C:\certs\ca.pem

Un serveur lancé avec --require-tls refuse SSLMODE=disabled (erreur 3159).

PREPONCLIENT. Par défaut, SQLPrepare utilise les requêtes préparées du serveur (protocole binaire : types exacts, BLOB envoyés par morceaux). Mettre PREPONCLIENT=1 si un outil prépare des requêtes que le serveur n'accepte pas sous cette forme : le pilote échappe alors lui-même les valeurs et envoie le texte complet.

COMPRESS. Utile sur un lien lent (résultats volumineux) ; sur le réseau local, le gain est nul et le processeur travaille plus. Sans effet sur une instance en langage PostgreSQL.

Délais. La connexion n'attend jamais sans fin : passé le délai de connexion, elle échoue en HYT00. Une lecture ou une écriture qui dépasse READTIMEOUT ou WRITETIMEOUT après la connexion échoue en HYT01 ; sans ces délais, une requête longue n'est pas interrompue (le délai propre à une instruction se règle par SQL_ATTR_QUERY_TIMEOUT, 29.8). Un délai ne peut dépasser une semaine. Une connexion refusée ou impossible échoue en 08001, une liaison rompue en 08S01.

SQLDriverConnect. Le pilote n'ouvre aucune boîte de dialogue : avec SQL_DRIVER_PROMPT ou SQL_DRIVER_COMPLETE, il essaie avec la chaîne reçue. La chaîne rendue à l'application est la chaîne complète effective, sans le mot de passe. SQLConnect (nom de source, compte, mot de passe) passe par les mêmes paramètres.

29.3 Sources de données (DSN)#

Une source de données (DSN) range les mots de la chaîne de connexion sous un nom ; l'application n'écrit plus que DSN=nom (et, au besoin, UID et PWD).

Windows#

Une source se range dans le registre : HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBC.INI\<nom> pour une source Système (visible de tous les comptes), HKEY_CURRENT_USER\SOFTWARE\ODBC\ODBC.INI\<nom> pour une source Utilisateur, avec une valeur Driver (chemin de miraj_odbc.dll) et un mot du tableau 29.2 par valeur, et le nom dans la clé ...\ODBC.INI\ODBC Data Sources (valeur MIRAJ ODBC Driver). Exemple pour une source Utilisateur, dans PowerShell :

$k = "HKCU:\SOFTWARE\ODBC\ODBC.INI\MIRAJ ventes"
New-Item $k -Force | Out-Null
Set-ItemProperty $k Driver   "C:\Program Files\Miraj Express\miraj_odbc.dll"
Set-ItemProperty $k SERVER   "127.0.0.1"
Set-ItemProperty $k PORT     "7007"
Set-ItemProperty $k DATABASE "ventes"
New-Item "HKCU:\SOFTWARE\ODBC\ODBC.INI\ODBC Data Sources" -Force | Out-Null
Set-ItemProperty "HKCU:\SOFTWARE\ODBC\ODBC.INI\ODBC Data Sources" "MIRAJ ventes" "MIRAJ ODBC Driver"

La source se voit ensuite dans odbcad32.exe (64 bits), onglet DSN utilisateur ou DSN système. Le mot de passe n'est pas à ranger dans la source : l'application le demande et le transmet à la connexion. Le pilote ne fournit pas de fenêtre de saisie propre à MIRAJ dans odbcad32.exe (bouton Configurer) : les sources se créent par le registre comme ci-dessus.

macOS et Linux : odbc.ini#

unixODBC lit les sources dans ~/.odbc.ini (utilisateur) et dans odbc.ini du dossier de configuration (/etc/odbc.ini sous Linux, /Library/ODBC/odbc.ini sous macOS ; odbcinst -j en donne les chemins). Le pilote lit ces fichiers lui-même quand la chaîne contient DSN=, dans cet ordre : $ODBCINI, ~/.odbc.ini, $ODBCSYSINI/odbc.ini, /etc/odbc.ini, /usr/local/etc/odbc.ini, /opt/homebrew/etc/odbc.ini, ~/Library/ODBC/odbc.ini, /Library/ODBC/odbc.ini ; le premier fichier qui contient la section l'emporte (casse du nom ignorée, commentaires ; et # admis). Exemple :

[MIRAJ ventes]
Driver     = MIRAJ ODBC Driver
Description = Base des ventes
SERVER     = 127.0.0.1
PORT       = 7007
UID        = lecteur
DATABASE   = ventes
SSLMODE    = verify-full
SSLCA      = /etc/ssl/miraj-ca.pem

Vérification, sans écrire de programme (isql est livré avec unixODBC) :

isql -v "MIRAJ ventes" lecteur 'mot de passe'

Un mot de passe écrit dans odbc.ini (PWD = ...) y est en clair : réserver cet usage aux postes de confiance et protéger le fichier (chmod 600 ~/.odbc.ini).

29.4 Exemples#

Python (pyodbc)#

import pyodbc

cn = pyodbc.connect(
    "DRIVER={MIRAJ ODBC Driver};SERVER=127.0.0.1;PORT=7007;"
    "UID=root;PWD=mot de passe;DATABASE=ventes")
cur = cn.cursor()
cur.execute("SELECT id, nom FROM client WHERE ville = ?", "Alger")
for ligne in cur.fetchall():
    print(ligne.id, ligne.nom)
cn.close()

Excel#

Données → Obtenir des données → À partir d'autres sources → À partir d'ODBC, puis choisir une source de données (DSN) ou Chaîne de connexion et saisir la chaîne (DRIVER={MIRAJ ODBC Driver};SERVER=...), puis les identifiants, la table et Charger. Excel doit être en 64 bits (Fichier → Compte → À propos d'Excel). Sous macOS, Excel passe par iODBC : le pilote doit être dans /Library/ODBC/odbcinst.ini (fait par le paquet), la source dans ~/Library/ODBC/odbc.ini ou /Library/ODBC/odbc.ini.

Power BI Desktop#

Obtenir les données → ODBC, choisir le DSN ou coller la chaîne de connexion dans Options avancées, puis les identifiants (Base de données). Le mode Import est celui qui convient (le pilote n'a pas de mode DirectQuery propre). Une passerelle de données locale (actualisation dans le service en ligne) doit avoir le pilote installé sur la machine de la passerelle, et la source en DSN système.

Access (tables liées)#

Access 64 bits seulement. Données externes → Source de données ODBC → Lier à la source de données, onglet Source de données machine (DSN système ou utilisateur), choisir les tables. Pour une table sans clé primaire déclarée, Access demande les colonnes qui identifient une ligne : les choisir pour pouvoir modifier la table liée.

LibreOffice Base#

Fichier → Nouveau → Base de données → Se connecter à une base de données existante → ODBC, saisir le nom du DSN (LibreOffice s'appuie sur unixODBC sous Linux et macOS, sur le Driver Manager sous Windows) ; le nom d'utilisateur se demande à l'étape suivante.

FireDAC, DBeaver, autres#

FireDAC : DriverID=ODBC, ODBCDriver=MIRAJ ODBC Driver (ou DataSource=<DSN>). DBeaver (pilote générique ODBC) et tout outil qui accepte un DSN ou une chaîne ODBC fonctionnent de même.

29.5 Instance en langage PostgreSQL#

Le même pilote se connecte à une instance lancée en langage PostgreSQL (--sql-mode POSTGRESQL,…, chapitre 30), sur le même port, sans autre réglage :

DRIVER={MIRAJ ODBC Driver};SERVER=127.0.0.1;PORT=7007;UID=app;PWD=...;DATABASE=ventes

Choix du protocole. Avec PROTOCOL=auto (défaut), le pilote envoie d'abord la demande TLS du protocole PostgreSQL et lit un octet : une instance en langage PostgreSQL continue sur cette connexion ; une instance en langage MIRAJ est rejointe par une nouvelle connexion du protocole hérité. Le langage reconnu est retenu par hôte et port pour la durée du processus : la connexion supplémentaire n'a lieu qu'une fois. PROTOCOL=miraj ou PROTOCOL=postgresql impose le protocole (un protocole imposé à tort échoue aussitôt, sans attente).

Connexion. Authentification SCRAM-SHA-256, ou mot de passe en clair sous TLS et en boucle locale (16.10). SSLMODE, SSLCA, SSLCERT et SSLKEY ont le même sens qu'en langage MIRAJ (verify-ca y vérifie la chaîne sans le nom d'hôte). DATABASE nomme la base MIRAJ courante (un schéma, en langage PostgreSQL) ; une base inconnue est refusée (3D000). INITSTMT s'écrit dans le langage de l'instance.

Ce qui change pour l'application.

DomaineInstance en langage PostgreSQL
SQLcelui du chapitre 30 ; les marqueurs ? deviennent $1, $2… (hors littéraux et commentaires) ; séquences d'échappement traduites dans ce langage ({d '…'} → '…'::date, {fn CONVERT(x, SQL_INTEGER)} → CAST(x AS integer))
PréparationSQLPrepare prépare une instruction nommée du serveur, réutilisée à chaque SQLExecute (une variante typée est préparée une fois si les types liés changent) ; SQLExecDirect passe par l'instruction anonyme ; PREPONCLIENT=1 écrit les littéraux de ce langage
Paramètresenvoyés en texte avec leur type (int8, numeric, float8, bytea, date, timestamp ; texte et heures non typés)
Résultatslus ligne à ligne au fil de SQLFetch ; SQL_ATTR_MAX_ROWS limite les lignes envoyées par le serveur ; plusieurs instructions dans un texte : un résultat par instruction (SQLMoreResults)
Métadonnéestypes de PostgreSQL (SQL_DESC_TYPE_NAME : int4, varchar, numeric, bool, bytea, timestamp, timestamptz…), booléen en SQL_BIT, précision et échelle, nullabilité, table, colonne et schéma d'origine, auto-incrément (lus dans pg_attribute, une fois par table)
CatalogueTABLE_CAT vaut miraj, TABLE_SCHEM la base MIRAJ ; un schéma nul ou vide désigne la base courante (toutes sans base courante) ; types nommés comme PostgreSQL, du nom court de pg_type.typname (TYPE_NAME de SQLColumns : varchar, bpchar, int4, int8, timestamptz…, le même que SQL_DESC_TYPE_NAME, alors que information_schema.columns.data_type porte le nom du standard, character varying) ; SQLGetTypeInfo rend les types de ce langage ; PK_NAME de SQLPrimaryKeys est le nom de la contrainte, <table>_pkey
SQLGetInfoSQL_DBMS_NAME PostgreSQL, SQL_DBMS_VER 16.04.0000, SQL_IDENTIFIER_QUOTE_CHAR ", SQL_SCHEMA_TERM schema, pas de catalogue dans les noms (SQL_CATALOG_NAME N) ; SQL_DATABASE_NAME et SQL_ATTR_CURRENT_CATALOG valent miraj
Base couranteSQL_ATTR_CURRENT_CATALOG avec le nom d'une base fait SET search_path
TransactionsAUTOCOMMIT, SQLEndTran, isolation (SET SESSION CHARACTERISTICS AS TRANSACTION …) et mode lecture seule comme en langage MIRAJ
ErreursSQLSTATE de PostgreSQL (42P01, 23505…), code natif 0
AnnulationSQLCancel envoie une demande d'annulation du protocole (pas de seconde session) ; l'instruction échoue en HY008

Un pilote PostgreSQL tiers (psqlODBC) fonctionne aussi sur une telle instance (chapitre 30).

29.6 Limites#

  • Pas de 32 bits : le pilote est livré en 64 bits seulement (Windows x64, macOS Apple silicon, Linux 64 bits). Les applications 32 bits ne le voient pas (29.1).
  • Curseur en avant seul : pas de défilement ni de curseur modifiable. SQLFetchScroll n'accepte que SQL_FETCH_NEXT. Un autre type de curseur demandé par l'application est remplacé par le curseur en avant, avec l'avertissement 01S02 (option modifiée).
  • Niveaux : fonctions ODBC Core et niveau 1 ; pas de niveau 2 (pas de SQLSetPos, de SQLBulkOperations, de SQLBrowseConnect). Les mises à jour se font en SQL (INSERT, UPDATE, DELETE).
  • Un seul flux réseau par connexion : une seconde instruction exécutée alors qu'un SELECT est à moitié lu fait tamponner en mémoire le reste du premier résultat ; les curseurs entrelacés et le COMMIT avec curseur ouvert fonctionnent, mais un très gros résultat laissé à moitié lu occupe de la mémoire.
  • Non pris en charge : paramètres de sortie (SQL_PARAM_OUTPUT, {? = call}), données envoyées au vol avec PARAMSET_SIZE > 1, signets, descripteurs d'application explicites liés à une instruction.
  • Heures : une valeur TIME négative ou supérieure à 24 h lue en SQL_C_TYPE_TIME est rendue sans signe ; la lire en SQL_C_CHAR donne la valeur exacte.
  • Annulation : les fonctions de catalogue (SQLTables, SQLColumns…) ne sont pas annulables.
  • Instance en langage PostgreSQL (29.5) : résultats en texte (pas de format binaire) ; pas de lastrowid du protocole (utiliser INSERT … RETURNING) ; SQLDescribeParam ne décrit pas les types des paramètres ; la nullabilité d'une colonne calculée est annoncée SQL_NULLABLE ; COPY n'est pas disponible par ODBC (requête simple seulement, voir 30.11).
  • Catalogue : le schéma ODBC est toujours vide ; les index du serveur sont tous de type hachage ; les colonnes AUTO_INCREMENT ne sont pas signalées par SQLColumns.
  • Authentification : protocole hérité, mot de passe natif et SHA-2 (pas ed25519) ; protocole PostgreSQL, SCRAM-SHA-256 et mot de passe en clair (29.5).
  • TLS : pas de clé privée du client protégée par mot de passe .
  • Fenêtre de configuration : pas de boîte de dialogue MIRAJ dans odbcad32.exe (29.3).
  • Dépendances : l'annulation d'une requête (SQLCancel) ouvre une seconde connexion et envoie KILL QUERY : le compte doit avoir le droit de tuer ses propres requêtes (instance en langage PostgreSQL : demande d'annulation du protocole, sans droit particulier).
  • Transactions : AUTOCOMMIT et les niveaux d'isolation sont ceux de MIRAJ (chapitre 14).
  • Les limites du serveur s'appliquent aussi : types non pris en charge, instructions non reconnues.

29.7 Désinstallation#

Windows#

Désinstaller MIRAJ depuis Paramètres → Applications (2.2) : l'assistant retire miraj_odbc.dll et la déclaration du pilote (la clé MIRAJ ODBC Driver et la valeur de ODBC Drivers). Les sources de données créées par l'utilisateur restent dans le registre (elles ne fonctionnent plus) ; les supprimer dans odbcad32.exe. Après une installation par zip, retirer la déclaration avant de supprimer le dossier :

.\Retirer-ODBC.ps1

macOS#

La désinstallation d'un .pkg n'est pas gérée par macOS : retirer le pilote à la main, dans un terminal.

sudo /usr/local/miraj-express/bin/miraj-odbc-unregister.sh    # retire la section des odbcinst.ini
sudo rm /usr/local/miraj-express/lib/libmiraj_odbc.dylib

Le script ne touche qu'à la section [MIRAJ ODBC Driver] ; les autres pilotes et les sources de données (odbc.ini) restent. Le reste de MIRAJ se désinstalle comme décrit en 21.14.

Linux#

sudo /opt/miraj/odbc/unregister.sh               # retire la section de odbcinst.ini

puis supprimer le dossier décompressé.

29.8 Référence : fonctions, attributs et informations#

Fonctions ODBC#

Le pilote exporte chaque fonction en deux variantes quand elle prend du texte : sans suffixe (UTF-8, en entrée comme en sortie) et W (UTF-16). SQLGetFunctions annonce exactement les fonctions ci-dessous.

FamilleFonctions
HandlesSQLAllocHandle, SQLFreeHandle, SQLFreeStmt, SQLSetEnvAttr, SQLGetEnvAttr
ConnexionSQLConnect, SQLDriverConnect, SQLDisconnect, SQLSetConnectAttr, SQLGetConnectAttr, SQLGetInfo, SQLGetFunctions, SQLNativeSql, SQLEndTran
ExécutionSQLPrepare, SQLExecute, SQLExecDirect, SQLBindParameter, SQLNumParams, SQLDescribeParam, SQLParamData, SQLPutData, SQLCancel, SQLCancelHandle, SQLSetStmtAttr, SQLGetStmtAttr, SQLSetCursorName, SQLGetCursorName
RésultatsSQLNumResultCols, SQLDescribeCol, SQLColAttribute, SQLBindCol, SQLFetch, SQLFetchScroll (SQL_FETCH_NEXT), SQLGetData, SQLRowCount, SQLMoreResults, SQLCloseCursor
DescripteursSQLGetDescField, SQLSetDescField, SQLGetDescRec, SQLSetDescRec, SQLCopyDesc
CatalogueSQLTables, SQLColumns, SQLPrimaryKeys, SQLForeignKeys, SQLStatistics, SQLSpecialColumns, SQLProcedures, SQLProcedureColumns, SQLTablePrivileges, SQLColumnPrivileges, SQLGetTypeInfo
DiagnosticsSQLGetDiagRec, SQLGetDiagField

Exécution. SQLExecDirect sans paramètre envoie le texte tel quel ; avec des paramètres, ou par SQLPrepare / SQLExecute, l'instruction est préparée par le serveur (valeurs typées) ; une instruction que le serveur ne sait pas préparer passe automatiquement par la substitution des valeurs dans le texte, comme avec PREPONCLIENT=1. Les tableaux de paramètres (SQL_ATTR_PARAMSET_SIZE, liaison par colonne ou par ligne, vecteur d'état, SQL_ATTR_PARAMS_PROCESSED_PTR) et les données envoyées au vol (SQLParamData / SQLPutData) sont acceptés. Un SELECT est lu ligne à ligne au fil de SQLFetch ; un texte de plusieurs instructions ou un CALL rend un résultat par instruction (SQLMoreResults). La lecture par blocs (SQL_ATTR_ROW_ARRAY_SIZE, SQL_ATTR_ROWS_FETCHED_PTR, SQL_ATTR_ROW_STATUS_PTR, liaison par colonne ou par ligne, SQL_ATTR_ROW_BIND_OFFSET_PTR) et SQLGetData sur toute colonne, dans n'importe quel ordre, y compris les colonnes liées, sont disponibles.

Catalogue. Les fonctions de catalogue lisent information_schema du serveur. Le catalogue ODBC est la base MIRAJ (TABLE_CAT) ; sans catalogue donné, la base courante sert de défaut, et toutes les bases sans base courante. Avec SQL_ATTR_METADATA_ID désactivé (défaut), les noms de table, de colonne et de procédure sont des motifs (%, _, échappement \) ; activé, ce sont des identifiants. SQLPrimaryKeys rend la clé sous le nom PRIMARY.

Séquences d'échappement#

ODBCLangage MIRAJLangage PostgreSQL
{d '2026-09-15'}'2026-09-15''2026-09-15'::date
{t '10:11:12'}'10:11:12''10:11:12'::time
{ts '2026-09-15 10:11:12'}'2026-09-15 10:11:12''2026-09-15 10:11:12'::timestamp
{fn UCASE(x)}UCASE(x)UCASE(x)
{fn CONVERT(x, SQL_INTEGER)}CAST(x AS SIGNED)CAST(x AS integer)
{fn TIMESTAMPADD(SQL_TSI_DAY, …)}SQL_TSI_DAY → DAYidem
{oj a LEFT OUTER JOIN b ON …}a LEFT OUTER JOIN b ON …idem
{call p(?, ?)}CALL p(?, ?)idem
{escape '\'}ESCAPE '\\'ESCAPE '\'

Les littéraux et les commentaires ne sont jamais modifiés. SQL_ATTR_NOSCAN à SQL_NOSCAN_ON désactive la traduction.

Types de données#

Colonne MIRAJType SQL ODBC
TINYINTSQL_TINYINT
SMALLINT, YEARSQL_SMALLINT
MEDIUMINT, INTSQL_INTEGER
BIGINTSQL_BIGINT
FLOATSQL_REAL
DOUBLESQL_DOUBLE
DECIMAL(p,s)SQL_DECIMAL (précision et échelle de la colonne)
DATESQL_TYPE_DATE
TIMESQL_TYPE_TIME
DATETIME, TIMESTAMPSQL_TYPE_TIMESTAMP
BIT(1)SQL_BIT (BIT(n) : SQL_BINARY)
CHAR, ENUM, SETSQL_WCHAR
VARCHARSQL_WVARCHAR
TEXT et textes longsSQL_WLONGVARCHAR
BINARYSQL_BINARY
VARBINARYSQL_VARBINARY
BLOB, géométriesSQL_LONGVARBINARY

Les textes sont annoncés en Unicode (le serveur envoie de l'UTF-8) ; leur longueur est comptée en caractères. Sous ODBC 2 (SQL_ATTR_ODBC_VERSION), les dates sont SQL_DATE, SQL_TIME et SQL_TIMESTAMP. Une valeur binaire lue en SQL_C_CHAR donne sa représentation hexadécimale ; SQL_C_NUMERIC prend la précision et l'échelle du descripteur de l'application quand elles y sont fixées, sinon celles de la colonne.

Attributs#

NiveauAttributEffet
ConnexionSQL_ATTR_AUTOCOMMITSET autocommit
ConnexionSQL_ATTR_TXN_ISOLATIONSET SESSION TRANSACTION ISOLATION LEVEL (les quatre niveaux ODBC)
ConnexionSQL_ATTR_ACCESS_MODESET SESSION TRANSACTION READ ONLY ou READ WRITE
ConnexionSQL_ATTR_CURRENT_CATALOGUSE base (lecture : base courante)
ConnexionSQL_ATTR_LOGIN_TIMEOUT, SQL_ATTR_CONNECTION_TIMEOUTdélais de connexion et de session, à défaut des mots de la chaîne (29.2)
ConnexionSQL_ATTR_CONNECTION_DEADlecture seule : la connexion répond-elle encore
ConnexionSQL_ATTR_METADATA_ID, SQL_ATTR_ODBC_CURSORS, SQL_ATTR_QUIET_MODE, SQL_ATTR_PACKET_SIZE, SQL_ATTR_TRACE, SQL_ATTR_TRACEFILEmémorisés
InstructionSQL_ATTR_QUERY_TIMEOUTdélai de l'instruction, appliqué par le serveur (max_statement_time) ; dépassé : HYT00
InstructionSQL_ATTR_MAX_ROWS, SQL_ATTR_MAX_LENGTHlignes rendues au plus, octets rendus au plus par valeur
InstructionSQL_ATTR_NOSCANtraduction des séquences d'échappement
InstructionSQL_ATTR_ROW_ARRAY_SIZE, SQL_ATTR_ROW_BIND_TYPE, SQL_ATTR_ROW_BIND_OFFSET_PTR, SQL_ATTR_ROW_STATUS_PTR, SQL_ATTR_ROWS_FETCHED_PTRlecture par blocs
InstructionSQL_ATTR_PARAMSET_SIZE, SQL_ATTR_PARAM_BIND_TYPE, SQL_ATTR_PARAM_BIND_OFFSET_PTR, SQL_ATTR_PARAM_STATUS_PTR, SQL_ATTR_PARAMS_PROCESSED_PTRtableaux de paramètres
InstructionSQL_ATTR_CURSOR_TYPE, SQL_ATTR_CONCURRENCY, SQL_ATTR_CURSOR_SCROLLABLE, SQL_ATTR_CURSOR_SENSITIVITY, SQL_ATTR_USE_BOOKMARKScurseur en avant seul, en lecture seule ; une autre valeur est remplacée avec l'avertissement 01S02

SQLEndTran envoie COMMIT ou ROLLBACK à la connexion, ou à toutes celles d'un environnement. Les attributs fixés avant la connexion sont appliqués dès qu'elle est établie. Une valeur invalide rend HY024.

Informations (SQLGetInfo)#

Principales valeurs sur une instance en langage MIRAJ (celles d'une instance en langage PostgreSQL sont en 29.5) :

InformationValeur
SQL_DRIVER_NAMEmiraj_odbc.dll, libmiraj_odbc.dylib ou libmiraj_odbc.so
SQL_DRIVER_ODBC_VER03.80
SQL_DBMS_NAMEMIRAJ
SQL_DBMS_VERversion annoncée par le serveur, au format dd.dd.dddd
SQL_ODBC_INTERFACE_CONFORMANCESQL_OIC_LEVEL1
SQL_SQL_CONFORMANCESQL_SC_SQL92_ENTRY
SQL_IDENTIFIER_QUOTE_CHAR`
SQL_CATALOG_TERM, SQL_CATALOG_NAMEdatabase, Y
SQL_DATABASE_NAMEbase courante
SQL_DATA_SOURCE_NAME, SQL_SERVER_NAMEnom de la source (DSN), serveur de la connexion
SQL_TXN_CAPABLESQL_TC_DDL_COMMIT
SQL_DEFAULT_TXN_ISOLATIONSQL_TXN_SERIALIZABLE
SQL_TXN_ISOLATION_OPTIONles quatre niveaux
SQL_CURSOR_COMMIT_BEHAVIOR, SQL_CURSOR_ROLLBACK_BEHAVIORSQL_CB_PRESERVE
SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1SQL_CA1_NEXT
SQL_GETDATA_EXTENSIONSSQL_GD_ANY_COLUMN, SQL_GD_ANY_ORDER, SQL_GD_BOUND
SQL_DATETIME_LITERALSdates, heures et horodatages SQL-92
SQL_DATA_SOURCE_READ_ONLYN

Diagnostics#

SQLGetDiagRec et SQLGetDiagField rendent le SQLSTATE, le code natif et le message. Une erreur du serveur garde son SQLSTATE et son code MIRAJ (42S02 et 1146 pour une table inconnue) et son message est préfixé [MIRAJ][ODBC Driver][MIRAJ Server] ; une erreur du pilote est préfixée [MIRAJ][ODBC Driver] (code natif 0). SQLSTATE propres au pilote :

SQLSTATECas
08001connexion impossible, ou refus TLS
08S01liaison rompue
HYT00délai de connexion, ou délai de l'instruction (SQL_ATTR_QUERY_TIMEOUT) dépassé
HYT01délai de lecture ou d'écriture de la session dépassé
HY008instruction annulée (SQLCancel)
01S02option de curseur remplacée
01004texte tronqué au tampon