[Из песочницы] Разработка для Microsoft SQL Server: Unix way

Привет, Хабр! Средние и крупные проекты, в которых целиком, либо значительная часть бизнес-логики реализована в хранимых процедурах СУБД, имеют ряд неудобств по управлению кодом модулей. А именно:

Отсутствие управления версиями и отслеживание изменений кода; Сложности при синхронизация тестовой и рабочей инфраструктуры; Скудность средств по поиску, навигации и обзору кода. Да, есть коммерческие продукты, решающие эти проблемы полностью или частично, однако, на взгляд автора, делают это не эффективно и не элегантно. В виду этого, реализовано отображение модулей и структуры БД на файловую систему, с помощью FUSE (Filesystem in Userspace), в проекте SQLFuse. Теперь последователи Unix way смогут пройти и здесь.Рассмотрим последовательность действий для монтирования опытной БД.

Подготовка к монтированиюДля сборки и монтирования понадобятся следующее ПО: Модуль FUSE ядра Linux; Драйвер FreeTDS; Необходимый софт для сборки. Обычно называется в популярных дистрибутивах Linux как base-devel, включающий в себя комплятор gcc, средство make и т.п.; GNU Bison и Flex. Убедитесь, что модуль ядра FUSE загружен: modprobe -a fuse После того, как софт установлен, необходимо клонировать репозитарий git: git clone https://github.com/AlexandrMov/SQLFuse.git Сборка проекта выполняется командами: make clean make Настройка Если компиляция и сборка прошла успешно, далее необходимо настроить конфигурационный файл sqlfuse.conf, который находится в директории conf, клонированного репозитория: # глобальная группа параметров, применяются ко всем профилям [global] # количество сеансов maxconn=1 # наименование приложения, передаваемое при подключении к SQL Server appname=SQLFuse

# пользовательский профиль подключения [AdventureWorks2008R2] # имя или адрес хоста/экземпляра SQL Server servername=192.168.6.50 # база данных dbname=AdventureWorks2008R2 # профиль авторизации, определённый в sqlfuse.auth.conf auth=advauth Параметр auth ссылается на имя группы, определённое в файле sqlfuse.auth.conf: # пользовательский профиль авторизации [advauth] # логин пользователя username=fuse # пароль пользователя password=123 Вместо параметра auth в файле sqlfuse.auth.conf допускается определение username и password в файле sqlfuse.conf. Этого не сделано нарочно, так как автор параноик при редактировании профилей подключений, кто-нибудь может подсмотреть пароль пользователя. При указании экземпляра сервера, например, SQLServer\SQLEXPRESS, символ »\» можно не экранировать. Это верно и для параметра username, если необходимо авторизоваться через Active Directory.

Не забудьте про то, что БД AdwentureWorks2008R2 должна быть подключена, и выбранный пользователь имеет все необходимые права для модификации модулей SQL Server.Известные проблемы Если у Вас возникают проблемы с кодировками, то попробуете использовать параметры to_codeset и from_codeset задающие направление конвертирования: from_codeset=UTF-8 to_codeset=CP1251 При возникновении это ошибки: Heterogeneous queries require the ANSI_NULLS and ANSI_WARNINGS options to be set for the connection. This ensures consistent query semantics. Enable these options and then reissue your query.Используете параметр ansi_npw=true для принудительного включения опций QUOTED_IDENTIFIER, ANSI_NULLS, ANSI_WARNINGS, ANSI_PADDINGS в состояние ON: Монтирование Создадим папку advworks в корне клонированного репозитория SQLFuse и смонтируем в неё нашу БД: mkdir advworks ./sqlfuse -o profilename=AdventureWorks2008R2 ./advworks Можно воспользоваться опцией -d, чтобы иметь возможность следить за ошибками, выдаемые SQL Server: ./sqlfuse -d -o profilename=AdventureWorks2008R2 ./advworks &> ./advworks.log & Основные действия над модулями Приведу для примера несколько простых действий над объектами сервера.Просмотр и навигация по структуре БД в MidnightCommander: a5e775b99fa9d277598a1b90f0776e29.png Создание нового поля в таблице Person.Person и его удаление: echo «COLUMN TestColumn NVARCHAR (50) NOT NULL» > ./Person/Person/TestColumn rm ./Person/Person/TestColumn Копирование процедуры из схемы HumanResources в схему dbo: cp ./HumanResources/uspUpdateEmployeeLogin ./dbo/uspUpdateEmployeeLogin Поиск процедуры по наименованию во всех схемах: find ./ -maxdepth 2 -iname *Employee* -type f -print Таким образом, управление и навигация по модулям становится как по обычным директориям с файлами: возможно применение систем управления версиями, патчей и любимых редакторов кода, то есть вся философия Unix налицо и для SQL Server. имейте ввиду, что операция усечения (truncate) пока не поддерживается, — это значит, выполнить команду

echo » NOT NULL» >> TestColumn не получится. Хотя и заблокировано на уровне файловой системы операция, но всё же не рекомендовал выполнять это, так как может привести к пересозданию колонки и потере данных! Всегда сохраняйте оригиналы модулей перед редактированием!

Если вы ошиблись в описании модуля или произошёл разрыв соединения, файловая система вернёт ошибку -EFAULT («Не верный адрес»).Поддерживаемые модули На момент, когда писался пост, SQLFuse поддерживал следующие модули для чтения/записи: Хранимые процедуры, функции; Ограничения CHECK, DEFAULT; Колонки и триггеры. Только для чтения доступны схемы, таблицы, представления. Не отображаются совсем ограничения FOREIGN KEY, PRIMARY KEY и индексы. Когда появится больше свободного времени допишу и этот функционал.Пришлось немного упростить синтаксис T-SQL, во избежания путаницы и более гибкого управления модулями. Все осталось прежним, за исключением того, что в определении ограничений и колонок убрана избыточность в описании таблицы. Определения будут выглядеть следующим образом:

Колонки: /*ALTER TABLE Person.Person ADD/ALTER/DROP*/ COLUMN TestColumn DATETIME — … Ограничение CHECK: /*ALTER TABLE Person.Person ADD/DROP*/ WITH CHECK CONSTRAINT CK_Test CHECK — … Ограничение DEFAULT: /*ALTER TABLE Person.Person ADD/DROP*/ DEFAULT (GETDATE ()) FOR (TestColumn) — … В частях, где закомментированы указания о таблице назначения, SQLFuse сделает подстановку необходимого кода автоматически, исходя из местоположения файла модуля. Имя модуля, которое определено в тексте файла, не играет никакой роли, оно будет заменено на имя файла, схемы и/или таблицы по необходимости. В текстах модулей не может быть несколько пакетов команд, т.е. GOЭпилог или что дальше? По мере поступления свободного времени, в планах реализовать: Поддержку ограничений и индексов, а также манипуляцию с таблицами, представлениями и схемами; Логирование команд SQL и вывод их через канал или просто файл; Сохранение резервных копий при манипуляции с модулями, поддержка отката при ошибках; Описать в следующем посте формирование определений таблиц, и преобразование структуры в скрипты SQL. Кого заинтересовала идея и кто хочет принять участие в разработке, — милости просим: весь исходный код доступен под лицензией GPLv3. Автор будет рад любым замечаниям и предложениям.P.S. Могу рассказать про опыт разработки файловой системы пользовательского режима на FUSE, если кому интересно.

Источники данных

© Habrahabr.ru