Форум » LetoDB, HbNetio. » Leto DB Server (продолжение 10) (продолжение) » Ответить

Leto DB Server (продолжение 10) (продолжение)

Dima: Продолжаем тут

Ответов - 191, стр: 1 2 3 4 5 6 7 8 9 10 All

SergKis: SergKis пишет: leto сервер делает все ok для полей типа ^ и + - типы T, @ превращаются в = - пустое поле типа = не заполняется значением TimeStamp причина в разном case:[pre2] leto1.c(line 1950) case HB_FT_MODTIME: cType = '@'; break; case HB_FT_DATETIME: case HB_FT_DAYTIME: cType = 'T'; break; rdd\dbf1.c(line 3050) case HB_FT_TIMESTAMP: pThisField->bType = pArea->bTableType == DB_DBF_VFP ? 'T' : '@'; pField->uiLen = 8; pThisField->bLen = ( BYTE ) pField->uiLen; pThisField->bFieldFlags = HB_FF_BINARY; pArea->uiRecordLen += pField->uiLen; break; case HB_FT_MODTIME: pThisField->bType = '='; pField->uiLen = 8; pThisField->bLen = ( BYTE ) pField->uiLen; pArea->uiRecordLen += pField->uiLen; pArea->fModStamp = TRUE; break; [/pre2] т.е. в cdx типы T,@ - HB_FT_TIMESTAMP, тип = HB_FT_MODTIME, в leto другие

SergKis: полная катавасия со структурой (поля типа TIMESTAMP, MODTIME): - на клиенте подаем в dbCreate ..., {"TM", "@", 8, 0}, {"TS", "=", 8, 0},... - на сервере имеем в HS_CREATETABLE (пришло с клиента) ..., {"TM", "T", 8, 0}, {"TS", "@", 8, 0},... - на сервере имеем в HS_OPENTABLE (после dbStruct)..., {"TM", "@", 8, 0}, {"TS", "@", 8, 0},... - на клиенте после dbStruct имеем ..., {"TM", "=", 8, 0}, {"TS", "=", 8, 0},... придется остатья на старой версии (двухпотчной)

Pasha: SegKis пишет: смотрю в сервере отключены триггера - это специально или нарочно ? Конечно, не специально, и не нарочно. Эта реализация была пропущена при реорганизации кода почти 4 года назад. Поправил.


SergKis: Pasha добавил в server.prg: [pre2] #include "hbsxdef.ch" ... leto_HrbLoad() IF ! EMPTY( oApp:cTrigger ) WrLog( "Trigger "+oApp:cTrigger+" "+_u2s(leto_Driver( oApp:nDriver )) ) HB_RddInfo( RDDI_TRIGGER, oApp:cTrigger, leto_Driver( oApp:nDriver ) ) ENDIF IF ! EMPTY( oApp:cPendingTrigger ) WrLog( "pendingTrigger "+oApp:cTrigger+" "+_u2s(leto_Driver( oApp:nDriver )) ) HB_RddInfo( RDDI_PENDINGTRIGGER, oApp:cPendingTrigger, leto_Driver( oApp:nDriver ) ) ENDIF ... /////////////////////////////////////////////////////////////////////////////// FUNCTION tst_Trigger( nEvent, nArea, nPos, xTrigVal ) LOCAL i := nEvent, j := '', k k := _u2s(nEvent)+':'+_u2s(nArea)+':'+_u2s(nPos)+':'+_u2s(xTrigVal) WrLog(procname()+':'+k) IF nEvent == EVENT_POSTUSE // 2 dbInfo(DBI_TRIGGER, .F.) j := 'EVENT_POSTUSE' k := _u2s(nEvent)+':'+j+':'+_u2s(nArea)+':'+_u2s(nPos)+':'+_u2s(xTrigVal) WrLog(procname()+':'+k) dbInfo(DBI_TRIGGER, .T.) RETURN .T. ELSEIF nEvent == EVENT_PRECLOSE // 11 dbInfo(DBI_TRIGGER, .F.) j := 'EVENT_PRECLOSE' k := _u2s(nEvent)+':'+j+':'+_u2s(nArea)+':'+_u2s(nPos)+':'+_u2s(xTrigVal) WrLog(procname()+':'+k) dbInfo(DBI_TRIGGER, .T.) RETURN .T. ELSEIF nEvent < EVENT_UPDATE .or. nEvent > EVENT_ZAP dbInfo(DBI_TRIGGER, .F.) j := 'EVENT_UPDATE-EVENT_ZAP' k := _u2s(nEvent)+':'+j+':'+_u2s(nArea)+':'+_u2s(nPos)+':'+_u2s(xTrigVal) WrLog(procname()+':'+k) dbInfo(DBI_TRIGGER, .T.) RETURN .T. ENDIF dbInfo(DBI_TRIGGER, .F.) DO CASE CASE nEvent == EVENT_UPDATE // 3 j := 'EVENT_UPDATE' CASE nEvent == EVENT_APPEND // 4 j := 'EVENT_APPEND' CASE nEvent == EVENT_DELETE // 5 j := 'EVENT_DELETE' CASE nEvent == EVENT_RECALL // 6 j := 'EVENT_RECALL' CASE nEvent == EVENT_PACK // 7 j := 'EVENT_PACK' CASE nEvent == EVENT_ZAP // 8 j := 'EVENT_ZAP' ENDCASE k := _u2s(nEvent)+':'+j+':'+_u2s(nArea)+':'+_u2s(nPos)+':'+_u2s(xTrigVal) WrLog(procname()+':'+k) * CASE nEvent == EVENT_PREUSE // 1 * CASE nEvent == EVENT_POSTUSE // 2 * CASE nEvent == EVENT_PACK // 7 * CASE nEvent == EVENT_ZAP // 8 * CASE nEvent == EVENT_PUT // 9 * CASE nEvent == EVENT_GET // 10 * CASE nEvent == EVENT_PRECLOSE // 11 * CASE nEvent == EVENT_POSTCLOSE // 12 * CASE nEvent == EVENT_PREMEMOPACK // 13 * CASE nEvent == EVENT_POSTMEMOPACK // 14 dbInfo(DBI_TRIGGER, .T.) RETURN .T. /////////////////////////////////////////////////////////////////////////////// STATIC FUNCTION _u2s( uValue ) LOCAL cType := ValType( uValue ) IF cType == "L" RETURN iif( uValue, ".T.", ".F." ) ELSEIF cType == "N" RETURN AllTrim( Str( uValue ) ) ELSEIF cType == "D" RETURN Dtoc( uValue ) ELSEIF cType == "A" RETURN 'ARRAY['+AllTrim( Str( len(uValue) ) )+']' ELSEIF cType == "C" RETURN trim(uValue) ELSEIF cType == "U" RETURN 'NIL' ELSE uValue := 'VALTYPE='+cType ENDIF RETURN uValue letodb.ini: [Main] Port = 2812 DataPath = . EnableFileFunc = 1 Trigger = tst_Trigger ;PendingTrigger = tst_Trigger [/pre2] тестовая test_dbf.prg: [pre2] #include "wvtwin.ch" #include "hbgtinfo.ch" #include "rddleto.ch" #include "dbinfo.ch" REQUEST HB_GT_WVT REQUEST HB_GT_WVT_DEFAULT REQUEST HB_CODEPAGE_LV866 REQUEST LETO, DBFCDX Function Main( cPath ) Local aNames := { "Petr", "Ivan", "Alexander", "Pavel", "Alexey", "Fedor", ; "Konstantin", "Vladimir", "Nikolay", "Andrey", "Dmitry", "Sergey" } Local i, aStru Local cFont Field NAME, NUM, INFO, DINFO hb_gtInfo( HB_GTI_CODEPAGE, 866) hb_setCodePage( "LV866" ) hb_setTermCP( "LV866" ) hb_GtInfo( HB_GTI_FONTNAME , cFont ) hb_gtInfo( HB_GTI_FONTQUALITY, 3 ) RDDSETDEFAULT( "LETO" ) SET DATE FORMAT "dd/mm/yy" cPath := "//127.0.0.1:2812/temp/" ? "Connect to " + cPath + " - " IF ( leto_Connect( cPath ) ) == -1 nRes := leto_Connect_Err() IF nRes == LETO_ERR_LOGIN ?? "Login failed" ELSEIF nRes == LETO_ERR_RECV ?? "Recv Error" ELSEIF nRes == LETO_ERR_SEND ?? "Send Error" ELSE ?? "No connection" ENDIF Return Nil ELSE ?? "Ok" ENDIF dbCreate( cPath+"test1", { {"NAME" , "C", 10, 0}, ; {"NUM" , "N", 4, 0}, ; {"INFO" , "C", 32, 0}, ; {"DINFO" , "D", 8, 0}, ; {"TM" , "@", 8, 0}, ; {"TS" , "=", 8, 0}, ; {"VM" , "^", 8, 0}, ; {"ID" , "+", 4, 0} ; } ) ? "File has been created" USE ( cPath+"test1" ) New ? "File has been opened", used(), alias() aStru := dbStruct() ? "Fields:", Len( aStru ) FOR i := 1 TO Len( aStru ) ? i, padr(aStru[i,1], 10), aStru[i,2], aStru[i,3], aStru[i,4], hb_FieldType(i) NEXT inkey(0) FOR i := 1 TO Len( aNames ) APPEND BLANK REPLACE NAME WITH aNames, NUM WITH i+1000, ; INFO WITH "This is a record number "+Ltrim(Str(i)), ; DINFO WITH Date()+i-1 // dbCommit() // dbGoto(RecNo()) // dbSkip(0) dbGoto(RecNo()) ? str(RecNo(), 3), NAME, NUM, TM, TS, VM, ID NEXT ? ? "Records has been added", LastRec() ? "Press any key to finish..." Inkey(0) Return Nil получаем letodb.log: 02/23/15 12:03:17: Leto DB Server has been started. Leto DB Server v.2.15 ! INIT: DataPath=., ShareTables=0, MaxUsers=500, MaxTables=5000, CacheRecords=10 02/23/15 12:03:17: Trigger tst_Trigger DBFCDX 02/23/15 12:18:09: Send STOP to server... 02/23/15 12:18:12: Server has been closed. [/pre2] т.е. триггер ставится, но работает, для PendingTrigger такой же результат.

SergKis: PS. повторяю искаженное:[pre2] FOR i := 1 TO Len( aNames ) APPEND BLANK REPLACE NAME WITH aNames[ i ], NUM WITH i+1000, ; ... [/pre2]

SergKis: SergKis пишет:т.е. триггер ставится, но работает, для PendingTrigger такой же результат. что то буквы съелись. Должно быть: т.е. триггер ставится, но НЕ работает, для PendingTrigger такой же результат.

alkresin: SergKis пишет: полная катавасия со структурой (поля типа TIMESTAMP, MODTIME): - на клиенте подаем в dbCreate ..., {"TM", "@", 8, 0}, {"TS", "=", 8, 0},... - на сервере имеем в HS_CREATETABLE (пришло с клиента) ..., {"TM", "T", 8, 0}, {"TS", "@", 8, 0},... А можно короткий тестовый пример, чтоб сразу откомпилировать и проверить ?

SergKis: alkresin пишет:А можно короткий тестовый пример, чтоб сразу откомпилировать и проверить ? Отправлено: 10.02.15 00:02. Заголовок: Режим: RddInfo( RDDI..

SergKis: alkresin letodb..prg добавил: ... [pre2] hs_createtable(...) ... aStru := Array( nLen, 4 ) FOR i := 1 TO nLen aStru[i,1] := GetCmdItem( cCommand, nPos + 1, @nPos ) aStru[i,2] := GetCmdItem( cCommand, nPos + 1, @nPos ) aStru[i,3] := Val( GetCmdItem( cCommand,nPos + 1,@nPos ) ) aStru[i,4] := Val( GetCmdItem( cCommand,nPos + 1,@nPos ) ) NEXT WLog(procname()+":"+hb_valtoexp(aStru)) // добавил ... hs_opentable(...) ... // line: ~457 aStru := dbStruct() WLog(procname()+":"+hb_valtoexp(aStru)) // добавил ... [/pre2]

SergKis: PS опять буква сълась WrLog(...) добавлял

alkresin: Ту небольшую путаницу я, вроде, исправил. Остается один неприятный момент с теми полями, которые формируются автоматически на сервере при добавлении записи. Поскольку на клиентской стороне работает буферизация, то если добавить запись и потом сразу прочитать, то она берется не с сервера. а из буфера - и значения тех полей пустые.

SergKis: alkresin пишет:на клиентской стороне работает буферизация,... как правило, сразу может понадобится поле "+" для заполнения в другую таблицу, в массив ключей, ... как осуществлять доступ ? делать dbcommit, leto_commit, закрывать\открывать таблицу ? на даты типа Timestamp и "^" запрос, как првило отложенный (могут быть в тегах индекса)

SergKis: PS. всегда в cdx, ntx, six было dbSkip(0) - перечитать\перезаполнить буфер

SergKis: alkresin пишет:Ту небольшую путаницу я, вроде, исправил. Работает. Большое СПАСИБО Вместо dbSkip(0) обновляет буфер на клиенте dbGoto(RecNo())

SergKis: SergKis пишет:Работает поторопился, timestamp работает, а "^" и "+" - что то не то при отображении в dbf все хорошо ? str(RecNo(), 3), NAME, str(NUM, 4), TS, VM, ID дает: [pre2] Rec NAME NUM TS VM ID === ========== ==== ===================== ==================== ========== 1 Petr 1001 05/03/15 14:26:54.731 16660054396318011 1413165115 2 Ivan 1002 05/03/15 14:26:54.731 16660054396318267 1413165115 3 Alexander 1003 05/03/15 14:26:54.731 16660054396318523 943406395 4 Pavel 1004 05/03/15 14:26:54.747 16660054396318779 3878971 5 Alexey 1005 05/03/15 14:26:54.747 16660054396319035 989870896 6 Fedor 1006 05/03/15 14:26:54.747 16660054396319291 3878912 7 Konstantin 1007 05/03/15 14:26:54.762 16660054396319547 993540925 8 Vladimir 1008 05/03/15 14:26:54.762 16660054396319803 993853499 9 Nikolay 1009 05/03/15 14:26:54.762 16660054396320059 1023425280 10 Andrey 1010 05/03/15 14:26:54.778 4264973925457342779 993853440 11 Dmitry 1011 05/03/15 14:26:54.778 4264973925457408315 993853440 12 Sergey 1012 05/03/15 14:26:54.778 4264973925457473851 993853440 [/pre2]

alkresin: А у меня все нормально отображается. Это ведь тот ваш пример, только dbSkip(0) заменено на go Recno() ?

alkresin: Все ясно. Это я небольшое исправление в серверной части не выложил на CVS - думал, оно не имеет значение, а в моем рабочеи каталоге оно осталось. Теперь выложил.

SergKis: alkresin пишет:Теперь выложил. Работает. Большое СПАСИБО.

Andrey: Установил наконец то сервер на Win2012. Вроде работает. Пытаюсь дальше разбираться.... Как можно отловить перезагрузку и работоспособность сервера LetoDB ? Т.е. при обращениях к ЛетоДБ как проверять, доступен он или нет (инет упал, сервер перегрузился и т.д.) - как обрабатывать ошибки ?

Dima: Andrey пишет: Установил наконец то сервер на Win2012. Вроде работает. Только он глючит порой не по теме , пытались его тоже юзать , откатились на 2008. Andrey пишет: Как можно отловить перезагрузку и работоспособность сервера LetoDB ? Не читал letodb\readme_rus.txt ? Цитата [pre2] Возможно проверить доступность сервера перед открытием файлов вызовом функции leto_Connect( cAddress ), которая вернет -1 в случае неудачной попытки: IF leto_Connect( "//192.168.5.22:2812/mydir/" ) == -1 Alert( "Can't connect to server ..." ) ENDIF + пункт 7.1 Управление соединением [/pre2] В LETODB в этом плане масса способов что бы проверить запущен ли (работает) LETODB по сравнению с ADS



полная версия страницы