Бэкап описаний из блока внутри вопроса

Issue #122 closed
Oleg Sychev repo owner created an issue

Originally reported on Google Code with ID 122

Весь код обработки описаний узлов переместился в блок. Довольно странно при этом хранить
соответствующую таблицу в вопросе.

Но нужно продумать как идентифицировать строки из (потенциально) разных источников.
Как вариант могу предложить использовать два поля: имя таблицы и идентификатор в ней.
Т.е. для нашего вопроса будет имя таблицы question_answers и ее id. Тогда перепутать
будет невозможно...

Reported by oasychev on 2012-05-08 17:24:22

Comments (33)

  1. Former user Account Deleted

    ``` Хорошо, пусть будет так. Однако, я не совсем понимаю что хранит block_formal_langs_processed_string в $tokenstream - я так понимаю там block_formal_langs_token_stream? Во-вторых, я не совсем понимаю, как всё это повлияет на форму редактирования вопроса - её логика останется прежней? И будут ли какие-то скрипты для установки нового блока и функции для удобного получения/вставки/обновления описания лексем? ```

    Reported by `mamontov.dp` on 2012-05-08 17:40:56

  2. Oleg Sychev reporter

    ``` Его и хранит. Логика остается прежней, просто надо самому создать эту строку (возможно туда надо добавить помимо поля с id еще и имя таблицы) - написав для этого конструктор, и передавать ее в объект языка для сканнига/парсинга.

    Функции для получения описаний лексем уже есть, это по сути сейчас единственные функции в классе. Для вставки/обновления ... можно добавить необходимые функции.

    Просто работа с этой таблицей - чтение/запись, бэкап/рестор - должна вестись через блок, а не вопрос... Записи в таблице будут создаваться только для тех строк (ответов в вашем случае), для которых есть описания... ```

    Reported by `oasychev` on 2012-05-08 17:46:13

  3. Former user Account Deleted

    ``` Меня смущает тот факт, что в описании функции node_description($nodenumber) по идее описано, что мы каждый раз должны обращаться к таблице (что в момент загрузки объекта языка не есть хорошо, особенно когда нам надо редактировать описания, а работы по синтаксическому анализу - тем более). Куда удобнее и быстрее их получать их в момент конструирования самого объекта строки общим количеством, и потом, т.к. они кому-то нужны запихивать их в строку. Во-вторых обновление и вставку лексем вопроса с текущей логикой реализовать будет бессмысленно, так как проще и быстрее будет обратиться к таблице напрямую, чем через функцию класса. ```

    Reported by `mamontov.dp` on 2012-05-08 18:02:17

  4. Oleg Sychev reporter

    ``` А причем объект языка и node_description? Объект строки - отдельная вещь. Один объект языка может работать со множеством объектов строк.

    Удобнее всего кешировать описания узлов при первом использовании. Потому что есть много мест где нужен объект строки без описаний. Поэтому в конструкторе не надо. Я бы сделал так: завел protected кеш который заполняется описаниями всех узлов если запрошено описание хотя бы одного узла...

    Обновление/вставку описаний придется делать через блок, т.к. таблица уйдет туда. Возможно что получившаяся функция будет статической в классе блока, но ни в коем случае не напрямую из вопроса, это нарушает инкапсуляцию. Код работы с таблицами блока должен быть в блоке, а не вопросе... ```

    Reported by `oasychev` on 2012-05-08 18:59:24

  5. Former user Account Deleted

    ``` В моём случае значительно больше мест, где нужны сами описания без лексем. Ладно, я сейчас сделал у себя тестовую таблицу в блоке, попробую добавить статические функции, которые дадут мне возможность делать нормальную вставку/обновление символов. ```

    Reported by `mamontov.dp` on 2012-05-08 19:22:06

  6. Oleg Sychev reporter

    ``` Дмитрий, я думаю такие функции работы с БД не должны быть public. Блок должен предоставлять более высокоуровневый интерфейс: сохранять (обновлять, удалять) описания для всей строки, а не по одному... ```

    Reported by `oasychev` on 2012-05-09 00:06:32

  7. Former user Account Deleted

    ``` В таком случае текущий интерфейс строки вообще не подходит для реализации. В нём нельзя задать таблицу-источник, как я понимаю stringid - должен указывать на id строки, но самое неудобное заключается в том, что теперь циклов в работе с БД не избежать. А тот интерфейс такое позволяет. ```

    Reported by `mamontov.dp` on 2012-05-09 06:23:09

  8. Former user Account Deleted

    ``` И да, в момент сохранения и обновления описаний мне вообще эта строка не нужна. Мне нужен только массивы описаний и id ответов, которым они соответствуют, причем все эти данные можно выяснить абсолютно без сканирования строки. В момент получения описаний для редактирования вопроса также токены не нужны ибо работать с массивом описаний удобнее (их можно собрать в значение поля, используя implode). ```

    Reported by `mamontov.dp` on 2012-05-09 07:01:10

  9. Oleg Sychev reporter

    ``` Ну так добавьте поле про таблицу-источник. Я не думаю, что использование методов класса чему-то мешает.Можно сделать статический метод класса block_formal_langs_processed_string который бы получал данные для переданного массива объектов (я так понимаю что при сохранении/обновлении циклов не избежать в любом случае).

    Точно также класс block_formal_langs_processed_string не обязан актуально содержать токены, я бы даже сделал поля с токенами и деревом защищенными и сделал методы доступа, которые проверяли их заполнение (не null) и если нет то заполняли при первом обращении. "Ленивые вычисления" здесь вполне подойдут мне кажется. Необходимый минимум это строка или id и имя таблицы (я не зря не создавал конструктора, потому что в разных местах эти объекты будут конструироваться по-разному; но методы-хелперы по созданию объекта из строки и БД будут полезны).

    Цель класса block_formal_langs_processed_string - централизовать в едином месте код, обрабатывающий данные о строке в зависимости от особенностей языка (может ли парсить и т.д.), при этом оставляя классы языка/сканера/парсера без состояния. ```

    Reported by `oasychev` on 2012-05-09 12:28:21

  10. Former user Account Deleted

    ``` Простите не понял - откуда получал, массива объектов чего? У нас при сохранении описаний не нужно лишний раз разбирать строку для того, чтобы установить у каждого символа описания. Логично думаю, просто добавить поле с массивом описаний, которые будут соответствовать символу (раз мы все равно по индексу достаем описание, ничего нам не мешает так сделать). Тогда удаление и получение также будет довольно простым, впрочем циклов вида "для каждого ответа на вопрос" и связанных с ними замедлений не избежать... ```

    Reported by `mamontov.dp` on 2012-05-09 18:40:41

  11. Oleg Sychev reporter

    ``` Ну создайте при классе статическую функцию которой передается массив объектов строк (я же написал что можно без разбора) - например строк-ответов - и которая все получает и заполняет поля с описаниями. В чем проблема то? Просто привяжите функцию к классу, чтобы зря не болталась...

    Поле с описаниями добавить можно и нужно, но оно - как и токены, и дерево - должно заполняться лениво. У меня было мало времени, поэтому я не мог сделать полноценный класс во всех деталях - мне важнее было показать идею. Но если есть проблемы с пониманием - давайте в пятницу на встрече их решим... ```

    Reported by `oasychev` on 2012-05-09 19:30:08

  12. Oleg Sychev reporter

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

    Дмитрий, несколько моментов: 1) в тех случаях, когда геттер/сеттер один лучше пользоваться "магическими" методами PHP чем унылыми функциям set_xxx. 2) если возможно, я бы предпочел иметь все функции (в т.ч. статические), связанные с описаниями узлов, при классе processed_string, а не раскиданными по двум классам. 3) функции, которые работают с описаниями нескольких строк сразу мы давно обсуждали, чтобы не было циклов с запросами к БД, но их пока нет. Даже заголовков с TODO... 4) (Сергей, это касается и вас) - на предефайнед язык достаточно 3 класса: язык, сканер и парсер. Промежуточные классы-адаптера сканера и парсера можно убрать, системы генерации позволяют вставить весь код адаптации непосредственно в сгенерированные классы сканера/парсера.

    Сергей, слейте эти изменения (вам может быть удобнее отменить ваши). От вас по этому issue нужно чтобы заработал сканер английского языка как я описывал в комментарии 1 к #121, ну и Си сканер. И чтобы эти сканеры стыковались с классами языка...

    ```

    Reported by `oasychev` on 2012-05-25 14:01:10

  13. Oleg Sychev reporter

    ``` Ну для полного фиксед не мешало бы в блоке бэкап/рестор сделать... ```

    Reported by `oasychev` on 2012-07-27 15:43:14 - Status changed: `InProgress`

  14. Oleg Sychev reporter
    К релизу бэкап-рестор нужен обязательно!
    

    Reported by oasychev on 2012-12-14 17:11:55 - Labels added: Priority-Critical - Labels removed: Priority-Medium

  15. Oleg Sychev reporter
    Описания должны бэкапиться из кода блока, но как внутренняя часть вопроса (или в чем
    еще используются). Т.е. надо расширить бэкап вопроса так, чтобы он вызвал блок для
    бэкапа/рестора описаний.
    
    Обязательно необходимо к релизу! Без этого ни один серьезный ВУЗ использовать вопрос
    не будет. Сам вопрос бекапится автоматически через код от poasquestion, но таблицы
    описаний это не касается. Надо расширить бэкап ответов так, чтобы он хранил (и восстанавливал)
    описания. Ссылки на Moodle Docs под бэкапу выложить или сами найдете?  Примеры - в
    любом модуле, из блоков - только в тех, где есть таблицы.
    

    Reported by oasychev on 2013-01-11 21:17:15 - Status changed: Accepted - Labels added: Type-Enhancement - Labels removed: Type-Defect

  16. Former user Account Deleted
    У меня возник вопрос: что делать с языком? Его экспортировать или не трогать?
    

    Reported by mamontov.dp on 2013-01-20 19:02:36

  17. Oleg Sychev reporter
    Если язык predefined, то надо экспортировать только достаточно информации, чтобы его
    определить при восстановлении - служебное имя + версия?
    А для пользовательских языков надо конечно все экспортировать...
    

    Reported by oasychev on 2013-01-21 10:54:12

  18. Former user Account Deleted
    В самом Moodle, как я понял при бекапе используется декларативное описание данных, которое
    несколько не предполагает вышеуказанный usecase. Впрочем, можно экспортировать все.
    

    Reported by mamontov.dp on 2013-01-21 11:24:13

  19. Oleg Sychev reporter
    Посмотрите как экспортируется любой вопрос Moodle. Дополнительные данные к ответам есть
    в numerical например, правда по одной строке на ответ...
    

    Reported by oasychev on 2013-01-21 11:33:31

  20. Former user Account Deleted
    Проблема в том, что в данном случае экспорт зависит от конкретных данных вопроса которые
    на момент вызова основного метода недоступны. Есть вариант как-то сработать с SQL,
    который будет собирать данные, но это не самый красивый вариант, хотя бы потому что
    как-то придется решать проблему с разными полями при бекапе.
    

    Reported by mamontov.dp on 2013-01-21 11:37:13

  21. Former user Account Deleted
    Для описаний как раз такой проблемы нет - просто выбрать записи при бекапе довольно
    легко.
    

    Reported by mamontov.dp on 2013-01-21 11:37:52

  22. Oleg Sychev reporter
    Язык - часть вопроса и бэкапиться вместе с вопросом, в вопросе же id есть и данные о
    языке получить можно; описания - бэкапятся вместе с ответами, т.к. они их часть. 
    

    Reported by oasychev on 2013-01-21 12:18:25

  23. Former user Account Deleted
    Хорошо, как можно получить id вопроса в define_question_plugin_structure()? Может быть
    я просто не там смотрю, но здесь нигде нет явной возможности узнать какие поля мы создаем
    в зависимости от конкретного question instance. И да, насколько я понимаю, backup::VAR_PARENTID
    - не даст в данном случае результата, т.к. это просто плейсхолдер, который потом заменяется
    на то, что нужно.
    

    Reported by mamontov.dp on 2013-01-21 12:24:03

  24. Oleg Sychev reporter
    http://docs.moodle.org/dev/Backup
    
    А зачем в define_question_plugin_structure то? Данные же не там нужны...
    Можно одинаковые данные о разных языках бэкапить, просто пустые они у predefined будут...
    

    Reported by oasychev on 2013-01-21 12:46:51

  25. Oleg Sychev reporter
    Пусть будет одинаковая структура с пустыми данными. Просто рестор должен быть чуть умнее,
    чтобы правильно отресторить....
    

    Reported by oasychev on 2013-01-21 12:53:54

  26. Former user Account Deleted
    Спасибо, но я уже видел эту ссылку и она представляет собой общие слова, которые не
    описывают реальный механизм.
    Вы сами выше сказали, что бэкапить нужно те поля у языка, которые нужны (т.е. все что
    есть у userdefined, имя и версию у остальных). Это относится к структуре данных плагина,
    что определяется в данном методе. 
    Насчет одинаковых данных - это ровно то, что я и предлагал сделать выше.
    

    Reported by mamontov.dp on 2013-01-21 12:54:18

  27. Oleg Sychev reporter
    При попытке забэкапить категорию из двух вопросов, первый восстановился нормально, а
    во втором - ошибки полезли при восстановлении
    Notice: Undefined index: 5407 in Z:\home\moodle\www\question\type\correctwriting\backup\moodle2\restore_qtype_correctwriting_plugin.class.php
    on line 236
    Notice: Undefined index: 5407 in Z:\home\moodle\www\question\type\correctwriting\backup\moodle2\restore_qtype_correctwriting_plugin.class.php
    on line 236
    Notice: Undefined index: 5407 in Z:\home\moodle\www\question\type\correctwriting\backup\moodle2\restore_qtype_correctwriting_plugin.class.php
    on line 236
    Notice: Undefined index: 5407 in Z:\home\moodle\www\question\type\correctwriting\backup\moodle2\restore_qtype_correctwriting_plugin.class.php
    on line 236
    Notice: Undefined index: 5407 in Z:\home\moodle\www\question\type\correctwriting\backup\moodle2\restore_qtype_correctwriting_plugin.class.php
    on line 236
    
    Файл бэкапа прикладываю; если надо посмотреть содержимое - копию поменять расширение
    в zip. 
    

    Reported by oasychev on 2013-02-18 10:52:15

    <hr> * Attachment: backup-moodle2-course-2-tpr-20130216-1517-nu.mbz

  28. Former user Account Deleted
    Проблему обнаружил, новый коммит исправляет. После этого смотрел в банк вопросов - описания
    соответствуют тем, что были в файле. Fixed не ставлю, т.к. могут возникнуть другие
    проблемы. 
    

    Reported by mamontov.dp on 2013-02-24 18:43:01

  29. Oleg Sychev reporter
    ОК, посмотрю
    К релизу еще с картинкой проблемы посмотрите - чтобы галочку для перемещенной такую
    же сделать, как и для отсутствующей лексемы; и насчет шрифтов, а также переводимости
    строк answer/response...  Там должны быть пустяки...
    

    Reported by oasychev on 2013-02-24 18:46:32

  30. Former user Account Deleted
    Конечно, я уже занимаюсь этим. Прошу прощения за задержку - было много дел. С картинкой
    придется повозится, а вот шрифты и локализация думаю завтра вечером будут точно.
    

    Reported by mamontov.dp on 2013-02-24 18:48:11

  31. Oleg Sychev reporter
    Со шрифтом просто гляньте на тот файл, что я проставил ссылку, идущий с Moodle. Мне
    кажется он лучше, но полной программы просмотра шрифта нет под рукой... Если лучше
    - добавленный вами шрифт можно прибить.
    

    Reported by oasychev on 2013-02-24 18:51:11

  32. Log in to comment