On-line: гостей 2. Всего: 2 [подробнее..]
АвторСообщение
moderator


Пост N: 928
Зарегистрирован: 06.07.06
ссылка на сообщение  Отправлено: 17.04.15 09:18. Заголовок: Триггеры в Letodb


Об установке/активизации триггера с клиента. Сейчас это работает:
dbInfo( DBI_TRIGGER, ... ) - можно и включить/отключить, и новую процедуру установить.
Я считаю это принципиально неверным, но убирать совсем это дело тоже, наверное, неправильно - может, кто-то использует это вовсю. В конце концов, каждый - сам кузнец своего счастья. Добавлю, наверное, опцию в letodb.ini, которая разрешает установку этого параметра с клиента ( по умолчанию должно быть запрещено - все опции по умолчанию должны обеспечивать безопасность и целостность базы ).

И по поводу установки триггеров для каждой таблицы индивидуально.
Предлагаю сделать это так: в letodb.ini добавляем параметр, который это разрешает, можно и для отдельных папок ( [DATABASE] ). Далее, чтобы установить триггер для таблицы sklad/otdel10/prihod.dbf, помещаем в letoudf.hrb процедуру с названием, например, trig_sklad_otdel10_prihod - и все. При наличии разрешения и при наличии такой процедуры сервер все делает сам.


Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 20 [только новые]


постоянный участник




Пост N: 591
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 17.04.15 13:09. Заголовок: alkresin пишет:чтобы..


alkresin пишет:
 цитата:
чтобы установить триггер для таблицы sklad/otdel10/prihod.dbf, помещаем в letoudf.hrb процедуру с названием, например, trig_sklad_otdel10_prihod - и все


как быть, если таблицы prihod.dbf находятся по подкаталогам месяцев, по годам, т.е. имя таблицы одно, а мест расположений много ?
надо как то группировать, нескольким таблицам (может по шаблону) один триггер



Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 592
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 17.04.15 13:16. Заголовок: В SixNsx была метода..


В SixNsx была метода в триггере:
в EVENT_PREUSE (при наличии ini у dbf), если он отсутсвовал, читать структуру, индексы из ini, делать dbCreate, OrdCreate.
как правильно поступать в letodb, при наличии ini у таблицы ?


Спасибо: 0 
ПрофильЦитата Ответить
moderator


Пост N: 931
Зарегистрирован: 06.07.06
ссылка на сообщение  Отправлено: 17.04.15 13:47. Заголовок: Теперь по умолчанию ..


Теперь по умолчанию dbInfo(DBI_TRIGGER,...) не может изменить установки триггера.
Чтобы разрешить dbInfo() менять установки, ставьте в letodb.ini:
EnableSetTrigger = 1

SergKis пишет:

 цитата:
как быть, если таблицы prihod.dbf находятся по подкаталогам месяцев, по годам, т.е. имя таблицы одно, а мест расположений много ?
надо как то группировать, нескольким таблицам (может по шаблону) один триггер


Можно сделать, например, так: называть такие функции trigall_prihod(), а в коде сервера добавить проверку наличия такой функции, если нет trig_path_prihod().


 цитата:
как правильно поступать в letodb, при наличии ini у таблицы ?


Наверное, в коде триггерной функции это можно сделать.

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 593
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 17.04.15 17:09. Заголовок: alkresin пишет:Можно..


alkresin пишет:
 цитата:
Можно сделать, например, так: называть такие функции trigall_prihod(), а в коде сервера добавить проверку наличия такой функции, если нет trig_path_prihod().


сейчас в триггре, можно фильтровать "нужные" таблицы:
cTable := (nArea)->(dbInfo(DBI_FULLPATH)) и т.д. (сейчас некоторые табл.отсекаю от триггера)

FUNCTION my_Trigger( nEvent, nArea, nPos, xTrigVal , nUserStru) может надо добавить в параметры nUserStru
т.к. функ. на сервере letoUseArea( nUserStru, cFileName, cAlias, lShared, lReadOnly, cdp ), ...

alkresin пишет:
 цитата:
Наверное, в коде триггерной функции это можно сделать.


функции letoUseArea(...), letoOrdListAdd(...), letoOrdCreate(...) есть, а leto_dbCreate(...) нет.
правильно ли использовать dbCreate(...) ?






Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 604
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 20.04.15 10:40. Заголовок: SergKis пишет:функци..


SergKis пишет:
 цитата:
функции letoUseArea(...), letoOrdListAdd(...), letoOrdCreate(...) есть, а leto_dbCreate(...) нет.
правильно ли использовать dbCreate(...) ?


в UDF_Init и TRIGGER dbCreate(...) работает, а letoUseArea(...), ... не работают нет nUserStru
в UDF_Init можно создать, открыть таблицу dbUseArea(...), но в TRIGGER она закрыта, а доступны только открытые с клиента.
Что и как надо делать, для открытия таблиц(ы) в UDF_Init ? О таблице(ах) клиент ничего не знает.


Спасибо: 0 
ПрофильЦитата Ответить
moderator


Пост N: 935
Зарегистрирован: 06.07.06
ссылка на сообщение  Отправлено: 20.04.15 15:01. Заголовок: В udf_init() можно т..


В udf_init() можно только открыть с помощью dbUseArea() для каких-либо операций и здесь же закрыть.

 цитата:
О таблице(ах) клиент ничего не знает.


Естественно, он знает только о тех таблицах, которые сам открыл.

Чтобы добавить nUserStru в параметры вызова триггера, надо полностью изменить реализацию триггеров в letodb сервере. Сейчас все операции по вызову триггерных процедур осуществляются на уровне DBFCDX ( из dbf1.c ), letodb сервер только устанавливает имена процедур, а надо, чтобы он непосредственно вызывал их, тогда он сможет и nUserStru передать. Правда, в этом случае появится новая проблема - триггеры не будут срабатывать из udf-функций, если там манипуляции с таблицей будут осуществляться с помощью прямого использования DBFCDX ( т.е., просто будет: APPEND BLANK, REPLACE... )


Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 605
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 20.04.15 16:22. Заголовок: alkresin пишет:Чтобы..


alkresin пишет:
 цитата:
Чтобы добавить nUserStru в параметры вызова триггера, надо полностью изменить реализацию триггеров...


Со всем, сказанным, согласен, но ...
Если в сервере завести "условного" клиента с nUserStru 0 или 9999 (принадлежащего серверу), то менять работу триггера не надо, можно в UDF_Init, Trigger работать от имени этого клиента, так же как сейчас работаем UDF функцией с клиента - весь набор функций сервера leto_.... доступен .

Спасибо: 0 
ПрофильЦитата Ответить
moderator


Пост N: 936
Зарегистрирован: 06.07.06
ссылка на сообщение  Отправлено: 21.04.15 14:39. Заголовок: SergKis пишет: Если..


SergKis пишет:

 цитата:
Если в сервере завести "условного" клиента с nUserStru 0 или 9999 (принадлежащего серверу)


Я обдумывал такой вариант.
Он всем хорош, но: триггер запускается в результате операции, производимой клиентом, а действия, производимые в триггерной процедуре, будут исполняться от имени системы, все файлы, используемые в этой процедуре, надо будет открывать/закрывать по-новой ( а если они открыты клиента в exclusive mode ? ). Может, это все и не критично, но подумать еще надо.

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 606
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 21.04.15 17:24. Заголовок: alkresin пишет:Может..


alkresin пишет:
 цитата:
Может, это все и не критично, но подумать еще надо.


Согласен. По моим потребностям сегодня, в тригере работаем с табл. уже открыми с клиента (как сейчас) и плюс доп. таблицы, окрытые на сервере, о которых клиент ничего не знает, Несколько открытых в UDF_Init и некоторые табл., открываются при открытии с клиента определенных таблиц, т.е. таблицы не пересекаются (например ведение логов, требует законадательсво). Сегодня это код на клиенте.
Если имеем UDF_Init, то надо и UDF_Stop или UDF_Exit (задествовать при перезагрузке letoudf.hrb и завершении letodb).

Спасибо: 0 
ПрофильЦитата Ответить
moderator


Пост N: 937
Зарегистрирован: 06.07.06
ссылка на сообщение  Отправлено: 22.04.15 13:32. Заголовок: SergKis пишет: Если..


SergKis пишет:

 цитата:
Если имеем UDF_Init, то надо и UDF_Stop или UDF_Exit (задествовать при перезагрузке letoudf.hrb и завершении letodb).


UDF_Exit - не проблема, а вот с перезагрузкой... Она ведь выполняется в потоке клиента - соответственно, все действия в предполагаемой UDF_Stop и в вызываемой еще раз UDF_Init будут в этом потоке.

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 607
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 22.04.15 15:01. Заголовок: alkresin пишет: все ..


alkresin пишет:
 цитата:
все действия в предполагаемой UDF_Stop и в вызываемой еще раз UDF_Init будут в этом потоке.


UDF_Stop (если есть) должен отрабатывать как UDF_Init на сервере перед WrLog( "Server has been closed." ) и возможно при
ELSEIF cCommand != NIL .AND. Lower( cCommand ) == "reload", т.е.перед загрузкой new letoudf.hrb UDF_Stop и после relod, UDF_Init из new загруженной hrb. Я такое имел ввиду, но может, что не так понял ?
т.е. если в работе был Hash массив, чтобы его сохранить и перечитать, в new версии hrb.



Спасибо: 0 
ПрофильЦитата Ответить
moderator


Пост N: 938
Зарегистрирован: 06.07.06
ссылка на сообщение  Отправлено: 23.04.15 11:23. Заголовок: SergKis пишет: UDF_..


SergKis пишет:

 цитата:
UDF_Stop (если есть) должен отрабатывать как UDF_Init на сервере перед WrLog( "Server has been closed." )


Ну, вообще-то, эту роль я отвел Udf_Exit() ( уже сделал ) - название, симметричное Udf_Init(), только вызывается он из EXIT процедуры.


 цитата:
и возможно при
ELSEIF cCommand != NIL .AND. Lower( cCommand ) == "reload"


Отсюда его вызывать вряд ли имеет смысл - это ведь другой процесс, другой экземпляр исполняемого модуля сервера, который не имеет доступа к ресурсам работающего сервера.
Вот из hs_UdfReload() - можно, он, вроде, будет отрабатывать в основном потоке. Я ошибся, посчитав, что эта функция вызывается в потоке клиента - меня сбил столку код из letofunc.c,
где эта функция вызывается в ответ на запрос с клиента udf_rel - но на клиенте такой запрос нигде не формируется. Павел мог бы пояснить, для чего этот фрагмент в letofunc.c.

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 608
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 23.04.15 13:30. Заголовок: alkresin пишет:эту р..


alkresin пишет:
 цитата:
эту роль я отвел Udf_Exit() ( уже сделал )


Это здорово. Спасибо. Еще три вопроса:
 
1. AutoMakeDir = [0] \ 1 ; автоматическое создание поддиректорий, при создании hs_dbcreate(...),
что бы облегчить код клиента (при переводе с clipper, vo, другой разработчик,...). Уж очень хлопотно ...
в 2-х поточной версии сделано и работает:Скрытый текст



2. Тоже связанный с hs_createtable(). Сегодня клиент (работает c mysql и перевожу на letodb) ничего не знает о некоторых полях записи, которые ведет сервер, + при переводе разных clipper программ на letodb, в структурах возникает дублирование (не по именам, по значениям), которые решить измененнием кода клиента - большой геморой. В связи с этим просьба (при наличии letoudf.hrb) она, может быть востребованна. Ввести UDF_hs_CrateTable(aStru), которой передавать структуру таблицы и возвращать функция должна также модифицированный массив структуры (если такая функция задана в hrb),
т.е. в hs_createtable( nUserStru, cCommand ) добавить вызов:
Скрытый текст

3. Это скорее пожелание. Некоторые функции из UDF перевести в leto_..., есть leto_Sum, leto_groupby и
например UDF_getFields --> leto_getFields. Тогда у многих клиентов (организация) не надо устанавливать letoudf.hrb ... ,
это часто делают сторонние люди (нет удаленного доступа) и могут быть проблеммы (версии, ...)
Эти изменения полностью закрывают потребности в функционале letodb, по моему мнению.


Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 609
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 23.04.15 13:43. Заголовок: PS. функция должна п..


PS. функция должна получать еще имя таблицы, т.е. UDF_hs_CrateTable(aStru, cName)

Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 3255
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 30.04.15 11:35. Заголовок: Вот из hs_UdfReload(..



 цитата:
Вот из hs_UdfReload() - можно, он, вроде, будет отрабатывать в основном потоке. Я ошибся, посчитав, что эта функция вызывается в потоке клиента - меня сбил столку код из letofunc.c,
где эта функция вызывается в ответ на запрос с клиента udf_rel - но на клиенте такой запрос нигде не формируется. Павел мог бы пояснить, для чего этот фрагмент в letofunc.c.



Если это еще актуально. Запрос на перезагрузку letoudf.hrb выдается не с клиента, а на сервере командой:

letodb reload

При этом посредством SendMessage сообщение передается службе/демону letodb, и им обрабатывается как раз в этом фрагменте в letofunc.c

Спасибо: 0 
ПрофильЦитата Ответить
moderator


Пост N: 941
Зарегистрирован: 06.07.06
ссылка на сообщение  Отправлено: 30.04.15 13:01. Заголовок: Я имел ввиду несколь..


Я имел ввиду несколько строчек в letofunc.c, начиная с 8267:

else if( !strcmp( ptr,"udf_rel" ) )
...

которые, по идее, предназначены для обработки команды с клиента - но в клиентской части такой команды нет.

Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 3256
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 30.04.15 13:28. Заголовок: Там еще обрабатывают..


Там еще обрабатываются команды stop, ну и reload тоже

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 622
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 30.04.15 15:23. Заголовок: Pasha пишет:Если это..


Pasha пишет:
 цитата:
Если это еще актуально. Запрос на перезагрузку letoudf.hrb выдается не с клиента, а на сервере командой:
letodb reload


срабатывае пока так:
UDF_INIT letodb test
UDF_INIT letodb reoload
UDF_EXIT letodb stop
а зачем сообщение о перезагрузке letoudf.hrb идет в letodb_0.log, а не в основной ?
letodb_0.log:
127.0.0.1

04/30/15 15:17:28: letoudf.hrb has been unloaded.

04/30/15 15:17:28: E:\LETO\LetoDb\bin\letoudf.hrb has been loaded.



Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 635
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 25.05.15 11:07. Заголовок: работа триггера слом..


работа триггера сломалась.
/* $Id: Changelog,v 1.350.2.236 2015/05/06 14:12:51 ptsarenko Exp $ */
...
letodb.ini
[Main]
Port = 2812
DataPath = .
EnableFileFunc = 1
Trigger = UDF_Test_Trigger

letodb.log
05/25/15 10:51:35: Leto DB Server has been started.
Leto DB Server v.2.15b3 ! INIT: DataPath=., ShareTables=0, MaxUsers=500, MaxTables=5000, CacheRecords=10
05/25/15 10:51:35: E:\LETO\LetoDb\bin\letoudf.hrb has been loaded.
05/25/15 10:51:35: UDF_INIT // в UDF_Init добавлен WrLog(...)
05/25/15 10:53:37: Send STOP to server...
05/25/15 10:53:40: Server has been closed.

letoudf.prg
 
FUNCTION UDF_Init
/*
* This function called immediately after loading letoudf.hrb, if exist
*/
SET AUTORDER TO 1
WrLog(Procname())
RETURN Nil
...
////////////////////////////////////////////////////////////////// проверка
FUNCTION UDF_Test_Trigger( nEvent, nArea, nPos, xTrigVal )

dbInfo(DBI_TRIGGER, .F.)

WrLog( hb_valtoexp({ GetTriggerEvent[nEvent], nEvent, nArea, nPos, xTrigVal }) ) // нет вывода

dbInfo(DBI_TRIGGER, .T.)

RETURN .T.

FUNCTION GetTriggerEvent( nEvent )
LOCAL a := { ;
'EVENT_PREUSE ', ; // 1
'EVENT_POSTUSE ', ; // 2
'EVENT_UPDATE ', ; // 3
'EVENT_APPEND ', ; // 4
'EVENT_DELETE ', ; // 5
'EVENT_RECALL ', ; // 6
'EVENT_PACK ', ; // 7
'EVENT_ZAP ', ; // 8
'EVENT_PUT ', ; // 9
'EVENT_GET ', ; // 10
'EVENT_PRECLOSE ', ; // 11
'EVENT_POSTCLOSE ', ; // 12
'EVENT_PREMEMOPACK ', ; // 13
'EVENT_POSTMEMOPACK', ; // 14
'EVENT_ERROR ' ; //
}
IF nEvent > len(a) .or. nEvent < 1
nEvent := len(a)
ENDIF
RETURN a[ nEvent ]




Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 636
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 26.05.15 10:51. Заголовок: SergKis пишет:работа..


SergKis пишет:
 цитата:
работа триггера сломалась.


разобрался.
Триггер не работает при создании с открытием.
dbCreate(cPath+cFile, aStru, 'LETO', .T., 'MYALIAS')
при
dbCreate(cPath+cFile, aStru, 'LETO')
USE ( cPath+cFile ) NEW ALIAS MYALIAS
все нормально с триггером


Спасибо: 0 
ПрофильЦитата Ответить
Ответ:
1 2 3 4 5 6 7 8 9
большой шрифт малый шрифт надстрочный подстрочный заголовок большой заголовок видео с youtube.com картинка из интернета картинка с компьютера ссылка файл с компьютера русская клавиатура транслитератор  цитата  кавычки моноширинный шрифт моноширинный шрифт горизонтальная линия отступ точка LI бегущая строка оффтопик свернутый текст

показывать это сообщение только модераторам
не делать ссылки активными
Имя, пароль:      зарегистрироваться    
Тему читают:
- участник сейчас на форуме
- участник вне форума
Все даты в формате GMT  3 час. Хитов сегодня: 343
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет