Форум » LetoDB, HbNetio. » LetoDB 2.17 » Ответить
LetoDB 2.17
alkresin: Обновил номер сборки с 1 до 2 и выложил исходники на Sourceforge, а то там лежала версия более чем годичной давности.
Ответов - 45, стр:
1 2 3 All
SergKis: Есть еще одно место для замены: http://www.kresin.ru/letodb.html
alkresin: Выложил на http://www.kresin.ru/letodb.html обновленные дистрибутивы: исходники, бинарные сборки для Windows (Borland 5.5) и Linux Debian 7 (должны работать и на Ubuntu).
Pasha: Александр, не посмотрите такую ситуацию: если выдать: leto_CloseAll() leto_CloseAll() или leto_CloseAll() leto_disconnect() то на 2-м вызове получается gpf во 2-м случае gpf происходит по той же причине, что и в 1-м, т.к. leto_disConnect() вызывает leto_CloseAll() Насколько я понимаю, в leto_CloseAll() надо еще как-то вызывать метод release, кроме метода close, для тех рабочих областей, которые закрываются
alkresin: Что-то у меня не получилось воспроизвести это. Поставил в конец tests/test_dbf.prg два вызова leto_CloseAll() - полет нормальный...
SergKis: Получил такую ситуацию с длинным именем переменной сервера (добавка кода в tests\test_var.prg):[pre2] ... j := subs(cPath+'temp2.dbf', 3) j := StrTran(j, DEF_CH_SEP, "_") j := StrTran(j, ".", "_") j := "Var_"+StrTran(j, ":", "_") ? "Adding long name ", j, "to [main] (Ok) " lRes := leto_varSet( "main", j, "Value = "+j,LETO_VCREAT ) IF lRes ?? " - ", "Ok" ? "long name ", j, "[main]", leto_varGet( "main",j ) ? "Delete var_long (Ok) [", j, "]" lRes := leto_varDel( "main", j ) IF lRes ?? " - ", "Ok" ELSE ?? " - ", "Err (" + Ltrim(Str(leto_ferror())) + ")" ENDIF ELSE ?? " - ", "Err (" + Ltrim(Str(leto_ferror())) + ")" ENDIF ... [/pre2] с выделенными строками удаления работает нормально, если убрать строки удаления переменной с длинным именем, то валится ShowVars() после arr1 := leto_varGetlist( arr[ i ] ), причем так, что спасает только перезапуск сервера
SergKis: Вопрос снят. Мах. длина имени переменной в leto_VarGetList() - 23 байта. Буду исходить из этого.
SergKis: Pasha, alkresin Можно ли на клиенте получить установки сервера из ini EnableFileFunc = 0 Pass_for_Login = 1 Pass_for_Data = 1 Pass_for_Manage = 1 для понимая состояния сервера Например установка Pass_for_Login = 1 сваливает сервер, при коннекте с пустыми user, password это делает manage.exe из поставки \utils\* ======= letodb.ini ======= [MAIN] Port = 2812 DataPath = . EnableFileFunc = 0 Pass_for_Login = 1 ======= LetoDb.log ======= 07/24/16 14:29:31: Leto DB Server has been started. Leto DB Server v.2.17b2 ! INIT: DataPath=., ShareTables=0, MaxUsers=500, MaxTables=5000, CacheRecords=10 07/24/16 14:29:31: C:\LETO\LetoDb\bin\letoudf.hrb has been loaded. ERROR! ParseCommand() leto_errInternal!!!!!!!!!!!!!!!!!! 07/24/16 14:31:24: Can't STOP the server (not started?)... ============ LetoDb_crash.log ============ Breakdown at: 2016.07.24 14:30:03 Unrecoverable error 6005: Exception error:%s Exception Code:C0000005 ACCESS_VIOLATION Exception Address:004E0B64 EAX:00000000 EBX:00512F08 ECX:00512F08 EDX:004DF35C ESI:00000000 EDI:0231FD8E EBP:0231FD28 CS:EIP:0023:004E0B64 SS:ESP:002B:0231F7FC DS:002B ES:002B FS:0053 GS:002B Flags:00010246 Exception Parameters: 00000000 00000000 CS:EIP: 8A 1E 46 84 DB 0F 84 C1 08 00 00 80 FB 25 75 08 SS:ESP: 0231FD8E 00000000 00512F08 4F525245 50202152 65737261 6D6D6F43 28646E61 000A0D29 00000000 00000000 00000000 00000000 00000000 00000000 00000000 C stack: EIP: EBP: Frame: OldEBP, RetAddr, Params... 004E0B64 0231FD28 0231FD50 004E0A5A 004DF35C 00512F08 00000000 00000000 00000000 0231FE8C 00000000 00512F08 004E0A5A 0231FD50 0231FE78 00403E8D 00512F08 00000000 0231FE8C 0028273C 00000030 0026E0A4 4C5C3A43 5C4F5445 00403E8D 0231FE78 0231FEAC 0041143E 00000000 00000000 00000000 004E7BC8 02220000 01E23094 006930F4 000000A0 0041143E 0231FEAC 0231FF7C 004E79C4 00000000 00000000 00000000 01E23094 00000094 00000006 00000002 000023F0 004E79C4 0231FF7C 0231FF8C 004E79F7 01E23094 004E7BC8 004E79F7 0231FF8C 0231FF98 772F495D 01E23094 772F495D 0231FF98 0231FFDC 778898EE 01E23094 B4508399 00000000 00000000 01E23094 00000000 00000000 00000000 Modules: 00400000 00128000 C:\LETO\LetoDb\bin\leto2016.exe 77840000 00168000 C:\windows\SYSTEM32\ntdll.dll 772E0000 00140000 C:\windows\SYSTEM32\KERNEL32.DLL 76490000 000CF000 C:\windows\SYSTEM32\KERNELBASE.dll 76EF0000 00150000 C:\windows\SYSTEM32\USER32.DLL 77690000 00077000 C:\windows\SYSTEM32\ADVAPI32.DLL 75290000 0004D000 C:\windows\SYSTEM32\WS2_32.DLL 74EE0000 0001E000 C:\windows\SYSTEM32\IPHLPAPI.DLL 76900000 00108000 C:\windows\SYSTEM32\GDI32.dll 766B0000 000BE000 C:\windows\SYSTEM32\msvcrt.dll 77050000 0003E000 C:\windows\SYSTEM32\sechost.dll 765F0000 000B1000 C:\windows\SYSTEM32\RPCRT4.dll 76780000 00007000 C:\windows\SYSTEM32\NSI.dll 714F0000 00008000 C:\windows\SYSTEM32\WINNSI.DLL 75270000 0001D000 C:\windows\SYSTEM32\SspiCli.dll 75260000 00009000 C:\windows\SYSTEM32\CRYPTBASE.dll 75200000 00051000 C:\windows\SYSTEM32\bcryptPrimitives.dll 76AE0000 00025000 C:\windows\system32\IMM32.DLL 76C60000 000F7000 C:\windows\SYSTEM32\MSCTF.dll 6F3A0000 00045000 C:\windows\system32\mswsock.dll ------------------------------------------------------------------------ Unrecoverable error 6005: Exception error:%s Exception Code:C0000005 ACCESS_VIOLATION Exception Address:004E0B64 EAX:00000000 EBX:00512F08 ECX:00512F08 EDX:004DF35C ESI:00000000 EDI:0231FD8E EBP:0231FD28 CS:EIP:0023:004E0B64 SS:ESP:002B:0231F7FC DS:002B ES:002B FS:0053 GS:002B Flags:00010246 Exception Parameters: 00000000 00000000 CS:EIP: 8A 1E 46 84 DB 0F 84 C1 08 00 00 80 FB 25 75 08 SS:ESP: 0231FD8E 00000000 00512F08 4F525245 50202152 65737261 6D6D6F43 28646E61 000A0D29 00000000 00000000 00000000 00000000 00000000 00000000 00000000 C stack: EIP: EBP: Frame: OldEBP, RetAddr, Params... 004E0B64 0231FD28 0231FD50 004E0A5A 004DF35C 00512F08 00000000 00000000 00000000 0231FE8C 00000000 00512F08 004E0A5A 0231FD50 0231FE78 00403E8D 00512F08 00000000 0231FE8C 0028273C 00000030 0026E0A4 4C5C3A43 5C4F5445 00403E8D 0231FE78 0231FEAC 0041143E 00000000 00000000 00000000 004E7BC8 02220000 01E23094 006930F4 000000A0 0041143E 0231FEAC 0231FF7C 004E79C4 00000000 00000000 00000000 01E23094 00000094 00000006 00000002 000023F0 004E79C4 0231FF7C 0231FF8C 004E79F7 01E23094 004E7BC8 004E79F7 0231FF8C 0231FF98 772F495D 01E23094 772F495D 0231FF98 0231FFDC 778898EE 01E23094 B4508399 00000000 00000000 01E23094 C0000005 00000000 0231F210 Modules: 00400000 00128000 C:\LETO\LetoDb\bin\leto2016.exe 77840000 00168000 C:\windows\SYSTEM32\ntdll.dll 772E0000 00140000 C:\windows\SYSTEM32\KERNEL32.DLL 76490000 000CF000 C:\windows\SYSTEM32\KERNELBASE.dll 76EF0000 00150000 C:\windows\SYSTEM32\USER32.DLL 77690000 00077000 C:\windows\SYSTEM32\ADVAPI32.DLL 75290000 0004D000 C:\windows\SYSTEM32\WS2_32.DLL 74EE0000 0001E000 C:\windows\SYSTEM32\IPHLPAPI.DLL 76900000 00108000 C:\windows\SYSTEM32\GDI32.dll 766B0000 000BE000 C:\windows\SYSTEM32\msvcrt.dll 77050000 0003E000 C:\windows\SYSTEM32\sechost.dll 765F0000 000B1000 C:\windows\SYSTEM32\RPCRT4.dll 76780000 00007000 C:\windows\SYSTEM32\NSI.dll 714F0000 00008000 C:\windows\SYSTEM32\WINNSI.DLL 75270000 0001D000 C:\windows\SYSTEM32\SspiCli.dll 75260000 00009000 C:\windows\SYSTEM32\CRYPTBASE.dll 75200000 00051000 C:\windows\SYSTEM32\bcryptPrimitives.dll 76AE0000 00025000 C:\windows\system32\IMM32.DLL 76C60000 000F7000 C:\windows\SYSTEM32\MSCTF.dll 6F3A0000 00045000 C:\windows\system32\mswsock.dll
SergKis: Еще вопросик по v.2.17.b2. Что не так делаю при создании защищенной переменной на сервере ( LETO_VDENYWR - запрет присваивания значения другим пользователем ) [pre2] letoudf.prg ======= #include "rddleto.ch" ... FUNCTION UDF_Init LOCAL cGroupName := "letodb.ini" LOCAL nUserStru // := 1 SET AUTORDER TO 1 LETO_VARSET(nUserStru, cGroupName, "lLower" , oApp:lLower, LETO_VCREAT + LETO_VDENYWR) RETURN Nil Test_Var.prg ======== ... ? "Get [letodb.ini] lLower =",leto_varGet( "letodb.ini", "lLower" ) // ... = .F. ? "Error =",leto_ferror() // 0 ? "Set [letodb.ini] lLower = .T." leto_varSet( "letodb.ini", "lLower", .T. ) ? "Error =",leto_ferror() // 0 ? "Get [letodb.ini] lLower =",leto_varGet( "letodb.ini", "lLower" ) // ... = .T. ? "Error =",leto_ferror() // 0 ... [/pre2]
Pasha: SergKis пишет: Можно ли на клиенте получить установки сервера из ini EnableFileFunc = 0 Pass_for_Login = 1 Pass_for_Data = 1 Pass_for_Manage = 1 для понимая состояния сервера Например установка Pass_for_Login = 1 сваливает сервер, при коннекте с пустыми user, password Получить параметры сервера до коннекта с ним конечно невозможно. Другое дело, что коннект с любыми параметрами не должен сваливать сервер. Посмотрю, в чем там дело.
SergKis: Pasha пишет: Получить параметры сервера до коннекта с ним конечно невозможно Разговор о после коннекта. Пытаюсь создать на сервере и получить на клиенте такие данные (к примеру):[pre2] небольшие изменения для тестов: leto2016.prg ============ METHOD New() CLASS HApp ... msglog(procname(),"leto_SetAppOptions(...)") // !!! сработал вызов leto_SetAppOptions( iif( Empty(::DataPath ),Nil,::DataPath ), ; // 1 ::nDriver, ; // 2 ::lFileFunc, ; // 3 ::lAnyExt, ; // 4 ::lPass4L, ; // 5 ::lPass4M, ; // 6 ::lPass4D, ; // 7 ::cPassName, ; // 8 ::lCryptTraffic, ; // 9 ::lShare, ; // 10 ::lNoSaveWA, ; // 11 nMaxVars, ; // 12 nMaxVarSize, ; // 13 nCacheRecords, ; // 14 nTables_max, ; // 15 nUsers_max, ; // 16 nDebugMode, ; // 17 lOptimize, ; // 18 nAutOrder, ; // 19 nMemoType, ; // 20 lForceOpt, ; // 21 ::cTrigger, ; // 22 ::cPendingTrigger, ; // 23 lSetTrigger ) // 24 RETURN Self ... FUNCTION MsgLog( ... ) LOCAL i, nParams := pCount(), aParams := hb_aParams() LOCAL hFile, cFile := "_MsgLog.txt", xVal, cTp hFile := iif( File(cFile), FOpen(cFile, 2) , FCreate(cFile) ) IF hFile < 1 RETURN .F. ENDIF FSeek( hFile, 0, 2) IF nParams > 0 FOR i := 1 TO nParams xVal := aParams[ i ] cTp := ValType( xVal ) IF cTp == 'C' ; xVal := iif(Empty(xVal), "'"+"'", trim(xVal)) ELSEIF cTp == 'N' ; xVal := hb_ntos(xVal) ELSEIF cTp == 'L' ; xVal := iif(xVal, ".T.", ".F.") ELSEIF cTp == 'D' ; xVal := hb_DtoC(xVal, 'DD.MM.YYYY') ELSEIF cTp == 'A' ; xVal := "ARRAY[" + hb_NToS( Len(xVal) ) + "]" ELSEIF cTp == 'H' ; xVal := "HASH[" + hb_NToS( Len(xVal) ) + "]" ELSEIF cTp == 'B' ; xVal := "'" + "B" + "'" ELSEIF cTp == "T" ; xVal := hb_TSToStr( xVal, .T. ) ELSEIF cTp == 'U' ; xVal := 'NIL' ELSE ; xVal := "'" + cTp + "'" ENDIF FWrite(hFile, xVal + Chr(9) ) NEXT ENDIF FWrite( hFile, Chr(13)+Chr(10), 2 ) FClose( hFile ) RETURN .T. letoudf.prg =========== #include "rddleto.ch" ... FUNCTION UDF_Init /* * This function called immediately after loading letoudf.hrb, if exist */ LOCAL aVar := {}, nUserStru := NIL, cGroupName := "letodb.ini", aIni SET AUTORDER TO 1 msglog("-----------------------------------------") aIni := rdIni(hb_dirBase()+"letodb.ini") msglog("rdIni(...) :") msglog(hb_valtoexp(aIni)) msglog("Is variable PUBLIC oApp :", __MVEXIST("oApp")) aAdd(aVar, { 'lFileFunc' , leto_GetAppOptions( 3) }) aAdd(aVar, { 'lAnyExt' , leto_GetAppOptions( 4) }) aAdd(aVar, { 'lPass4L' , leto_GetAppOptions( 5) }) aAdd(aVar, { 'lPass4M' , leto_GetAppOptions( 6) }) aAdd(aVar, { 'lPass4D' , leto_GetAppOptions( 7) }) aAdd(aVar, { 'nCacheRecords', leto_GetAppOptions(14) }) aAdd(aVar, { 'nDebugMode' , leto_GetAppOptions(17) }) aAdd(aVar, { 'lOptimize' , leto_GetAppOptions(18) }) aAdd(aVar, { 'nAutOrder' , leto_GetAppOptions(19) }) aAdd(aVar, { 'nMemoType' , leto_GetAppOptions(20) }) aAdd(aVar, { 'lForceOpt' , leto_GetAppOptions(21) }) If !empty(leto_GetAppOptions(22)) .or. !empty(leto_GetAppOptions(23)) aAdd(aVar, { 'lSetTrigger' , leto_GetAppOptions(24) }) EndIf LETO_VARSET(nUserStru, cGroupName, "Options", hb_valtoexp(aVar), ; LETO_VCREAT+LETO_VDENYWR) msglog("leto_GetAppOptions(...) :") aEval(aVar, {|x,y| msglog(y, x[1], x[2]) }) msglog("-----------------------------------------") RETURN Nil полученный протокол: _MsgLog.txt =========== ----------------------------------------- Run: leto2016.exe TEST HAPP:NEW leto_SetAppOptions(...) ----------------------------------------- rdIni(...) : {{"MAIN", {{"PORT", "2812"}, {"DATAPATH", "."}, {"ENABLEFILEFUNC", "1"}}}} Is variable PUBLIC oApp : .T. leto_GetAppOptions(...) : 1 lFileFunc NIL 2 lAnyExt .F. 3 lPass4L NIL 4 lPass4M NIL 5 lPass4D NIL 6 nCacheRecords NIL 7 nDebugMode NIL 8 lOptimize .F. 9 nAutOrder 0 10 nMemoType 0 11 lForceOpt .F. -----------------------------------------Run: leto2016.exe RELOAD HAPP:NEW leto_SetAppOptions(...) ----------------------------------------- rdIni(...) : {{"MAIN", {{"PORT", "2812"}, {"DATAPATH", "."}, {"ENABLEFILEFUNC", "1"}}}} Is variable PUBLIC oApp : .F. leto_GetAppOptions(...) : 1 lFileFunc NIL 2 lAnyExt .F. 3 lPass4L NIL 4 lPass4M NIL 5 lPass4D NIL 6 nCacheRecords NIL 7 nDebugMode NIL 8 lOptimize .F. 9 nAutOrder 0 10 nMemoType 0 11 lForceOpt .F. ----------------------------------------- [/pre2] не понял, почему leto_GetAppOptions() дает такие странные данные после leto_SetAppOptions(...) ?
Петр: SergKis пишет: не понял, почему leto_GetAppOptions() дает такие странные данные после leto_SetAppOptions(...) ? А что здесь странного ? [pre2]HB_FUNC( LETO_GETAPPOPTIONS ) // mt { USHORT uiNum = hb_parni(1); switch( uiNum ) { case 1: hb_retc( pDataPath ); break; case 2: hb_retni( uiDriverDef ); break; case 4: hb_retl( bAnyExt ); break; case 10: hb_retl( bShareTables ); break; case 11: hb_retl( bNoSaveWA ); break; case 18: hb_retl( bOptimize ); break; case 19: hb_retni( uiAutOrder ); break; case 20: hb_retni( uiMemoType ); break; case 21: hb_retl( bForceOpt ); break; } } [/pre2] что может возвратить leto_GetAppOptions(3)? или не дописали или так задумано.
SergKis: Петр пишет [pre2] 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 ... LOCAL lOptimize := .F. LOCAL lForceOpt := .F. LOCAL lSetTrigger := .F. т.е. 1.переменные инициализированы leto_SetAppOptions(...) 2. ::lFileFunc определена из ini ELSEIF aIni[i,2,j,1] == "ENABLEFILEFUNC" ::lFileFunc := ( aIni[i,2,j,2] == '1' ) leto_GetAppOptions() для нее дает NIL др. то же не так как устанавливались 3. по разному уст. среда tread - режим TEST PUBLIC oApp - доступна - режим RELOAD PUBLIC oApp - нет [/pre2]
Петр: SergKis пишет: leto_GetAppOptions() для нее дает NIL я уточнил свой вопрос, что должна возвращать leto_GetAppOptions(3), исходя из ее реализации?
SergKis: Петр пишет я уточнил свой вопрос, что должна возвращать leto_GetAppOptions(3), исходя из ее реализации? Исторически, я так понимаю, leto_GetAppOptions использовалась только для внутренних вызовов. Если так и оставлять, тогда должен быть доступна PUBLIC oApp в UDF функциях или приводить leto_GetAppOptions к состоянию использованию в UDF, а под словом "странные" результаты, я имел ввиду несоответствие устанавливаемых и получаемых данных
Петр: SergKis пишет: а под словом "странные" результаты, я имел ввиду несоответствие устанавливаемых и получаемых данных Поскольку описания ни leto_GetAppOptions ни leto_SetAppOptions нет в readme.txt, мы только можем догадываться о мотивах такой реализации. Если leto_GetAppOptions используется только на сервере (для внутренних вызовов), тогда ее реализацию можно назвать кривой
SergKis: Петр пишет тогда ее реализацию можно назвать кривой У каждой задачи, при взгляде назад (исторически) можно найти кучу старых реализаций, с сегодняшней точки зрения являющейся мусором, кривой реализацией. "Лучшее - враг хорошего !" (c)
Pasha: SergKis пишет: не понял, почему leto_GetAppOptions() дает такие странные данные после leto_SetAppOptions(...) ? Пока единственное назначение функций leto_GetAppOptions()/leto_SetAppOptions() - запись/чтение глобальных установок между prg-кодом (это server.prg) и С-кодом (letofunc.c). Поскольку для server.prg нет необходимости чтения ряда параметров, это чтение и не реализовано в функции leto_GetAppOptions(). В дальнейшем планировалось переписать значительную часть кода из server.prg на C, и необходимость в в этих функция отпала бы. Но пока это не сделано. Раз уж клиенту надо знать значение ряда глобальных установок сервера, имеет смысл реализовать это чтение в leto_GetAppOptions(). Тогда клиент сможет их получать посредством вызовов udf-функций.
Pasha: Пошли какие-то глюки с git. Когда я делаю коммит, то его сразу не видно. Сделаю следующий коммит - становится видно предыдущий. Таким образом, я сегодня сделал коммит, и стал виден вчерашний. А мой сегодняшний будет виден, когда я сделаю следующий. Такой кордебалет начался с августа.
alkresin: В console.prg добавил возможность чтения/записи переменных ( leto_var... ). P.S. Глюков с коммитом не заметил.
alkresin: Leto_Ping() теперь принимает в качестве параметра адрес сервера или номер соединения - чтобы удобнее было пинговать при подключении к нескольким серверам. Leto_setCurrentConnection() тоже может теперь принимать адрес сервера вместо номера соединения и возвращает номер предыдущего соединения. Наверное, стоит build 3 выпустить.
alkresin: Вышла 3-я сборка, пакет с исходниками выложен на Sourceforge, исходники и пара бинарных - у меня на сайте: http://www.kresin.ru/letodb.html
Andrey: Какая сейчас последняя версия LetoDB ? Судя по сайту - 2.17 b3, это правильно ? Там сборка для Debian 7 32-bit, а на Debian 11 64-bit она будет работать ? Какие есть возможности архивирования одного файла на сервере ? Как можно сделать архив всех баз каталога ? Возможно ли отображение бегунка архивации у клиента, кто делает архив ? Поделитесь опытом пожалуйста.
alkresin: Да, 2.17 b3. > Там сборка для Debian 7 32-bit, а на Debian 11 64-bit она будет работать ? Нет. А в чем проблема собрать из исходников? Хотя я могу выложить Debian 11 64-bit, если надо. > Какие есть возможности архивирования одного файла на сервере ? > Как можно сделать архив всех баз каталога ? Наверное, через udf можно. Я архивацию баз обычно запускаю через cron (планировщик заданий в Линукс).
Andrey: alkresin пишет: Нет. А в чем проблема собрать из исходников? Хотя я могу выложить Debian 11 64-bit, если надо. Спасибо ! Мне уже собрали, пока тестирую.
Andrey: LetoDB стоит на Linux, делаю: start dbedit -f -letodb=//000.000.000.000:2880/ Не работает с версией 2.17 Но наверное, так и должно быть...
Pasha: Andrey пишет: start dbedit -f -letodb=//000.000.000.000:2880/ Почему такой ip ? И порт не стандартный. С такими параметрами наверное так и должно быть
Andrey: Ip правильный, порт тоже. Здесь просто 0 показал. На сервере установлено 2 задачи LetoDB и LetoDbf
Pasha: Если харбор-программа, утилита manage коннектится с такими параметрами, то и dbedit тоже будет коннектиться.
Andrey: Утилита manage коннектится с такими параметрами, а dbedit - нет. После нескольких попыток, перестановок, запустилось окно. Спасибо Pasha !
Andrey: А как отображать длительные расчёты в функциях UDF, которые выполняются на сервере ? Как показать бегунок процесса расчётов ? Программа при длительном запросе UDF просто висит - белый экран и отображается: Программа не отвечает
Pasha: Клиент выдает запрос серверу и ждет ответа, сервер выполняет udf и возвращает результат. В процессе выполнения udf никакого обмена пакетами между клиентом и сервером нет и быть не может. Поэтому перед вызовом udf надо повесить сообщение, и ждать результата. Ну или выполнять udf в отдельном потоке.
PSP: Andrey пишет: Как показать бегунок процесса расчётов ? Вот в майкрософт не сильно парятся про это) Делают какие-нибудь двигающиеся кружочки/квадратики, чтобы видно было, что процесс не завис. И похер им, что проценты не показывает) И ты так сделай)
SergKis: Andrey пишет: Как показать бегунок процесса расчётов ? Можно исп. переменные сервера, для user, перед запуском создать, на сервере их заполнить в начале длит. операции (счетчик и max. значение). По мере работы, переменную счетчик, вести на сервере, на клиенте по таймеру считывать их значения и считать процент, по окончании операции с клиента переменные удалить - практически все так же, как и обычная работа длит. операции с прерыванием по Esc, например. Это то же можно предусмотреть добавив переменную сервера для прерывания, ее анализировать в длит. операции. Схема, совершенно такая же, как и в обычной работе. Имена переменных делать от user-а (nUserStru для leto 2.17, leto_MgID() для leto 3.0) например или еще как, решения есть
Andrey: PSP пишет: Делают какие-нибудь двигающиеся кружочки/квадратики, чтобы видно было, что процесс не завис. И похер им, что проценты не показывает) И ты так сделай) Сделал. Авишка висит и не двигается... Правда отдельный поток не пробовал ещё.
alkresin: На самом деле варианты решения разные есть, надо только проявить фантазию. Можно, например, написать небольшую программу, которая будет по запросу выполнять эти "длительные расчёты", сделать ее клиентом letodb и запускать ее автоматически. Программа должна будет с определенной периодичностью опрашивать переменную letodb (leto_varget()) и, если найдет там запрос на работу, выполнит ее, записав результат (leto_varset()) в другую переменную. Может и промежуточные сведения записывать. Другие клиетны должны будут просто писать запрос в определенную переменную letodb и периодически опрашивать ее в ожидании ответа.
Pasha: Можно фрагментировать долгоиграющую udf на много мелких. Скажем, вместо udf, которая считает всех абонентов, использовать udf, которая считает абонентов из некоего диапазона, и вызывать эту udf много раз, перебрав всех.
Andrey: А нельзя в сам сервер встроить механизм загрузки программ клиента. Т.е. даёшь в коде программы команду загрузить допустим <мой_код>.hrb (.prg, не надо) Который располагаешь рядом с letoudf.hrb или в другом каталоге, потом выполняешь свой код, а потом при завершении выгружаешь этот <мой_код>.hrb И в letoudf.hrb лишнего кода не будет и программисту лишний раз его пере компилировать НЕ НАДО !
Pasha: Да можно В letoudf.hrb надо добавить функцию: #ifndef HB_HRB_BIND_DEFAULT #define HB_HRB_BIND_DEFAULT 0x0 #endif Function UDF_HrbLoad( nUserStru, cHrbName ) Local pHrb := hb_HrbLoad(HB_HRB_BIND_DEFAULT, hb_dirBase() + cHrbName ) Return ! Empty(pHrb) Положить свой hrb модуль в папку letodb на сервере, и вызывать загрузку этого модуля с клиента.
Andrey: Pasha пишет: Положить свой hrb модуль в папку letodb на сервере, и вызывать загрузку этого модуля с клиента. А как выгружать ? Или не нужно этого делать ?
Pasha: Можно так: #ifndef HB_HRB_BIND_DEFAULT #define HB_HRB_BIND_DEFAULT 0x0 #endif Static aHrb := {} ... Function UDF_HrbLoad( nUserStru, cHrbName ) Local pHrb := hb_HrbLoad(HB_HRB_BIND_DEFAULT, hb_dirBase() + cHrbName ) Local nId if ! Empty(pHrb) AADD(aHrb, pHrb) nId := Len(aHrb) else nId := 0 endif Return nId Function UDF_HrbUnload( nUserStru, nId ) if nId # 0 .and. nId <= Len(aHrb) .and. aHrb[nId] # 0 hb_hrbUnload(aHrb[nId]) aHrb[nId] := 0 endif Return nil
Andrey: Спасибо БОЛЬШОЕ ! Буду пробовать...
Andrey: А ещё вопрос про архивы базы на ЛетоДб. ЛетоДб стоит у заказчика, крутится круглосуточно, прога постоянно в памяти. А нельзя сделать/назначить время когда бы делался архив БД автоматом самостоятельно ? Зачем ставить планировщик, смотреть его, а если нет доступа к серверу, только через чужого админа. А админа сейчас вообще не найдешь... А так указал в ини-файле время срабатывания архивации и указать путь архивации и пускай делает эту операцию само ЛетоДб ! И ещё запуск утилиты после архивации, чтобы в облако переслало этот архив. И будет счастье программисту, не надо лазить проверять делается ли архив или нет.
SergKis: Andrey пишет А так указал в ини-файле время срабатывания архивации и указать путь архивации и пускай делает эту операцию само ЛетоДб Паша пишет Клиент выдает запрос серверу и ждет ответа, сервер выполняет udf и возвращает результат. В процессе выполнения udf никакого обмена пакетами между клиентом и сервером нет и быть не может. Делай клиента рядом с сервером, который будет выполнять все, что ты написал выше, как пример, смотри LetoDBf-master\utils\backup
Andrey: А как в LetoDb-2.17 удалить пользователя ? По доке нашёл это: [pre2] 7.8 Функции управления пользователями LETO_USERADD( cUserName, cPass [, cRights ] ) --> lSuccess LETO_USERPASSWD( cUserName, cPass ) --> lSuccess LETO_USERRIGHTS( cUserName, cRights ) --> lSuccess LETO_USERFLUSH() --> lSuccess LETO_USERGETRIGHTS() --> cRights[/pre2] В версии 3.00 есть возможность удалять одного юзера: [pre2] Leto_UserDelete( cUsr )[/pre2]
Dima: Andrey пишет: Leto_UserDelete( cUsr ) это в LetoDbf а в LetoDb судя по сырцам этого нет
полная версия страницы