Séquences et recherches
Deux motifs de requête reviennent assez souvent pour que Liberty livre un assistant dédié à chacun :
| Motif | But | SQL typique |
|---|---|---|
| Séquence | Calculer la prochaine valeur pour une colonne id. | SELECT COALESCE(MAX(<col>), 0) + 1 AS NEXT_ID FROM <table> |
| Recherche | Fournir des paires valeur + libellé à une liste déroulante liée à une colonne d'écran. | SELECT <value>, <label> FROM <table> ORDER BY <label> |
Tous deux passent par la fenêtre Scaffold — cochez une table, cochez la ou les colonnes, obtenez un aperçu SQL en direct, enregistrez. L'enregistrement écrit deux fichiers atomiquement : la requête dans le connecteur et l'entrée correspondante dans le dictionnaire.
Où les trouver
Paramètres → Connecteurs → sélectionnez un connecteur → barre de modes : Séquences (ou Recherches) → + Ajouter une séquence (ou + Ajouter une recherche).
La fenêtre s'ouvre, introspecte le pool et liste les schémas/tables.
Séquence — générer le prochain id
Une séquence dans Liberty est une requête qui retourne un nombre — le prochain id à attribuer à une nouvelle ligne. Elle alimente la règle SEQUENCE du dictionnaire : un champ d'écran marqué SEQUENCE lit la requête de séquence à chaque ouverture du dialogue pour un INSERT.
Champ par champ
| Champ | Notes |
|---|---|
| Table | La source. Le sélecteur de schéma apparaît sur les pools multi-schémas. |
| Colonne clé | La colonne dont MAX(...) + 1 donne la valeur suivante. L'introspection du pool liste chaque colonne avec son type SQL. |
| WHERE facultatif | Le corps d'une clause WHERE (sans le mot-clé). Utilisez des paramètres :placeholder si le filtre doit varier par appel — par ex. region = :region pour cadrer la séquence par région. |
| Nom de la requête | Auto-suggéré comme get_<keyCol>_from_<table>_get (raccourci par slugify). Surchargez librement. Le suffixe _get est une convention — les séquences sont des requêtes de lecture. |
| Identifiant de séquence | La clé sous [sequences.*] dans le dictionnaire. Auto-suggéré comme get_<keyCol>_from_<table>. |
| Description | Apparaît dans les listages et infobulles. Pré-remplie comme « Récupérer <col> depuis <table> ». |
| SQL généré | Aperçu en direct. Modifiable — vos modifications tiennent jusqu'à ce que vous changiez les entrées colonne/table/WHERE, ce qui restaure la forme générée. |
Ce qui est enregistré
| Fichier | Entrée |
|---|---|
| Fichier connecteur | { name = "<queryName>", type = "sequence", sql = "..." } |
| Fichier dictionnaire | [connectors.<conn>.sequences.<seqId>] query = "<queryName>", dd_id = "<keyCol>", description facultative |
L'entrée du dictionnaire est ce que la règle SEQUENCE consulte. Une colonne d'écran marquée par la règle SEQUENCE avec sequence = "<seqId>" appelle cette requête à l'ouverture du dialogue pour un INSERT et pré-remplit le champ avec le résultat.
Note sur la concurrence
SELECT MAX(...) + 1 n'est pas atomique — deux INSERT simultanés peuvent lire le même MAX et produire une collision. Acceptable quand :
- Votre INSERT se déroule derrière une interface transactionnelle (l'utilisateur voit un dialogue à la fois).
- La colonne id porte une contrainte d'unicité au niveau base qui rejettera le doublon (l'écran rapporte l'erreur et l'opérateur recommence).
Pour des charges à forte concurrence, définissez la colonne comme une SEQUENCE de base (SEQUENCE Postgres, SEQUENCE Oracle, colonne Identity) et faites retourner nextval(...) à la requête de séquence — la base garantit l'unicité.
Recherche — alimenter les options d'une liste déroulante
Une recherche dans Liberty est une requête qui retourne des lignes de paires (valeur, libellé) — la source d'une liste déroulante sur une colonne d'écran. Elle alimente la règle LOOKUP du dictionnaire : une colonne marquée LOOKUP avec lookup = "<id>" est rendue comme une liste déroulante alimentée par la requête de recherche.
Champ par champ
| Champ | Notes |
|---|---|
| Table | La source des lignes de la liste déroulante. |
| Colonne valeur | Le code stocké sur la ligne quand l'utilisateur choisit une option. Le type compte — une colonne valeur VARCHAR(8) attend une colonne cible VARCHAR sur l'écran. |
| Colonne libellé | Le texte montré à l'utilisateur. Choisissez Identique à la colonne valeur quand la valeur est déjà lisible (par ex. code pays affiché tel quel). |
| WHERE facultatif | Corps d'une clause WHERE sans le mot-clé. Motifs courants : active = 'Y', deleted_at IS NULL. Utilisez des paramètres :placeholder pour des recherches en cascade (par ex. n'afficher que les régions du pays sélectionné — voir Liaison de paramètres). |
| Nom de la requête | Auto-suggéré comme get_<table>_get. |
| Identifiant de recherche | La clé sous [lookups.*] dans le dictionnaire. Auto-suggéré comme get_<table>. |
| Description | Apparaît dans les listages et infobulles. |
| SQL généré | Aperçu en direct, modifiable. Le ORDER BY <label> est ajouté automatiquement — retirez-le si les lignes ont un ordre intrinsèque. |
Ce qui est enregistré
| Fichier | Entrée |
|---|---|
| Fichier connecteur | { name = "<queryName>", type = "lookup", sql = "..." } |
| Fichier dictionnaire | [connectors.<conn>.lookups.<lookupId>] query = "<queryName>", value = "<valueCol>", label = "<labelCol>", description facultative |
Recherches en cascade
Quand la liste déroulante doit être filtrée par un autre champ du même écran — par ex. Rôle dépend d'Application — la recherche nécessite un :placeholder dans la clause WHERE, et la colonne de l'écran déclare un filter_from qui référence le parent. Le câblage côté écran se trouve dans Concepts → Conditions de formulaire (jusqu'à la sortie de la section Construire les écrans) ; la requête de recherche elle-même a juste besoin du :placeholder.
SELECT role_id, role_name
FROM roles
WHERE app_id = :app_id
ORDER BY role_name
Et ensuite
- Liaison de paramètres — pour les séquences/recherches qui prennent des paramètres du contexte d'écran.
- Variantes SQL par dialecte — pour une recherche qui touche Postgres et Oracle.
- Concepts → Dictionnaire — la référence plus large :
SEQUENCE,LOOKUP,LOGIN,SYSDATEet les autres règles du dictionnaire.