Ti piace ripetere le operazioni di routine? A me no. Eppure, ogni volta che lavoravo con il repository di Rostelecom nel client SQL, dovevo scrivere manualmente tutti i join tra le tabelle. E questo nonostante il fatto che nel 90% dei casi i campi e le condizioni di join coincidessero da una query all'altra! Sembrerebbe che qualsiasi client SQL abbia funzioni di completamento automatico, ma per i repository non sempre funziona: raramente vengono impostati unique constraint e foreign key per migliorare le prestazioni, e senza di essi il programma non può sapere come sono collegate le entità e cosa possa offrirti.
Dopo aver attraversato negazione, rabbia, trattativa, depressione e avvicinandomi all'accettazione, ho deciso: perché non provare a implementare il completamento automatico da solo, con blackjack e donne? Uso il client DBeaver, scritto in Java, che ha una versione community con codice sorgente aperto. Ho pensato a un semplice piano:
- Trovare nel codice sorgente le classi responsabili del completamento automatico
- Reindirizzarle per lavorare con metadati esterni e recuperare informazioni sui join
- ??????
- PROFIT
Con il primo punto sono riuscito a capire rapidamente — ho trovato nel bug tracker una richiesta per la correzione dell'autocompletamento e nel relativo ho scoperto la classe SQLCompletionAnalyzer. Ho dato un'occhiata al codice — è esattamente quello che mi serviva. Resta solo da riscriverlo affinché funzioni. Ho aspettato una serata libera e ho iniziato a riflettere sulla realizzazione. Ho deciso di gestire le regole delle relazioni tra le tabelle (metadati) in json. Non avevo esperienza pratica con questo formato e il compito sembrava un'opportunità per rimediare a questa mancanza.
Per lavorare con json, ho deciso di utilizzare la libreria di Google. Qui sono iniziate le sorprese. Come si è scoperto, dbeaver, essendo un'applicazione vera e propria, è scritta sulla piattaforma Eclipse utilizzando il framework OSGi. Per gli sviluppatori esperti questa cosa offre semplicità nella gestione delle dipendenze, ma per me sembrava più una sorta di magia nera a cui non ero affatto pronto: come al solito, ho scritto l'importazione delle classi di cui avevo bisogno dalla libreria json-simple all'inizio della classe modificata, l'ho specificata in pom.xml, ma dopo il progetto si rifiutava categoricamente di compilarsi correttamente e falliva con errori.
Le correzioni delle compilationi sono state effettuate: ho specificato la libreria non nel pom.xml, ma nel manifesto manifest.mf, come richiesto da OSGI, indicandola come import-package. Non è la soluzione più elegante, ma funziona. Qui è emerso un altro imprevisto. Se stai sviluppando in IntelliJ IDEA, non puoi semplicemente avviare il debug del tuo progetto basato su Eclipse: uno sviluppatore inesperto deve soffrire quanto un analista senza completamento automatico delle query. Sono venuti in aiuto gli stessi sviluppatori di Beaver, che hanno indicato nella wiki tutti i passaggi necessari. La cosa frustrante è che, anche dopo tutte queste procedure, il progetto non voleva avviarsi in debug con la libreria JSON collegata tramite import-package (anche se nel prodotto finale continuava a compilarsi correttamente).
A quel punto avevo già avvertito il disagio nell'utilizzare JSON per il mio compito: d'altra parte, i metadati dovevano essere modificati manualmente, e per questo il formato XML è più adatto. Un'altra ragione a favore di XML era la presenza in JDK di tutte le classi necessarie, il che ha permesso di smettere di lottare con una libreria esterna. Con grande piacere ho trasferito tutti i metadati da JSON a XML e ho iniziato a rivedere la logica di completamento automatico.
Esempio di metadati
dim_account
dim_partner
dim_account
dim_branchDi conseguenza ho nelle classi SQLUtils e SQLCompletionAnalyzer. L'idea è questa: se il programma non riesce a suggerire le frasi di completamento automatico secondo la logica di base, verifica la presenza di possibili join tramite un file xml esterno. Nel file sono memorizzate coppie di tabelle con l'indicazione dei campi sui quali queste tabelle devono essere collegate. Le restrizioni sulle date tecniche di validità dei record eff_dttm ed exp_dttm e il flag di cancellazione logica deleted_ind vengono impostati per impostazione predefinita.
Dopo aver apportato modifiche al codice, è emersa la domanda: chi si occuperà di riempire il file dei metadati? Ci sono molte entità nell'archivio, e scrivere tutte le relazioni manualmente è poco pratico. Alla fine, ho deciso di affidare questo compito ai miei colleghi analisti. Ho caricato il file dei metadati su svn, da cui viene effettuato il checkout nella directory locale con il programma. Il principio è semplice: è stata aggiunta una nuova entità all'archivio? Un analista inserisce le possibili giunzioni nel file, fa il commit delle modifiche, e gli altri effettuano il checkout per godere del completamento automatico: comunità, accumulo di conoscenze e simili. Ho tenuto un workshop per i colleghi sull'uso del programma e ho scritto un articolo in Confluence: ora l'azienda ha uno strumento più comodo.
Lavorare su questa funzionalità mi ha fatto capire che non bisogna avere paura di esplorare i progetti open source: di norma, hanno un'architettura chiara e anche conoscenze di base del linguaggio sono sufficienti per fare esperimenti. Con una certa dose di perseveranza, si può persino eliminare le operazioni routinarie odiate, risparmiando tempo per nuove sperimentazioni.
Fonte: habr.com
