Хабрахабр

Как перестать делать одно и то же

Вы любите из раза в раз повторять рутинные операции? Вот и я нет. Но каждый раз в SQL-клиенте при работе с хранилищем Ростелекома приходилось прописывать все джойны между таблицами ручками. И это притом, что в 90% случаев поля и условия соединения таблиц совпадали от запроса к запросу! Казалось бы, любой SQL-клиент имеет функции автозаполнения, но для хранилищ оно не всегда работает: в них редко заводятся unique constraint и foreign key в целях повышения производительности, а без этого программе не узнать, как между собой связаны сущности и что она может тебе предложить.

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

  1. Найти в исходном коде классы, отвечающие за автозаполнение
  2. Переориентировать их на работу с внешними метаданными и подтягивать оттуда информацию о джойнах
  3. ??????
  4. PROFIT

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

Тут начались сюрпризы. Для работы с json решил использовать библиотеку json-simple от гугла. Для опытных разработчиков эта штука дает удобство управления зависимостями, для меня же больше была похожа на темную магию, к которой я был явно не готов: как обычно прописываю импорт нужных мне классов из библиотеки json-simple в шапке редактируемого класса, указываю ее в pom.xml, после чего проект категорически отказывается нормально собираться и валится с ошибками. Как выяснилось, dbeaver, как труъ-приложение, написан на платформе эклипса с использованием OSGi-фреймворка.

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

Вторым аргументом в пользу xml было наличие в JDK всех необходимых классов, что дало возможность прекратить борьбу с внешней библиотекой. К тому моменту я успел прочувствовать неудобство использования json для моей задачи — все-таки метаданные предполагалось редактировать вручную, и для этого формат xml лучше подходит. С большим удовольствием перенес все метаданные из 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>

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

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

А при определенной доле упорства даже получится избавиться от ненавистных рутинных операций, сэкономив себе время на новые эксперименты. Работа над этой фичей дала мне понимание, что не стоит бояться ковырять опенсорсные проекты — как правило, у них понятная архитектура, и даже базовых знаний языка будет достаточно для экспериментов.

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть