Автор | Сообщение |
|
| постоянный участник
|
Пост N: 4156
Зарегистрирован: 12.09.06
|
|
Отправлено: 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" Помню что где то обсуждали, а результат не запомнил...
|
|
|
Ответов - 54
, стр:
1
2
3
All
[только новые]
|
|
|
| постоянный участник
|
Пост N: 1143
Зарегистрирован: 17.02.12
|
|
Отправлено: 07.08.16 10:54. Заголовок: Pasha Спасибо. :sm..
Pasha Спасибо.
|
|
|
|
| постоянный участник
|
Пост N: 1150
Зарегистрирован: 17.02.12
|
|
Отправлено: 08.08.16 19:51. Заголовок: Pasha Можно ли более..
Pasha Можно ли более информанивным сделать сообщение в log ERROR! UDF: not a valid name ? Добавить имя функции и источник, адрес
|
|
|
|
| постоянный участник
|
Пост N: 1238
Зарегистрирован: 09.10.06
|
|
Отправлено: 08.08.16 20:26. Заголовок: Извините за возможно..
Извините за возможно глупый вопрос, а откуда можно скачать обновленные исходники, а то с sourceforge что-то не совсем свежее качается.
|
|
|
|
| постоянный участник
|
Пост N: 1151
Зарегистрирован: 17.02.12
|
|
Отправлено: 08.08.16 21:01. Заголовок: Петр https://source..
|
|
|
|
| постоянный участник
|
Пост N: 1239
Зарегистрирован: 09.10.06
|
|
Отправлено: 08.08.16 21:23. Заголовок: Спасибо за ссылку. ..
Спасибо за ссылку. цитата: | nParam = leto_GetParam( szData, &pp2, &pp3, NULL, NULL ); // leto_writelog( NULL, 0, "UDF: %s, CMD=%d\r\n", pp2, uiCommand ); |
| Павел не добавил закомментированную строку. Добавьте у себя, тогда сравнивая letodb.log и letodb_Х.log цитата: | Leto DB Server v.2.17b2 ! INIT: DataPath=f:\leto\data, ShareTables=0, MaxUsers=500, MaxTables=5000, CacheRecords=10 08/02/16 23:51:17: F:\leto\letoudf.hrb has been loaded. UDF: str, CMD=3 UDF: udf_diskSpace, CMD=3 UDF: str, CMD=2 UDF: udf_diskSpace, CMD=2 |
| цитата: | 127.0.0.1 MASTER-H test_udf.exe ERROR! UDF: not a valid name ERROR! UDF: not a valid name |
| вы б получили необходимую информацию. Как по мне, leto_wUsLog() нужно модифицировать для передачи дополнительной информации по типу leto_writelog() Ну и лог сервера вести без указания времени события как-то некрасиво, что-ли
|
|
|
|
| постоянный участник
|
Пост N: 1152
Зарегистрирован: 17.02.12
|
|
Отправлено: 09.08.16 07:37. Заголовок: Петр пишет нужно мод..
Петр пишет цитата: | нужно модифицировать для передачи дополнительной информации ... лог сервера вести без указания времени события как-то некрасиво |
| Согласен. К имени функции и времени в доп. инф. важно идентифицировать и пользователя (имя, адрес, exe) по возможности ...
|
|
|
|
| постоянный участник
|
Пост N: 1153
Зарегистрирован: 17.02.12
|
|
Отправлено: 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 для такой ситуации ?
|
|
|
|
| Администратор
|
Пост N: 3481
Зарегистрирован: 23.05.05
|
|
Отправлено: 09.08.16 08:32. Заголовок: Вызов leto_ParseReco..
Вызов leto_ParseRecords заполняет skip-буфер, который затем можно в цикле обработать. Пример как раз показан в комментариях к UDF_dbEval: leto_ParseRecords( leto_Udf('UDF_dbEval', <xScope>, <xScopeBottom>, <xOrder>, <cFilter>, <lDeleted> ) ) while ! eof() ... skip enddo dbInfo( DBI_CLEARBUFFER ) В случае набора произвольных записей такой способ был бы неправильным, так как это не является набором записей, следующих друг за другом последовательно. Поэтому лучше всего будет как раз возврат в udf массива записей с последующей их обработкой на клиенте: aRecs := leto_udf("udf_func", ...) for each cRec in aRecs leto_ParseRec(cRec) // обработка next
|
|
|
|
| постоянный участник
|
Пост N: 1154
Зарегистрирован: 17.02.12
|
|
Отправлено: 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 )
|
|
|
|
| постоянный участник
|
Пост N: 1156
Зарегистрирован: 17.02.12
|
|
Отправлено: 09.08.16 11:22. Заголовок: PS Пояснение. Имеем ..
PS Пояснение. Имеем 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 или тут камень есть ?
|
|
|
|
| постоянный участник
|
Пост N: 1157
Зарегистрирован: 17.02.12
|
|
Отправлено: 10.08.16 15:33. Заголовок: SergKis пишет Теоре..
SergKis пишет цитата: | Теоретически, вроде, ни что не мешает ? На клиенте ордер 2, на сервере отработали по ордеру 1 или тут камень есть ? |
| Pasha пишет цитата: | Поэтому лучше всего будет как раз возврат в udf массива записей с последующей их обработкой на клиенте: aRecs := leto_udf("udf_func", ...) for each cRec in aRecs leto_ParseRec(cRec) // обработка next |
| Pasha прав В итоге сделал так Скрытый текст
FUNCTION UDF_AddRecID( nUserStru, cFieldName, xOrder, aFldVal, xMin ) LOCAL nPos := FieldPos( cFieldName ), nLen, a, p LOCAL xKey, lApp, lOver := .F., xOrd1, xOrd2, nDec IF ! Empty( xOrder ) IF Valtype(xOrder) == "A" xOrd1 := xOrder[1] xOrd2 := xOrder[2] ELSE xOrd1 := xOrder ENDIF OrdSetFocus( xOrd1 ) ENDIF IF leto_TableLock( nUserStru, 1 ) dbGoBottom() xKey := FieldGet( nPos ) IF Empty(xKey) .and. ! Empty(xMin) xKey := xMin IF ValType( xKey ) == "C" nLen := hb_FieldLen( nPos ) If left(xKey, 1) == "0" .and. ! "." $ xKey xKey := left(xKey+space(nLen), nLen) Else xKey := right(space(nLen)+xKey, nLen) EndIf ENDIF ENDIF IF ValType( xKey ) == "N" xKey ++ IF hb_FieldType(nPos) $ 'NF' lOver := xKey > Val( Replicate( "9", hb_FieldLen( nPos ) ) ) ELSEIF hb_FieldLen( nPos ) == 2 lOver := xKey > 0x7FFF ELSEIF hb_FieldLen( nPos ) == 4 lOver := xKey > 0x7FFFFFFF ENDIF ELSEIF ValType( xKey ) == "C" nLen := Len(xKey) If "." $ xKey nDec := nLen - RAt(".", xKey) xKey := Str( Val(xKey) + 1, nLen, nDec ) ElseIf left(xKey, 1) == "0" xKey := StrZero( Val(xKey) + 1, nLen ) Else xKey := Str( Val(xKey) + 1, nLen ) EndIf lOver := ('*' $ xKey) ENDIF IF lOver lApp := .F. ELSE lApp := ( UDF_AddRec( nUserStru, xOrd2 ) != Nil ) ENDIF 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 IF xOrder != Nil OrdSetFocus( xOrder ) ENDIF lSetDel := Set( _SET_DELETED, .f. ) dbGoTop() Set( _SET_DELETED, lSetDel ) IF ! Eof() .and. Deleted() .and. Empty( OrdKeyVal() ) IF( lApp := leto_RecLock( nUserStru ) ) dbRecall() ENDIF ELSE dbAppend() IF ( lApp := ! NetErr() ) leto_RecLock( nUserStru, RecNo() ) ENDIF ENDIF IF lApp xRet := leto_rec( nUserStru ) ENDIF RETURN xRet на клиенте DO WHILE ! EOF() aRec := RecGet() // {{cFieldName, xFieldValue}, ... } cRec := Leto_Udf("UDF_AddRecID", 'IDREC', {'IDR', 'DEL'}, aRec) If cRec = Nil ? "error ...." EndIf SKIP ENDDO
|
|
|
|
|
|
| постоянный участник
|
Пост N: 5124
Зарегистрирован: 12.09.06
|
|
Отправлено: 08.10.16 10:18. Заголовок: Всем привет ! Вопрос..
Всем привет ! Вопрос возник по эксплуатации ЛетоДб. Перед отправкой записей в базу на сервер, я проверяю в папке наличие файла и считываю оттуда его содержимое. Типа ключа для каждой фирмы. Код в программе: IF !LETO_FILE(cFile) MsgStop( "Нет файла КЛЮЧА на сервере!" ) RETURN .F. ENDIF Периодически юзера жалуются на появление такой ошибки ! Проверяю в это же время сервер - доступен. Пока юзер не перегрузит комп, ошибка не уходит. Иногда и после перезагрузки остаётся. Как с этим бороться ?
|
|
|
|
| Администратор
|
Пост N: 3496
Зарегистрирован: 23.05.05
|
|
Отправлено: 08.10.16 14:15. Заголовок: Можно описать ситуац..
Можно описать ситуацию подробнее ? Сервер находится тырнете или в локалке ? Коннект к серверу до выполнения leto_file выполнялся или нет ? Файл ключа все время существует или нет ? Что в cFile ? Коннект с сервером может прерваться или связь стабильная ? Без такого контекста отвечать на подобный вопрос трудно.
|
|
|
|
| постоянный участник
|
Пост N: 5125
Зарегистрирован: 12.09.06
|
|
Отправлено: 08.10.16 21:20. Заголовок: Pasha пишет: Можно ..
Pasha пишет: цитата: | Можно описать ситуацию подробнее ? |
| Сервер в инете. Программа делает коннект до сервера и работает дальше, т.е. отправляет записи на сервер ЛетоДб через 1-5 минут. Спустя 1 час или 5 часов - начинается такая фигня. Инет стабильный, коннект вроде не прерывается. Содержимое в cFile - 20-40 символов. В момет появления ошибки, захожу со своего компа - файлы все на месте и сервер ЛетоДб нормально отвечает.
|
|
|
|
| Администратор
|
Пост N: 3497
Зарегистрирован: 23.05.05
|
|
Отправлено: 09.10.16 08:57. Заголовок: Если сервер живой, и..
Если сервер живой, и файл на сервере существует, то логично предположить, что неудача leto_file связана с нарушением связи с сервером с этого клиента. В таком случае после if !LETO_FILE можно поставить проверку связи, например, вызовом функции LETO_MGGETINFO
|
|
|
|
| moderator
|
Пост N: 1032
Зарегистрирован: 06.07.06
|
|
Отправлено: 09.10.16 09:29. Заголовок: Pasha пишет: В тако..
Pasha пишет: цитата: | В таком случае после if !LETO_FILE можно поставить проверку связи, например, вызовом функции LETO_MGGETINFO |
| Надо будет для проверки связи сделать ф-ю leto_Ping() - тем более, что команду такую сервер обрабатывает. Помнится, это чуть-ли не первая команда, которую я в свое время сделал.
|
|
|
|
| moderator
|
Пост N: 1033
Зарегистрирован: 06.07.06
|
|
Отправлено: 09.10.16 09:37. Заголовок: Andrey пишет: Пока ..
Andrey пишет: цитата: | Пока юзер не перегрузит комп, ошибка не уходит. Иногда и после перезагрузки остаётся. |
| Вот это и в самом деле странно. Я бы до перезагрузки компа проверил ping к серверу - обычную команду ping, ну и если он проходит, то проверил бы как отрабатывает leto_Connection(). цитата: | Перед отправкой записей в базу на сервер, я проверяю в папке наличие файла и считываю оттуда его содержимое. |
| Немного не в тему, но: а почему бы не использовать здесь leto_var...() функции ?
|
|
|
|
| Администратор
|
Пост N: 3498
Зарегистрирован: 23.05.05
|
|
Отправлено: 09.10.16 14:43. Заголовок: alkresin пишет: Над..
alkresin пишет: цитата: | Надо будет для проверки связи сделать ф-ю leto_Ping() - тем более, что команду такую сервер обрабатывает. Помнится, это чуть-ли не первая команда, которую я в свое время сделал. |
| Еще в файловых функциях вроде LetoFileExist можно добавить обработку: if( uiRes ) { ... } else s_iError = 1000; Можно вместо этого перенести установку if( !lRet ) s_iError = 1000; из функции leto_SendRecv в функцию leto_DataSendRecv Тогда ошибку связи с сервером во многих функциях, в том числе файловых, можно будет проверить вызовом LETO_FERROR()
|
|
|
|
| постоянный участник
|
Пост N: 5126
Зарегистрирован: 12.09.06
|
|
Отправлено: 09.10.16 14:51. Заголовок: alkresin пишет: Нем..
alkresin пишет: цитата: | Немного не в тему, но: а почему бы не использовать здесь leto_var...() функции ? |
| Да наверно из-за не знания. Я когда начал изучать документацию по Лето, то не понял, для чего они. Самостоятельно не всегда знаешь/понимаешь что нужно в том или ином случае. Желательно бы в документацию включить доп.материалы для тех или иных действий и код приводить полностью. Например: 1) Коннект к серверу (это есть вроде) 2) Проверка доступности сервера и переподключение к серверу. 3) Проверка доступа клиента к базе, т.е. разрешение к записи/чтения к базе. Это я реализовал простой проверкой наличия файла (у каждой фирмы свой файл) и содержимого самого файла (типа ключа проверки). 4) Работа с базами на двух и более серверах ЛетоДБ 5) Синхронизация по таймеру ( и событию) локальной и серверной базы и наоборот с сервера на локальную. и т.д.
|
|
|
|
| moderator
|
Пост N: 1035
Зарегистрирован: 06.07.06
|
|
Отправлено: 10.10.16 14:26. Заголовок: Pasha пишет: Можно ..
Pasha пишет: цитата: | Можно вместо этого перенести установку |
| Так и сделал. И Leto_Ping() добавил: возвращает .T., если все в порядке.
|
|
|
Ответов - 54
, стр:
1
2
3
All
[только новые]
|
|