Хранение на сервере парсерных переменных системных типов
Misha v.3 [04 декабря 2007]
Периодически возникает потребность в рамках сессии пользователя хранить какие-либо его данные на сервере (например при заполнении многостраничных форм или для того, чтобы не сообщать ему какие-либо идентификаторы в явном виде).
Для решения подобных задач может быть использованы разные хранилища: hashfile, файлы или база данных, но возможно удобнее всего делать это с помощью hashfile, т.к. это реализуется достаточно просто и не нужно писать много кода для удаления устаревшей информации.
Однако используя hashfile на сервере можно хранить только строки, из-за этого требуется написать некоторое количество кода, если нужно сохранить некую структуру данных.
Предлагаемые классы имеют интерфейс, аналогичный интерфейсу hashfile, но позволяют хранить данные в разных хранилищах (в hashfile, в БД и в файлах) и умеют хранить не только строки, поддерживаются переменные следующих системных классов: string, int, double, date, bool, table, hash, file, xdoc и xnode (с image и пользовательскими классами — облом).
В случае необходимости несложно перейти с использования одного хранилища на другое (правда скрипты по переносу данных предстоит написать вам самим, т.к. основное назначение классов — хранение сессионной информации, потеря которой не критична).
Пример использования:
# вместо StorageHF может быть StorageFile и StorageSQL
# правда в последнем случае изменятся параметры конструктора, вместо $.sDataDir надо будет
# определить $.oSql и в БД создать таблицу для хранилища.
$oStorage[^StorageHF::create[test;
$.sDataDir[/../data/storage]
]]
^if(!def $cookie:uid){
$cookie:uid[^math:uuid[]]
}
$sUID[$cookie:uid]
...
$hData[^oStorage.get[$sUID]]
^if(!def $hData){
$hData[
$.a[1]
$.b[
$.c[2]
]
]
^oStorage.set[$sUID;
$.value[$hData]
$.expires(2) ^rem{ *** 2 дня *** }
]
}
...
# используем $hData
Параметры конструкторов:
У всех классов обязательным первым параметром является название хранилища.
Во втором параметре можно определить время хранения данных ($.expires) «по умолчанию», смысл которого совпадает с оным у системного класса hashfile (0 — кешировать «навечно»; числовое не нулевое значение (может быть дробным) — записать на указанное число дней; дата — хранить до указанной даты).
Немного подробнее про каждый из классов:
- StorageFile:
- Название хранилища — название директории, где будут храниться файлы с данными (одно хранилище — один каталог с файлами; одна запись — два файла в этом каталоге, именем файла будет являться MD5 сумма от значения ключа);
- С помощью второго необязательного параметра $.sDataDir можно задать каталог, где будут храниться директории всех хранилищ;
- Планируется, что этот класс будет использоваться из SQL классов для кеширования результатов запросов.
- StorageHF:
- Название хранилища — название hashfile (т.е. одно хранилище — два файла вне зависимости от количества записей в нём);
- С помощью второго необязательного параметра $.sDataDir можно задать каталог, где будут храниться все hashfile-ы. Можно создавать несколько объектов класса StorageHF указывая одно имя хранилища — в реалиях для хранения будет использоваться один hashfile и его повторного отрытия производиться не будет. После операций записи в hashfile с него снимаются блокировки (для этого необходим parser 3.2.2);
- Планируется, что это будет основным используемым классом для хранения сессионных данных посетителя.
- StorageSQL:
- Название хранилища — название таблицы в БД (одно хранилище — одна таблица; одна запись — одна строка в этой таблице);
- При создании объекта необходимо указать обязательный параметр $.oSql, через который класс будет делать все SQL запросы;
- Во втором параметре можно задать названия столбцов в вашей SQL таблице с помощью $.sPKColumn, $.sTypeColumn, $.sExpiresColumn, $.sValueColumn и $.sKeyColumn. Значениями «по умолчанию» являются uid, type, expires, value и name соответственно;
- Планируется, что этот класс очень редко будет использоваться для хранения сессионных данных посетителя, и нужен он будет лишь в тех случаях, когда хранить надо много данных, а ограничения класса StorageHF не позволяют делать это.
Ограничения:
Ни один из предлагаемых классов не умеет хранить объекты типа image и объекты пользовательских типов.
В мои планы входит сделать так, чтобы можно было несложным перекрытием методов расширять функциональность и вызывать методы, которые умеют сохранять/загружать данные пользовательских типов, но пока в этом направлении не делалось совершенно ничего.
Кроме этого классы пока не умеют сохранять хеши с таблицами-значениями.
Также классы имеют собственные особенности/ограничения:
- StorageFile:
- Класс не имеет ограничений на длину записи;
- Позволяет хранить таблицы и хеши, значения которых содержат символы табуляции или перевода строки (автоматически делается средствами языка при сохранении/загрузки таблиц с указанием $.encloser)
- StorageHF:
- Класс пока имеет проблемы с сохранением таблиц и хешей, значения которых содержат символы табуляции или перевода строки;
- Длина записи (ключ + значение) имеет ограничение в 8000 символов (ограничение hashfile).
- StorageSQL:
- Класс пока имеет проблемы с сохранением таблиц и хешей, значения которых содержат символы табуляции или перевода строки;
- Длина данных ограничена 65535 символами (если вдруг надо больше измените тип поля для хранения данных например с text на mediumtext).
Да, забыл сказать, что для работы этих классов требуется доступность Lib.p, Convert.p, а для работы со StorageSQL потребуется ещё и объект одного из SQL классов.
Скачать:
Storage.zip
(15.10.2014
6,6 КБ)
Архив классов для хранения данных на сервере с примером, демонстрирующим хранение разных системных типов данных.