Remote Data Services

di Andrea Salvi, in ASP - Scripting,

L'accesso remoto ai dati pone in genere problemi legati al numero di connessioni possibili sul database server. Se ogni utente per tutto il tempo necessario all'utilizzo dei dati, mantiene una connessione aperta al database, il numero delle connessioni non potrà che essere limitato.
Il problema viene risolto in maniera molto efficace da RDS unitamente ai recordset disconnessi, riducendo in modo drastico il traffico di rete.
Unico limite: occorre usare IE 3.0 se non si utilizza DHTML e se i componenti ADO necessari sono installati sul client, altrimenti IE 4.0 e successivi.

RDS è un'estensione di ADO, utilizza cioè ADO per trasferire dati dal provider al client tramite un sistema a tre livelli (client, intermedio, fonte dati) basato su IIS.
Il lato client di un sistema client-server a tre livelli effettua una richiesta di dati passando una serie di parametri al livello intermedio (server Web). I componenti RDS sul lato server elaborano la richiesta e la inoltrano al sistema di gestione della fonte dati; quest'ultimo a sua volta, recupera i dati richiesti e li passa allo strato intermedio che li trasferisce al client che ha effettuato la richiesta.
Il recordset, che costituisce il risultato della richiesta, viene memorizzato nella cache del client, che può utilizzarlo come se si fosse in presenza di una connessione.
E' inoltre possibile trasferire nuovamente il recordset dal client allo stadio intermedio, riconnettersi al database e quindi utilizzare i metodi del recordset per salvare o annullare le modifiche.

Il modello di programmazione con oggetti di RDS prevede tre componenti:

  • RDS.DataSpace
  • RDSServer.DataFactory
  • RDS.DataControl

L'oggetto RDS.DataSpace contiene un solo metodo, CreateObject, utilizzato per ottenere un proxy per l'oggetto di gestione (applicazione server, ad esempio RDSServer.DataFactory ) al quale restituisce un puntatore .  Il proxy comunica con un oggetto stub lato server corrispondente che impacchetta i dati e li trasmette al proxy.
In pratica, quando l'applicazione client esegue una chiamata di metodo pensando di effettuarla nei confronti dell'oggetto reale, in realtà chiama un metodo del proxy. Quest'ultimo con i parametri passati al metodo crea un package ed invia una richiesta al processo server. Il processo server porge la richiesta allo stub che chiama il metodo dell'oggetto reale passandogli i parametri contenuti nel package. La strada inversa viene percorsa per i valori di ritorno.

Il programma server predefinito è RDSServer.DataFactory , un oggetto aziendale generico (in pratica una Dll ActiveX) che riceve le richieste dal client e fornisce l'accesso in lettura e scrittura alle fonti dati specificate, ma non contiene alcuna regola di convalida o di gestione.
Se le esigenze sono maggiori rispetto a quelle soddisfatte da RDSServer.DataFactory, possono essere definiti oggetti aziendali personalizzati che contengano regole di convalida o di gestione e che restituiscano recordset disconnessi, recordset cioè dissociati da una Connection ed inseriti in cache che possono essere visualizzati e manipolati.
(Per creare un recordset disconnesso si deve impostare a adUseClient la proprietà CursorLocation sulla Connection o sul recordset prima di aprire la connessione.
Se si usa un oggetto Connection esplicito, occorre distaccarlo dal recordset dopo che questi è stato popolato, impostando la proprietà ActiveConnection a Nothing
Se si vuole permettere al client di modificare i dati si deve creare il recordset usando il blocco ottimistico ed un cursore statico o keyset.).

RDS.DataControl cumula le funzionalità di RDS.DataSpace e RDSServer.DataFactory e permette il collegamento del recordset restituito da una query a controlli associati ai dati.
Per utilizzarlo, è necessario impostare (in fase di progettazione o in fase di esecuzione) solo le proprietà SQL , Connect e Server dell'oggetto. Penserà poi  lo stesso oggetto a richiamare l'oggetto di gestione predefinito, RDSServer.DataFactory:

Gli esempi proposti (uno senza ed uno con l'uso del DataControl) fanno riferimento al database utilizzato nell'articolo ' Un elenco telefonico aziendale '.
Qualora non sia stato già fatto, occorre impostare una fonte dati ODBC per il nostro database Elenco.mdb attribuendogli il nome (DSN), "Elenco".
Si tratta di esempi molto semplici che quindi non necessitano di commenti molto approfonditi. La maggior parte di codice ha ad oggetto la gestione della paginazione tramite due pulsanti. Il codice relativo al RDS (anche a dimostrazione della estrema semplicità dell'utilizzo di questa tecnica) occupa poche righe per ogni esempio.
Il codice poò inoltre essere copiato ed incollato su due file con estensione "HTM" e fatto funzionare immediatamente.

E se non usiamo il DataControl?

In questo caso il codice da usare è il seguente:

<html>

<head>
<meta name="VI60_defaultClientScript" content="VBScript">
<meta NAME="GENERATOR" Content="Microsoft FrontPage 3.0">
<title></title>
</head>

<body>
<div name="stringa" id="stringa">
Attendere caricamento dati......
</div>






<div align="center"><center>
<table border="0" width="38%" cellspacing="5" cellpadding="0">
<tr>
<td width="50%"><p align="right"><input type="button" value="Indietro" id="Indietro" name="Indietro"></td>
<td width="50%"><p align="left"><input type="button" value="Avanti" id="Avanti" name="Avanti"></td>
</tr>

</table>
</center></div>

      
</body>

</html>
<script ID="clientEventHandlersVBS" LANGUAGE="vbscript">
<!--
Dim RS
Dim PagCorrente
PagCorrente = 1

 <b> Sub window_onload</b> 

<!-- Dichiariamo le variabili DS (Data Space) e DF (Data Factory)-->

Dim DS 
Dim DF
Avanti.disabled = true
Indietro.disabled = true

<!-- Creiamo l'oggetto DataSpace   -->

Set DS =CreateObject("RDS.DataSpace") 

<!-- Specifichiamo l'applicazione server creando nel contempo una sua istanza. Abbiamo così un riferimento alla applicazione. Invece di specificare direttamente il nome del server, utilizzando una pagina asp, sarebbe possibile individuare il nome del server stesso tramite il metodo Request.ServerVariables ("http://<%=Request.ServerVariables("SEVER_NAME")%>"    -->

Set DF = DS.CreateObject("RDSServer.DataFactory", "http://localhost")

<!-- Eseguiamo l'applicazione trasmettendole tramite il metodo Query, la stringa di connessione per identificare la fonte dati e la richiesta da eseguire. Dentro la variabile RS  sarà memorizzando il recordset restituito.  -->

Set RS = DF.Query("DSN=Elenco;UID=;PWD=;", "SELECT * FROM Elenco")
RS.PageSize = 10
Indietro.disabled = true
call VisualizzaPagina(PagCorrente)

 <b>End Sub</b> 

<!-- Tutto il resto è ordinaria amministrazione. Le Sub seguenti permettono la paginazione all'interno di una tabella. All'uscita distruggiamo il Recordset -->

 <b> Sub VisualizzaPagina(NumPagina)</b> 

dim sTable
dim i
sTable="<TABLE name=tb1 id=tb1 align=center WIDTH=75% BORDER=1 cellspacing=1 cellpadding=1> "
sTable = sTable & "<TR align=center bgcolor=red>"
sTable = sTable & " <TD name=td1 id=td1>" 
sTable = sTable & "ID" 
sTable = sTable & " </TD>"
sTable = sTable & " <TD name=td1 id=td1>" 
sTable = sTable & "NOME"
sTable = sTable & " </TD>"
sTable = sTable & " <TD name=td1 id=td1>" 
sTable = sTable & "COGNOME" 
sTable = sTable & " </TD>"
sTable = sTable & "</TR>"

RS.AbsolutePage = NumPagina

i = 1

while not(RS.EOF) and (i<11)

sTable = sTable & "<TR>"
sTable = sTable & " <TD name=td1 id=td1>" 
sTable = sTable & RS("id") 
sTable = sTable & " </TD>"
sTable = sTable & " <TD name=td1 id=td1>" 
sTable = sTable & RS("nome") 
sTable = sTable & " </TD>"
sTable = sTable & " <TD name=td1 id=td1>" 
sTable = sTable & RS("Cognome") 
sTable = sTable & " </TD>"
sTable = sTable & "</TR>"

RS.MoveNext

i = i + 1

wend

sTable = sTable & " </TABLE>"
stringa.innerHTML = sTable 
Call AttivaBottoni

 <b> End Sub

Sub Avanti_onclick</b> 

PagCorrente = PagCorrente + 1
call VisualizzaPagina(PagCorrente)
Call AttivaBottoni

 <b> End Sub

Sub Indietro_onclick</b> 

PagCorrente = PagCorrente - 1
call VisualizzaPagina(PagCorrente)
Call AttivaBottoni

 <b> End Sub

Sub window_onunload</b> 

RS.close
set RS = nothing

 <b> End Sub

Sub AttivaBottoni</b> 

if (PagCorrente < RS.PageCount) then
   Avanti.disabled = false
else
   Avanti.disabled = true
end if 

if (PagCorrente > 1) then
   Indietro.disabled = false
else
   Indietro.disabled = true
end if 

 <b> End Sub</b> 

-->

</script>
2 pagine in totale: 1 2
Contenuti dell'articolo

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti