L'altro giorno mentre facevo _konsulenza_ ad un amico su un programma che usava mySql ho visto una interessante tecnica, ke mi ha dato modo di fare alkune riflessioni... ma cosa avrà mai visto il M.rkino ke lo ha fatto addirittura pensare?
Mah la kosa ke è ho visto è abbanza semplice. Il programma usa mysql, mysql non ha le stored procedure - o per lo meno non le ha nelle versioni ke io konosco - l'esigenza di avere le procedure sul server ha portato gli sviluppatori del programma a crearsi una tabella con tutti i comandi SQL. Ogni richiesta al db significata una pre-interrograzione della tabella dei comandi per estrarre il comando da eseguire.
I comandi sono stati catalogati con tanto di markup per i parametri... per cui la kosa era stata fatta intelligentente nonostante mi trovassi davanti ad un programma in VB5 e abbastanza datato :-p
Sono ormai abbastanza convinto che la DataAccess globale non sia una kosa kosì praticabile... è vero con il pattern factory e sfruttando le interfaccie System.Data comuni a tutti i proviser di ADO è fattibile scrivere del codice indipendente dalla base dati... ma ahimè i comandi SQL sono acora fin troppo legati alle varie basi dati, per cui ecco il limite a scrivere SQL ANSI... ma anch'esso non va bene poichè i markup dei paramentri sono diversi da db a db :-(
Sono quindi sempre più convinto che scrivere dei provider dati per ogni database in modo da poter scrivere uno strado business indipendente dal tipo e dalla struttura del db sia cosa buona e giusta :-D
Problema principale dello scrivere provider per ogni tipo di db rimane kmq l'effort e la mantenibilità.
L'effort perchè più l'applicazione parte con tanta roba e più occorre pensare e scrivere codice, matenibilità perchè se c'è esigenza di cambiare la struttura del db e ho scritto la cosa per N tipologia di db devo modificare le N strutture (e qsto è il minimo) oltre che gli N dataprovider. Quello ke mi è venuto in mente e raccontarò non credo diminuisca i punti da modificare così radicalmente ma diminuirà le parti da ricompilare e aumentarà le parti da configurare... a molti questo piace di più :-p
Il compilato fa sempre un pò paura! :-o
Cosa mai mi è venuto in mente? beh dopo tutte le premesse fatte la cosa potrebbe assomigliare molto ad un finale scontato :-p L'idea mia è quella che potrebbe essere interessante avere un repository non di soli comandi SQL ma di comandi generici. Quindi non solo i comandi SQL ma anche stored procedure. A seconda del tipo di database si avranno ovviamente comandi diversi ma per ogni singola funzionalità i comandi dovranno rispettare la stessa struttura dati sia in output (struttura del datareader) che in input (stesso numero e tipologia di parametri). L'idea è quella di avere un applicazione la cui interoperabilità con la base dati sia semplicemente legata alla configurazione/riscrittura dei comandi testuali. Tali comandi dovranno rispettare il contratto deciso da ben precise strutture I/O, un pò come la classe deve rispettare una certa interfaccia. In questo modo in combinazione con OleDb e con qualche limitazione sui movimenti si può effettivamente avere qlla che si chiama la DataAccess Globale. Per quanto detto è ovviamente importatissimo usare i parameters anche nella definizione dei comandi SQL!
Qui sopra qnd parlo di "repository di comandi generici" non si deve intendere che il repository sia necessariamente un db, oltre al fatto che non ci sono limitazioni sulle ottimizzazioni che si possono pensare per la gestione di tale repository - esmepio precaricamento e caching.
Una cosa molto simile a quanto detto è il progetto IBatisNet, qui per scaricarlo e qui un tutorial. E' un progetto interessante in quanto offre sia il repository di comandi SQL (anche dinamici) sia il data mapping sulle custom entities; solo due piccoli nei: fa uso di Reflection - come ovvio per un data mapping generico - indebolendo le performance (la parte dati dovrebbe essere a mio avviso quanto più veloce); la configurazione di IBAstisNet è NON banale ed è paragonabile ad linguaggio studiato verticalmente per la costruzione di comandi SQL. Il suddetto linguaggio viene poi interpretato, e questo è decisamente fonte di altri errori a runtime oltre a quelli che già ci sono scrivendo i comandi SQL.
Userò mai questa mia idea provando a creare un libreria che generalizzi quanto pensato e mi dia delle classi di supporto? Non lo so, rimango molto convinto della potenza dei DataAccessProvider, come proposto da Andrea nella sua sessione Designs Patterns applied in quanto non danno alcuna limitazione sulla tecnologia e comandi con cui interoperare con il db. Certo che potrebbe essere interessante avere un providere concreto che fa uso di questa pensata. L'idea è di poter dire che l'applicazione offre un provider dati ottimizzato per - ad esempio - Sqlserver, e un provider globale configurabile (configuraizone che ppotrebbe essere anke NON banale) con cui interoperare con altre basi dati. NOn è detto che le basi dati debbano tutte avere la stessa struttura, le costraints sulle strutture è sull'I/O dei comandi.
Mi sono anke chiesto: ma il mio eventuale dataprovider globale è poi così indietro rispetto a qllo specifico per una certa base dati? beh sicuramente c'è differenza tra l'uso di System.Data.Oledb e System.Data.SqlClient piuttosto System.Data.OracleClient. Ma a parte questo? A parte questo c'è che la configurazione NON banale dei comandi potrebbe dare luogo a errori di runtime... ma sia chiaro che anche un dataprovider specifico non é immune dagli errori di runtime. Il compilatore non ci dirà mai nulla se sbagliamo il nome di una colonna oppure se proviamo a leggere una stringa non numerica come se fosse un numero...
wow in _soli_ 3 gg sono riuscito a fare il dump di mille lucrubrazioni... inziamo a sal vare qui, poi rileggerò e correggerò :-p
posted @ martedì 14 dicembre 2004 11:14