А если без шуток, то у меня такое ощущение, что это вы меня не поняли. И ваши пояснения только укрепляют меня в этом ощущении.
>> Так может быть, вам стоило бы задуматься о центральном репозитории кода, в который бы и сабмиттились изменения БД?
Вообще, ваш насмешливый тон здесь неуместен. Естественно, что над этой проблемой работали несколько неглупых людей в нашей фирме, и поверьте мне, что они задумывались о многих вещах, говорить о которых не хватит места в этой статье.
Наша стандартная схема — как раз и есть то, о чем вы говорите, называя ее Центральным репозиторием, и она выполняет как раз те же самые функции.
То, что вы называете словом «сабмититься», происходит, когда я, по просьбе кого-то из разработчиков, заливаю новые изменения в стандартную схему — используя все тот же uniVersions.
>> А еще, говорят, ревью кода — хорошая практика :)
И снова ваш насмешливый тон неуместен. Разумеется, при обнаружении отличий в телах триггеров или пакетов я вначале вникаю в суть этих отличий, и только потом вношу изменения (то есть анализ происходит именно до сабмита).
Практика — критерий истины. Наша программа реально работает.
У нас пытались внедрить CVS, но не пошло (только мешало). В другой фирме, где я подрабатывал, все с ним работают, но мне оно не показалось удобным. Наверное, все дело в общей культуре всех участников процесса :-)
У нас фактически это и происходит, я сам и есть CVS. Я сам заливаю изменения в стандартную схему, и сам раздаю новые релизы с обновленными образами структуры БД.
P.S. Спасибо за разъяснение. Указание момента, когда именно выполняется code review, сразу объясняет, что оно такое :-)
Кто-то из нас кого-то не понимает. Попробуйте говорить по-русски :-)
Есть у нас «Центральный репозиторий» — это стандартная схема, куда никому нет доступа, кроме меня и еще пары человек. Но изменения в базах делаются у клиентов как решение мелких задач, а я потом заливаю отличия в стандартную схему в офисе, откуда потом они попадают ко всем остальным.
«Ревью кода» — рефакторинг — я делаю регулярно, когда сливаю отличия в пакетах. Если нужно залить только часть текста, то там моя программа бессильна — точнее, она только показывает отличия, а я открываю пакет в Toad или PL/SQL Developer, вручную переношу туда изменения и снова сравниваю измененный пакет в uniVersions
Профилактика — это не дать вносить изменения в обход стандартного протокола.
А когда изменения уже есть — пусть их показывает ваша или моя программа — это уже наступила фаза для «лечения».
У нас нет системы контроля версий, а разработка часто ведется прямо на сервере клиента, и обновленные триггера и пакеты часто там и остаются (а потом теряются при апгрейде и восстанавливаются после криков «Караул!» методом сравнения с образом вчерашней структуры).
Работают у нас вчерашние (а часто и сегодняшние) студенты, у которых высшая оценка своему труду — «Все работает». А как именно оно работает, и как это отразится на других — им невдомек. Текучка кадров — объективная реальность.
Поэтому фактически все апгрейды выполняют специально обученные люди как раз в полуавтоматическом режиме, сливая отличающиеся объекты по одному. Shift+Click :-)
1. Отдельно — нет, вроде бы… но напишите нашему руководству :-)
Я распространением не занимаюсь, мое дело — конструирование и кодинг, а остальное мне неинтересно :-)
2. Мы сравниваем не только с эталоном — нередко приходится сравнивать две версии одной клиентской схемы (например, оригинал — с офисной копией)
Если перед изменением структуры надо выполнить специфические действия — пишется скрипт (по старой технологии), при апгрейде пронумерованные скрипты выполняются до сравнения.
3. Такие ситуации возникают нечасто. Во-первых, меняя структуру, мы помним о десятках действующих клиентов. А в тех редких случаях, когда это случается, мы пишем скрипты, я о них уже упоминал несколько раз.
Фактически uniVersions выросла из программы, применяющей эти пронумерованные скрипты, и эта возможность в ней осталась, хотя и потеряла свою актуальность после разработки алгоритма сравнения с эталоном.
Большинство инструментов только показывают отличия, не решаясь что-то менять.
uniVersions позволяет синхронизировать объект «одной кнопкой» (фактически — Shift+Click)
Эта комбинированная операция делает три действия:
— генерирует скрипт на разницу
— выполняет скрипт на сервере
— обновляет описание объекта
Как результат — синий или красно-белый значок на дереве становится чисто белым, а пользователь переходит к другому «цветному» значку.
Люди! У меня сравниваются не только таблицы :-) а и такие вещи, как synonym, public synonym, public grant, policy, context, role, privilege…
Универсальные инструменты убоги как раз в силу своей универсальности. Наш инструмент заточен под Oracle, причем только на 10g и выше — мы не решали задачу универсальности, а делали вещь «для внутреннего употребления» :-)
Зато можно «отлынивать» и ничего не рисовать — я могу сравнивать даже схемы, которые делали другие люди.
Здесь ключевая фраза — «Разработчиков к DDL не пускаем» :-) У нас уже пустили, и обратного хода нет.
Да, пакеты не имеют такой четкой иерархической структуры, поэтому у нас есть ответственные за модули, и изменения в закрепленных за ними пакетах проходят через них… а остальное — через меня :-)
А зачем их сравнивать «за раз»? Чтобы сделать «один универсальный скрипт»? А чем плохо для каждой схемы генерировать на лету персональный скрипт — благо это делается за считанные секунды?
У нас есть стандартная схема, ее XML-образ помещается в каждый новый релиз продукта.
Но сравнивать приходится и разные копии одной и той же БД. Например, в процессе внедрения продукта у клиента у нас в офисе стоит структурная копия какой-то БД, которая уже установлена и у клиента. Изменения вносятся и там, и тут — а потом надо их синхронизировать, причем в обе стороны.
Тут уже нельзя все сделать «одной кнопкой», надо вникать в различия и разбираться, что в какую сторону синхронизировать.
Если поле вдруг стало NOT NULL, то тот, кто его таким сделал, должен был позаботиться о тех клиентах, у кого оно уже содержит пустые значения.
Тут есть два решения:
1. Полю задается DEFAULT, и перед применением NOT NULL вначале делается UPDATE всех пустых значений.
2. Программист сам пишет скрипт на заполнение этих пустых полей, и этот скрипт включается в пронумерованный список скриптов, которые применяется перед сравнением (старая методика)
Этот метод действительно не подходит для среднестатистического пользователя. Это инструмент для профессионалов — как осциллограф, например.
1. Да, именно так. Кроме того, что администраторы и штатные программисты клиентов свободно игрались с таблицами, триггерами и пакетами — так этим же занимались и наши внедренцы, которым важно было быстро решить проблему, заткнуть дыру… а там — хоть трава не расти.
Эти люди не до конца отдавали себе отчет в необходимости поддержания единой структуры БД у всех клиентов, не понимали или не хотели понимать, что любой последующий апгрейд, сделанный другим человеком, не знающим об этих локальных изменениях, просто сведет на нет все усилия предыдущего сотрудника.
2. Да, скрипт генерируется на клиентской машине. Да, процесс получается полуавтоматический, и может быть даже полностью автоматическим — если вы уверены, что на вашей БД нет локальных изменений в структуре. А если у человека нет специальных знаний — лучше бы ему не делать апгрейд.
1. Поделиться — пожалуйста! Утилита uniVersions входит в состав программного продукта UNA.md (http://una.md) — по вопросам приобретения обращайтесь по контактам, указанным на сайте.
Я расписал алгоритм так подробно, потому что считаю, что любые идеи не могут принадлежать кому-то одному, а являются достоянием всего человечества. И даже тот, у кого нет прав на программный продукт UNA.md, тем не менее имеет право знать, какие идеи в него заложены.
2. Действительно, это напоминает описанный в статье третий подход, хотя есть и различия. Фактически, к написанию статьи (моей первой статьи на хабре) меня подтолкнуло вот это предложение: «Отдельных статей, посвященных этому подходу, я, к сожалению, не нашел. Буду благодарен за ссылки на существующие статьи, если таковые имеются.»
Мне не нравится аналогия с исходным кодом. Исходный код не имеет такой четкой иерархической структуры, как структура БД, и описанный мной метод к исходному коду абсолютно неприменим.
Я использую текстовые файлы только для сохранения и восстановления образов объектной структуры — сама же работа по выявлению различий и формированию скрипта происходит в памяти программы с объектной структурой, которая не является текстовым файлом.
Наверное, я неправильно использовал в тезисах термин «XML-образ». Для меня XML — это иерархическая структура в памяти, но кто-то понимает под этим только файл, то есть текстовое представление этой структуры.
Так вот, сравниваются не файлы, а объекты в памяти, экземпляры классов объектной модели.
3. Сравнение хранимых данных — это отдельная тема, описанная программа этим не занимается.
Дело в том, что взаимосвязи между данными, правила их идентификации и сравнения зависят от конкретного продукта, его бизнес-логики и не формализованы настолько четко, насколько мы это имеем в случае с метаданными Oracle.
Не думаю, чтобы можно было разработать сколько-нибудь универсальный инструмент для такой задачи.
>> на каждом интернет-ресурсе — свой стиль общения и свои нормы
Смею предположить, что не стиль меняет людей, а наоборот.
«Не стоит прогибаться под изменчивый мир» :-)
Еще раз извините, если я был неправ
Точнее, когда это делаю я, а не студенты.
>> Так может быть, вам стоило бы задуматься о центральном репозитории кода, в который бы и сабмиттились изменения БД?
Вообще, ваш насмешливый тон здесь неуместен. Естественно, что над этой проблемой работали несколько неглупых людей в нашей фирме, и поверьте мне, что они задумывались о многих вещах, говорить о которых не хватит места в этой статье.
Наша стандартная схема — как раз и есть то, о чем вы говорите, называя ее Центральным репозиторием, и она выполняет как раз те же самые функции.
То, что вы называете словом «сабмититься», происходит, когда я, по просьбе кого-то из разработчиков, заливаю новые изменения в стандартную схему — используя все тот же uniVersions.
>> А еще, говорят, ревью кода — хорошая практика :)
И снова ваш насмешливый тон неуместен. Разумеется, при обнаружении отличий в телах триггеров или пакетов я вначале вникаю в суть этих отличий, и только потом вношу изменения (то есть анализ происходит именно до сабмита).
Практика — критерий истины. Наша программа реально работает.
У нас фактически это и происходит, я сам и есть CVS. Я сам заливаю изменения в стандартную схему, и сам раздаю новые релизы с обновленными образами структуры БД.
P.S. Спасибо за разъяснение. Указание момента, когда именно выполняется code review, сразу объясняет, что оно такое :-)
Есть у нас «Центральный репозиторий» — это стандартная схема, куда никому нет доступа, кроме меня и еще пары человек. Но изменения в базах делаются у клиентов как решение мелких задач, а я потом заливаю отличия в стандартную схему в офисе, откуда потом они попадают ко всем остальным.
«Ревью кода» — рефакторинг — я делаю регулярно, когда сливаю отличия в пакетах. Если нужно залить только часть текста, то там моя программа бессильна — точнее, она только показывает отличия, а я открываю пакет в Toad или PL/SQL Developer, вручную переношу туда изменения и снова сравниваю измененный пакет в uniVersions
А когда изменения уже есть — пусть их показывает ваша или моя программа — это уже наступила фаза для «лечения».
У нас нет системы контроля версий, а разработка часто ведется прямо на сервере клиента, и обновленные триггера и пакеты часто там и остаются (а потом теряются при апгрейде и восстанавливаются после криков «Караул!» методом сравнения с образом вчерашней структуры).
Работают у нас вчерашние (а часто и сегодняшние) студенты, у которых высшая оценка своему труду — «Все работает». А как именно оно работает, и как это отразится на других — им невдомек. Текучка кадров — объективная реальность.
Поэтому фактически все апгрейды выполняют специально обученные люди как раз в полуавтоматическом режиме, сливая отличающиеся объекты по одному. Shift+Click :-)
Мне тоже он очень нравится — для целей администрирования он «лучший».
Но для работы с PL/SQL лучше и удобнее PL/SQL Developer — писать пакеты я предпочитаю в нем.
Я уже говорил, что у меня сравниваются не файлы, а объекты в памяти программы, написанной на С++
Только так я могу сам управлять процессами идентификации и сравнения объектов метаданных.
(под идентификацией я понимаю алгоритм обнаружения аналогичного объекта в другой структуре — точнее, принятия решения, это он же или не он)
Как выяснилось, делает она у вас далеко не «все» :-)
Я распространением не занимаюсь, мое дело — конструирование и кодинг, а остальное мне неинтересно :-)
2. Мы сравниваем не только с эталоном — нередко приходится сравнивать две версии одной клиентской схемы (например, оригинал — с офисной копией)
Если перед изменением структуры надо выполнить специфические действия — пишется скрипт (по старой технологии), при апгрейде пронумерованные скрипты выполняются до сравнения.
3. Такие ситуации возникают нечасто. Во-первых, меняя структуру, мы помним о десятках действующих клиентов. А в тех редких случаях, когда это случается, мы пишем скрипты, я о них уже упоминал несколько раз.
Фактически uniVersions выросла из программы, применяющей эти пронумерованные скрипты, и эта возможность в ней осталась, хотя и потеряла свою актуальность после разработки алгоритма сравнения с эталоном.
и потом, я уже говорил — мне для сравнения схем не нужно ничего, кроме самих схем, и это очень удобно.
uniVersions позволяет синхронизировать объект «одной кнопкой» (фактически — Shift+Click)
Эта комбинированная операция делает три действия:
— генерирует скрипт на разницу
— выполняет скрипт на сервере
— обновляет описание объекта
Как результат — синий или красно-белый значок на дереве становится чисто белым, а пользователь переходит к другому «цветному» значку.
Универсальные инструменты убоги как раз в силу своей универсальности. Наш инструмент заточен под Oracle, причем только на 10g и выше — мы не решали задачу универсальности, а делали вещь «для внутреннего употребления» :-)
Зато можно «отлынивать» и ничего не рисовать — я могу сравнивать даже схемы, которые делали другие люди.
Да, пакеты не имеют такой четкой иерархической структуры, поэтому у нас есть ответственные за модули, и изменения в закрепленных за ними пакетах проходят через них… а остальное — через меня :-)
У меня была задача навести порядок в структурах баз, и я придумал и сделал этот инструмент не «для галочки», а чтобы решить проблему
А зачем их сравнивать «за раз»? Чтобы сделать «один универсальный скрипт»? А чем плохо для каждой схемы генерировать на лету персональный скрипт — благо это делается за считанные секунды?
У нас есть стандартная схема, ее XML-образ помещается в каждый новый релиз продукта.
Но сравнивать приходится и разные копии одной и той же БД. Например, в процессе внедрения продукта у клиента у нас в офисе стоит структурная копия какой-то БД, которая уже установлена и у клиента. Изменения вносятся и там, и тут — а потом надо их синхронизировать, причем в обе стороны.
Тут уже нельзя все сделать «одной кнопкой», надо вникать в различия и разбираться, что в какую сторону синхронизировать.
Тут есть два решения:
1. Полю задается DEFAULT, и перед применением NOT NULL вначале делается UPDATE всех пустых значений.
2. Программист сам пишет скрипт на заполнение этих пустых полей, и этот скрипт включается в пронумерованный список скриптов, которые применяется перед сравнением (старая методика)
Этот метод действительно не подходит для среднестатистического пользователя. Это инструмент для профессионалов — как осциллограф, например.
Эти люди не до конца отдавали себе отчет в необходимости поддержания единой структуры БД у всех клиентов, не понимали или не хотели понимать, что любой последующий апгрейд, сделанный другим человеком, не знающим об этих локальных изменениях, просто сведет на нет все усилия предыдущего сотрудника.
2. Да, скрипт генерируется на клиентской машине. Да, процесс получается полуавтоматический, и может быть даже полностью автоматическим — если вы уверены, что на вашей БД нет локальных изменений в структуре. А если у человека нет специальных знаний — лучше бы ему не делать апгрейд.
Я расписал алгоритм так подробно, потому что считаю, что любые идеи не могут принадлежать кому-то одному, а являются достоянием всего человечества. И даже тот, у кого нет прав на программный продукт UNA.md, тем не менее имеет право знать, какие идеи в него заложены.
2. Действительно, это напоминает описанный в статье третий подход, хотя есть и различия. Фактически, к написанию статьи (моей первой статьи на хабре) меня подтолкнуло вот это предложение: «Отдельных статей, посвященных этому подходу, я, к сожалению, не нашел. Буду благодарен за ссылки на существующие статьи, если таковые имеются.»
Мне не нравится аналогия с исходным кодом. Исходный код не имеет такой четкой иерархической структуры, как структура БД, и описанный мной метод к исходному коду абсолютно неприменим.
Я использую текстовые файлы только для сохранения и восстановления образов объектной структуры — сама же работа по выявлению различий и формированию скрипта происходит в памяти программы с объектной структурой, которая не является текстовым файлом.
Наверное, я неправильно использовал в тезисах термин «XML-образ». Для меня XML — это иерархическая структура в памяти, но кто-то понимает под этим только файл, то есть текстовое представление этой структуры.
Так вот, сравниваются не файлы, а объекты в памяти, экземпляры классов объектной модели.
3. Сравнение хранимых данных — это отдельная тема, описанная программа этим не занимается.
Дело в том, что взаимосвязи между данными, правила их идентификации и сравнения зависят от конкретного продукта, его бизнес-логики и не формализованы настолько четко, насколько мы это имеем в случае с метаданными Oracle.
Не думаю, чтобы можно было разработать сколько-нибудь универсальный инструмент для такой задачи.