--- parser3/operators.ru.txt 2002/02/22 11:23:33 1.14
+++ parser3/operators.ru.txt 2002/06/10 14:37:35 1.42
@@ -15,7 +15,7 @@ Xне сделано, видимо, не будет сделано
пустая таблица не defined
пустой hash не defined
!eq ne lt gt le ge для сравнения строк,
- !in "/dir/" для проверки[раньше ^start]
+ !in "/dir/" для проверки
["внутри не допустимы, если надо сравнить со сложным,
пусть это будет переменная].
!is 'type' для проверки типа левого операнда,
@@ -49,19 +49,43 @@ Xне сделано, видимо, не будет сделано
!^switch[значение]{^case[вариант1[;вариант2...]]{действие}^case[DEFAULT]{действие по умолчанию}}
!^while(условие){тело}
!^for[i](0;4){тело}[[разделитель]|{разделитель который выполняется перед непустым очередным не первым телом}]
- X^exit[] + - прекращяет обработку запроса.
+ !^use[модуль]
+ !^try{
+ ...
+ !^throw[sql.connect;вася;болван] // был ^error[текст]
+ ...
+ }{
+ ^if($exception.type eq sql){
+ $exception.handled(1) ^rem{флаг, что exception обработан}
+ ....
+ }
+
+ ^switch($exception.type){
+ ^case[sql;mail]{
+ $exception.handled(1)
+ код, обрабатывающий sql ошибку
+ $exception.type = sql.connect
+ $exception.file $exception.lineno [если не запрещены при компиляции]
+ $exception.source = вася
+ $exception.comment = болван
+ }
+ ^case[_default]{
+ код, обрабатывающий другую ошибку
+ ^throw[$exception] << re-throw
+ }
+ }
+ }
+ ^exit[] + - прекращяет обработку запроса.
удобно сделать после выставления 401 ошибки
- X^return[результат] + - отваливает из выполнения метода,
+ ^return[результат] + - отваливает из выполнения метода,
выдавая нестандартный результат
- X^break[] + - обрывает цикл
- X^continue[] + - обрывает итерацию цикла
- !^use[модуль]
- X^try{код}{...catch...} пока не придумал, как лучше
+ ^break[] + - обрывает цикл
+ ^continue[] + - обрывает итерацию цикла
!^untaint[[as-is|file-spec|http-header|mail-header|uri|table|sql|js|xml|html|optimized-html]]{код}
default as-is
!^taint[[lang]][код]
default "just tainted, language unknown"
- !^process[строка, которая будет process-ed, как код]
+ !^process{строка, которая будет process-ed, как код}
!^connect[protocol://строка соединения]]{код с ^sql[...]-ями}
!mysql://user:pass@{host[:port]|[/unix/socket]}/database?
charset=cp1251_koi8&
@@ -69,9 +93,11 @@ Xне сделано, видимо, не будет сделано
compress=1&
named_pipe=1
- !pgsql://user:pass@{host[:port]|[local]}/database
+ !pgsql://user:pass@{host[:port]|[local]}/database?
+ client_encoding=win,[to-find-out]&
+ datestyle=ISO,SQL,Postgres,European,NonEuropean=US,German,DEFAULT=ISO
- oracle://user:pass@service?
+ !oracle://user:pass@service?
NLS_LANG=RUSSIAN_AMERICA.CL8MSWIN1251&
NLS_LANGUAGE language-dependent conventions
NLS_TERRITORY territory-dependent conventions
@@ -114,13 +140,25 @@ odbc c:\drives\y\parser3project\odbc\
ставить такой префикс перед открывающим апострофом, впритык, везде без проблелов
/**имя_поля**/'literal'
!^rem{}
- !^error[текст]
!^cache[файл](секунд){код}
+ !относительное задание времени
!скэшировать строку, которая получается при выполнении кода на 'секунд' секунд
!если 0секунд, значит не кэшировать, а старый такой стереть
+ !^cache[файл][expires date]{код}
+ !абсолютное задание времени
+ X^cache[файл] удалить файл [не ругает, если его нет] // такое было, больше не будет, делать ^cache(0)
+ !^cache(секунд)
+ !^cache[expires date]
+ !сигнализирует вышестоящему ^cache "уменьши до стольких-то 'секунд'/'expires'"
+ !в пределе: ^cache(0) отменить кэширование
+ X^cache[read]
+ сигнализирует вышестоящему ^cache "взять скэшированное насильно, игнорируя expires",
+ выдаёт bool "получилось/нет"
+
Xесть глобальный флажок в свойствах/командной строке "не оптимизировать"
- !и есть исключение: ^untaint[html]{код} не оптимизируется безотностительно флажка
+ !и есть исключение: ^untaint[html]{код} не оптимизируется
+ Xбезотностительно флажка
!у всех макросов есть локальная переменная $result, если в неё что положить,
!то _это_ будет результатом макроса, а не его тело
@@ -193,7 +231,7 @@ odbc c:\drives\y\parser3project\odbc\
!^имя.div(на сколько /)
!^имя.mod(на сколько %)
!^имя.format[формат]
- !^int/double:sql{query}[[$.limit(2) $.offset(4) $.default(0)]]
+ !^int/double:sql{query}[[$.limit(2) $.offset(4) $.default{0}]]
запрос, результат которого должен быть один столбец/одна строка
!string
@@ -205,7 +243,7 @@ odbc c:\drives\y\parser3project\odbc\
пример:
^if(def $form:name) не пуста?
^if($user.isAlive) истина? [автопреобразование к числу, не ноль?]
- !^string::sql{query}[[$.limit(2) $.offset(4) $.default[n/a]]]
+ !^string::sql{query}[[$.limit(2) $.offset(4) $.default{n/a}]]
результат запроса должен быть один столбец/одна строка
!^имя.int[] .int(default) целочисленное значение строки.
если ломается преобразование, берётся default
@@ -213,15 +251,15 @@ odbc c:\drives\y\parser3project\odbc\
если ломается преобразование, берётся default
!^имя.format[формат] %d %.2f %02d...
!^строка.match[шаблон][[опции поиска]] $prematch $match $postmatch $1 $2...
- опции поиска=
- i CASELESS
- x whitespace in regex ignored
- s singleline = $ считается концом всего текста
- m multiline = $ считается концом строки[\n], не концом всего текста
- g найти все вхождения, а не одно
+ опции поиска=
+ i CASELESS
+ x whitespace in regex ignored
+ s singleline = $ считается концом всего текста
+ m multiline = $ считается концом строки[\n], не концом всего текста
+ g найти все вхождения, а не одно
!^строка.match[шаблон][опции поиска]{замена}
- опции поиска+=
- g заменить все вхождения, а не одно
+ опции поиска+=
+ g заменить все вхождения, а не одно
!^строка.{l|r}split[разделитель] таблица из столбца $piece
!^строка.upper|lower[]
X^строка.truncate(предел терпенья) стиль :(
@@ -241,11 +279,11 @@ odbc c:\drives\y\parser3project\odbc\
числовое значение равно count[]
!^table::create[[nameless]]{данные} старое имя "set"
!^table::create[table]
- клонирует таблицу
+ клонирует таблицу
!^table::load[[nameless;]путь]
!если не nameless, названия колонок берутся из первой строки
!пустые строки, и строки в первой колонке содержащие '#', игнорируются
- !^table::sql{query}[[$.limit(2) $.offset(4)]]
+ !^table::sql{query}[[$.limit(2) $.offset(4) todo:$.default{ ^table::create[...] }]]
!^таблица.save[[nameless|append;]путь]
!$таблица.поле
!$таблица.fields+ из named таблицы выдаёт текущую запись как Hash
@@ -265,11 +303,16 @@ odbc c:\drives\y\parser3project\odbc\
!^таблица.join[таблица] - добавляет записи из таблицы.
таблицы должны иметь одинаковую структуру.
!^таблица.flip[] выдаёт транспонированную, надо куда-то сложить, потом пользовать
- !^таблица.locate[поле;значение] выдаёт bool
+ !^таблица.locate[поле;значение] передвигает текущую строку, если найдёт. выдаёт bool
+ !^таблица.locate(логическое выражение) передвигает текущую строку, если найдёт. выдаёт bool
!^таблица.hash[поле, что будет ключом][[поле значений|table поля значений]]+
значением $hash.ключ будет hash в котором поля значений будут ключами
поля значений могут быть не указаны, тогда ими будут все столбцы, включая ключевой
!^таблица.columns[]+ таблица из одного столбца $column
+ !$отобранное[^таблица.select(выражение)] = таблица из тех же столбцов и строк, у которых условие совпало
+ $adults[^man.select($man.age>=18)]
+ ^таблица.color[цвет1;цвет2]
+
!hash
!в выражении
@@ -284,9 +327,11 @@ odbc c:\drives\y\parser3project\odbc\
перезаписывает одноимённые
!^hash.sub[вычитаемое]
!^a.union[b] = объединение
+ одноимённые остаются
!^a.intersection[b] = пересечение
+ значения a
!^a.intersects[b] = bool
- !^hash::sql{запрос}[[$.limit(2) $.offset(4)]]
+ !^hash::sql{запрос}[[$.limit(2) $.offset(4) todo:$.default{$.field[]...}]]
получается hash(ключи=значения первая колонка ответа)
of hash(ключи=названия остальных колонкок ответа)
!^hash._keys[]+ таблица из одного столбца $key
@@ -327,6 +372,7 @@ odbc c:\drives\y\parser3project\odbc\
! $value[abc] field: {abc}<<часть
! $attribute[zzz] field: abc; {attribute=zzz}<<часть
!$response:body[DATA] замещает стандартный ответ
+ !$response:status
!^response:clear[] забыть все заданные response поля
!$response:charset
кодировка клиента т.е. та,
@@ -415,12 +461,15 @@ Xhashfile
]
]
]
- !для отправки используется программа с параметрами, задаваемая
- $MAIL.sendmail[команда]
- если не будет задана, проверяется, доступна ли
- /usr/sbin/sendmail или
+ !для отправки
+ под unix используется программа с параметрами, задаваемая
+ $MAIL.sendmail[команда]
+ если не будет задана, проверяется, доступна ли
+ /usr/sbin/sendmail или
/usr/lib/sendmail
- и, если доступна, то запускается с параметром "-t".
+ и, если доступна, то запускается с параметром "-t".
+ под win32 используется SMTP протокол, сервер задаётся
+ $MAIL.SMTP[smtp.domain.ru]
!image
!$картинка[^image::measure[DATA]]
@@ -483,10 +532,11 @@ Xhashfile
каталоги для dest создаются с правами 775
каталог старого файла стирается, если после move он остаётся пуст
!^file:lock[имя файла]{код}
- файл при необходимости создаётся
- блокируется
- выполняется код
- разблокируется
+ файл при необходимости создаётся
+ блокируется
+ выполняется код
+ разблокируется
+ Xchmod[...] НЕТ И НЕ БУДЕТ, ЧТОБЫ НЕ МОГЛИ СДЕЛАТЬ executable и запустить, даже если ftp запрещает chmod.
!math
!$math:PI
@@ -501,18 +551,26 @@ Xhashfile
!date
!время типа time можно использовать в выражениях, подставляет
- количество дней с epoch [1 января 1970 (UTC)], дробное
+ количество дней с epoch [1 января 1970 (UTC)], дробное
!всё происходит в localtime,
!временная зона задаётся вне parser средствами OS
!^date::now[]
+ !^date::now(смещение в днях) выдаёт сейчас+смещение
!^date::create(дней с epoch) // старое имя set
- !^date::create(year;month;day[;hour[;minute[;second]]]) // старое имя set
- !$date.year month day hour minute second weekday read-only
- !^date.roll[year|month|day](+/- 1) сдвигает дату
+ !^date::create(year;month[;day[;hour[;minute[;second]]]]) // старое имя set
+ ^date::sql-create[дата в формате %Y-%m-%d %H:%M:%S]
+ для удобного создания по значению из базы
+ формат1: %Y[-%m[-%d[ %H[:%M[:%S]]]]]
+ формат2: %H:%M[:%S]
+ !$date.year month day hour minute second weekday todo:yearday
+ read-only
+ !^date.roll[year|month|day](+-смещение) сдвигает дату
!^date.sql-string[] %Y-%m-%d %H:%M:%S
where published='$дата.sql-string[]'
- !^date:calendar[rus|eng;год;месяц] выдаёт таблицу
- !^date:calendar[rus|eng;год;месяц;день] выдаёт таблицу
+ !^date:calendar[rus|eng;год;месяц] выдаёт неименованную таблицу
+ столбцы: 0..6
+ !^date:calendar[rus|eng;год;месяц;день] выдаёт именнованную таблицу
+ столбцы: year, month, day, weekday
xdoc(xnode)
DOM1 attributes:
@@ -561,12 +619,13 @@ xdoc(xnode)
!cdata-section-elements = qnames
!indent = "yes" | "no"
!media-type = string />
+ !параметры передаются как есть, не xpath выражения
!.string[output options]
!.save[file.xml;output options] с шапкой
!.file[output options] = file
output options идентичны атрибутам xsl:output
- [исключение: игнорируется cdata-section-elements, нужно будет, сделаю]
+ [исключение: игнорируется cdata-section-elements, нужно будет, сделаю]
выдаёт media-type при подстановке $response:body[сюда]
@@ -642,7 +701,7 @@ xdoc(xnode)
!XPath:
!^node.select[xpath/query/expression] = array of nodes,
- empty array if nothing found
+ empty array if nothing found
!^node.selectSingle[xpath/query/expression] = first node if any
!^node.selectBool[xpath/query/expression] = bool if any
!^node.selectNumber[xpath/query/expression] = double if any
@@ -714,21 +773,24 @@ xdoc(xnode)
file
!$status:rusage hash
- !utime user time used
- !stime system time used
- !maxrss max resident set size
- !ixrss integral shared text memory size
- !idrss integral unshared data size
- !isrss integral unshared stack size
+ !utime user time used
+ !stime system time used
+ !maxrss max resident set size
+ !ixrss integral shared text memory size
+ !idrss integral unshared data size
+ !isrss integral unshared stack size
+
+!DATA::=string | file
!MAIN
это класс, загружаемый на автомате из parser3.conf,
кучи auto.p и запрашиваемого документа:
!parser3.conf
cgi:
- 1.0) полный путь из переменной окружения PARSER_ROOT_CONFIG
- 1.1) configure sysconfdir|windows directory
- 2)рядом с бинарником parser'а
+ 1. или полный путь из переменной окружения HTTP_PARSER_ROOT_CONFIG
+ или configure sysconfdir|windows directory
+ 2. или полный путь из переменной окружения HTTP_PARSER_SITE_CONFIG
+ или рядом с бинарником parser'а
isapi: windows directory
apache module:
1) ParserRootConfig [httpd.conf only]
@@ -741,23 +803,34 @@ xdoc(xnode)
!результат которого передаётся в его @post-process[data] if($data is string) ...
!результат которого отдаётся пользователю
- !если встречается ошибка, её можно красиво сообщить пользователю,
+!если встречается ошибка и try не задан, её можно красиво сообщить пользователю,
!определив
- !@exception[origin;source;comment;type;code;stack]
- !origin файл(строка) где случилась проблема
- !source строка, из-за которой случилась проблема
- !comment комментарий english
- !type строка "тип проблемы" (пока пусто)
- !code строка "код проблемы" (пока пусто)
- !stack табличка из колонок origin name,
- там лежат в обратном порядке имена[name] и места вызовов[origin]
+ !@unhandled_exception[exception;stack]
+ !$exception.type строка "тип проблемы"
+ !$exception.file $exception.lineno файл и строка где случилась проблема [если не запрещены при компиляции]
+ !$exception.source строка, из-за которой случилась проблема
+ !$exception.comment комментарий english
+ !stack табличка из колонок file line name,
+ там лежат в обратном порядке имена[name] и места вызовов[file line]
операторов/методов, приведших к ошибке.
- !нужно выключить русский apache: CharsetDisable on
+!системные типы ошибок:
+ !parser.compile ^test[} компиляция (непарная скобка, ...)
+ !parser.runtime ^if(0). параметры (больше/меньше, чем нужно, не тех типов, ...)
+ !number.zerodivision ^eval(1/0) ^eval(1%0)
+ !number.format ^eval(abc*5)
+ !file.lock shared/exclusive lock error
+ !file.missing ^file:delete[delme] not found
+ !file.access ^table::load[.] no rights
+ !image.format ^image::measure[index.html] not gif/jpg
+ !sql.connect ^connect[mysql://baduser:pass@host/db]{} not found/timeout
+ !sql.execute ^void:sql{select bad} syntax error
+ !xml ^xdoc::create{} any error in xml/xslt libs
+ !smtp.connect not found/timeout
+ !smtp.execute communication error
-!DATA::=string | file
+!нужно выключить русский apache: CharsetDisable on
----
- если в MAIN будет определён флаг $ORIGINS(1) то вместо обычного вывода страницы будет
+!если в MAIN будет определён флаг $ORIGINS(1) то вместо обычного вывода страницы будет
выдан список фрагментов результата с указанием их происхождения