vai al contenuto principale

Attributi derivati

Un attributo derivato è definito a partire da altri attributi; il suo valore non è persistito nel database, bensì è calcolato a runtime.

Nella lista degli attributi di una classe, gli attributi derivati sono contraddistinti dal prefisso /.

Passando il mouse su un attributo derivato, un tooltip mostra l’espressione che lo definisce. Selezionandolo, tutti gli attributi usati per definirlo sono cerchiati in rosso; viceversa, se viene selezionato un attributo coinvolto in almeno un’espressione, tutti gli attributi derivati calcolati a partire da esso sono cerchiati in blu.

Tooltip attributi derivati

Nell’esempio in figura, il valore dell’attributo /weight sulla classe Shipping_component è calcolato moltiplicando il valore degli attributi quantity e /unit_weight (cerchiati in rosso); a partire da esso viene poi calcolato il valore dell’attributo /total_weight sulla classe Shipping (cerchiato in blu), che riporta il peso totale aggregato su tutti gli oggetti Shipping_component associati a uno Shipping.

È possibile modificare l’espressione utilizzata in qualunque attributo derivato facendo click destro su di esso e scegliendo Edit expression dal menu contestuale.

Restrizioni #

Gli attributi derivati dipendono da altri attributi presenti nel database. Per questo motivo, con essi non è possibile compiere alcune delle operazioni normalmente consentite con gli attributi nativi:

Tipologie #

Livebase supporta due tipi di attributo derivato:

  • Math, calcolato mediante un’espressione matematica che può contenere riferimenti ad altri attributi presenti nella stessa classe;
  • Query, calcolato in base al valore di un attributo presente in una classe correlata (collegata con una relazione o un cammino di relazioni).

Attributi math #

Un attributo math è un attributo il cui valore è calcolato mediante un’espressione matematica definita attraverso il Math expression editor.

Creare un attributo math #

Fai click destro su una classe per aprire il suo Class menu e seleziona New derived attribute > Math. Il Math expression editor si apre ed è possibile scrivere l’espressione matematica per calcolare l’attributo.

Crea un attributo math

Il Math expression editor #

Il Math expression editor consente di definire espressioni, nelle quali è possibile referenziare il valore degli altri attributi presenti nella stessa classe.

Il Math expression editor

Math expression editor

Le icone in basso a destra consentono di inserire gli elementi dell’espressione scegliendoli direttamente da un menu a tendina. Vediamole in dettaglio:

  • apre la lista degli attributi della classe per cui si sta definendo l’espressione; sono inclusi anche gli attributi derivati definiti in precedenza e gli attributi di piattaforma abilitati;
  • apre la lista globale delle classi Enum e per ognuna mostra i suoi letterali; è disabilitata se nel modello sono assenti classi Enum;
  • apre la lista globale delle classi Singleton e per ognuna mostra i suoi attributi; è disabilitata se nel modello sono assenti classi Singleton;
  • apre la lista delle User properties, ovvero informazioni relative all’utente corrente della Cloudlet al momento in cui l’espressione è valutata. Queste corrispondono agli attributi predefiniti della classe _User (come username, timezone, etc.). Nell’espressione, l’utente corrente è rappresentato dalla variabile __CurrentUser;
  • apre la lista delle System properties, informazioni di sistema come data e ora correnti, che dipendono dalla configurazione della Cloudlet. Nell’espressione, il sistema è rappresentato dalla variabile __System;
  • apre una lista di costanti;
  • apre una lista contenente operatori matematici e logici;
  • apre il function picker.

Function Picker #

Il Function picker raccoglie un insieme di funzioni di utilità per definire espressioni, tra cui funzioni insiemistiche / matematiche o operatori su date e stringhe. Selezionando una funzione dalla lista ne viene mostrata la descrizione, che include i parametri richiesti in input con i corrispondenti tipi di dato. Cliccando su Show Examples è possibile consultare esempi di utilizzo di ciascuna funzione.

Designer expression editor function picker

Esempio di attributo math #

Posizionando il cursore sopra un attributo math, compare un tooltip che mostra l’espressione che lo definisce.

Attributo math

Un attributo math e l’espressione utilizzata per calcolarlo

Nell’esempio mostrato in figura è stato selezionato l’attributo /age, che determina l’età di un impiegato (Employee); per fare ciò, esso utilizza l’attributo nativo date_of_birth per calcolare la differenza in anni tra la data attuale e la data di nascita dell’impiegato. Vediamo ora nel dettaglio come avviene questo calcolo.

L’espressione utilizza la funzione dateDiff(d1,d2,calendarField), dove d2 è il termine dell’espressione che viene sottratto a d1:

  • la data corrente (__System.date) è stata inserita al posto di d1, selezionando date: date dalle proprietà di sistema;
  • date_of_birth è stato inserito al posto di d1, selezionandolo dalla lista degli attributi;
  • poiché l’età è normalmente espressa in anni, l’espressione deve restituire come risultato un numero intero (integer) che esprima la differenza tra le due date in termini di anni; per fare ciò, il campo calendarField è stato sostituito con field.year.

Al termine dell’inserimento, il messaggio Expression has been validated as INTEGER conferma che l’espressione utilizzata è valida.

Nota che /full_name è anch’esso un attributo math. Questo attributo è stato creato definendo un Object title su più attributi. Maggiori informazioni su questa operazione sono disponibili nel paragrafo dedicato.

Attributi query #

Un attributo query è calcolato a partire dal valore di un attributo presente su una classe differente da quella su cui è definito e collegata con una relazione o un cammino di relazioni alla classe d’interesse. L’attributo puntato dalla query è detto attributo target, mentre il percorso di relazioni attraversate è detto Path.

Selezionando un attributo query, l’attributo target corrispondente viene evidenziato in rosso. Viceversa, selezionando un attributo coinvolto in una query, vengono cerchiati in blu tutti gli attributi definiti a partire da esso. Questo meccanismo ci consente di conoscere il cammino compiuto dalla query per raggiungere l’attributo.

Designer employee team query attribute red tooltip

Designer employee team query attribute blue

Ci possono essere più percorsi che collegano la classe su cui è definita la query e la classe dell’attributo target. La raggiungibilità delle classi non dipende dalla navigabilità dei ruoli: è sufficiente che esista una relazione tra due classi affinché essa sia percorribile in entrambi i versi.

Posizionando il cursore sopra un attributo query, compare un tooltip che mostra l’espressione che lo definisce, come mostra la seguente figura:

Un attributo query

Un attributo query

Nell’esempio, invece di persistere l’informazione relativa alla città di residenza di un impiegato (Employee) utilizzando un attributo nativo, si è scelto di modellare le città in maniera indipendente, come oggetti della classe City. Per associare un impiegato a una città è dunque possibile utilizzare l’attributo derivato /city, che ha come target l’attributo name presente nella classe City.

Creare un attributo query #

Fai click destro su una classe per aprire il suo Class menu e seleziona New derived attribute > Query.

In alternativa, seleziona l’attributo target, trascinalo e rilascialo sulla classe dove vuoi creare la query e seleziona Link here dal menu contestuale.

Crea un attributo query

Il Designer sceglie il nome di default di una query in questo modo:

  • se il ruolo ha cardinalità a uno, il nome di default è nomeRuolo_nomeAttributo;
  • se il ruolo ha cardinalità a molti, il nome di default include in testa la funzione di aggregazione usata;
  • in entrambi i casi, se l’attributo source è l’unico attributo di quella classe, nomeAttributo viene omesso.

Il Query expression editor #

Sotto la sezione Path è presente una lista di tutti gli attributi raggiungibili dalla classe di partenza navigando i suoi ruoli . Da qui è possibile selezionare l’attributo target della query espandendone il percorso. Gli attributi della classe di partenza non sono selezionabili.

Ciascun tipo di attributo è raffigurato con un’icona diversa: attributi nativi: , attributi math: , attributi query: .

Il path selezionato dalla query è riportato anche in forma testuale (es. city_.name). Questa stringa può essere editata per modificare manualmente il path della query.

Il Query expression editor

Query expression editor

Query su valori multipli #

Una query il cui percorso attraversa almeno un ruolo a molti recupererà valori multipli per l’attributo puntato, uno per ogni oggetto della classe interessato dalla relazione; è dunque necessario definire in che modo aggregare questo insieme di valori per rappresentarli in un unico attributo (ad es. concatenando i valori, sommandoli, selezionando il valore massimo, etc.). A seconda del tipo di dato dell’attributo puntato, la tendina Aggregation function presenta diverse opzioni; nella tabella sono riportati tutte le funzioni disponibili:

FunzioneSignificato
Count allL’attributo contiene il conteggio dei record trovati.
Count distinctCome sopra, ma non include record con valori duplicati.
Concat (comma separated)L’attributo è una stringa contenente tutti i valori dei record trovati, separati tra loro da virgole.
Concat distinct (comma separated)Come sopra, ma non include record con valori duplicati.
Max / MinRestituisce il valore massimo/minimo tra i record trovati.

Se la sorgente è un attributo numerico sono disponibili ulteriori operatori:

FunzioneSignificato
SumRestituisce la somma dei valori dei record trovati.
AverageRestituisce il valore medio tra quelli dei record trovati.
Standard deviationRestituisce la deviazione standard tra i valori dei record trovati.

Per attributi booleani abbiamo inoltre:

FunzioneSignificato
Logical ANDRestituisce TRUE se tutti i record sono veri, FALSE altrimenti
Logical ORRestituisce TRUE se almeno un record è vero, FALSE altrimenti

Query con condizioni di filtraggio #

È possibile filtrare i record trovati dalla query in modo analogo a quanto avviene in una clausola WHERE SQL, definendo una condizione di filtraggio (filtering condition) mediante un’espressione; ciò è utile soprattutto quando la query recupera valori multipli.

Cliccando sul pulsante Add filter del Query expression editor si apre un editor sostanzialmente identico al Math expression editor, con una importante differenza: l’espressione di una filtering condition deve sempre restituire un valore booleano (TRUE oppure FALSE). Se l’espressione è corretta, l’editor mostra il messaggio Expression has been validated as BOOLEAN e consente di confermare l’inserimento.

Quando l’espressione utilizza direttamente un solo attributo booleano, il risultato dipenderà semplicemente dal valore assunto da tale attributo; in casi del genere è possibile evitare di scrivere <AttributeName> = true e usare direttamente <AttributeName>.

Esempio di attributo query #

Nel seguente esempio vogliamo determinare quanti progetti (Project) sono stati portati a termine da un impiegato (Employee).

Query complessa

Una query con funzione di aggregazione e condizione di filtraggio

L’attributo completed su Project rappresenta lo stato del progetto: il valore TRUE equivale a dire che è stato completato.

La query /completed_projects nella classe Employee punta verso l’attributo name di Project. L’associazione ha cardinalità a molti (un impiegato può essere assegnato a più progetti) quindi occorre aggregare i dati con un operatore per poterli rappresentare con un unico attributo. Dal Query expression editor è stata dunque selezionata come Aggregation function l’opzione COUNT_DISTINCT. In questo modo è stato ottenuto il conteggio di tutti i progetti assegnati a un impiegato.

Per completare la definizione della query è necessario escludere dal conteggio tutti i progetti non ancora completati (per i quali l’attributo completed ha dunque valore FALSE). Per fare ciò, abbiamo impostato la condizione Project.completed=true.