Отправлено: 04.05.15 22:44. Заголовок: Вопросы новичка... (продолжение)
Взял последнюю версию с "Новая страница с бинарниками", установил на Win2008 Server, чуток помучился с портом... Собрал на МиниГуи+BCC 551 - \MiniGui\batch\hbmk2.bat rddleto.hbp Получил rddleto.lib - 131072 байт - правильный ли размер ? И еще Warning-и лезут: lib\.hbmk\win\bcc\rddsys.c: source\client\letocl.c: source\client\leto1.c: source\client\letomgmn.c: source\common\blowfish.c: source\common\common_c.c: source\common\hbip.c: TLIB 4.5 Copyright (c) 1987, 1999 Inprise Corporation /P32 lib\rddleto.lib -+ lib\.hbmk\win\bcc\rddsys.obj -+ lib\.hbmk\win\bcc\letocl.obj -+ lib\.hbmk\win\bcc\leto1.obj -+ lib\.hbmk\win\bcc\letomgmn.obj -+ lib\.hbmk\win\bcc\blowfish.obj -+ lib\.hbmk\win\bcc\common_c.obj -+ lib\.hbmk\win\bcc\hbip.objWarning: 'rddsys' not found in library Warning: 'letocl' not found in library Warning: 'leto1' not found in library Warning: 'letomgmn' not found in library Warning: 'blowfish' not found in library Warning: 'common_c' not found in library Warning: 'hbip' not found in library
Так должно быть или нет ?
Вопрос сразу напрашивается с путями - как писать правильно "\" или "/" : Local cPathServer := "//127.0.0.1:2812/" cPathServer := cPathServer +"DATE_TEST_PATH\test.dbf"
Помню что где то обсуждали, а результат не запомнил...
Вызывать можно функции, указанные в request, ну и некоторые другие. Я пересматривал этот набор - он вполне безопасен. Впрочем, я уже добавил параметр EnableUDF в letodb.ini, для возможности отключения udf.
Т.е. имя UDF функции должно начинаться с UDF_ (UDF_() - не проходит) - хак с выполнением стандартных и функций leto через механизм leto_udf на сервере отсекается. Ну и сделал более осмысленным описание ошибки для leto_wUsLog. Мне кажется такое решение более логичным существующего.
Прошу прощения, пропустил при коммите server.prg. Поправлю. Да, EnableUDF запрещает вызовы UDF. Может быть, имеет смысл еще добавить флаг UDFPrefix, который позволял бы вызовы только функций с именами UDF_*
Отправлено: 05.08.16 08:39. Заголовок: Как вариант, еще вме..
Как вариант, еще вместо одного letoudf.hrb можно использовать 2 (или более), например, letoudf_st.hrb и letoudf_us.hrb. Запуск letoudf_st.hrb не зависит от EnableUDF, запуск letoudf_us.hrb (и остальных), соответственно, зависит.
Отправлено: 05.08.16 09:48. Заголовок: Pasha пишет Может бы..
Pasha пишет
цитата:
Может быть, имеет смысл еще добавить флаг UDFPrefix
Я тоже за Но можно просто обойтись режимом 0 1 2 - спрефиксоом udf_ (пока не вижу причин нескольких префиксов, но может ошибаюсь) а то возникнет желание на каждого user уст. разрешено\нет udf, как с файловыми, mg ф-ими
Отправлено: 05.08.16 11:01. Заголовок: Петр пишет можно и н..
Петр пишет
цитата:
можно и на уровне функций, т.е. доступна ли функция a() пользователю b
Скорее возникает желание в udf знать что то с LETO_USERGETRIGHTS( nUserStru ) (такой нет) + доп. установку на user в Pass_File = "leto_users" доплнительных данных (байт 10-20). Например так на клиенте LETO_USERPARAM( cUserName, cParam ) --> lSuccess LETO_USERPARAM( cUserName ) --> cParam и на сервере LETO_USERPARAM( nUserStru [, cUserName ] ) --> cParam LETO_USERGETRIGHTS( nUserStru[, cUserName ] ) --> cRights
Отправлено: 05.08.16 11:51. Заголовок: И еще есть желание (..
И еще есть желание (многие сервера обеспечивают) иметь алиасные пути к файлам и таблицам, например секция в letodb.ini (привязка разработки к реальном данным на сервере) [ALIAS] \TMP\ = \TEST\TABL\BLS\ \WRK\ = \TEST\WRK\ \MY1\ = \TEST\MY1\ \MY2\ = \TEST\MY2\ на клиенте пишем \tmp\table01.dbf \tmp\table02.dbf на сервере происходит подмена на реальное значение \TMP\ и т.д. в 2-х поточной версии для dbf я это делал, для файловых ф-й ( C ) сложновато для меня
Отправлено: 05.08.16 13:22. Заголовок: И последнее. Не хват..
И последнее. Не хватает команды типа ( если стоит EnableFileFunc = 0 и нет hrb, а теперь и режим 0 для udf) 1. CRATE TABLE myTable ... IF NOT EXISTS - трудно управлять созданием таблицы, особенно если нет созданных каталогов к ней, возможно по установке в ini (а может и всегда) разрешать автосоздание дирректорий при их отсутсвии 2. DROP TABLE myTable - удалить таблицу вместе с индексами
PS Реализация CREATE TABLE ... IF NOT EXISTS могла бы выглядеть к примеру так:
FUNCTION hs_createtable( nUserStru, cCommand ) ... LOCAL cRecData LOCAL lTable := .F., lAutoCreate := leto_GetAppOptions( 26 ) // к примеру ... IF Lower(cName) = "/mem:" cDataPath := "" cName := Substr(cName, 2) ELSE cDataPath := leto_GetAppOptions( 1 ) ENDIF cFileName := cDataPath + cName
IF !empty(cDataPath) // обработка алиаса, если использовать механизм cFileName := SetAlias2Path( cFileName ) // заменяем ALIAS (если есть) на реальный путь // If lAutoCreate lTable := hb_FileExists(cFileName) If ! lTable CreateDir(cFileName) EndIf EndIf ENDIF
If ! lTable
BEGIN SEQUENCE WITH { |e|break( e ) } leto_SetUserEnv( nUserStru ) dbCreate( cFileName, aStru, leto_Driver( nDriver ), .T. , cRealAlias ) RECOVER USING oError lres := .F. END SEQUENCE
EndIf ...
STATIC FUNCTION CreateDir( cDBF ) LOCAL aCt := {} LOCAL i := RAt(DEF_SEP, cDBF) LOCAL cCt := Left(cDBF, i-1)
DO WHILE ! hb_DirExists( cCt ) i := RAt(DEF_SEP, cCt) IF i == 0 ; EXIT ENDIF AAdd( aCt , subs(cCt, i+1) ) cCt := Left( cCt, i-1) ENDDO i := Len( aCt ) DO WHILE i > 0 cCt += (DEF_SEP + aCt[i--]) MakeDir( cCt ) ENDDO
Отправлено: 05.08.16 20:00. Заголовок: SergKis пишет: Еще ..
SergKis пишет:
цитата:
Еще такая есть хотелка - класс для работы с Hash массивом с синхронизированными методами доступа к его элементам, для работы в udf
Добавил request на сервере для хеш-функций. Сделал префикс UDF_* обязательным по умолчанию для вызовов udf, с возможностью отключения этого режима. А функция hb_dbDrop поддерживается letodb уже давно, т.к. метод letoDrop реализован на клиенте.
DATA nPort INIT 2812 DATA ip DATA nTimeOut INIT -1 DATA DataPath INIT "" DATA LogFile INIT "" DATA lLower INIT .F. DATA lFileFunc INIT .F. DATA lAnyExt INIT .F. DATA lShare INIT .F. // .T. - new mode, which allows share tables with other processes DATA lNoSaveWA INIT .F. // .T. - new mode, which forces dbUseArea() each time "open table" is demanded DATA nDriver INIT 0 DATA lPass4M INIT .F. DATA lPass4L INIT .F. DATA lPass4D INIT .F. DATA cPassName INIT "leto_users" DATA lCryptTraffic INIT .F. DATA cTrigger DATA cPendingTrigger DATA nMaxVars DATA nMaxVarSize DATA nCacheRecords INIT 10 DATA nTables_max DATA nUsers_max DATA nDebugMode INIT 0 DATA lOptimize INIT .F. DATA nAutOrder DATA nMemoType DATA lForceOpt INIT .F. DATA lSetTrigger INIT .F. DATA lUDF INIT .T.
METHOD New()
ENDCLASS METHOD New() CLASS HApp LOCAL cIniName := "letodb.ini" LOCAL aIni, i, j, cTemp, cPath, nDriver LOCAL nPort := ::nPort // LOCAL nMaxVars, nMaxVarSize LOCAL nCacheRecords := ::nCacheRecords LOCAL nTables_max := NIL LOCAL nUsers_max := NIL LOCAL nDebugMode := 0 // LOCAL lOptimize := .F. // LOCAL nAutOrder LOCAL nMemoType // LOCAL lForceOpt := .F. // LOCAL lSetTrigger := .F. // LOCAL lUDF := .T.
letodb.log 08/07/16 00:04:18: Leto DB Server has been started. Leto DB Server v.2.17b2 ! INIT: DataPath=., ShareTables=0, MaxUsers=500, MaxTables=5000, CacheRecords=10 08/07/16 00:04:18: C:\LETO\letodb-code-0324bd6820c3d9644f815b7dac76309859220501\bin\letoudf.hrb has been loaded. 08/07/16 00:11:54: Send STOP to server... 08/07/16 00:11:57: Server has been closed.
сборка leto-core-6bc3... тот же пример ---------------------------------------------- letodb.ini Port = 2812 DataPath = . EnableFileFunc = 1
результат
Connect to //127.0.0.1:2812/ - Ok
leto_GetAppOptions found hb_DiskSpace found 422226853888 UDF_AppendRec - found Press any key to finish...
letodb.log 08/06/16 23:47:17: Leto DB Server has been started. Leto DB Server v.2.17b2 ! INIT: DataPath=., ShareTables=0, MaxUsers=500, MaxTables=5000, CacheRecords=10 08/06/16 23:47:17: C:\LETO\letodb-code-6bc3e8f667ff4d65caeb620eafca574aba1bd166\bin\letoudf.hrb has been loaded. 08/06/16 23:49:51: Send STOP to server... 08/06/16 23:49:54: Server has been closed.
letodb.log 08/07/16 09:10:27: Leto DB Server has been started. Leto DB Server v.2.17b2 ! INIT: DataPath=., ShareTables=0, MaxUsers=500, MaxTables=5000, CacheRecords=10 08/07/16 09:10:27: C:\LETO\letodb-code-7e89fed2f632e34d814bf8518ec08707be6b0e45\bin\letoudf.hrb has been loaded. 08/07/16 09:17:03: Send STOP to server... 08/07/16 09:17:06: Server has been closed.
letodb_0.log 127.0.0.1 LENOVO Test_Udf.exe ERROR! UDF: not a valid name ERROR! UDF: not a valid name
клиент пересобран с rddleto.lib из этой сборки результат
Connect to //127.0.0.1:2812/ - Ok
not found leto_GetAppOptions not found hb_DiskSpace UDF_AppendRec - found Press any key to finish...
Отправлено: 07.08.16 09:42. Заголовок: Pasha Не очень пони..
Pasha Не очень понимаю режим с EnableUDF = 0 Для меня важно, что бы удаленный "продвинутый" user не смог через вызов leto_udf("...") сломать инфу сервера (сборку всех серверов не проконтролируешь на request функций), т.е. leto_ferase, leto_fRename, leto_drop, leto_memowrit,leto_FileWrite, leto_dirremove, Leto_FileAttr, ... dbCreate, fErase, fRename, fCreate, hb_memowrit, StrFile, hb_DirBase, hb_progname, exename, ... leto_getAppOptions( ... ), что дает доступ к путям, файлам настройки, паролей сервера может еще какие, сразу не вспомнишь. Все это, если надо можно организовать в hrb
Отправлено: 07.08.16 09:57. Заголовок: Из readme: Ena..
Из readme: EnableUDF = 1 - если 1 (по умолчанию), разрешено использование udf-функций с префиксом "UDF_", если 2, разрешено использование udf-функций с любыми именами, если 0, вызовы udf-функций запрещены;
По умолчанию, при значении параметра 1, разрешены только вызовы функций с префиксом udf_, т.е. вызов UDF_AppendRec разрешен, а hb_DiskSpace, dbCreate и пр. - нет. При значении 2 разрешены вызовы всех функций. При значении 0 вызовы udf запрещены. Если хочется ограничить вызовы опасных функций, то пусть будет значение по умолчанию, в для hb_DiskSpace и пр. надо сделать обертки в letoudf.hrb: например udf_DiskSpace
Отправлено: 09.08.16 07:59. Заголовок: Pasha Вопросик. В UD..
Pasha Вопросик. В UDF применяются след. ф-ии для тек.записи leto_rec( nUserStru ) и потом на клиенте Leto_ParseRec( cRecBuf ) для списка записей leto_dbEval( nUserStru ) и потом на клиенте leto_ParseRecords( cRecs ) варианта превратить array в cRecs не увидел, типа a := {} For i := 1 To 10 dbAppend() AADD(a, RecNo()) Next cRecs := ???( a ) или остается только вариант (без BM фильтра) a := {} For i := 1 To 10 dbAppend() AADD(a, leto_rec( nUserStru )) Next Return a
и на клиенте по массиву делать Leto_ParseRec( aRecs[ i ] )
или надо обязательно применять BM filter для такой ситуации ?
В случае набора произвольных записей такой способ был бы неправильным, так как это не является набором записей, следующих друг за другом последовательно. Поэтому лучше всего будет как раз возврат в udf массива записей с последующей их обработкой на клиенте:
aRecs := leto_udf("udf_func", ...) for each cRec in aRecs leto_ParseRec(cRec) // обработка next
Отправлено: 09.08.16 09:37. Заголовок: Pasha пишет Поэтому ..
Pasha пишет
цитата:
Поэтому лучше всего будет как раз возврат в udf массива записей с последующей их обработкой на клиенте:
Это понятный механизм
цитата:
В случае набора произвольных записей такой способ был бы неправильным, так как это не является набором записей, следующих друг за другом последовательно.
Имеем на сервере
FUNCTION UDF_dbEval( nUserStru, xScope, xScopeBottom, xOrder, cFilter, lDeleted ) LOCAL cRecs
leto_SetEnv( xScope, xScopeBottom, xOrder, cFilter, lDeleted ) GO TOP cRecs := leto_dbEval( nUserStru ) leto_ClearEnv( xScope, xScopeBottom, cFilter )
RETURN cRecs
в результате cRecs (на клиенте), после leto_setenv и leto_clearenv мы имеем как раз произвольный набор записей, т.к. Env устанавливалась на сервере, а на клиенте как было так и осталось, т.е. cRecs полученный leto_dbeval и array recno => cResc, обработка клиентом одинакова leto_ParseRecords( leto_Udf('UDF_Append2cRecs", 10 ) ) // добавлено 10 записей while ! eof() ... skip enddo dbInfo( DBI_CLEARBUFFER )
USE ( cPath+"test3" ) New INDEX ON NUM TAG KOD FOR ! deleted() INDEX ON NAME TAG NAM FOR ! deleted() INDEX ON NUM TAG DEL FOR deleted() USE ... USE ( cPath+"test3" ) New SHARED If OrdCount() > 0 OrdSetFocus(2) // по наименованию на клиенте EndIf сейчас делаем так For i := 1 To 10 cRecBuf := Leto_Udf("UDF_AppendRec", "NUM", {'KOD', 'DEL'}, 10) // по тэгу KOD добавление на сервере Leto_ParseRec( cRecBuf ) IF RLock() REPL NAME with "Name_"+strzero(RecNo(), 7), ; INFO with "Info_"+iif(j == "N", hb_ntos(NUM), NUM)+"-"+j dbUnLock() ENDIF ? i, RecNo(), NUM, NAME Next в чем разница, если сразу добавить 10 записей на сервере (присвоив код) и вернув cResc (на сервере можно и leto_dbeval для новых записей получить в cRecs), сделать leto_ParseRecords(cRecs) и заполнить их в цикле ? Теоретически, вроде, ни что не мешает ? На клиенте ордер 2, на сервере отработали по ордеру 1 или тут камень есть ?
IF lApp If ! empty(aFldVal) FOR EACH a IN aFldValue IF ( p := FieldPos(a[1]) ) > 0 IF ! ( p == nPos .or. hb_FieldType(p) $ "+=^" ) FieldPut(p, a[2]) ENDIF ENDIF NEXT EndIf FieldPut( nPos, xKey ) dbCommit() ENDIF leto_TableUnLock( nUserStru, 1 ) ELSE lApp := .F. ENDIF
RETURN if( lApp, leto_rec( nUserStru ), Nil )
FUNCTION UDF_AddRec( nUserStru, xOrder ) LOCAL lApp, lSetDel, xRet
Отправлено: 08.10.16 10:18. Заголовок: Всем привет ! Вопрос..
Всем привет ! Вопрос возник по эксплуатации ЛетоДб. Перед отправкой записей в базу на сервер, я проверяю в папке наличие файла и считываю оттуда его содержимое. Типа ключа для каждой фирмы. Код в программе: IF !LETO_FILE(cFile) MsgStop( "Нет файла КЛЮЧА на сервере!" ) RETURN .F. ENDIF Периодически юзера жалуются на появление такой ошибки ! Проверяю в это же время сервер - доступен. Пока юзер не перегрузит комп, ошибка не уходит. Иногда и после перезагрузки остаётся. Как с этим бороться ?
Отправлено: 08.10.16 14:15. Заголовок: Можно описать ситуац..
Можно описать ситуацию подробнее ? Сервер находится тырнете или в локалке ? Коннект к серверу до выполнения leto_file выполнялся или нет ? Файл ключа все время существует или нет ? Что в cFile ? Коннект с сервером может прерваться или связь стабильная ? Без такого контекста отвечать на подобный вопрос трудно.
Отправлено: 08.10.16 21:20. Заголовок: Pasha пишет: Можно ..
Pasha пишет:
цитата:
Можно описать ситуацию подробнее ?
Сервер в инете. Программа делает коннект до сервера и работает дальше, т.е. отправляет записи на сервер ЛетоДб через 1-5 минут. Спустя 1 час или 5 часов - начинается такая фигня. Инет стабильный, коннект вроде не прерывается. Содержимое в cFile - 20-40 символов. В момет появления ошибки, захожу со своего компа - файлы все на месте и сервер ЛетоДб нормально отвечает.
Отправлено: 09.10.16 08:57. Заголовок: Если сервер живой, и..
Если сервер живой, и файл на сервере существует, то логично предположить, что неудача leto_file связана с нарушением связи с сервером с этого клиента. В таком случае после if !LETO_FILE можно поставить проверку связи, например, вызовом функции LETO_MGGETINFO
Отправлено: 09.10.16 09:29. Заголовок: Pasha пишет: В тако..
Pasha пишет:
цитата:
В таком случае после if !LETO_FILE можно поставить проверку связи, например, вызовом функции LETO_MGGETINFO
Надо будет для проверки связи сделать ф-ю leto_Ping() - тем более, что команду такую сервер обрабатывает. Помнится, это чуть-ли не первая команда, которую я в свое время сделал.
Отправлено: 09.10.16 09:37. Заголовок: Andrey пишет: Пока ..
Andrey пишет:
цитата:
Пока юзер не перегрузит комп, ошибка не уходит. Иногда и после перезагрузки остаётся.
Вот это и в самом деле странно. Я бы до перезагрузки компа проверил ping к серверу - обычную команду ping, ну и если он проходит, то проверил бы как отрабатывает leto_Connection().
цитата:
Перед отправкой записей в базу на сервер, я проверяю в папке наличие файла и считываю оттуда его содержимое.
Немного не в тему, но: а почему бы не использовать здесь leto_var...() функции ?
Надо будет для проверки связи сделать ф-ю leto_Ping() - тем более, что команду такую сервер обрабатывает. Помнится, это чуть-ли не первая команда, которую я в свое время сделал.
Еще в файловых функциях вроде LetoFileExist можно добавить обработку:
if( uiRes ) { ... } else s_iError = 1000;
Можно вместо этого перенести установку
if( !lRet ) s_iError = 1000;
из функции leto_SendRecv в функцию leto_DataSendRecv Тогда ошибку связи с сервером во многих функциях, в том числе файловых, можно будет проверить вызовом LETO_FERROR()
Немного не в тему, но: а почему бы не использовать здесь leto_var...() функции ?
Да наверно из-за не знания. Я когда начал изучать документацию по Лето, то не понял, для чего они. Самостоятельно не всегда знаешь/понимаешь что нужно в том или ином случае. Желательно бы в документацию включить доп.материалы для тех или иных действий и код приводить полностью. Например: 1) Коннект к серверу (это есть вроде) 2) Проверка доступности сервера и переподключение к серверу. 3) Проверка доступа клиента к базе, т.е. разрешение к записи/чтения к базе. Это я реализовал простой проверкой наличия файла (у каждой фирмы свой файл) и содержимого самого файла (типа ключа проверки). 4) Работа с базами на двух и более серверах ЛетоДБ 5) Синхронизация по таймеру ( и событию) локальной и серверной базы и наоборот с сервера на локальную. и т.д.
Отправлено: 10.10.16 17:57. Заголовок: Тогда код делать так..
Тогда код делать такой ?
IF Leto_Ping() IF !LETO_FILE(cFile) MsgStop( "Нет файла КЛЮЧА на сервере!" ) RETURN .F. ELSE // передача записей на сервер MyWriteRecnoLetoDb() ENDIF ELSE MsgStop("Ошибка соединения с сервером LetoDB !") ENDIF
Отправлено: 11.10.16 14:13. Заголовок: alkresin пишет: В т..
alkresin пишет:
цитата:
В тексте исходников :).
Спасибо !
Можно ли сделать следующие: при изменении базы на сервере - получать событие клиентам, что база изменилась ? Желательно бы и номер изменённой записи получать.
Можно ли сделать следующие: при изменении базы на сервере - получать событие клиентам, что база изменилась ?
Клиент-серверная архитектура подразумевает следующий подход: клиент запросил - сервер ответил и забыл про клиента. Сам сервер не должен никому ничего слать без запроса. Т.е., для того, чтобы клиент знал про изменение баз, он должен сам об этом побеспокоиться.
Отправлено: 11.10.16 14:57. Заголовок: Andrey пишет: при и..
Andrey пишет:
цитата:
при изменении базы на сервере - получать событие клиентам, что база изменилась ? Желательно бы и номер изменённой записи получать.
Правильно тут написали: общение с сервером всегда происходит по схеме запрос - ответ, причем запрос может послать только клиент. Можно записывать информацию об изменениях в базе, например, в переменную LetoDB (leto_Var...() функции), это может делать как клиент, изменивший базу, так, наверное, и сервер в соответствующем триггере. Но чтобы другой клиент об этом узнал, ему надо время от времени, по таймеру например, читать эту переменную с сервера.
Отправлено: 12.10.16 00:42. Заголовок: alkresin пишет: Но ..
alkresin пишет:
цитата:
Но чтобы другой клиент об этом узнал, ему надо время от времени, по таймеру например, читать эту переменную с сервера.
Тогда наверное алгоритм SergKis - построение индекса на сервере по полю TimeStamp (в базе) даёт более простой результат синхронизации БД на сервере и клиенте. Я алгоритм уже попробовал. Хотелось бы понять и другие.
alkresin пишет:
цитата:
Можно записывать информацию об изменениях в базе, например, в переменную LetoDB (leto_Var...() функции), это может делать как клиент, изменивший базу, так, наверное, и сервер в соответствующем триггере.
Не представляю как это сделать. Покажите пожалуйста схему как это делать.
Схема самая простая. Есть Leto-переменные, каждая имеет свое имя, они собраны по группам, каждая группа тоже имеет свое имя. Предположим, вы решили сделать по группе для каждой базы - base1, base2, base3, ... и в каждой группе переменную modtime (modification time), куда будете записывать дату и время последнего изменения в том формате, который вам нравится. Программа при записи данных в базу пишет одновременно и в соответствующую переменную:
Отправлено: 13.10.16 14:18. Заголовок: Похожую ситуацию когда-то приходилось отрабатывать
Что-то подобное я делал(было дело!!): ... Здесь код изменения записи пользователем и сохранение в базе а далее отработка .... Leto_varDel("KRS",""),; leto_varSet( "KRS","var_cDate",DToC(Date()),LETO_VCREAT ),; // дата текущая создаем если нет переменную leto_varSet( "KRS","var_cTime",Time(),LETO_VCREAT ),; // время текущее создаем если нет переменную leto_varSet( "KRS","var_cCBU",cCBU,LETO_VCREAT ),; // CBU пользователя создаем если нет переменную IIF(lSchedul,(MsgTray("Изменение купли-продажи!", "Обновление!") , SysWait(3) , MsgTray(""), Popup_Var()),nil) // всплывающее сообщение пользователю ..... Функция Popup_Var() вызывается в таймере
//---------------------------работаем с переменными сервера----------- //-----------------проверка для отправки сообщения пользователям Function Popup_Var()
If !Empty(Secs( leto_varGet( "KRS","var_cTime" ))) IF (Secs(Time()) - Secs( leto_varGet( "KRS","var_cTime" ) )) > 2 MsgTray("Данные обновлены!" , "КЦ - " + leto_varGet( "KRS","var_cCBU" )) ; SysWait(5) ; MsgTray("") leto_varDel( "KRS","" ) // удаляет всю группу с переменными EndIf Else leto_varDel( "KRS","" ) // удаляет всю группу с переменными EndIf Return nil ... Функция MsgTray - выдает сообщение нужным пользователям об изменениях.
Вот такой алгоритм. Правда все на FiveWin, но это сути не меняет.
Первая установка letodb. Команда File не работает (файл есть, пишет .F.). Команда leto_file - тоже, т.к., по-моему, не читает letodb.ini (там разрешил файловые функции). Там путь прописан:DataPath ="/MYwrk/", а в log пишет DataPath =. Где копать?
Отправлено: 12.02.24 15:12. Заголовок: VI Вот рабочий вари..
VI Вот рабочий вариант установки Leto2011.exe (2-х поточная) и LetoDbF.exe (в ней изменены имена ini и log файлов на LetoDbF.*), совместная работа (это local работа - отладка, у клиента так же, но с адресами своими)Скрытый текст
Volume in drive D is DATA Volume Serial Number is E86E-69F5
ini рабочего места клиента [COM] PathXml = .\XML ; directory for excel reporting Host = 127.0.0.1 ; Port = 2816 ;
Всегда работаю от текущего каталога, т.е. везде в путях стоят точки или .\ LetoDbF всегда добавляет DataPath к исп. именам файлов на клиенте эту добавку, попробуйте задать (внутри имя приводятся к одному разделителю, как надо). DataPath = C:\Mywrk от такого задания отказался из за копирования, так от текущего все забрал, вместе с настройками и ...
Отправлено: 12.02.24 15:48. Заголовок: Спасибо за то, что попытались помочь.
Как вижу, основная проблема в том, что функции Leto_file (и другие файловые) у меня не работают, хотя в .ini разрешены. И вообще, ни одна установка, отличная от заданного значения по умолчанию, не меняется (например, CDX/NTX). Letodb.ini лежит там же, где и запускаемый letodb.exe. Впрочем, и функция File() не работает тоже (а должна ли?), причем перебраны все возможные сочетания путей.
Отправлено: 12.02.24 16:02. Заголовок: VI Может дело в сбо..
VI Может дело в сборке сервера, у меня никогда не было такой штуки. Посмотрите в MiniGui пример SAMPLES\Advanced\LetoDbf, там был рабочий вариант сервера
Подскажите, пожалуйста, по рабочим областям/открытым базам в функциях UDF_
Select M leto_Use( nUserStru, fileName1) RC1 = RecCount()
Select D leto_Use( nUserStru, fileName2) RC2 = RecCount()
Select M RC3 = RecCount()
Открываю в M, файл читается. Открываю в D, файл читается. Снова возвращаюсь в M - там ничего нет. RecCount()=0, обащения по именам полей - никак. Что я упускаю при попытке открыть пару .dbf и работать с ними одновременно? Те же задачи при доступе функцией с клиента и подключении через '//192.168.88.7:2812/' работают прекрасно.
Отправлено: 14.05.25 08:51. Заголовок: Lopatin В чем смысл..
Lopatin В чем смысл в UDF_ исп. leto_Use( nUserStru, fileName2) ? В LetoDb 2.0 версии, если правильно помню (давно ушел на 3.0), строится таблица свои алиасы типа A00001,... и в udf надо пользоваться ф-ями для получения алиаса и номера области. В udf, по мне, достаточно делать обычные USE ... со своим alias, отработать по ним и закрыть. На стороне сервера обычный rdd
Все даты в формате GMT
3 час. Хитов сегодня: 17
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет