Progettazione di un oggetto di incapsulamento simile a SQL per uso programmatico

0

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.

    
posta topherg 24.05.2013 - 01:29
fonte

3 risposte

1

Se lo fai perché ne hai bisogno, dovresti davvero considerare l'utilizzo di ActiveRecord, perché fa tutto ciò che stai cercando di fare, e altro:

link

(non reinventare la ruota).

Se stai facendo questo per esercizio accademico, potresti comunque trarne un beneficio guardando i file in ActiveRecord e poi usando i concetti che apprendi dalla revisione del codice.

    
risposta data 24.05.2013 - 08:46
fonte
1

Se insisti di farlo da solo

  1. non
  2. guarda API dei criteri di ibernazione o < a href="http://docs.oracle.com/javaee/6/tutorial/doc/gjitv.html"> API dei criteri JPA per l'ispirazione.

Non conosco PHP, ma sarei sorpreso se non ci fossero molte librerie per questo per PHP

    
risposta data 24.05.2013 - 11:31
fonte
1

Quello che hai attualmente sembra molto simile a un ORM . Potresti esaminare come vengono implementati gli ORM nei framework stabiliti.

D'altro canto, le implementazioni ORM esistenti sono tutte (a mia conoscenza) database di destinazione che supportano le interfacce SQL. Se è tua intenzione scegliere come target anche i database NoSQL, potrebbe essere meglio ripensare il tuo approccio e non iniziare da una sintassi simile a SQL.

Si potrebbe iniziare con un DataCollection (tabella o join), sul quale si applicano i filtri (dove), Ordering (order by) e OutputSpecification (select columns), che quindi genera un nuovo DataCollection.

Questo approccio può ancora essere convertito in SQL senza troppi problemi (anche se sarà più difficile rispetto al tuo attuale approccio), ma potrebbe prestarsi meglio per l'elaborazione in contesti che non usano SQL (direttamente).

    
risposta data 24.05.2013 - 11:57
fonte

Leggi altre domande sui tag