API orientate ai dati

Le API orientate ai dati consentono di gestire l’intero modello dati.

Panoramica del modello dati

Adobe Campaign non offre un’API di lettura dedicata per entità (nessuna funzione getRecipient o getDelivery, ecc.). Utilizza i metodi di lettura e modifica dei dati QUERY & WRITER per accedere ai dati del modello.

Adobe Campaign consente di gestire le raccolte: le query consentono di recuperare un insieme di informazioni raccolte in tutta la base. A differenza dell'accesso in modalità SQL, le API di Adobe Campaign restituiscono una struttura XML anziché colonne di dati. Adobe Campaign crea quindi documenti compositi con tutti i dati raccolti.

Questa modalità operativa non offre la mappatura uno-a-uno tra gli attributi e gli elementi dei documenti XML e le colonne delle tabelle nel database.

I documenti XML sono memorizzati nei campi di tipo MEMO del database.

Descrizione del modello

È necessario avere familiarità con il modello dati Adobe Campaign per poter gestire i campi del database negli script.

Per una presentazione del modello dati, fare riferimento alla descrizione del modello dati Adobe Campaign.

Per generare la struttura, fai riferimento a questo articolo: Come generare un modello dati o un dizionario dati.

Query e processo di scrittura

Lo schema di introduzione seguente descrive gli scambi di basso livello per la lettura (ExecuteQuery) e la scrittura (Writer) tra il database e il cliente (pagine web o console client Adobe Campaign).

ExecuteQuery

Per colonne e condizioni, è possibile utilizzare Query.

Questo consente di isolare il SQL sottostante. Il linguaggio di query non dipende dal motore sottostante: alcune funzioni verranno nuovamente mappate, che potrebbero generare diversi ordini SELECT SQL.

Per ulteriori informazioni, consulta Esempio sul metodo 'ExecuteQuery' dello schema 'xtk:queryDef'.

Il metodo ExecuteQuery è presentato in ExecuteQuery (xtk:queryDef).

Scrivi

I comandi di scrittura consentono di scrivere documenti semplici o complessi, con voci in una o più tabelle della base.

Le API transazionali consentono di gestire le riconciliazioni tramite il comando updateOrInsert : un comando consente di creare o aggiornare i dati. Puoi anche configurare l'unione delle modifiche (unisci): questa modalità operativa consente di autorizzare aggiornamenti parziali.

La struttura XML offre una visualizzazione logica dei dati e consente di analizzare la struttura fisica della tabella SQL.

Il metodo Write è presentato in Write / WriteCollection (xtk:session).

ExecuteQuery (xtk:queryDef)

Questo metodo consente di eseguire query dai dati associati a uno schema. Richiede una stringa di autenticazione (deve essere effettuato l'accesso) e un documento XML che descrive la query da inviare come parametri. Il parametro return è un documento XML contenente il risultato della query nel formato dello schema a cui fa riferimento la query.

Definizione del metodo "ExecuteQuery" nello schema "xtk:queryDef":

<method name="ExecuteQuery" const="true">
  <parameters>
    <param desc="Output XML document" name="output" type="DOMDocument" inout="out"/>
  </parameters>
</method>
NOTA

Questo è un metodo "const". I parametri di input sono inclusi in un documento XML nel formato dello schema "xtk:queryDef".

Formato del documento XML della query di input

La struttura del documento XML della query è descritta nello schema "xtk:queryDef". Questo documento descrive le clausole di una query SQL: "select", "where", "order by", "group by", "have".

<queryDef schema="schema_key" operation="operation_type">
  <select>
    <node expr="expression1">
    <node expr="expression2">
    ...
  </select>
  <where> 
    <condition expr="expression1"/> 
    <condition expr="expression2"/>
    ... 
  </where>
  <orderBy>
    <node expr="expression1">
    <node expr="expression2">
    ...
  </orderBy>
  <groupBy>
    <node expr="expression1">
    <node expr="expression2">
    ...
  </groupBy>
  <having>
    <condition expr="expression1"/> 
    <condition expr="expression2"/>
    ...
  </having>
</queryDef>

È possibile definire una sottoquery ( <subquery> ) in un elemento <condition> . La sintassi di un <subquery> si basa sulla sintassi di un <querydef>.

Esempio di un <subquery> : </subquery>

<condition setOperator="NOT IN" expr="@id" enabledIf="$(/ignored/@ownerType)=1">
  <subQuery schema="xtk:operatorGroup">
     <select>
       <node expr="[@operator-id]" />
     </select>
     <where>
       <condition expr="[@group-id]=$long(../@owner-id)"/>
     </where>
   </subQuery>
</condition>  
  

Una query deve fare riferimento a uno schema iniziale dall'attributo schema .

Il tipo di operazione desiderata viene immesso nell'attributo operation e contiene uno dei seguenti valori:

  • get: recupera un record dalla tabella e restituisce un errore se i dati non esistono,
  • getIfExists: recupera un record dalla tabella e restituisce un documento vuoto se i dati non esistono,
  • seleziona: crea un cursore per restituire più record e restituisce un documento vuoto in assenza di dati,
  • conteggio: restituisce un conteggio di dati.

La sintassi XPath viene utilizzata per individuare i dati in base allo schema di input. Per ulteriori informazioni su XPaths, fare riferimento a Schemi di dati.

Esempio con l’operazione "get"

Recupera il cognome e il nome di un destinatario ( schema "nms:recipient") con un filtro sul messaggio di posta elettronica.

<queryDef schema="nms:recipient" operation="get">
  <!-- fields to retrieve -->
  <select>
    <node expr="@firstName"/>
    <node expr="@lastName"/>
  </select> 

  <!-- condition on email -->
  <where>  
    <condition expr="@email= 'john.doe@aol.com'"/>
  </where>
</queryDef>

Esempio con l'operazione "select"

Restituisce l’elenco dei destinatari filtrati in una cartella e il dominio di posta elettronica con un ordinamento decrescente in base alla data di nascita.

<queryDef schema="nms:recipient" operation="select">
  <select>
    <node expr="@email"/>
    <!-- builds a string with the concatenation of the last name and first name separated by a dash -->      
    <node expr="@lastName+'-'+@firstName"/>
    <!-- get year of birth date -->
    <node expr="Year(@birthDate)"/>
  </select> 

  <where>  
     <condition expr="[@folder-id] = 1234 and @domain like 'Adobe%'"/>
  </where>

  <!-- order by birth date -->
  <orderBy>
    <node expr="@birthDate" sortDesc="true"/> <!-- by default sortDesc="false" -->
  </orderBy>
</queryDef>

Le espressioni possono essere campi semplici o espressioni complesse come le operazioni aritmetiche o la concatenazione di stringhe.

Per limitare il numero di record da restituire, aggiungi l'attributo lineCount all'elemento <querydef>.

Per limitare a 100 il numero di record restituiti dalla query:

<queryDef schema="nms:recipient" operation="select" lineCount="100">
...

Per recuperare i successivi 100 record, esegui nuovamente la stessa query, aggiungendo l'attributo startLine .

<queryDef schema="nms:recipient" operation="select" lineCount="100" startLine="100">
...

Esempio con l’operazione "count"

Per contare il numero di record in una query:

<queryDef schema="nms:recipient" operation="count"">
  <!-- condition on the folder and domain of the e-mail -->
  <where>  
    <condition expr="[@folder-id] = 1234" and @domain like 'Adobe%'"/>
  </where>
</queryDef>
NOTA

Usiamo nuovamente la condizione dell’esempio precedente. Le clausole <select> e non vengono utilizzate. </select>

Raggruppamento dati

Per recuperare gli indirizzi di posta elettronica a cui si fa riferimento più volte:

<queryDef schema="nms:recipient" operation="select">
  <select>
    <node expr="@email"/>
    <node expr="count(@email)"/>
  </select>

  <!-- e-mail grouping clause -->
  <groupby>
    <node expr="@email"/>
  </groupby>

  <!-- grouping condition -->
  <having>
    <condition expr="count(@email) > 1"/>
  </having>

</queryDef>

La query può essere semplificata aggiungendo l'attributo groupBy direttamente al campo da raggruppare:

<select>
  <node expr="@email" groupBy="true"/>
</select>
NOTA

Non è più necessario compilare l'elemento <groupby>.

Bracketing in condizioni

Di seguito sono riportati due esempi di bracketing sulla stessa condizione.

  • La versione semplice in un’unica espressione:

    <where>
      <condition expr="(@age > 15 or @age <= 45) and  (@city = 'Newton' or @city = 'Culver City') "/>
    </where>
    
  • Versione strutturata con elementi <condition>:

    <where>
      <condition bool-operator="AND">
        <condition expr="@age > 15" bool-operator="OR"/>
        <condition expr="@age <= 45"/>
      </condition>
      <condition>
        <condition expr="@city = 'Newton'" bool-operator="OR"/>
        <condition expr="@city = 'Culver City'"/>
      </condition>
    </where>
    

È possibile sostituire l’operatore "OR" con l’operazione "IN" quando più condizioni si applicano allo stesso campo:

<where>
  <condition>
    <condition expr="@age IN (15, 45)"/>
    <condition expr="@city IN ('Newton', 'Culver City')"/>
  </condition>
</where>

Questa sintassi semplifica la query quando nella condizione vengono utilizzati più di due dati.

  • Link 1-1 o N1: quando la tabella ha la chiave esterna (il collegamento inizia dalla tabella), i campi della tabella collegata possono essere filtrati o recuperati direttamente.

    Esempio di filtro sull’etichetta della cartella:

    <where>
      <condition expr="[folder/@label] like 'Segment%'"/>
    </where>
    

    Per recuperare i campi della cartella dallo schema "nms:recipient":

    <select>
      <!-- label of recipient folder -->
      <node expr="[folder/@label]"/>
      <!-- displays the string count of the folder -->
      <node expr="partition"/>
    </select>
    
  • Collegamenti raccolta (1N): il filtraggio sui campi di una tabella di raccolta deve essere eseguito tramite l'operatore EXISTS o NOT EXISTS .

    Per filtrare i destinatari che si sono abbonati al servizio di informazione "Newsletter":

    <where>
      <condition expr="subscription" setOperator="EXISTS">
        <condition expr="@name = 'Newsletter'"/>
      </condition>
    </where>
    

    Il recupero diretto dei campi di un collegamento di raccolta dalla clausola <select> non è consigliato perché la query restituisce un prodotto cardinale. Viene utilizzato solo quando la tabella collegata contiene un solo record (ad esempio <node expr="">).

    Esempio sul collegamento della raccolta "abbonamento":

    <select>
      <node expr="subscription/@label"/>
    </select>
    

    È possibile recuperare un sotto-elenco contenente gli elementi di un collegamento di raccolta nella clausola <select>. Gli XPaths dei campi di riferimento sono contestuali dall'elemento di raccolta.

    Gli elementi di filtro ( <orderby> ) e di restrizione ( <where> ) possono essere aggiunti all’elemento di raccolta.

    In questo esempio, per ogni destinatario la query restituisce l'e-mail e l'elenco dei servizi di informazione a cui il destinatario si abbona:

    <queryDef schema="nms:recipient" operation="select">
      <select>
        <node expr="@email"/>
    
        <!-- collection table (unbound type) -->
        <node expr="subscription">  
          <node expr="[service/@label]"/>    
          <!-- sub-condition on the collection table -->
          <where>  
            <condition expr="@expirationDate >= GetDate()"/>
          </where>
          <orderBy>
            <node expr="@expirationDate"/> 
          </orderBy>
        </node>
      </select> 
    </queryDef>
    

Binding dei parametri della clausola "where" e "select"

Il binding dei parametri consente al motore di impostare i valori dei parametri utilizzati nella query. Questo è molto utile, in quanto il motore è responsabile dell'escape dei valori, e c'è il vantaggio aggiuntivo di una cache per i parametri da recuperare.

Quando viene creata una query, i valori "associati" vengono sostituiti da un carattere (? in ODBC, #[index]# in postgres…) nel corpo della query SQL.

<select>
  <!--the value will be bound by the engine -->
  <node expr="@startDate = #2002/02/01#"/>                   
  <!-- the value will not be bound by the engine but visible directly in the query -->
  <node expr="@startDate = #2002/02/01#" noSqlBind="true"/> 
</select>

Per evitare di eseguire il binding di un parametro, l'attributo "noSqlBind" deve essere compilato con il valore "true".

IMPORTANTE

Se la query include istruzioni "order-by" o "group-by", i motori di database non saranno in grado di "eseguire il binding" dei valori. È necessario inserire l'attributo @noSqlBind="true" nelle istruzioni "select" e/o "where" della query.

Suggerimento per la creazione delle query:

Per semplificare la sintassi di una query, puoi scrivere la query utilizzando l’editor di query generico nella console client di Adobe Campaign ( Tools/ Generic query editor… menu). Per eseguire questa operazione:

  1. Selezionare i dati da recuperare:

  2. Definisci la condizione del filtro:

  3. Esegui la query e premi CTRL+F4 per visualizzare il codice sorgente della query.

Formato del documento di output

Il parametro return è un documento XML nel formato dello schema associato alla query.

Esempio di ritorno dallo schema "nms:recipient" in un'operazione "get":

<recipient email="john.doe@adobe.com" lastName"Doe" firstName="John"/>

In un'operazione di selezione, il documento restituito è un'enumerazione di elementi:

<!-- the name of the first element does not matter -->
<recipient-collection>   
  <recipient email="john.doe@adobe.com" lastName"Doe" firstName="John"/>
  <recipient email="peter.martinez@adobe.com" lastName"Martinez" firstName="Peter"/>
  <recipient...
</recipient-collection>  

Esempio di documento restituito per l'operazione di tipo "count":

<recipient count="3"/>

Alias

Un alias consente di modificare la posizione dei dati nel documento di output. L'attributo alias deve specificare un XPath nel campo corrispondente.

<queryDef schema="nms:recipient" operation="get">
  <select>
    <node expr="@firstName" alias="@firstName"/>
    <node expr="@lastName"/>
    <node expr="[folder/@label]" alias="@My_folder"/>
  </select> 
</queryDef>

Restituisce:

<recipient My_folder="Recipients" First name ="John" lastName="Doe"/>

Invece di:

<recipient firstName="John" lastName="Doe">
  <folder label="Recipients"/>
</recipient>

Esempio di messaggi SOAP

  • Query:

    <?xml version='1.0' encoding='ISO-8859-1'?>
    <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='http://xml.apache.org/xml-soap' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
      <SOAP-ENV:Body>
        <ExecuteQuery xmlns='urn:xtk:queryDef' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
          <__sessiontoken xsi:type='xsd:string'/>
          <entity xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
            <queryDef operation="get" schema="nms:recipient" xtkschema="xtk:queryDef">
              <select>
                <node expr="@email"/>
                <node expr="@lastName"/>
                <node expr="@firstName"/>
              </select>
              <where>
                <condition expr="@id = 3599"/>
              </where>
            </queryDef>
          </entity>
        </ExecuteQuery>
      </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>
    
  • Risposta:

    <?xml version='1.0' encoding='ISO-8859-1'?>
    <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='http://xml.apache.org/xml-soap' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
      <SOAP-ENV:Body>
        <ExecuteQueryResponse xmlns='urn:xtk:queryDef' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
          <pdomOutput xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
            <recipient email="john.doe@adobe.com" lastName"Doe" firstName="John"/>
          </pdomOutput>
        </ExecuteQueryResponse>
      </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>
    

Write / WriteCollection (xtk:session)

Questi servizi vengono utilizzati per inserire, aggiornare o eliminare un'entità ("metodo Write") o una raccolta di entità ("metodo WriteCollection").

Le entità da aggiornare sono associate a uno schema di dati. I parametri di input sono una stringa di autenticazione (deve essere eseguito l’accesso) e un documento XML contenente i dati da aggiornare.

Questo documento è completato da istruzioni per la configurazione delle procedure di scrittura.

La chiamata non restituisce alcun dato, tranne gli errori.

Definizione dei metodi "Write" e "WriteCollection" nello schema "xtk:session":

<method name="Write" static="true">
  <parameters>
    <param name="doc" type="DOMDocument" desc="Difference document"/>
  </parameters>
</method>
<method name="WriteCollection" static="true">
  <parameters>
    <param name="doc" type="DOMDocument" desc="Difference collection document"/>
  </parameters>
</method>
NOTA

Questo è un metodo "statico". I parametri di input sono inclusi in un documento XML nel formato dello schema da aggiornare.

Panoramica

La riconciliazione dei dati funziona in base alla definizione delle chiavi immesse nello schema associato. La procedura di scrittura cerca la prima chiave idonea in base ai dati immessi nel documento di input. L’entità viene inserita o aggiornata in base alla sua esistenza nel database.

La chiave dello schema dell'entità da aggiornare viene completata in base all'attributo xtkschema .

La chiave di riconciliazione può quindi essere forzata con l'attributo _key contenente l'elenco di XPaths che compongono la chiave (separati da virgole).

È possibile forzare il tipo di operazione popolando l'attributo _operation con i seguenti valori:

  • inserire: forza l'inserimento del record (la chiave di riconciliazione non è utilizzata),
  • insertOrUpdate: aggiorna o inserisce il record in base alla chiave di riconciliazione (modalità predefinita),
  • aggiorna: aggiorna il record; non fa nulla se i dati non esistono,
  • elimina: elimina i record,
  • Nessuno: utilizzato solo per la riconciliazione dei collegamenti, senza aggiornamento o inserimento.

Esempio con il metodo 'Write'

Aggiornamento o inserimento di un destinatario (operazione implicita "insertOrUpdate") con indirizzo e-mail, data di nascita e città:

<recipient xtkschema="nms:recipient" email="john.doe@adobe.com" birthDate="1956/05/04" folder-id=1203 _key="@email, [@folder-id]">
  <location city="Newton"/>
</recipient>

Eliminazione di un destinatario:

<recipient xtkschema="nms:recipient" _operation="delete" email="rene.dupont@adobe.com" folder-id=1203 _key="@email, [@folder-id]"/>
NOTA

Per un’operazione di eliminazione, il documento di input deve contenere solo i campi che costituiscono la chiave di riconciliazione.

Esempio con il metodo 'WriteCollection'

Aggiornamento o inserimento per diversi destinatari:

<recipient-collection xtkschema="nms:recipient">    
  <recipient email="john.doe@adobe.com" firstName="John" lastName="Doe" _key="@email"/>
  <recipient email="peter.martinez@adobe.com" firstName="Peter" lastName="Martinez" _key="@email"/>
  <recipient ...
</recipient-collection>

Esempio 1

Associazione della cartella a un destinatario in base al nome interno (@name).

<recipient _key="[folder/@name], @email" email="john.doe@adobe.net" lastName="Doe" firstName="John" xtkschema="nms:recipient">
  <folder name="Folder2" _operation="none"/>
</recipient>

Gli attributi "_key" e "_operation" possono essere immessi in un elemento collegato. Il comportamento su questo elemento è lo stesso dell’elemento principale dello schema di input.

La definizione della chiave dell’entità principale ("nms:recipient") è costituita da un campo da una tabella collegata (elemento <folder> schema "xtk:folder") e dall’e-mail.

NOTA

L'operazione "none" immessa nell'elemento cartella definisce una riconciliazione sulla cartella senza aggiornare o inserire.

Esempio 2

Aggiornamento della società (tabella collegata nello schema "cus:company") da un destinatario:

<recipient _key="[folder/@name], @email" email="john.doe@adobe.net" lastName="Doe" firstName="John" xtkschema="nms:recipient">
  <company name="adobe" code="ERT12T" _key="@name" _operation="update"/>
</recipient>

Esempio 3

Aggiunta di un destinatario a un gruppo con la tabella di relazione del gruppo ("nms:rcpGrpRel"):

<recipient _key="@email" email="martin.ledger@adobe.net" xtkschema="nms:recipient">
  <rcpGrpRel _key="[rcpGroup/@name]">
    <rcpGroup name="GRP1"/>
  </rcpGrpRel>
</recipient>
NOTA

La definizione della chiave non viene immessa nell'elemento <rcpgroup> perché una chiave implicita basata sul nome del gruppo è definita nello schema "nms:group".

Elementi di raccolta XML

Per impostazione predefinita, tutti gli elementi della raccolta devono essere compilati per aggiornare gli elementi della raccolta XML. I dati del database verranno sostituiti con i dati del documento di input. Se il documento contiene solo gli elementi da aggiornare, è necessario compilare l'attributo "_operation" su tutti gli elementi di raccolta da aggiornare per forzare un'unione con i dati XML del database.

Esempio di messaggi SOAP

  • Query:

    <?xml version='1.0' encoding='ISO-8859-1'?>
    <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='http://xml.apache.org/xml-soap' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
      <SOAP-ENV:Body>
        <Write xmlns='urn:xtk:persist' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
          <__sessiontoken xsi:type='xsd:string'/>
          <domDoc xsi:type='ns:Element' SOAP-ENV:encodingStyle='http://xml.apache.org/xml-soap/literalxml'>
            <recipient xtkschema="nms:recipient" email="rene.dupont@adobe.com" firstName="René" lastName="Dupont" _key="@email">
          </domDoc>
        </Write>
      </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>
    
  • Risposta:

    <?xml version='1.0' encoding='ISO-8859-1'?>
    <SOAP-ENV:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ns='http://xml.apache.org/xml-soap' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
      <SOAP-ENV:Body>
        <WriteResponse xmlns='urn:' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
        </WriteResponse>
      </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>
    

    Restituisce con errore:

    <?xml version='1.0'?>
    <SOAP-ENV:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
      <SOAP-ENV:Body>
        <SOAP-ENV:Fault>
          <faultcode>SOAP-ENV:Server</faultcode>
          <faultstring xsi:type="xsd:string">Error while executing the method 'Write' of service 'xtk:persist'.</faultstring>
          <detail xsi:type="xsd:string">PostgreSQL error: ERROR:  duplicate key violates unique constraint &quot;nmsrecipient_id&quot;Impossible to save document of type 'Recipients (nms:recipient)'</detail>
        </SOAP-ENV:Fault>
      </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>
    

In questa pagina