r250 - 14 Nov 2016 - 15:31:46 - Sergej ZnamenskijYou are here: TWiki >  IS4UGP Web > Summer2009Plan > TzLotciya

Лоция системы

Содержание:

Замечания

Структура записей

Каждая запись в базе состоит из ключа записи и её значения, и то и другое являются строками произвольной длины.

Ключ записи конкатенируется из

  • логического ключа ( ЛК - это начало КЗ ), начинающегося на заглавную букву если данное первичное и на строчную если системное
  • указания времени его появления,
  • указания автора записи либо специфической информации о её происхождени,
  • байта особенности интерпретации.
Если в записи содержится исполняемый код, то её ключ не может содержать никаких символов кроме латинских букв и цифр, '/' и '_'. Для ускорения обработки символ '_' встречается в ключе записи только перед временем сохранения записи.

Время в СУБД "Ботик"

Машина времени предполагает, что каждое значение данного связывается с моментом времени t1, с которого оно становится активным.

Подробнее

Последний байт ключа записи для   интерпретация значения
данных тестирования рабочих данных
d D отметка об удалении данного
f F табличка прикрепленных файлов: в каждой строке имя файла, далее возможно пробел и описание
h H хеш, добываемый split /\,\s* | \s\=\>\s/
l L ссылка (либо список ссылок) на актуальное данного, ключ которого начинается на записанную строку (лексикографически наибольший если таких несколько)  
v V строка  
j J сериализованные в JSON  
s S сериализованные в Storable  
c C сериализованные в JSON изменения  

Сущности базы данных BotikDB?

находится тут

Контексты и фрагменты страничек

Несколько взаимосвязанных фрагментов страницы образуют совместное дело. Часть URL страницы (или фрагмента) до последнего '/' это и есть её $Context, то есть общее начало ключей всех первичных данных, поступающих через www-формы, например,

Контекст данных Пояснение Пример
$pm перловый модуль pm/Server
$Pm исходные тексты комплекта перловых модулей и сгенерированные ими сообщения об ошибках
P/$taskname
H6
$Нtml шаблоны html, жалобы и предложения пользователей
H$id
H6
$Conference информация о научной (научно-практической) конференции
C$id
C3
$Context произвольный контекст W0/M082/S12
$Council данные по учёному совету УГП
W0/D0
W0/D0
$Chair данные по конкретной кафедре
W0/D$id
W0/D2
$Group информация учебной группы
W0/$group
W0/M071
W0/UUU0
$Specialty рабочие планы по специальности
$Council/$specialty
W0/D0/Spec2
$Course преподавание дисциплины в семестре-группе
W0/$group/S$id
W0/M082/S12
W0/M082/S12/joined_as => UUU0/U12 (W0/UUU0/U12) W0/UUU0/U12/joined => M082/S12, W0/UUU0/U12/data_in => M082/S12
$User регистрационные данные пользователя и личные настройки
L/$login
L/vasya
$Building информация о корпусе (строении)
$Workplace/block$id
W0/block1
$Cоntrol контрольные мероприятия по дисциплине в семестре-группе
$Course/control
W0/M082/S12/соntrol
$Syllabus семестровая программа
по дисциплине
в группе
$Course/syllabus
W0/M082/S12/syllabus
$Lesson ветка конкретного занятия в группе
W0/$group/S$id/$lesson_type$lesson_number
W0/M082/S12/p17
W0/UUU0/U12/p17
$Person учётные данные персоны
P$person
P186
$Room информация о комнате (аудитории)
$Building/room$id
W1/block2/room10
$Talk информация о попытке сделать доклад на конференции
$Conference/T$id
C2/T34
$Workplace данные организации
W$id
W65
$ApprovedDocument оправдательный документ пропуска занятий студентом
W0/P$id/ApprovedDocument$id
W0/P245/ApprovedDocument5
$Payd оплата образовательных услуг вида $n=0,1,2,3 для первого семестра, $n=4,5,6,7 для второго семестра и т. д.
W0/$Person/Payd$n
W0/P246/Payd7
$Applications заявка на поступление A1, A45
$Schedule Расписание преподавания дисциплины в семестре
W0/$year.halph/Sched$id
W0/$year.halph/Sched$id

Идентфикаторы базовых сущностей состоят из начинающегосяся с заглавной буквы и содержащего только латинские буквы сокращённого идентификатора наиболее общего типа сущности (W, C, S, Spec, ...), за которым следует порядковый номер экземпляра.

Переменная Пояснение Пример
$time время сохранения записи 111115415
в секундах
c начала эпохи (1970)
$btime время последнего изменения исходных данных
$etime время, до которого есть надежда на неизменность данных
$specialty специальность Spec1, Spec2, Spec3
$lesson_type вид занятия (лекция, практическое, лабораторное, контрольная работа, централизованное тестирование, рубежный контроль (недефференцируемый, дифференцированный), экзамен, зачет (недефференцируемый, дифференцированный)) l,p,x,c, ct, r, r_d,e,z,z_d
$lesson_number порядковый номер занятия данного вида
по конкретной дисциплине в семестре и группе
1,2,3,...
$enter_year две последние цифры года поступления 06
$group id учебной группы
_специальность_ .$enter_year. номер
M071, I082, E093
$login логин пользователя vasya
$id порядковый номер объекта (в порядке появления в системе) 1,2,3,...
$importance Важность дела done, can, news, changes, must, error
$workplace порядковый номер организации
УГП, ИПС, ...
0,1,...

Фрагменты страницы специальности или направления

Фрагмент URL, пример Доступ
Заголовок Учебный план по (Наименование и код специальности/направления со ссылкой на файл стандарта)] https://edu.botik.ru/$Specialty/title
https://edu.botik.ru/W0/D0/Spec2/title
'0'
Отметка об утверждении https://edu.botik.ru/$Specialty/confirmed
https://edu.botik.ru/W0/D0/Spec1/confirmed
'0'
Интерфейс формирования группы редактирования изменений https://edu.botik.ru/$Specialty/delegate
https://edu.botik.ru/W0/D0/Spec1/delegate
'r','u'
Интерфейс редактирования изменений (если не завершено редактирование, это ToDo для членов группы редактирования) https://edu.botik.ru/$Specialty/change
https://edu.botik.ru/W0/D0/Spec1/change
'c','r','u'
Интерфейс утверждения согласованных изменений к ранее утверждённой таблице (это ToDo ректора при наличии неутверждённых, но согласованных изменений) https://edu.botik.ru/$Specialty/confirm
https://edu.botik.ru/W0/D0/Spec1/confirm
'r'
Интерфейс просмотра утверждённой таблицы с отметкой об утверждении https://edu.botik.ru/$Specialty/confirmed
https://edu.botik.ru/W0/D0/Spec1/confirmed
'c','r','u'
|

Фрагменты других страниц

$URL (без https://edu...) значение
/$Chair/jobs Страница учебной нагрузки по кафедре
/$Chair/confirm_jobs Отметка об утверждении или интерфейс утверждения
/$Chair/change_jobs Интерфейс (пере)распределения нагрузки с показом отличий от утверждённого
/$Chair/editing_jobs Таблица нагрузки с показом отличий изменений от утверждённого варианта
/$Chair/confirmed_jobs Таблица нагрузки
/$Syllabus/all Страница учебной дисциплины в семестре и группе
/$Syllabus/join Список ключей $Sylabus совмещённых курсов
/$Syllabus/program Программа учебной дисциплины в группе
/$Syllabus/confirm_program Отметка об утверждении или интерфейс утверждения
/$Syllabus/change_program Интерфейс изменения программы учебной дисциплины в группе
/$Syllabus/editing_program Текст программы с показом отличий изменений от утверждённого варианта
/$Syllabus/confirmed_program Утверждённый текст программы
/$Syllabus/journal Рабочий журнал преподавателя
/$Lesson/change_info Изменение информации по конкретному занятию
/$Lesson/view_info Информация по конкретному занятию
/$Course/new_lesson Создание нового занятия
/$Group/plan Рабочий Учебный План Группы
/$Group/view_plan таблица рабочего учебного плана группы
/$Group/teaching Страница текущей активности, итогов и задолженностей по группе
/$Group/currentteaching Сводная таблица текущей успеваемости с выделением отстающих
/$Group/teaching_credits Сводная таблица итоговой успеваемости за прошлые семестры с ярким выделением задолженностей

Ключи первичных данных общего назначения, переносимых скриптом из lattice

Контекст Ключ значение примеры
$Workpace/ name официальное наименование организации 'Негосударственное образовательное учреждение высшего профессионального образования Институт программных систем «УГП имени А.К. Айламазяна».', Учреждение Российской академии наук Институт программных систем РАН''
$Workpace/ shortname официальное краткое наименование организации 'НОУ ВПО УГП имени А.К. Айламазяна', 'ИПС РАН'
$Workpace/D$id/ name официальное наименование подразделения 'Кафедра математики', 'Исследовательский центр системного анализа'
$Workpace/ name.en официальное наименование организации на английском языке 'Ailamazyan Pereslavl University', ''
$Workpace/D$id/ shortname официальное краткое наименование подразделения 'ИЦСА'
$Person/$Workplace/ position должность 'ректор'
$Person/$Workplace/D$id/ position должность 'заведующий кафедрой'
$Person/ F фамилия 'Гулиев', 'де Бранж', 'фон Нейман'
$Person/ F_R фамилия в родительном падеже 'Гулиева'
$Person/ F_D фамилия в дательном падеже 'Гулиеву'
$Person/ F_V фамилия в винительном падеже 'Гулиева'
$Person/ F_T фамилия в творительном падеже 'Гулиевым'
$Person/ F_P фамилия в предложном падеже 'Гулиеве'
$Person/ I Имя (первое согласно паспорту) 'Ядулла'
$Person/ I_R Имя в родительном падеже 'Ядуллы'
$Person/ O отчество согласно паспорту (если в иностранном паспорте такой графы нет, то остальные имена) 'Иман оглы'
$Person/ O_V отчество в винительном падеже 'Иман оглы'
$Person/ login логин в системе 'nik'
$Person/ u_s учёная степень 'д. т. н.'
$Person/ u_z учёное звание 'профессор'
$Person/ b_d (birthday date) дата рождения  
$Person/ rb_n (record book number) номер зачетной книжки  
$Person/ login логин пользователя, привязанного к персоне  
$Person/ email email  
$Person/ skill квалификация "'математик, системный программист"
$Person/ education образование "высшее профессиональное"
$Group/ index Номер группы. Последний символ в названии группы (1М81). 1
$Group/ subjects Список id дисциплин группы '1, 2, 3'
$Group/ semestr Текущий семестр для группы '7'
$Group/ members список студентов группы 34, 24, 56
$Group/ speciality название специальности Spec1

Ключи первичных данных подсистемы учебной части, вносимые через административный интерфейс

Контекст Ключ значение примеры
$Workpace/ started_year год начала текущего учебного года '2009'
$Chair/ name официальное наименование 'Кафедра математики'
$Chair/$year/$semester/$group/S$id/ teacher$lesson_type id персоны преподавателя '346'
$Chair members Список членов кафедры (id персон) '312, 512, 431'
$Chair chair заведующей кафедры '45'
$Chair/$year/$semester/ confirmed_data утвержденные ключи данного контекста W0/D2/2009/2/confirmed_data

Спецификация ключей первичных данных подсистемы учебной части

Если в контексте программы есть ключ joined_as и (или) в контексте объединённой программы есть ключ data_in, то при чтении любого ключа из клнтекста производится наследование.

$Control/ confirmed содержит время утверждённой версии
списка контрольных мероприятий
'1212121890'
$Control/ $id.name наименование контрольного мероприятия 'коллоквиум'
'контрольная 2'
$Control/ $id.lessons на каком занятии(или каких занятиях) проводился согласно журналу преподавателя (вид и номер занятия) ''
'p17'
'p17,p18'
$Syllabus/ confirmed содержит время утверждённой версии программы '1212121890'
$Syllabus/ .submit содержит время записи изменения пункта программы '1212121890'
$Syllabus/ .number номер последнего редактировавшегося пункта программы, остальные данные
см. ниже при $id=''
'4'
'2а'
'2.6'
'1.4.5'
$Syllabus/ $id.item наименование пункта программы 'Формула Тейлора и её применения'
$Syllabus/ $id.exam список вопросов к экзамену по пункту программы. 'Формула Тейлора
Применения формулы Тейлора'
Примечание: в текущей версии не используется
$Syllabus/ $id.lessons список номеров занятий указанного типа,
на которых происходило освоение этого пункта (согласно журналу)
"p3, l11, l13"
$Syllabus/ $id.base список базовых вопросов и заданий 'разложить exp( x ) при а =0'
Примечание: в текущей версии не используется
$Syllabus/ $id.must список обязательных заданий '32-39([1], c.5), ...'
Примечание: в текущей версии не используется
$Syllabus/ $id.extra список дополнительных заданий ''
Примечание: в текущей версии не используется
$Syllabus/ $id.controls список номеров контрольных мероприятий,
на которых контролируется освоение этого пункта
'1-3, 5'
Примечание: в текущей версии не используется
$Syllabus/ ОК-$k отмечена общая компетенция OK-$k "1"
$Syllabus/ ПК-$k отмечена профессиональная компетенция ПK-$k "1"
$Syllabus/ info Цели и задачи дисциплины  
$Syllabus/ references Перечень литературы с указанием базового учебника и задачника 'Курс лекций 3564499gjk.pdf'
$Syllabus/ soft Перечень программного обеспечения дисциплины  
$Syllabus/ exam Цели и задачи дисциплины Перечень экзаменационных вопросов
$Syllabus/ skills Перечень основных знаний и умений по дисциплине (остаточные знания)  
$Syllabus/ comment Перечень требований преподавателя для допуска к экзамену и зачёту и другие примечания  
$Lesson/ info подробности по занятию от преподавателя  
$Lesson/ confirmed содержит время утвержденных итогов занятия '1212121890'
$Course/ can_note список id персон, которые имеют
право проставлять в пустых клеточках '.', 'б' или 'о'
 
$Course/ can_mark список id персон, которые имеют
право проставлять любые оценки
 
$Lesson/ date дата проведения занятия  
$Lesson/ time время проведения занятия  
$Lesson/ place аудитория $Room '/W0/block2/10'
$Lesson/$Person/ info подробности от студента 'fghfjhf7657.jpg
3564499gjk.doc'
$Lesson/$Person/ mark оценка студента с id $Person на занятии;
учитывается только пустая строка (пропуск занятия)
или десятичное число в начале строки
'3---'
$Lesson/ confirmed содержит время утверждённой версии оценок по контрольной или занятию '1212121890'
$Lesson/ subject тема занятия в виде id пункта программы курса  

$name поля html-формы (сохранится с ЛК "$Specialty/$n") значение примеры
confirmed время утверждённой версии плана '128729720'
confirmed1 время согласованной версии плана '128720000'
@edit/P$id персоне назначена роль редактирования '1', ''
S$id/Status Входит в текущий учебный план 1
S$id/name официальное наименование 'Математический анализ-1'
S$id/_/$Specialty1/S$id1 перезасчитывается по сданной дисциплине '?','1'
S$id/volume объем дисциплины по стандарту/число семестров '840/4'
S$id/h/$lesson_type часов на аудиторные занятия данного вида '36'
S$id/h/ksr часов на контроль самостоятельной работы '6'
S$id/$enter_year/semester номер семестра за период обучения, в котором должна изучаться дисциплина (1-10) '6' Если 0 то курс не будет читаться, а если данных нет, то должны браться из предыдущего года или предпред..., а если их и не было, то всё равно что 0
Sadd создать новую учебную дисциплину 1
S$id/edit редактировать либо завершить редактирование '1', ''
S$id/copy дублировать для последующего редактирования '1'
S$id/$enter_year/pass предусмотрен ли зачёт '1', '' см. выше
S$id/$enter_year/exam предусмотрен ли экзамен '1', '' см. выше
S$id/division раздел стандарта 'ЕН', 'ДС'
S$id/std_id идентификатор дисциплины в стандарте если есть 'Ф12'
S$id/Department Кафедра, ответственная за дисциплину '5'

$Specialty/name официальное наименование 'Прикладная математика и информатика'
$Specialty/type вид специальности (направления) 'специальность'
$Specialty/type_R вид специальности (направления) в родительном падеже 'специальности'
$Specialty/code код специальности (направления) '230700'
$Specialty/competences структура компетенций в соответствии со стандартом '{"OK" :[ "способен совершенствовать и развивать свой интеллектуальный и общекультурный уровень, самостоятельно обучаться новым методам исследования","способен свободно пользоваться русским языком и одним из иностранных языков, как средством делового общения",...],"ПК":[...]}'
$Specialty/standard уникальное имя документа стандарта 'dfsld54ds67x5sd.pdf'
starttime/$Group/Semestr$semestr момент начала аудиторных занятий в семестре номер $semestr (1-10) '1122333456'
$Specialty/short_name краткое наименование специальности 'ПМИ'
$Specialty/spec_short обозначение для специальности, испольуемое в названии группы 'Э'

Данные, формируемых скриптом, отслеживающим изменения в системе

Ключ в базе значение в базе в шаблон подставляется как значение данного пример значения
current/$Specialty/chair/$id/name W0/D$id/name $hash->{chair}{$id}{name}=... официальное наименование кафедры 'Кафедра математики'
stamp/$Specialty! confirmed1? $hash->{stamp}{confirmed}
$hash->{stamp}{confirmed1}
атрибуты подписи (подписей) (время утверждения, ФИО, должность, титулы) ['12345467111', 'С. М. Абрамов', 'ректор УГП', 'член-корр РАН', 'д.ф.-м.н.' ], ...
confirmed/$Specialty! 'confirmed' $hash->{confirmed} утверждённые значения всех полей форм name=>..., ...
delta1/$Specialty! 'confirmed' $hash->{delta1} значения всех согласованных полей форм, отличающихся от утверждённых name=>..., ...

Календарный план

Переменная Пояснение Пример
$group/moment/semester$id дата начала семестра $id в секундах
$Group/moment/session$i дата начала сесcии $id  
$Group/moment/controlweek$id дата окончания рубежного контроля в семестре $id  
$Group/moment/holiday$id дата начала каникул в семестре $id  
$Group/moment/opractic дата начала ознакомительной практики  
$Group/moment/ppractic дата начала производственной практики  
$Group/moment/dpractic дата начала преддипломной практики  

Ключи для интерфейсов взаимодействия студента с учебной частью

Контекст Ключ Пояснение Пример
$ApprovedDocument text Регистрационный номер оправдательного документа в подшивке или пояснение учебной части 233435676
$ApprovedDocument scan Ссылка на отсканированную копию документа  
$ApprovedDocument start Первый день покрываемого документом промежутка времени в секундах 26437895643
$ApprovedDocument end Последний день покрываемого документом промежутка времени в секундах 43556578768
$Payd text Пояснения учебной части 233435676
$Payd state Оплачена ли услуга (1/0) По умолчанию не оплачено (0)

Спецификация ключей вторичных данных

Приоритетности ToDo и классы иконок

Вид иконки узла определяется интересностью представленной в ней информации.
  1. Ветки без ToDo могут показываться закрытой папкой или коробкой.
  2. todo_done, иконка (зеленое вроде choice-yes наизнанку или v) подсвечивается сообщением об успешном завершении важной обработки, к подробности которой возможно ещё понадобятся.
  3. todo_info, иконка (что-то вроде bubble) подсвечивается сообщением из этого ключа.
  4. todo_call, иконка (розовый или оранжевый фонарик led-purple или с ) подсвечивается сообщением о срочной и важной информации из этого ключа.
  5. todo_task, то иконка (розовый или оранжевый восклицательный знак ALERT! наизнанку !) подсвечивается сообщением о важном несделанном деле из этого ключа.
  6. todo_error, то иконка (ярко красный крест вроде choice-no наизнанку или x ) подсвечивается сообщением об ошибке из этого ключа.

Здесь 1-3 мягкие, а 4-6 жёсткие, причём 6 должно бросаться в глаза.

Логический ключ значение примеры
a/$Context! авторизация доступа и особенности
обработки информации
для url, начинающихся на
https://edu.botik.ru/$Context
 
a/L/$login/$Context! Строка-идентификатор $cat категории доступа пользователя в контексте (=ветке); категория отличается от роли тем, что она ровно одна для каждого пользователя с авторизованным доступом 0 для guest
added$id/$Context/!/$indexes ссылка на неутверждённое добавляемое значение для подстановки в шаблон, здесь $indexes список индексов например, '3,2,7' означает, что $hash{added}->{3}{2}{7} по указанному в значении записи ключу добавляется на момент времени, указанный в $Context/confirmed$id
browser/$User Данные последнего использованного браузера  
cat/$cat/$Context/ общий префикс кода, строка, на которую надо заменить https://edu.botik.ru/$Context чтобы найти ключ кода, обновляющего хеш данных для заполнения шаблона если это значение Plans, то данные для https://edu.botik.ru/$Context/x/y будут обновлены первым имеющимся данными из списка /pm/u/$Context/x/y, /pm/u/Plans/x/y, /pm/u/Plans/x, /pm/u/Plans, /pm/u и вcтавлены в первый имеющийся шаблон из списка /pats/$Context/x/y, /pats/Plans/x/y, /pats/Plans/x, /pats/Plans  
changes Хеш изменившихся контекстов (ключи - контексты, а значения s (same) либо n (new) в зависимости от того, изменился ли набор ключей в контексте).    
confirmed/$Context/!/$indexes ссылка на утверждённое значение для подстановки в шаблон, здесь $indexes список индексов Для $indexes='3,a2,b7' значение записи - это ключ, актуальное на момент времени из $Context/confirmed значение которого будет подставлено в шаблон как $hash{confirmed}->{3}{a2}{b7}  
current/chair/$Context/!/$indexes ссылка на конкретное значение для подстановки в шаблон, здесь $hash это идентификатор в хеше, например, 'chair', а $indexes список индексов Для $indexes='3,a2,b7' значение записи - это ключ, значение которого будет подставлено в шаблон как $hash{chair} -> {3}{a2}{b7}  
deleted$id/$Context/!/$indexes ссылка на ранее утверждённое удаляемое значение для подстановки в шаблон    
hard/$user Последняя отметка о режиме ограниченного обслуживания 1  
inner_delay/$Context! время игнорирования попыток повторной записи сохраненного значения в пределах контекста;    
inner_delay/!   2  
inner_delay/browser/! 100  
inner_delay/url/! 100  
inner_delay/hard/! 10  
keep/$Context! минимальная и максимальная продолжительность хранения неактуального данного tmin tmax в секундах '24, 100000'  
type/Chair/W0/D список $id всех кафедр университета '1, 2, 4, 5'  
max_id/W! наибольший $id всех учреждений и организаций '1'  
max_id/D! наибольший $id всех подразделений учреждений и организаций '11'  
max_id/Spec$sid/S! наибольший $id всех учебных дисциплин по специальности $sid '113'  
max_id/P! наибольший $id всех персон '1213'  
max_id/Spec! наибольший $id всех специальностей '1213'  
outer_delay/$Context! плановая задержка индикации изменений в секундах за пределами контекста 60  
pattern_5P шаблоны html для фрагмента 5P ( для преддипломной практики группы)    
pattern_rawaccess шаблон html для доступа к базе данных на низком уровне    
pattern_rawaccess/listkeys шаблон html для показа 20 ключей без версий    
pattern_rawaccess/listversions шаблон html для показа 20 версий    
pm-dev/Server (?) код основного модуля системы без подстановок конкретных версий    
pm/Server код основного модуля системы с проставленными версиями    
pm-L/Server (?) ссылка на фиксированную рабочая версия системы 1  
pm-l/Server (?) ссылка на фиксированную тестовую версия системы 1  
raw/L/$login/$Context! права низкоуровневого доступа к закрытой информации 'r' только чтение, 'w' только запись, 'a' только - оба вида  
url/$User Последний запрошенный пользователем url    
whitepots! пустой список белых пятен истории ''  
whitepots/$Context! список белых пятен истории контекста (a1, b1, a2, b2 ...) '111234000, 111234012, 111234555, 111234600'  
type/StudentGroup/W0/Spec$spec Список групп, обучающихся по специальности M081,  
max_id/W0/$group_id/S$id/$lesson_type! Наибольшее id занятия типа $lesson_type в дисциплине S$id для группы $group_id '12'  
max_id/W0/$Person/ApprovedDocument! Наибольший id оправдательных документов для персоны $Person '12'  

Ключи персон-абитуриентов

Контекст Логический ключ значение
$Person/ F фамилия
$Person/ I имя (первое согласно паспорту)
$Person/ O отчество согласно паспорту (если в иностранном паспорте такой графы нет, то остальные имена)
$Person/ sex Пол
$Person/ phone Телефон
$Person/ login логин в системе
$Person/ email email
$Person/ address домашний адрес
$Person/ e_place (education place) закончил учебное заведение
$Person/ g_date (graduation date) дата окончания
$Person/ lang иностранный язык
$Person/ USE Результат ЕГЭ (математика)
$Person/ spec Интересуемое направление подготовки
$Person/ hostel Общежитие
$Person/ b_d (birthday date) Дата рождения
$Person/ b_p (birthday place) Место рождения
$Person/ certificate_num Номер аттестата
$Person/ USE_num Номер свидетельства ЕГЭ

Паспортные данные

Контекст Логический ключ значение
$Person/ p_series Серия
$Person/ p_number Номер
$Person/ p_place Кем выдан
$Person/ p_date Когда выдан
$Person/ p_citiz Гражданство

Военный билет

Контекст Логический ключ значение
$Person/ MI_number Номер
$Person/ MI_date Когда выдан
$Person/ MI_base К какому военкомату приписан

Приписное свидетельство

Контекст Логический ключ значение
$Person/ Certif_number Номер
$Person/ Certif_date Когда выдан
$Person/ Certif_base К какому военкомату приписан

Отец

Контекст Логический ключ значение
$Person/ F_F Фамилия
$Person/ F_I Имя
$Person/ F_O Отчество
$Person/ F_b_date Дата рождения
$Person/ F_address Адрес
$Person/ F_wplase Место работы
$Person/ F_post Должность

Мать

Контекст Логический ключ значение
$Person/ M_F Фамилия
$Person/ M_I Имя
$Person/ M_O Отчество
$Person/ M_date Дата рождения
$Person/ M_address Адрес
$Person/ M_wplase Место работы
$Person/ M_post Должность
$Person/ M_insur № страхового свидетельства
$Person/ M_INN ИНН

Отсканированные документы

Контекст Логический ключ значение
$Person/ Certificate_scan Cсылка на аттестат/диплом
$Person/ Passport_scan Cсылка на архив 2, 3, 5 стр. паспорта
$Person/ Med_scan Cсылка на мед. справку

Ключи заявок на постпление.

Контекст Логический ключ значение
$Applications/ person ID персоны, подавшей заявку
$Applications/ year год поступления заявки
$Applications/ status Статус(утверждена (3), усл.утверждена(2), отклонена (-1), новая заявка(1))
$Applications/ messages массив с сообщениями приемной комиссии

Лаконичность исходного кода

При работе с системой часто придется вникать в логику кода, находить и поправлять дефекты. Неудачные обозначения, запутанное и неоправданно усложненное изложение, дублирование кода, использование неудачных чужих разработок и "изобретение велосипеда" многократно усложняют и замедляют отладку и сопровождение.

Отсюда непреложные требования к коду, распространяющиеся на весь исходный код системы.

  • Минимально возможный совокупный объем (количество операторов, процедур, строк кода),
  • Абсолютная прозрачность (выразительные имена переменных и процедур, при необходимости короткие выразительные комментарии),
  • Опора на качественный многократно выверенный и документированный чужой код (если сторонние программные пакеты или библиотеки позволяют ускорить разработку, то они должны быть использованы).

Идеал недостижим, но каждый разработчик старается сделать код образцовым, чтобы не тратить попусту свое и чужое время.

Гарантию возможности безопасной откатки при замене программных модулей через web-интерфейс дает прозрачный тщательно выверенный защитный механизм "Лоция". Он включает:

  1. Небольшое число простых фрагментов кода, окруженных исчерпывающе ясными предостерегающими комментариями - "бакенами".
  2. Этот документ, описывающий все бакены с указанием содержащих их файлов и данных базы - "Лоцию".

Глобальные параметры и конфигурация системы

Каждая страничка имеет url вида http://edu.botik.ru/ версия _системы / имя_документа.

Подробнее

Конфигурационный файл Apache

Значения глобальных переменных, задаются в конфигурационном файле Apache /etc/apache2/sites-available/default так:

PerlSwitches -wT

PerlSetVar DataFile /var/lib/Botik/Database
PerlSetVar StoredFiles /var/lib/files

<Location /actual>
SetHandler modperl
PerlResponseHandler Apache2::Botik
PerlSetVar TestMode 0
</Location>

<Location /test>
SetHandler modperl
PerlResponseHandler Apache2::Botik
PerlSetVar TestMode 1
</Location>

и добываются так:

$r->dir_config('DataFile');

Предполагается, что

Директория Apache2/Botik содержит все версии всех нестандартных перловых модулей. В нее можно только подкладывать файлы с уникальными именами, но изменить положенные нельзя.

При сохранении в файл с вычисленным уникальным именем в сохраняемом коде автоматически подменяются:

Подробнее

и что $v = "Start_version$n" , где $n - номер версии файла.

После каждого внесенного изменения в загрузчик Apache2/Botik.pm нужно перезагружать Apache, т.к. Apache2::Reload() конфликтует с динамической загрузкой модулей.

Оформление исходных файлов и программный модуль Botik::Version

Требования к оформлению исходного кода

Подробнее

Загрузчик

Загрузчик это метод, который обрабатывает обращения к серверу.



sub handler
{
    my $r = shift;
    my $q = new Query ($r);
    
    # Вычисляем параметры запроса. 
    my ($login, $fragment, $time1, $time2) = get_request_info($q);
    my $access = get_access($fragment, $login, $time1, $time2);   

    return Apache2::Const::OK if ($access eq '0');   

    if ($q->param('type')  eq 'refresh'){
        # вычисляем изменения, произошедшые в контексте с момента последнего запроса пользователя ($time) 
        return get_changes($login, $fragment, $time1, $time2);
    }else{   
       # Вызываем функцию регистрации запроса 
       request_log($fragment, $user);
 
     # if ($q->param()){  # запрос к обычным данным может содержать время или даже два, проверяемое условие должно быть сложнее
         # В случае, если от пользователя пришли данные форм (или асинхронный запрос), вызываем функцию записи данных
        write_query($q).
     #}

      # Формируем страницу для пользователя 
      my $result = get_fragmen($fragment, $user, $time1, $time2);
    
      $r->print($result);
      }
   }
   return Apache2::Const::OK;
}

sub request_log {
    my ($fragment, $user) = @_;
    
    my $deltaT = 60;   # время ожидания запроса от пользователя для подтверждения его активности
    my $deltaTb  = 2;  # интервал, через который браузер посылает на сервер запросы на обновление со страницы
    my $time = system_time(); # вычисляем текущее время  

    my $last_request_time = get_last_request_time($fragment,$user);
    
   if ($time - $last_request_time  > delta){
      refresh_user_url($fragment, $url); # Записываем в базу данных ключ $url/$user 
   }
   
   if (is_first_request($fragment, $url)){
      # обновляем список активных пользователей фрагмента,  
      # (пользователь активный, если последний запрос от него пришел больше чем deltaT+deltaTb секунд назад)
      refresh_url($login, $fragment);
      
      # обновляем общий список активных пользователей и списки активных фрагментов url1-4, url2-8 и т.д.
      refresh_index($login, $fragment);
   } 
}

sub get_request_info{
   
}

sub get_fragmen{
   my ($fragment, $user, $time1, $time2) = @_;
}

get_fragment_data {
   my ($fragment, $user, $time1, $time2) = @_;
}

sub write_query{
   my ($query) = @_;
   my $time1 = $query->param('time1');
   foreach ($query->param()){
      db_write($_, $time1);   
   }
}

sub get_last_request_time{
   my ($fragment,$user) =@_;
   
}

sub refresh_user_url {
   my ($fragment, $login) = @_;
}


sub refresh_index {
   my ($login, $fragment) = @_;
}

sub get_changes{
   my ($login, $fragment, $time1, $time2) = @_;
   
   my $status;
   my $result = {};
   if ($status eq 'change'){
      my $html = get_fragment($fragment, $user); 
      $result->{$fragment} = [$status, $html];   
   } else{
         $result->{$fragment} = [$status];   
   }
   
   my $data = get_fragment_data($fragment, $user, $time1, $time2); # получаем хэш с данными, которыми заполняется шаблон 
      
   $result->{data} = $data;
   
   return $result;

}

Загрузчик

Загрузчик – это метод Apache2::Botik::Handler, который обрабатывает обращения к серверу. При получении запроса загрузчик запоминает момент начала обслуживания и подгружает основной пакет-обработчик pm::Server требуемой версии из БД. Для такой загрузки используется директива require, которая позволяет читать код из строки, как из файла. Для этого добавим в массив @INC ссылку на процедуру (code_loader), которая по имени модуля проверяет, какой модуль подгружается: если модуль стандартный (имя модуля не начинается с «pm», то она возвращает (), иначе возвращает ссылку на еще одну процедуру:


sub code_loader
{
   if (substr ($_[1], 0, 2) eq "pm")
   {
      my ($request_time, $mode) = ($_[0]->[1], $_[0]->[2]);
      my $key;
      die if db_read_key ($key, $mode, $_[1], 0, $request_time);
      return (\&get_code_str, $key);
   }
   return ();
}

sub handler
{
   ...
   $INC[0] = [\&code_loader, $request_time, $mode];
}

Процедура (get_code_str) при каждом вызове записывает в переменную $_ очередную строку кода (до символа \n) и возвращает 1, либо (если код закончился) возвращает 0.


 

Алгоритм выбора версии обработчика:

  1. Если режим тестовый и в базе есть ключ L/XX/pm/Server, то значение этого ключа есть ключ записи, хранящей исходный код обработчика, версия которого выбрана этим пользователем (XX - логин пользователя).
  2. Иначе если в базе есть подтвержденный ключ "pm/Server" (в рабочем режима тестовые данные игнорируются), то значение этого ключа есть ключ записи, хранящей исходный код обработчика, и пользователь получит фиксированную для режима версию данного шаблона.
  3. если в базе нет такого ключа, то используется последняя версия обработчика, доступная из pm/Server.

Вся дальнейшая обработка запроса включается этим подгруженным обработчиком и может включать в себя в указанном порядке:

  1. Возврат браузеру новости о текущем состоянии и запрошенные html если требуются.
  2. Сохранение изменений, произведенных пользователем (не для запросов с request_time: портить историю нельзя и жить вчерашним днём тоже).
  3. Дополнительную обработку информации.

Обработчик

  1. Формирует и отсылает ответ на запрос - новую страничку или список обновившихся фрагментов.
  2. Оценивает, не перегружен ли процесс запросами данного пользователя. Для этого он просматривает хранящийся в памяти загрузчика хранится лог активности за последнюю секунду ([имя_ пользователя, время начала обслуживания, продолжительность обслуживания], ...), удаляет устаревшее начало и оценивает активность пользователя и перегруженность системы процентом суммарного времени обработки запросов. Переоценка производится не чаще десяти раз в секунду, время последней оценки и хеш результатов хранятся в памяти загрузчика.
  3. Если перегрузка крайне опасная (>70% по системе в целом или >20% по пользователю) и запрос не административный, то выходит, сохраняя в базе тревожное сообщение о подробностях.
  4. Составляет список модулей, ответственных за сохранение данных и запускает их по очереди, они формируют хеши сохраняемых данных
  5. Пока перегрузки нет и время обработки не превысило нормы, подгружает и запускает модули, ответственные за случайные фрагменты странички для обработки данных, обновления приоритетов, пересчета списка ToDo и т.д., сохраняет данные, если база не занята другим процессом.

Сохранение данных

Обработчик pm::Server получает имена и значения измененных фрагментов. Например, при изменении оценки в отчете был сделан запрос по следующему url: http://edu.botik.ru/U/04/M/1P/P/7f?rep1/mark1 = 5, в этом случае обработчик получит:
  • U/04/M/1P/P/7f/rep1/mark1 – имя сохраняемого данного
  • 5 – его значение.

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



    # составление списка модулей для сохранения данных
    my $req = Apache2::Request->new ($r);
    foreach ($req->param) {
        $key_access = get_access_permiss($mode, "a/$_");
        if (exists $key_access->{'pm'}) {
            # получаем имя модуля, ответственного 
            # за сохранение ключа, и запоминаем в 
            # загрузчике
            my $pm_name = $key_access->{'pm'}; 
            $Apache2::Loader::handler::modules{$pm_name} = 1;
        }   
    }   

НАЧАЛО ЦИКЛА

Для выяснения, какой модуль ответственен за сохранение, делается запрос в базу данных по ключу:

a/U/04/M/1P/P/7f/rep1/mark1

и получает по вышеприведенным данным ключ

a/U/04/M/1P/_123456789021/L/vasyaН.

Этот ключ содержит в ключе pm имя модуля, ответственного за обработку. Оно запоминается ключем внутреннего хеша процедуры Apache2::Botik.pm::Handler, вызываемой сервером Apache для обработки очередного запроса.

Если несохраненных данных не осталось, цикл завершен

Что делать, если не удалось найти для каких-то несохраненных данных модуль для их сохранения?

Чтобы этого никогда не произошло, первым делом в контексте корня надо указать модуль, ответственный за сохранение всех данных (кроме тех контекстов, для которых модуль будет указан особо).

КОНЕЦ ЦИКЛА

В цикле вызываются модули для обработки


    # вызов модулей для сохранения данных из запроса
    foreach (keys %Apache2::Loader::handler::modules) {
        # получаем ключ с фиксированной версией модуля
        # TODO $r->user(), db_time() - брать из запроса
        my $mod_key = Apache2::Loader::get_real_module_key($_, $mode, $r->user(), db_time());
        # подгружаем модуль
        require $mod_key if $mod_key ne "";
        # вызывем функцию-исполнитель модуля
        $mod_key->exec_module($r);
        # удаляем модуль из списка модулей для сохранения данных
        delete $Apache2::Loader::handler::modules{$_};
    }   

НАЧАЛО ЦИКЛА

Вызывается например процедура &Apache2::Botik::Require('Pract"), поскольку модуль 'Pract" указан в ключе pm прочитанного из a/U/04/M/1P~_123456789021/L/vasyaН хеша и вызванный модуль в зависимости от загруженности сервера сохраняет в специальном хеше модуля данные или информацию об ошибках сохранения и может выполнить другую работу.

КОНЕЦ ЦИКЛА

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


    foreach (keys %Apache2::Loader::data_to_store) {
        store_record ($_);
        # Если не получилось записать в этот раз, удастся в другой
        delete $Apache2::Loader::data_to_store{$_};
    }   

Дополнительный цикл (в более поздней версии) Пока перегрузки нет и время обработки не превысило нормы, подгружает и запускает модули, ответственные за случайные фрагменты странички для обработки данных, обновления приоритетов, пересчета списка ToDo и т.д., сохраняет данные, если база не занята другим процессом.

Алгоритм определения версии подгружаемого кода (модуля или шаблона)

  1. Если режим тестовый и в настройках пользователя указана ссылка на версию кода, то запомнить ссылку;
  2. Иначе если существует актуальная ссылка на фиксированную версия кода, то запомнить ссылку;
  3. Загрузить ссылку либо прекратить обработку запроса.

Сейчас реализовано так:


    # возвращает ключ модуля
    sub get_real_module_key
    {
        my ($module, $test_mode, $login, $request_time) = @_; 
        my @res;
    
        # если режим тестовый
        if ($test_mode) {    
            # ищем пользовательскую тестовую версию кода 
            @res = db_read ("L/$login/pm/$module", $request_time);
    
            if (@res and index ($res[0], "L/$login/pm/$module") != 0) {
                @res = () if substr($res[0],-1) ne 'l'; 
            }   
        }   
            
        if (!@res) {
            # ищем утвержденную версию модуля;
            # если режим рабочий, то будет искать 
            # утвержденную рабоую версию, если тестовый -
            # утвержденную тестовую версию.
            my $ver = ($test_mode) ? 'l' : 'L'; # тестовая или рабочая версия
            @res = db_read ("pm-$ver/$module", $request_time);
                
            if (@res and index ($res[0], "pm-$ver/$module") != 0) { 
                @res = () if lc substr($res[0],-1) ne 'l';
            }   
        }   
            
        if (@res) {
            # значение найденного ключа может быть 
            # ключом-ссылкой, а нужен ключ с кодом модуля  
            if (lc substr($res[1],-1) eq 'l') {
                @res = get_value ($res[0], \$res[1]);
            }   
            # возвращаем имя модуля
            if ($res[0]) {
                $res[1] =~ s/\//::/g;
                return $res[1];
            }   
        }   
            
        warn "Can't find module $module";
        return ""; 
    }

Загрузка модулей

Загрузка требуемой версии модуля осуществляется процедурой &Apache2::Botik::Require( имя_модуля ); В загруженном коде добавлено время сохранения версии; например, &Apache2::Botik::Require( 'pm::Pract' ); превращается скажем в &Apache2::Botik::Require( 'pm::Pract_123456789076::L::vasyav' );. Эта процедура определяет версию модуля, которую нужно загрузить, и загружает модуль, сохраненный в базе по ключу pm/Pract_123456789076/L/vasyav. Существенное отличие загрузки перловых модулей от шаблонов в том, что для перлового модуля версии использованных в нем модулей фиксируются при сохранении, а для шаблонов определяются при чтении.
Edit | WYSIWYG | Attach | Printable | Raw View | Backlinks: Web, All Webs | History: r250 < r249 < r248 < r247 < r246 | More topic actions
IS4UGP.TzLotciya moved from IS4UGP.ТзЛоция on 21 Sep 2010 - 06:51 by Sergej Znamenskij - put it back
 
Powered by TWiki

This site is powered by the TWiki collaboration platformCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback