BugzillaORM
В Bugzilla половина кода в шаблонах, половина на основе полу-ORM’а Bugzilla::Object. Большая часть — говнокод. С одной стороны — ORM бы туда, было бы классно, НО! ORM мало, и нужен не он! Все (существующие) ORM-движки — это просто объектный интерфейс к базе данных. А нужно некое объектное ядро, которое бы позволяло создавать свои объекты, с полями различных типов, в том числе и ссылающимися на другие такие же объекты, с возможностью приписывания специальных особенностей полю, с общим механизмом хранения истории и с автоматическим базовым CRUD-интерфейсом.
Есть сущности:
- баг
- классификация, продукт, компонент
- тег (ключевое слово / keyword), milestone, версия, статус бага, agreement (кастомное поле!)
- вложение, комментарий, флаг, тип флага
- пользователь, группа
- как ни странно, «сущность» — «метакласс» (класс сущности)
У сущностей есть:
- ID — первичный ключ
- атрибуты
- ссылка на контролирующее поле и значения
то есть если другая сущность ссылается на эту, другим полем она должна ссылаться и на контролирующую - способ преобразования в строку
- Возможно, права доступа к сущности — привязка действий над сущностью (просмотр, правка, возможно, другие) к группам пользователей. Возможно, не нужно это сюда пихать.
У каждого атрибута есть:
- Тип
- Значение по умолчанию
- Вид показа в интерфейсе
- Копируется ли значение атрибута при клонировании сущности
- Показывается ли атрибут в форме создания сущности
- Ссылка на контролирующий атрибут той же сущности, что и этот, и на его значения
- Если выбрано, означает, что атрибут показывается, только если другой атрибут той же сущности, которой принадлежит этот, имеет одно из заданных значений
Важно, что зависимые сущности хранятся в денормализованном виде, то есть если мы хотим видеть поля «продукт» и «компонент» у бага, а выбранный «компонент» однозначно определяет «продукт», то всё равно хранятся и являются атрибутами бага они оба.
Типы атрибутов:
- Строка
- E-mail адрес — особенности: опционально скрывается ради антиспама, может иметь настройки уведомлений
- Boolean
- Decimal
- Дата
- Время
- Дата+время
- Single-Select → ссылка на сущность (то есть «многие к 1»)
- Необязательный вариант синглселекта — «1 к 1».
- существует в частичном виде — без выбора желаемой сущности
- Multi-Select → ссылка на несколько сущностей одного типа (то есть «многие ко многим»)
- Вариант мультиселекта — «список подчинённых» (то есть 1 ко многим). Например, список аттачментов бага, список комментов к багу.
- существует в частичном виде — без выбора желаемой сущности
- Файл (вложение).
Email-уведомления в общем виде задаются как уведомление на поле типа email, вытаскиваемое по цепочке из сущности (например bug.product.product_watcher.email) при изменении заданных атрибутов сущности.
Поля багов перечислены ниже. Жирное «да» в колонке «можно отключить» означает, что отключать можно уже сейчас (скорее всего, через параметры типа usevotes и т. п.). Нежирное «да» в колонках «можно отключить» и «можно менять тип» означают, что чисто теоретически логика работы Bugzilla это позволяет.
поле | тип | можно отключить? | можно менять тип? | примечания |
---|---|---|---|---|
short_desc | строка | нет | нет | |
classification | single-select | да | нет | |
product | single-select | да | нет | контролируется classification (или никем), у поля есть привязка к правам пользователя |
component | single-select | да | нет | контролируется product |
version | single-select | да | да | контролируется product, если тип = single-select. значение по умолчанию контролируется component |
rep_platform | single-select | да | да | специальная функция «угадывания» дефолтного значения |
bug_file_loc | строка | да | да | |
op_sys | single-select | да | да | специальная функция «угадывания» дефолтного значения |
bug_status | single-select | нет | нет | есть функция валидации (Bug Status Workflow) |
resolution | single-select | да | нет | у атрибута есть контролирующая видимость сущность (показывается только при bug_status.closed=1) |
status_whiteboard | строка | да | да | |
keywords | multi-select | да | да | показ в виде списка |
bug_severity | single-select | да | нет | |
priority | single-select | да | да | есть желание сделать decimal |
assigned_to | single-select | нет | нет | ссылка на пользователя. значение по умолчанию контролируется component |
reporter | single-select | нет | нет | ссылка на пользователя |
qa_contact | single-select | да | нет | ссылка на пользователя. значение по умолчанию контролируется component |
votes | decimal(,0) | да | нет | |
cc | multi-select | да | нет | ссылка на пользователей. значение по умолчанию контролируется component |
dependson | multi-select | да | нет | ссылка на баги. показ в виде списка |
blocked | multi-select | да | нет | ссылка на баги. показ в виде списка |
target_milestone | single-select | да | да | контролируется product, если тип = single-select |
see_also | multi-select | да | да | ссылка на баги. показ в виде списка (багов), если тип = single-select |
alias | строка | да | да | |
reporter_accessible | boolean | нет | нет | |
cclist_accessible | boolean | нет | нет | |
estimated_time | время | да | нет | |
remaining_time | время | да | нет | |
deadline | дата | да | нет | |
creation_ts | дата+время | нет | нет | |
delta_ts | дата+время | нет | нет | |
cf_agreement | single-select | да | да | контролируется product |
*** нет в fielddescs *** | ||||
lastdiffed | дата+время | нет | нет | скрыто в интерфейсе |
attachments | multi-select | нет | нет | 1 ко многим |
longdescs | multi-select | нет | нет | 1 ко многим |
flags | multi-select | да | нет | 1 ко многим |
Примечания:
- Все поля-ссылки на пользователей показываются в виде строки либо в виде combo-box’а, и у них есть функция валидации — она угадывает юзеров по некорректным именам.
Устаревшие поля / поля, которые ХЗ зачем нужны в таблице полей багов:
- assignee_accessible
- qacontact_accessible
- longdesc
- commenter
- longdescs.isprivate
- content
- bug_group
- flagtypes.name
- requestees.login_name
- setters.login_name
Вычисляемые поля багов:
work_time | Сумма work_time от связанных longdescs |
---|---|
percentage_complete | (Сумма work_time от dependson)/(Сумма estimated_time от dependson) |
owner_idle_time | Текущая дата минус MAX(дата последнего коммента от Assignee, дата последней активности от Assignee) |
days_elapsed | Текущая дата минус delta_ts |
everconfirmed | Менялся ли статус хоть раз на != UNCONFIRMED |
Поля вложений:
submitter | single-select, показ в виде select’а или строки, есть функция валидации (угадывания юзера по некорректному имени) |
---|---|
description | строка |
filename | строка |
mimetype | строка |
ispatch | boolean |
isobsolete | boolean |
isprivate | boolean |
isurl | boolean |
thedata | потенциально строка, а вообще-то обычно NULL, так как данные хранятся в локальных файлах |
Поля компонентов:
поле | тип | можно отключить? | можно менять тип? | примечания |
---|---|---|---|---|
name | строка | нет | нет | |
initialowner | single-select | да | нет | ссылка на пользователя |
initialqacontact | single-select | да | нет | ссылка на пользователя |
initialcc | multi-select | да | нет | ссылка на пользователей |
default_version | single-select | да | нет | ссылка на версию |
description | строка | да | да | |
product_id | single-select | нет | нет | |
wiki_url | строка | да | нет | |
is_active | boolean | да | нет |
Что ушло бы в ORM?
- Custom Fields, то есть, управление полями багов.
- Отключение стандартных полей типа OS, Hardware.
- Изменение типов стандартных полей типа целочисленных приоритетов.
- Добавление спецполей в продукты, компоненты и т. д. — сейчас это делается в коде.
- Версионирование всех объектов. История бы хранилась унифицированно. Не было бы отдельно таблиц bugs_activity и longdescs, соответственно не было бы и тормозов при проверке «Only bugs changed between…»
- Простые интерфейсы типа CRUD (Create/Read/Update/Delete), сейчас созданные непонятно каким копипастом. В основном имеется ввиду админка.
- Права на редактирование объектов.
- Валидаторы и подсказки значений.
- Корректная валидация зависимостей полей друг от друга.
- Часть SQL-запросов, написанных ручками в коде.
- Создание новых объектов типа SCRUM карточек.
- Мохнатая логика автоматической постановки/обновления багов из обработки входящих e-mailов и Excel-импорта
- Можно было бы прикрутить статистику по любым объектам, причём с Time Machine, то есть просмотром статистики за любой прошедший момент времени. :)
Текущая логика страницы создания бага:
- выбор classification, если она включена
- classification выбрана → выбор product, если он не вообще один
- тот же выбор продукта/классификации при клонировании багов
- продукт выбран → форма создания бага
- показ корректных списков возможных значений полей:
- типы флагов в зависимости от компонента
- cf_agreement в зависимости от продукта
- списки пользователей, относящихся к багу в combo-box’ы
- опциональный запрет на ввод приоритета на основе конфигурации (letsubmitterchoosepriority)
- список флажков — ограничителей доступа группами
- значения полей по умолчанию:
- которые совсем по умолчанию
- угадывание op_sys и rep_platform на основе заголовков запроса
- версия, qa_contact, assigned_to, cc по умолчанию для компонента
- хитрая логика для изменения списков cc при выборе компонентов
- assigned_to=ты при выборе статуса ASSIGNED
- показ поля resolution при выборе закрытого статуса
- версия из cookies
- загруженные из шаблона ввода бага
- загруженные из клонированного бага
- ссылка на старый аттач в описании нового клонированного бага
- хитрая логика для CC при клонировании багов
- напоминания о вводе времени
- предпросмотр комментариев
- постановка вложения сразу при создании бага
- переключатель Show Expert Fields
- Submit по Ctrl-Enter