Обычно это порядок добавления поля в тип
Есть возможность выстроить поля по алфавиту (внутренние имена полей)
Для этого есть специальный флажок
(Р) Скрипт это текстовый файл, который можно использовать для приведения системы в нужное состояние
Представьте себе, что вам нужно установить систему сразу нескольким однотипным (но не тождественным) заказчикам.
После установки заказчику нужно создать определенную конфигурацию системы. Это можно сделать с помощью операций. Каждая операция – один запрос, отправляемый на сервер. В цепочке таких операций может быть несколько десятков.
Если повторяющуюся цепочку операций заменить одним скриптом, то весь скрипт можно выполнить одним запросом на сервер. Кроме того, проверенный однажды скрипт гарантирует вам безошибочное выполнение всей цепочки на каждом следующем заказчике (при выполнении цепочки операций вручную очень вероятны ошибки)
Если на одной базе вы получили нужную конфигурацию, то некоторые части этой конфигурации иногда полезно восстановить на другой базе.
Для этого есть два механизма.
Первый механизм генерирует скрипт по некоторым специальным частям системы. Этот скрипт может быть выполнен на другой базе и восстановить эти части там.
Второй механизм генерирует SQL-запросы на некоторых специальных частях. Выполнение этих запросов на другой базе восстанавливает эти части там.
При формировании скрипта вы можете использовать файлы четырех типов
Каждый такой файл разбит на строки, он может быть прочитан и отредактирован в текстовом редакторе. Тип файла (один из четырех) определяется по первой строке.
№ |
Ключевое слово (должно присутствовать в первой строке файла) |
Тип файла |
1 |
FILES |
В этом файле перечисляются все остальные файлы (типов 2, 3, 4 – в любом порядке). Все они выполняются последовательно, один за другим. Такой файл может быть только один на запуск. Строчки файла имеют вид <ключевое слово> <путь к очередному файлу> Чтобы система могла правильно отработать пути, запуск идет с машины сервера |
2 |
SQL |
Этот файл выполняется на СУБД по стандартным правилам |
3 |
SCRIPT |
Этот файл интерпретируется системой и ведет к выполнению операций, перечисленных ниже |
4 |
QUERY |
Этот файл позволяет создать объект «запрос» и заполнить его по определенным правилам |
FILES
SQL x1.txt
SCRIPT x2.txt
QUERY x3.txt
Этот файл формируется специальными экспортными операциями в двух случаях
Файл формируется в кодировке UTF-8 и соответственно интерпретируется
В некоторых случаях после экспорта и перед импортом файл приходится редактировать вручную. Например, если в новой базе уже есть тип с таким именем. Тогда перед импортом надо провести замену имени типа во всех случаях.
Этот файл всегда состоит из двух частей. Строки SCRIPT и SET обязательны, остальные - нет
Первая часть начинается со строки SCRIPT и заканчивается строкой, содержащей SET. После этого и до конца файла – вторая часть.
Ключевые слова SCRIPT и SET должны начинаться с первой позиции строки. Часть строки после этого слова игнорируется и может содержать комментарий. В ключевых словах скрипта регистр важен.
Каждая строка первой части (кроме первой и последней) создает в системе один новый тип. Она может иметь вид
Код-типа
Или, если задать имя типа
Код-типа NAME Имя-типа
Или то же, что и в предыдущем варианте, но для абстрактного типа (имя типа может быть пустым)
Код-типа ABSTR Имя-типа
Все строки первой части выполняются пакетом. Если выполнение невозможно, не выполняется ни одна строка и пользователь получает сообщение об ошибке с текстом ошибочной
Ниже приведен перечень конструкций и связанные с ними операции и параметры к ним
№ |
|
|
1 |
<type> ICON <icon name> |
Тип с кодом <type> получит икону с именем <icon name> |
2 |
<tab::col> UNIQUE |
Поле таблицы <tab::col> для СУБД будет объявлено уникальным |
3 |
<tab::col>BASE <reftab:refcode> |
Полю таблицы <tab::col> будет присвоено базовое значение – номер ключа таблицы с кодом <reftab:refcode> |
4 |
<tab::col>BASE <value> |
Полю таблицы <tab::col> будет присвоено базовое значение <value> |
5 |
<path> VALUE <tab::col>=<reftab:refcode> |
Полю таблицы <tab::col> объекта <path> будет присвоено значение – номер ключа таблицы с кодом <reftab:refcode> |
6 |
<path> VALUE <tab::col>=<value> |
Полю таблицы <tab::col> объекта <path> будет присвоено значение <value> |
7 |
<type1> FROM <type2> |
В дереве наследования передвинуть тип <type1> под тип <type2> |
8 |
<type1> INTO <type2> |
В дереве вложенности передвинуть тип <type> под тип <type2> |
9 |
<type> OBJECT <path> |
Создать объект согласно пути <path> и типу <type> |
10 |
OBJECT2, INTO2, FROM2 |
То же, что выше, но вместо подвижки узла в нужном месте дерева создается ярлык этого узла |
11 |
<path1> MOVE <path> |
Передвинуть объект (или ярлык), расположенный на пути <path1> под объект на пути <path2> |
12 |
<tab::col> KEYREF <reftab> |
Добавить в таблицу ключ с именем <tab::col> сцепленный с таблицей <reftab> по номеру (первичному ключу) |
13 |
KEYREF2 |
То же, что выше, но ключ объявляется теневым |
14 |
<tab::col> PIC <outname> |
Создать поле-картинку <tab::col> с внешним именем <outname> |
15 |
<tab::col> DOC <outname> |
Создать поле-документ <tab::col> с внешним именем <outname> |
16 |
PIC2, DOC2 |
Как в двух предыдущих случаях соответственно, но поле объявляется теневым |
17 |
<tab::col> <format> <outname> |
Добавить поле в таблицу сообразно формату <format>, дать ему внешнее имя <outname> |
18 |
TIME, TIMESTAMP, DATE, BOOLEAN, TEXT, REAL, INTEGER |
Возможные форматы к конструкции, указанной выше |
19 |
TIME2, TIMESTAMP2, DATE2, BOOLEAN2, TEXT2, REAL2, INTEGER2 |
Все как в предыдущем случае, для получения формата цифра 2 убирается. Поле объявляется теневым |
20 |
DELETEYELLOW <path> |
Удалить в дереве объектов узел на пути <path> |
21 |
DELETEGREEN <path> |
Удалить в дереве наследования узел на пути <path> |
22 |
DELETEBLUE <path> |
Удалить в дереве вложенности узел на пути <path> |
23 |
<type> ITCAMEFROM <value> |
В типе <type> присвоить полю ITCAMEFROM значение <value> |
24 |
<type> IMADEIT <value> |
В типе <type> присвоить полю IMADEIT значение <value> |
25 |
<type> ABOUT <value> |
В типе <type> присвоить полю ABOUT значение <value> |
Внимание: в дереве объектов под ярлыком ничего создавать нельзя, под ярлык ничего двигать нельзя.
Ниже приведен перечень ключевых слов и связанные с ними операции и параметры к ним
Конструкция |
Смысл |
<t1> INTO <t2> |
Тип t1 соединить по вложенности с типом t2 |
<t1> INTO2 <t2> |
Ярлыки на тип t1 соединить по вложенности с типом t2 |
<t1>::<c>KEYREF<t2> |
Тип t1 соединить по ключу c типом t2 |
<path>QUERY<p> |
Первая строка файла. Будет создан объект-запрос (тип query), в тело будет записан сгенерированный запрос, в описание параметров – строка p |
<t1>::<c>[,<t1>::<c>]*OF<t2> |
Поле с таблицы t1, (далее по списку) будет выбрано из таблиц. Опорной таблицей будет t2. Остальные таблицы, перечисленные в этой строке (t1) будут связаны с ней через абсолютный номер (id) |
Примеры применения скрипта для запросов смотри ниже
1 |
Классы, в которых ведется исследовательская работа |
Перечислить группы, учеников в них, портфолио в учениках, предмет в портфолио, исследования в предмете |
student INTO group portfolio INTO student course INTO portfolio research INTO course object::code OF group object::name OF student object::name OF research |
2 |
Ученики, которые ведут исследовательскую работу |
Как (1), но без групп |
portfolio INTO student course INTO portfolio research INTO course object::name OF student object::name OF research |
3 |
Предмет, по которому ведется исследовательская работа |
Как (2), но без учеников, |
research INTO course object::name OF course object::name OF research |
4 |
Разработка индивидуального маршрута |
Перечислить группы, учеников в них, портфолио в учениках, предметы в портфолио, главы в предметах |
student INTO group portfolio INTO student course INTO portfolio chapter INTO course object::code OF group object::name OF student object::name OF course object::name, chapter::done OF chapter |
Рассмотри подробно первый пример
Смысл вычисляемого поля и смысл запроса
Классы, в которых ведется исследовательская работа |
Перечислить группы, учеников в них, портфолио в учениках, предмет в портфолио, исследования в предмете |
Текст скрипта
/o/qfx/1 QUERY no
student INTO group
portfolio INTO student
course INTO portfolio
research INTO course
object::code OF group
object::name OF student
object::name OF research
SET
Генерируемое тело запроса
SELECT t0t12.code, t0t14.name, t0t19.name
FROM object t0t12, object t0t14, object t0t16, object t0t18, object t0t19, group t12, student t14, research t19
WHERE t12.id>0 and t12.id=t0t12.id and t14.id>0 and t14.id=t0t14.id and t19.id>0 and t19.id=t0t19.id and t0t14.parent=t0t12.id and t0t18.parent=t0t14.id and t0t16.parent=t0t18.id and t0t19.parent=t0t16.id
ORDER BY t0t12.code, t0t14.name, t0t19.name
В нем слева три закладки, справа – текущий узел, его элементы данных и операции.
Одна закладка (объекты). Запуск определенных функций (запросов) с параметрами – в зависимости от положения пользователя. Данных и операций нет.
Одна закладка (объекты). Данные без функций и операций.
Одна закладка (объекты). Сверху – путь к узлу от корня, слева внизу – дети текущего узла, справа внизу –элементы данных и функции текущего узла (без параметров). Опреаций нет.
Три закладки. Упрощенный порядок создания новых узлов. Функций и операций нет.
Если деревья растут, то для работы с ними может быть удобен следующий набор специальных операций
Анонимный вход не требует, чтобы пользователь был добавлен в систему. Однако он требует знаний об объекте, с которым будет идти работа.
Обычно для попадания в узел требуется знать номер и код объекта
Один бланк =b
Пакет бланков =bbb
Одна функция =f
Список фукций =ff
Пакет функций = fff
Список картинок = vv
Пакет картинок = vvv
Внешнее (длинное) имя поля есть текст вопроса (с перечислением вариантов, если необходимо). Чтобы варианты случайно вращались, надо, чтобы
Большинство тестов, проводимых по сети. передает ответы на клиентский компьютер и проверяет правильность, используя Java-script. В некоторых случаях этот Java-script замаскирован оператором INCLUDE и не может быть прочитан человеком-клиентом. В остальных случаях его можно прочитать и это знание использовать.
В нашей системе ответы хранятся на сервере и с клиентской машины прочитать их невозможно
Представьте себе плохого студента, сдающего тест рядом с хорошим. Он, естественно попытается узнать у хорошего правильные ответы. Например, если надо выбрать ответ из набора вариантов (1, 2, 3, 4), то хорощий студент может сообщить плохому правильные ответы: на первый вопрос – 3, на второй – 1, на третий 4.
Чтобы этот фокус не сработал, в системе реализован механизм случайного вращения.
На каждый вопрос варианты вопросов и ответов синхронно вращаются на одно и то же случайное целое число. При чем вращение происходит при каждом обращении к серверу. Соответствие ответов и вопросов сохраняется, но номера правильных вариантов НЕ сохраняются. Поэтому один студент не может передать другому правильный номер ответа – этот номер все время меняется.
Предположим, хороший студент сдал зачет и его бланк хранится в базе. Предположим плохой студент хочет подсмотреть в этот бланк и хороший студент сообщил ему номер бланка.
Чтобы этот трюк не сработал, в системе заложен следующий простой механизм.
Анонимный вход в систему (смотри выше) требует ввести две строки.
Первая строка – номер объекта, его изменить нельзя.
Вторая строка – код объекта. Его можно изменить.
В процессе генерации бланков система выбирает номер по порядку из еще неиспользованных, а код принимается равным номеру. Если есть подозрение, что что студенты начнут использовать трюк, описанный выше, администратор пространства (или любой пользователь имеющий доступ к объекту через дерево) меняет код вручную или автоматически (смотри ниже). После чего пара строк, работавшая раньше для анонимного входа, теперь не работает
Автоматическое изменение кода бланка (смотри выше).
На тестовой папке есть функция «случаный замок». При ее запуске к кодам всех бланков приписывается длинное случайное число.
Чтобы проверить тест, автор теста должен сам сдать его (смотри ниже)
Сначала создается тестовая папка как тип. Чтобы эта папка умела считать результаты, ее надо унаследовать от типа TESTFOLDER
Чтобы сам бланк мог считать свои результаты, сам тест надо унаследовать от типа ANKTEST
Тестовую папку в синем дереве надо поместить под пользователя с данной тематикой. Тест надо поместить в эту папку
Затем в желтом дереве надо сгенерировать тестовых папок по числу экзаменов. Затем в каждой такой папке надо сгенерировать бланков по числу учеников, сдающих этот экзамен. Можно использовать методы группового создания объектов, описанные ваыше.
Обычно группы учеников (или группы ярлыков на учеников) создаются заранее. Если использовать эти списки как эталоны, то на бланках появятся имена учеников
На тестовой папке с бланками до сдачи теста получим таблицу результатов. В ней видны номера (коды) бланков и имена сдающих.
По мере появления учеников выделяте им коиентские компьютеры в сети, входите в бланк, используйте номера бланков (дважды: как номер и как код). На открытом бланке найдите имя (фамилию) ученика. Посадите учеников за те компьютеры, где открыты их бланки. Убедитесь, что они умеют вводить значения, выбирать значения из списка и продвигаться вдоль по бланку
Когда все задания выполнены и/или время истекло, ученик должен нажать кнопку «изменить» и дождаться ответа «ваши даные сохранены». В этом состоянии он, если еще есть время, может снова войти в тест и исправить результаты. Тайм-аут при такой работе не возникает. После окончания работы ученика, его браузер надо закрыть (все окна)
После того как тесты сохранены можно проанализировать результаты. Обычно для этого используются функции объекта – тестовой папки, иногда с параметрами
В обычных тестах заданы базовые значения. Анализ состоит в определеннии списка неправильных ответов и их процента в общей массе
В этих тестах из общей массы вопросов различные выборки соответствуют разным критериям. Анализ надо проводить как в предыдущем случае, но раздельно по каждому критерию
Как в предыдущем случае, но вопросы только на ДА/НЕТ.