parser

Хранение на сервере парсерных переменных системных типов

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 КБ)
Архив классов для хранения данных на сервере с примером, демонстрирующим хранение разных системных типов данных.