Sublime text для PL/SQL разработчика

от автора

Хотелось рассказать о том, как многими любимый Sublime Text можно использовать как неплохое средство для разработки на PL/SQL.

Хотелось бы начать с того, для чего нужен был этот велосипед, ведь есть вроде бы много других IDE для работы с SQL и в частности Oracle PL/SQL, такие как Toad for Oracle, SQL Navigator, PL/SQL Developer и даже бесплатный Oracle SQL Developer, однако у большинства из них есть несколько недостатков по сравнению с текстовыми редакторами типа Emacs, SciTe, Vim, Notepad++, Sublime Text и т.д.

Перечислю некоторые из них, данный список сугубо субъективный:

  • “Тяжеловесность” каждой IDE, это выражается не только в размере дистрибутива, но и общими ощущениями, наличием множества не нужных функций, кнопок, отзывчивостью и т.д.
  • Большинство приемлемых IDE являются платными, или условно бесплатными с ограниченным функционалом.
  • Хотелось бы кроссплатформенность, под это требование из приведенных IDE попадает только Oracle SQL Developer.
  • Функционал редактирования текста. В большинстве из них есть только базовые методы по работе с текстом: это набор текста, copy-paste, подсветка синтаксиса. Ни о каких “CTRL+D” как Sublime Text речи и не идет.
  • Простота расширения, практически все IDE закрыты, никакой поддержки самописных пагинов и т.д.

Есть еще один пункт, но он больше относится к организации проектов и задач на рабочем месте. Хотелось бы немного затронуть эту тему, так как организация на проектах наложила свой отпечаток на настройку Sublime Text.

У нас на работе есть одно правило — “В исходниках правда”. Т.е. мы работаем непосредственно с файлами-исходниками, а не в самой базе. В первую очередь потому что нам нужна версионность, да и систему контроля версий исходников ни кто не отменял. Таким образом мы всегда можем посмотреть что сейчас на базе и что у нас в SVN, чтобы понять в чем расхождения, если клиент например сам залез в базу что-то ручками подправил, например в процедуре или пакете. Так же у нас на работе все катается через sqlplus.

На нашем проекте принята определенная структура хранения исходников, где в каждом файле хранятся свои объекты. Н-р: таблицы по задаче лежат в папке “tables”, имя файла имеет название таблицы “table_contract.tab.sql”, представления лежат в папке “views” и файлы имеют название “vv_table_contract.sql”, пакеты лежат в папке “packages” и файлы пакетов имеют названия “contract_utl_spec.sql” и “contract_utl_body.sql” ну и так далее, основная концепция понятна и проста.

Если будет интересно как у нас организована структура, SVN, выпуск версий, обновление клиентов и т.д. с учетом того что мы пишем фактически только на SQL и PL/SQL, то могу попробовать написать на эту тему статью, хотя про организацию SQL кода на Хабре статьи были.

Подсветка синтаксиса и объектов БД

Начнем с простого — это подсветка синтаксиса. Речь пойдет не о цветовой палитре, это дело личное, а подсвечивать мы будем объекты БД, т.к. это удобно и код становиться более ясным и понятным. Вот пример того как это выглядит:

Для подсветки объектов я использую файл (PL_SQL (Oracle).tmLanguage) для подсветки синтаксиса из плагина github.com/bizoo/OracleSQL, о котором речь пойдет чуть позже.

В файле добавляем новый тег:

<dict> 	<key>match</key> 	<string>(?i)\b()\b</string> 	<key>name</key> 	<string>dbobject.oracle</string> </dict> 

Где между скобок добавляем новые объекты БД для подсветки. У меня это таблицы и представления. Список объектов я получаю простым скриптом:

select lower(rtrim(xmlcast(xmlagg(xmlelement(e,object_name,'|') order by object_name) as clob),'|'))    from all_objects  where owner = user    and object_type in ('TABLE', 'VIEW')  order by object_name 

Осталось настроить цвет объектов, делается это в файле вашей темы ..\Packages\Color Scheme — Default\YourTheme.tmTheme. Добавляем в файл:

<dict> 	<key>name</key> 	<string>String</string> 	<key>scope</key> 	<string>dbobject.oracle</string> 	<key>settings</key> 	<dict> 		<key>foreground</key> 		<string>#7F7F00</string> 	</dict> </dict> 

Всплывающая подсказка по объектам

Для настройки всплывающей подсказки по объектам по сочетанию ctrl+space, а так же для помощи в завершении слов или названий объектов был создан отдельный файл “db_objects.sublime-completions”, выглядит он примерно вот так:

{        "scope": "source.plsql.oracle",         "completions":         [ {"trigger": "abon_device\tTABLE", "contents": "abon_device"}, {"trigger": "abon_device_conflict\tTABLE", "contents": "abon_device_conflict"}, {"trigger": "abon_device_err\tTABLE", "contents": "abon_device_err"} … ] } 

Это стандартный формат для Sublime Text, для срабатывания по сочетании Ctrl+Space. Необходимые данные я достаю примерно таким же скриптом как и данные для подсветки объектов БД.

select '{"trigger": "'||object_name||'\t'||object_type||'", "contents": "'||object_name||'"},'    from all_objects  where owner = user    and object_type in ('TABLE', 'VIEW')  order by object_name 

Для помощи в завершении слов или названии объектов БД я использую плагин “All autocomplete” — данный плагин просматривает все открытые вкладки, выбирает в них все слова, исключая дубли и показывает тоже в подсказке. В итоге выглядит это примерно вот так.

Система контроля версий

В качестве системы контроля версий мы используем SVN. В репозитарии у Sublime Text есть много разных плагинов, я остановился на “TourtoiseSVN”, простой, необходимые базовые операции выполняет Commit, Update, Show log, Diff с соответствующими хот-кеями (Alt+C, Alt+L, Alt+U), а для более сложных вещей, типа тагирования или слияния есть одноименный клиент.

Поиск по объектам

Для поиска по объектам в задаче(проекте) я использую как стандартный функционал Sublime Text — Goto Anything, так и небольшой плагин который сам написал. Плагин очень простой и фактически немного дополняет стандартный Goto Anything тем что в поле ввода сразу же добавляет слово на котором стоит курсор. Код плагина:

import sublime, sublime_plugin import os.path, string import re  class MeOpenCommand(sublime_plugin.WindowCommand):     def run(self):         view = self.window.active_view()         for region in view.sel():             if region.begin() == region.end():                 word = view.word(region)             else:                 word = region             if not word.empty():                 keyword = view.substr(word)         self.window.run_command("show_overlay", {"overlay": "goto", "show_files": "true", "text": keyword}) 

С учетом того как у нас организованна структура файлов проекта, описанная в начале статьи я получил функционал для быстрого доступа к необходимому мне объекту.

Выполнение кода

Теперь переходим к самому интересному, это выполнение/прокатка скриптов из Sublime Text. Для выполнения этих целей я использую модифицированный под свои нужды и требования пакет github.com/bizoo/OracleSQL. Модификации были сделаны в основном в плане упрощения плагина, т.к. сам плагин тоже немного заточен под нужды автора. Сейчас плагин выглядит вот так:

oracle_exec.py

import sublime, sublime_plugin execcmd = __import__("exec") import re import os import thread import subprocess  class OracleExecCommand(execcmd.ExecCommand):     def run(self, dsn="", **kwargs): # Передаем параметры для прокатки скрипта, sqlplus.exe, строка подключения, имя файла активной вкладки в Sublime Text         cmd = ["sqlplus.exe", dsn, "@", self.window.active_view().file_name()] # Выполняем команду и регулярное выражение для поиска ошибок по F4 и Shift+F4 после прокатки скрипта, что тоже встроено в Sublime Text.         super(OracleExecCommand, self).run(cmd, "($file)(^([0-9]+))", "(^ORA-([0-9]+)(.+)(.+)$)|(PLS-([0-9]+)(.+)$)", **kwargs) 

oracle_functions.py

import sublime, sublime_plugin  # список баз и схем которые вам необходимы и с которыми вы работаете, где первый параметр это название какое вам захочется, а 2й параметр это стандартная строка для подключения через sqlplus instance_list = [["DB1", "user/pass@tnsname"], ["DB2", "user/pass@tnsname"]]  class OracleExecuteListCommand(sublime_plugin.WindowCommand):     def run(self, *args, **kwargs):         self.window.show_quick_panel(instance_list, self._quick_panel_callback)     def _quick_panel_callback(self, index):         if (index > -1):             self.window.run_command("oracle_exec", {"dsn": instance_list[index][1]}) 

Выглядит это следующим образом.

Таким же образом можно выполнят и простые SQL запросы. Единственное для этого необходимо сделать настройки sqlplus, для этого можно попробовать использовать login.sql, который должен срабатывать каждый раз при подключении через sqlplus. Я же не стал этого делать я просто сделал snippet на необходимые мне команды или вообще можно держать один файл для этих целей где уже все записано заранее.

Итог

В качестве итога я получил быстрый, легкий, бесплатный, кроссплатформенный и легко расширяемый инструмент для разработки PL/SQL, который так же отлично вписывается в правила на работе.

P.S.: Я понимаю что есть недостатки у данной “сборки”, однако для меня они не критичны, да и если побороть свою лень можно дописывать и дальше.

ссылка на оригинал статьи http://habrahabr.ru/post/272155/


Комментарии

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

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