Поле fake. Недосозданные (фиктивные) записи

Материал из Eludia
Перейти к: навигация, поиск

Обратимся к богатейшему опыту прошлых поколений разработчиков WEB-интерфейсов. Вот, допустим, нарисована на экране кнопка "Новый документ". Пользователь нажимает на неё – и видит форму с реквизитами. Такая же форма выдаётся при выборе одного из ранее введённых документов. Такая же или та же самая? Есть такой подход: разрабатывать 2 отдельные страницы с одинаковым внешним видом, только при обработке POST'а с одной выполнять INSERT, а с другой – UPDATE. Не надо долго объяснять, во что такое техническое решение обходится на этапе поддержки: поля могут переименовываться, меняться местами и т. д.

Другой вариант: реализовать один экран с параметром id, причём для корректных (целых положительных) значений id доставать запись из БД, а, скажем, для -1 – подставлять значения по умолчанию. Далее, параметр id передавать через hidden-поле и если он равен -1, то выполнять INSERT, иначе – UPDATE. Это уже лучше, но всё-таки далеко от идеала. Во-первых, наборы полей INSERT и UPDATE будут в основном дублироваться и при изменении множества реквизитов вам придётся выполнять двойную работу – но это сравнительно ерунда. Важно то, что описанный приём более-менее подходит только для тех случаев, когда реквизиты вновь создаваемой записи не зависят от прошлых действий пользователя. То есть это либо константы, либо, скажем, время создания или тот же id.

А ведь нередко новая запись должна наследовать контекст создания. Скажем, по кнопке "Новая платёжка" на карточке контракта должен создаваться документ, привязанный к данному контракту. Конечно, можно передавать значения автозаполняемых полей в качестве параметров. Но, во-первых, неудобно доставать значения для разных полей из разных источников (БД / параметры / фиксированные выражения), а во-вторых адресная строка не резиновая – ограничение 4 Кб не так уж и трудно нарушить (ответ на реплику в форуме). Кроме того, передавая содержимое БД через независимые параметры, вы открываете широчайший простор фантазии URL-шутников.

В общем, в Eludia всякая запись, отображаемая на экране, предварительно записана в БД. Нажав на кнопку "Новый документ", вы перейдёте (каким образом – об этом чуть ниже) на адрес с положительным $_REQUEST{id}, и в БД на тот момент уже будет существовать запись с этим номером.

Естественно, возникает вопрос: что выйдет, если пользователь отключится, не заполнив форму? Или, более точно, что увидят другие пользователи после создания, но до заполнения новой записи? Ответ такой: в Eludia недозаполненные записи отфильтровываются от полноценных по значению специального поля fake, автоматически создаваемого для каждой таблицы. Для записей, созданных функцией sql_do_insert это поле содержит положительное число (текущий номер сессии, о котором подробнее написано ниже). Процедура sql_do_update, чаще всего используемая для записи скалярных полей, автоматически обнуляет поле fake. Таким образом, все выборки должны содержать фильтр fake = 0 как минимум для основной таблицы запроса. При добавлении записи запускается сборка мусора. В каждый момент времени в каждой таблице может находиться не более одной фиктивной записи для каждого пользователя.

Функция sql_do_insert может работать в двух режимах. Если не установлена опция приложения $conf -> {core_recycle_ids} она каждый раз генерирует новую запись, а если установлена – то сначала пытается найти первую фиктивную запись, с которой не работает ни один из пользователей, активных в данный момент. Такой режим применяется для генерации номеров документов, если их одновременно регистрируют несколько операторов, причём пропуски в последовательности номеров нежелательны.

Зарезервированные значения поля fake

Записи с любыми отрицательными значениями fake должны скрываться во всех списках актуальных объектов, пригодных для выбора, но никогда не должны удаляться жёстко (DELETE).

-1
признак мягко удалённой записи (в возможностью восстановления).
-127
признак того, что запись была создана взамен жёстко удалённой, для заполнения пробела в нумерации;
-128
признак записи в таблице users, дублирующей карточку пользователя из БД другого приложения. Используется при серверном пиринге.
Персональные инструменты
Пространства имён

Варианты
Действия
Навигация
Разработчику
Администратору
Инструменты