Aller au contenu principal

Séquences et recherches

Deux motifs de requête reviennent assez souvent pour que Liberty livre un assistant dédié à chacun :

MotifButSQL typique
SéquenceCalculer la prochaine valeur pour une colonne id.SELECT COALESCE(MAX(<col>), 0) + 1 AS NEXT_ID FROM <table>
RechercheFournir 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.

Nouvelle séquence · [connectors.crm]Tablepublic.customers ▾Colonne clé(MAX retourne la suivante +1)customer_id ▾ · INT4WHERE facultatifex. region = :regionNom de la requêteget_customer_id_from_customers_getIdentifiant de séquenceget_customer_id_from_customersDescriptionRécupérer customer_id depuis customersAPERÇU SQL EN DIRECT · modifiableSELECT COALESCE(MAX(customer_id), 0) + 1 AS NEXT_IDFROM public.customers

Champ par champ

ChampNotes
TableLa 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 facultatifLe 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êteAuto-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équenceLa clé sous [sequences.*] dans le dictionnaire. Auto-suggéré comme get_<keyCol>_from_<table>.
DescriptionApparaî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é

FichierEntré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.

Nouvelle recherche · [connectors.crm]Tablepublic.regions ▾Colonne valeur(le code stocké sur la ligne)region_code ▾ · VARCHAR(8)Colonne libellé(la description montrée à l'utilisateur)region_name ▾ · VARCHAR(60)WHERE facultatifactive = 'Y'Nom de la requêteget_regions_getIdentifiant de rechercheget_regionsAPERÇU SQL EN DIRECT · modifiableSELECT region_code, region_nameFROM public.regionsWHERE active = 'Y' ORDER BY region_name

Champ par champ

ChampNotes
TableLa source des lignes de la liste déroulante.
Colonne valeurLe 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 facultatifCorps 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êteAuto-suggéré comme get_<table>_get.
Identifiant de rechercheLa clé sous [lookups.*] dans le dictionnaire. Auto-suggéré comme get_<table>.
DescriptionApparaî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é

FichierEntré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