Як перестати робити одне й те саме

Ви любите раз у раз повторювати рутинні операції? Ось і я нема. Але щоразу в SQL-клієнті під час роботи зі сховищем Ростелекома доводилося прописувати все джойни між таблицями ручками. І це при тому, що у 90% випадків поля та умови з'єднання таблиць збігалися від запиту до запиту! Здавалося б, будь-який SQL-клієнт має функції автозаповнення, але для сховищ воно не завжди працює: у них рідко заводяться unique constraint і foreign key з метою підвищення продуктивності, а без цього програмі не дізнатися, як між собою пов'язані сутності і що вона може тобі запропонувати.

Як перестати робити одне й те саме

Пройшовши через заперечення, гнів, торг, депресію та наближаючись до прийняття, я вирішив — а чому б самому не спробувати реалізувати автозаповнення з блэкджеком і як належить? Я користуюся клієнтом dbeaver, написаним на java, у нього є версія комьюніті з відкритим вихідним кодом. Дозрів нехитрий план:

  1. Знайти у вихідному коді класи, які відповідають за автозаповнення
  2. Переорієнтувати їх на роботу із зовнішніми метаданими та підтягувати звідти інформацію про джойни
  3. ???
  4. ПРИБУТОК

З першим пунктом досить швидко розібрався — знайшов у багтрекері запит на коригування автозаповнення та у зв'язаному коміте Знайшов клас SQLCompletionAnalyzer. Подивився код — те, що треба. Залишилося переписати його так, щоб усе працювало. Дочекався вільного вечора та почав продумувати реалізацію. Правила зв'язків таблиць (метадані) вирішили вести в json. У мене не було практичного досвіду роботи з цим форматом і поточне завдання бачилося можливістю це недогляд виправити.

Для роботи з json вирішив використати бібліотеку json-простий від гугла. Тут розпочалися сюрпризи. Як з'ясувалося, dbeaver, як тру-додаток, написаний на платформі екліпсу з використанням OSGi-фреймворку. Для досвідчених розробників ця штука дає зручність управління залежностями, для мене ж більше була схожа на темну магію, до якої я був явно не готовий: як завжди прописую імпорт потрібних мені класів з бібліотеки json-simple в шапці класу, що редагується, вказую її в pom. xml, після чого проект категорично відмовляється нормально збиратися та валиться з помилками.

Виправити помилки збірки в результаті вийшло: прописав бібліотеку не в pom.xml, а в маніфесті manifest.mf, як це вимагає OSGI, при цьому вказавши її як import-package. Не найкрасивіше рішення, але працює. Тут виник наступний сюрприз. Якщо ти ведеш розробку в intellij idea, не можна просто так взяти і запустити дебаг свого проекту, заснованого на платформі eclipse: недосвідчений розробник повинен страждати не менше ніж аналітик без автодоповнення запитів. На допомогу прийшли самі розробники бобра, які вказали у wiki всі танці з бубном, які треба зробити. Найприкріше, що навіть після всіх цих присідань проект не хотів запускатися в дебазі з підключеною через import-package бібліотекою json (притому, що готовий продукт він, як і раніше, успішно збирався).

До того моменту я встиг відчути незручність використання json для мого завдання — все-таки метадані передбачалося редагувати вручну, і для цього формат XML краще підходить. Другим аргументом на користь xml була наявність у JDK всіх необхідних класів, що дало змогу припинити боротьбу із зовнішньою бібліотекою. З великим задоволенням переніс усі метадані з json у xml і приступив до редагування логіки автозаповнення.

Приклад метаданих

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<tableRelations>
    <tableRelation>
        <leftTable>dim_account</leftTable>
        <rightTable>dim_partner</rightTable>
        <joinColumnPair leftColumn="partner_key" rightColumn="partner_key"/>
        <joinColumnPair leftColumn="src_id" rightColumn="src_id"/>
    </tableRelation>
    <tableRelation>
        <leftTable>dim_account</leftTable>
        <rightTable>dim_branch</rightTable>
        <joinColumnPair leftColumn="src_id" rightColumn="src_id"/>
        <joinColumnPair leftColumn="branch_key" rightColumn="branch_key"/>
    </tableRelation>
</tableRelations>

В результаті я вніс зміни класи SQLUtils і SQLCompletionAnalyzer. Ідея така: якщо прозі не вдалося підібрати відповідні пропозиції автозаповнення за базовою логікою, то вона перевіряє наявність можливих джойнів із зовнішнього файлу xml. У самому файлі зберігаються пари таблиць із зазначенням полів, якими ці таблиці потрібно пов'язувати. Обмеження на технічні дати дії записів eff_dttm та exp_dttm та прапор логічного видалення deleted_ind при цьому проставляються за замовчуванням.

Коли виправлення в код було внесено, постало питання — хто наповнюватиме файл із метаданими? Сутностей у сховищі багато, самому зв'язки прописувати накладно. Зрештою вирішив повісити це завдання на своїх колег-аналітиків. Файл метаданих виклав у svn, звідки робиться чекають у локальну директорію з програмою. Принцип такий: у сховищі з'явилася нова суть? Один аналітик вносить можливі джойни у ​​файл, коммітить зміни, інші роблять чекають до себе і насолоджуються працюючим автозаповненням: ком'юніті, накопичення знань і таке інше. Провів для колег воркшоп із використання проги, написав статтю в конфлюєнс — тепер у компанії одним зручним інструментом більше.

Робота над цією фічею дала мені розуміння, що не варто боятися колупати опенсорсні проекти — як правило, вони мають зрозумілу архітектуру, і навіть базових знань мови буде достатньо для експериментів. А за певної частки завзятості навіть вдасться позбутися ненависних рутинних операцій, заощадивши собі час на нові експерименти.

Джерело: habr.com

Додати коментар або відгук