Nelle ultime settimane, ho lavorato su una libreria di mappatura dei dati, che ha coinvolto molte ricerche, sperimentazione, pianto, incolpare la lavagna per non essere abbastanza grande e più ricerca. Ma ora ho un'idea completa di ciò che sto cercando di fare.
Ho deciso che prima di lavorare su qualsiasi adattatore di origine dati, ho bisogno di costruire una libreria di espressioni SQL. Le query non sono assemblate con una stringa di testo, ma sotto forma di un oggetto istanziato, contenente più altri oggetti associati a quale parte della query cui appartiene.
Pertanto, un oggetto query SELECT
avrà oggetti per columns
, table from
, joins
, where clause
, group bys
, having clause
, order bys
e limit
. Questi oggetti vengono quindi passati alla scheda di origine dei dati, che prenderà l'input e lo trasformerà in una query (o lo userà in altri modi) in modo che possa recuperare i dati in un modo comune.
Sebbene sia abbastanza buono per le query semplici, quando si tratta di query più complesse, in cui il riferimento di join o una condizione all'interno della clausola where è una query di selezione nidificata (ad esempio SELECT * FROM tblA INNER JOIN (SELECT * FROM tblB WHERE foo = 'bar')
o SELECT * FROM tblA WHERE alice IN (SELECT * FROM tblB WHERE foo = 'bar')
), I Sto avendo problemi a progettare un'interfaccia in cui una cosa del genere potrebbe essere definita, che in seguito sarebbe passata all'adattatore che potrebbe usarlo in qualsiasi modo necessario.
Quindi, chiunque può proporre un progetto che consenta la definizione di tali query in astratto che possa essere interpretata in una query sql o in una chiamata di funzione dell'interfaccia programmatica nosql?
Modifica
Il design del sistema è tale che tutte le tabelle e le colonne sono definite come oggetti (separatamente, ma con associazioni denominate per il collegamento). Ecco un esempio del codice che spero di essere in grado di eseguire:
tblA::select()
->where(new inCondition(
'tblAfooCol',
tblB::select()->where(new isNullCondition('tblBbarCol'))
)
)
->fetch();
Ora, invece di essere direttamente tradotto in SQL (che è molto semplice), sto provando a pianificare un modo in cui questo può essere restituito all'adattatore sorgente dati (internamente attraverso la funzione fetch
). Finora, il sistema che ho creato può gestire i comandi per una singola query SELECT
analizzata, ma è quando vengono utilizzate le query secondarie insieme alla query che verrà passata all'adattatore. Sto riscontrando dei problemi nel determinare come incapsulare la query secondaria in modo che l'adattatore possa elaborarla da sé. Come detto prima, convertirlo direttamente in SQL funziona alla grande, ma se voglio usarlo con uno speciale adattatore che non usa SQL (cioè un adattatore XML o MongoDB), senza una funzione per convertire l'SQL in comandi (o se è SQL, convertire parte della sintassi in una specifica valida per quel rmdbs) che può essere utilizzato può diventare molto intensivo del processore (solo per alcune query) e costa un bel po 'di prestazioni.