On-line: гостей 0. Всего: 0 [подробнее..]
АвторСообщение
постоянный участник




Пост 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"

Помню что где то обсуждали, а результат не запомнил...

Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 54 , стр: 1 2 3 All [только новые]


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


Пост N: 1225
Зарегистрирован: 09.10.06
ссылка на сообщение  Отправлено: 02.08.16 23:20. Заголовок: Pasha пишет: Вызыва..


Pasha пишет:

 цитата:
Вызывать можно функции, указанные в request, ну и некоторые другие. Я пересматривал этот набор - он вполне безопасен.
Впрочем, я уже добавил параметр EnableUDF в letodb.ini, для возможности отключения udf.



Для себя внес изменения в letofunc.c


 цитата:
const char * szErrUDF = "-UDF"; 
..
void leto_udf( PUSERSTRU pUStru, const char* szData ) // mt?
..

if( uiCommand == 0 )
{
leto_wUsLog(pUStru,"ERROR! UDF: not a valid command\r\n", 0);
return;
}

nParam = leto_GetParam( szData, &pp2, &pp3, NULL, NULL );
// leto_writelog( NULL, 0, "UDF: %s, CMD=%d\r\n", pp2, uiCommand );

if( strlen( pp2 ) < 5 || hb_strnicmp( pp2, "UDF_", 4 ) != 0 )
{
leto_wUsLog(pUStru,"ERROR! UDF: not a valid name\r\n", 0);

leto_SendAnswer( pUStru, szErrUDF, 4 );
pUStru->bAnswerSent = 1;

return;
}

if( nParam < ( uiCommand == 1 ? 3 : ( uiCommand == 3 ? 1 : 2 ) ) )
leto_SendAnswer( pUStru, szErr2, 4 );
else
..



Т.е. имя UDF функции должно начинаться с UDF_ (UDF_() - не проходит) - хак с выполнением стандартных и функций leto через механизм leto_udf на сервере отсекается. Ну и сделал более осмысленным описание ошибки для leto_wUsLog.
Мне кажется такое решение более логичным существующего.


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




Пост N: 1129
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 04.08.16 18:08. Заголовок: Pasha Скачал letodb-..


Pasha
Скачал letodb-code-618295e5b48bf8ef2a50ca089ba73af8f1b57b85б :
 цитата:
... + added EnableUDF option in letodb.ini


но в HAPP нет считывания с letodb.ini EnableUGF и нет установки
 
leto_SetAppOptions( iif( Empty(::DataPath ),Nil,::DataPath ), ::nDriver, ::lFileFunc, ;
::lAnyExt, ::lPass4L, ::lPass4M, ::lPass4D, ::cPassName, ::lCryptTraffic, ;
::lShare, ::lNoSaveWA, nMaxVars, nMaxVarSize, nCacheRecords, nTables_max, nUsers_max, ;
nDebugMode, lOptimize, nAutOrder, nMemoType, lForceOpt, ::cTrigger, ::cPendingTrigger, lSetTrigger ) // нет 25 элемента

или я не там смотрю.

 цитата:
EnableUDF = 1 - если 1 (по умолчанию), разрешено использование udf-функций;


EnableUDF = 0 что делает, отключает все вызовы udf ?
Если да, то чем отличается услановка в 0 и работа сервера без letoudf.hrb ?



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




Пост N: 3475
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 05.08.16 08:21. Заголовок: Прошу прощения, проп..


Прошу прощения, пропустил при коммите server.prg. Поправлю.
Да, EnableUDF запрещает вызовы UDF. Может быть, имеет смысл еще добавить флаг UDFPrefix, который позволял бы вызовы только функций с именами UDF_*

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


Пост N: 1231
Зарегистрирован: 09.10.06
ссылка на сообщение  Отправлено: 05.08.16 08:39. Заголовок: Как вариант, еще вме..


Как вариант, еще вместо одного letoudf.hrb можно использовать 2 (или более), например, letoudf_st.hrb и letoudf_us.hrb.
Запуск letoudf_st.hrb не зависит от EnableUDF, запуск letoudf_us.hrb (и остальных), соответственно, зависит.


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


Пост N: 1232
Зарегистрирован: 09.10.06
ссылка на сообщение  Отправлено: 05.08.16 08:41. Заголовок: Pasha пишет: Может ..


Pasha пишет:

 цитата:
Может быть, имеет смысл еще добавить флаг UDFPrefix


Имеет, мой голос - за

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




Пост N: 1130
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 05.08.16 09:48. Заголовок: Pasha пишет Может бы..


Pasha пишет
 цитата:
Может быть, имеет смысл еще добавить флаг UDFPrefix


Я тоже за
Но можно просто обойтись режимом
0
1
2 - спрефиксоом udf_ (пока не вижу причин нескольких префиксов, но может ошибаюсь)
а то возникнет желание на каждого user уст. разрешено\нет udf, как с файловыми, mg ф-ими

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


Пост N: 1234
Зарегистрирован: 09.10.06
ссылка на сообщение  Отправлено: 05.08.16 10:17. Заголовок: SergKis пишет: а то..


SergKis пишет:

 цитата:
а то возникнет желание на каждого user уст. разрешено


можно и на уровне функций, т.е. доступна ли функция a() пользователю b

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




Пост N: 1131
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 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


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




Пост N: 1132
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 05.08.16 11:06. Заголовок: Еще такая есть хотел..


Еще такая есть хотелка - класс для работы с Hash массивом с синхронизированными методами доступа к его элементам, для работы в udf

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




Пост N: 1134
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 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 ) сложновато для меня





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




Пост N: 1135
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 05.08.16 13:22. Заголовок: И последнее. Не хват..


И последнее. Не хватает команды типа ( если стоит EnableFileFunc = 0 и нет hrb, а теперь и режим 0 для udf)
1. CRATE TABLE myTable ... IF NOT EXISTS - трудно управлять созданием таблицы, особенно если нет созданных каталогов к ней, возможно по установке в ini (а может и всегда) разрешать автосоздание дирректорий при их отсутсвии
2. DROP TABLE myTable - удалить таблицу вместе с индексами

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




Пост N: 1136
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 05.08.16 15:15. Заголовок: PS Реализация CREATE..


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

RETURN .T.


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




Пост N: 3476
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 05.08.16 20:00. Заголовок: SergKis пишет: Еще ..


SergKis пишет:

 цитата:
Еще такая есть хотелка - класс для работы с Hash массивом с синхронизированными методами доступа к его элементам, для работы в udf



Добавил request на сервере для хеш-функций.
Сделал префикс UDF_* обязательным по умолчанию для вызовов udf, с возможностью отключения этого режима.
А функция hb_dbDrop поддерживается letodb уже давно, т.к. метод letoDrop реализован на клиенте.

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




Пост N: 1137
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 05.08.16 20:39. Заголовок: Pasha :sm36: А что..


Pasha
А что по поводу варианта
 цитата:
CREATE TABLE ... IF NOT EXISTS



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




Пост N: 1138
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 05.08.16 21:51. Заголовок: Pasha HApp разсогла..


Pasha
HApp разсогласовался по переменным DATA и LOCAL в Method New, потому прошла ошибка
 
ELSEIF aIni[i,2,j,1] == "ENABLEUDF"
::lUDF := ( aIni[i,2,j,2] == '1' )
...
leto_SetAppOptions( iif( Empty(::DataPath ),Nil,::DataPath ), ::nDriver, ::lFileFunc, ;
::lAnyExt, ::lPass4L, ::lPass4M, ::lPass4D, ::cPassName, ::lCryptTraffic, ;
::lShare, ::lNoSaveWA, nMaxVars, nMaxVarSize, nCacheRecords, nTables_max, nUsers_max, ;
nDebugMode, lOptimize, nAutOrder, nMemoType, lForceOpt, ::cTrigger, ::cPendingTrigger, lSetTrigger, lUDF )

Предлагаю Скрытый текст




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




Пост N: 1140
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 07.08.16 00:26. Заголовок: Pasha Что то в посл..


Pasha
Что то в последней версии udf не работает. Сборка borland, hb из последнего Minigui.

клиент
 
Function Test_Udf( cPath )
Local c,i,j,k,lRes

IF Empty( cPath )
cPath := "//127.0.0.1:2812/"
ELSE
cPath := "//" + cPath + Iif( Right(cPath,1) $ "/\", "", "/" )
ENDIF

? "Connect to " + cPath + " - "
IF ( leto_Connect( cPath ) ) == -1
nRes := leto_Connect_Err()
?? "Error", nRes
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
?

If leto_UdfExist("leto_GetAppOptions")
? "leto_GetAppOptions found"
Else
? "not found "+"leto_GetAppOptions"
EndIf

If leto_UdfExist('hb_DiskSpace')
? "hb_DiskSpace found", leto_udf( "hb_DiskSpace", "C:\", HB_DISK_FREE )
Else
? "not found "+"hb_DiskSpace"
EndIf
If leto_UdfExist('UDF_AppendRec')
? 'UDF_AppendRec - found'
Else
? 'UDF_AppendRec - not found'
EndIf
? "Press any key to finish..."
?
Inkey(0)

Return Nil

результат

Connect to //127.0.0.1:2812/ - Ok

not found leto_GetAppOptions
not found hb_DiskSpace
UDF_AppendRec - not found
Press any key to finish...


letodb.ini
Port = 2812
DataPath = .
EnableFileFunc = 1
EnableUDF = 1

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.



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




Пост N: 3478
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 07.08.16 08:56. Заголовок: Почему-то не был вид..


Почему-то не был виден коммит, который я сделал позавчера, хотя у меня он прошел нормально. Сейчас я его повторил.

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




Пост N: 1141
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 07.08.16 09:21. Заголовок: Pasha Что не то le..


Pasha
Что не то
 
letodb.ini
Port = 2812
DataPath = .
EnableFileFunc = 1
EnableUDF = 1

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...




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




Пост N: 1142
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 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




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




Пост N: 3479
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 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

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




Пост N: 1143
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 07.08.16 10:54. Заголовок: Pasha Спасибо. :sm..


Pasha
Спасибо.

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




Пост N: 1150
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 08.08.16 19:51. Заголовок: Pasha Можно ли более..


Pasha
Можно ли более информанивным сделать сообщение в log ERROR! UDF: not a valid name ?
Добавить имя функции и источник, адрес

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


Пост N: 1238
Зарегистрирован: 09.10.06
ссылка на сообщение  Отправлено: 08.08.16 20:26. Заголовок: Извините за возможно..


Извините за возможно глупый вопрос, а откуда можно скачать обновленные исходники, а то с sourceforge что-то не совсем свежее качается.


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




Пост N: 1151
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 08.08.16 21:01. Заголовок: Петр https://source..

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


Пост 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()

Ну и лог сервера вести без указания времени события как-то некрасиво, что-ли


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




Пост N: 1152
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 09.08.16 07:37. Заголовок: Петр пишет нужно мод..


Петр пишет
 цитата:
нужно модифицировать для передачи дополнительной информации ...
лог сервера вести без указания времени события как-то некрасиво


Согласен. К имени функции и времени в доп. инф. важно идентифицировать и пользователя (имя, адрес, exe) по возможности ...

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




Пост 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 для такой ситуации ?


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




Пост 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

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




Пост 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 )


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




Пост 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
или тут камень есть ?



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




Пост 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 прав
В итоге сделал так Скрытый текст



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




Пост N: 5124
Зарегистрирован: 12.09.06
ссылка на сообщение  Отправлено: 08.10.16 10:18. Заголовок: Всем привет ! Вопрос..


Всем привет !
Вопрос возник по эксплуатации ЛетоДб.
Перед отправкой записей в базу на сервер, я проверяю в папке наличие файла и считываю оттуда его содержимое.
Типа ключа для каждой фирмы.
Код в программе:
IF !LETO_FILE(cFile)
MsgStop( "Нет файла КЛЮЧА на сервере!" )
RETURN .F.
ENDIF

Периодически юзера жалуются на появление такой ошибки !
Проверяю в это же время сервер - доступен.
Пока юзер не перегрузит комп, ошибка не уходит. Иногда и после перезагрузки остаётся.
Как с этим бороться ?

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




Пост N: 3496
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 08.10.16 14:15. Заголовок: Можно описать ситуац..


Можно описать ситуацию подробнее ? Сервер находится тырнете или в локалке ? Коннект к серверу до выполнения leto_file выполнялся или нет ? Файл ключа все время существует или нет ? Что в cFile ? Коннект с сервером может прерваться или связь стабильная ?
Без такого контекста отвечать на подобный вопрос трудно.

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




Пост N: 5125
Зарегистрирован: 12.09.06
ссылка на сообщение  Отправлено: 08.10.16 21:20. Заголовок: Pasha пишет: Можно ..


Pasha пишет:

 цитата:
Можно описать ситуацию подробнее ?


Сервер в инете.
Программа делает коннект до сервера и работает дальше, т.е. отправляет записи на сервер ЛетоДб через 1-5 минут.
Спустя 1 час или 5 часов - начинается такая фигня.
Инет стабильный, коннект вроде не прерывается.
Содержимое в cFile - 20-40 символов.
В момет появления ошибки, захожу со своего компа - файлы все на месте и сервер ЛетоДб нормально отвечает.

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




Пост N: 3497
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 09.10.16 08:57. Заголовок: Если сервер живой, и..


Если сервер живой, и файл на сервере существует, то логично предположить, что неудача leto_file связана с нарушением связи с сервером с этого клиента. В таком случае после if !LETO_FILE можно поставить проверку связи, например, вызовом функции LETO_MGGETINFO

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


Пост N: 1032
Зарегистрирован: 06.07.06
ссылка на сообщение  Отправлено: 09.10.16 09:29. Заголовок: Pasha пишет: В тако..


Pasha пишет:

 цитата:
В таком случае после if !LETO_FILE можно поставить проверку связи, например, вызовом функции LETO_MGGETINFO


Надо будет для проверки связи сделать ф-ю leto_Ping() - тем более, что команду такую сервер обрабатывает. Помнится, это чуть-ли не первая команда, которую я в свое время сделал.

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


Пост N: 1033
Зарегистрирован: 06.07.06
ссылка на сообщение  Отправлено: 09.10.16 09:37. Заголовок: Andrey пишет: Пока ..


Andrey пишет:

 цитата:
Пока юзер не перегрузит комп, ошибка не уходит. Иногда и после перезагрузки остаётся.


Вот это и в самом деле странно. Я бы до перезагрузки компа проверил ping к серверу - обычную команду ping, ну и если он проходит, то проверил бы
как отрабатывает leto_Connection().


 цитата:
Перед отправкой записей в базу на сервер, я проверяю в папке наличие файла и считываю оттуда его содержимое.


Немного не в тему, но: а почему бы не использовать здесь leto_var...() функции ?


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




Пост 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()


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




Пост N: 5126
Зарегистрирован: 12.09.06
ссылка на сообщение  Отправлено: 09.10.16 14:51. Заголовок: alkresin пишет: Нем..


alkresin пишет:

 цитата:
Немного не в тему, но: а почему бы не использовать здесь leto_var...() функции ?



Да наверно из-за не знания. Я когда начал изучать документацию по Лето, то не понял, для чего они.
Самостоятельно не всегда знаешь/понимаешь что нужно в том или ином случае.
Желательно бы в документацию включить доп.материалы для тех или иных действий и код приводить полностью.
Например:
1) Коннект к серверу (это есть вроде)
2) Проверка доступности сервера и переподключение к серверу.
3) Проверка доступа клиента к базе, т.е. разрешение к записи/чтения к базе.
Это я реализовал простой проверкой наличия файла (у каждой фирмы свой файл) и
содержимого самого файла (типа ключа проверки).
4) Работа с базами на двух и более серверах ЛетоДБ
5) Синхронизация по таймеру ( и событию) локальной и серверной базы и наоборот с сервера на локальную.
и т.д.

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


Пост N: 1035
Зарегистрирован: 06.07.06
ссылка на сообщение  Отправлено: 10.10.16 14:26. Заголовок: Pasha пишет: Можно ..


Pasha пишет:

 цитата:
Можно вместо этого перенести установку


Так и сделал. И Leto_Ping() добавил: возвращает .T., если все в порядке.

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




Пост N: 5127
Зарегистрирован: 12.09.06
ссылка на сообщение  Отправлено: 10.10.16 17:57. Заголовок: Тогда код делать так..


Тогда код делать такой ?

IF Leto_Ping() 
IF !LETO_FILE(cFile)
MsgStop( "Нет файла КЛЮЧА на сервере!" )
RETURN .F.
ELSE
// передача записей на сервер
MyWriteRecnoLetoDb()
ENDIF
ELSE
MsgStop("Ошибка соединения с сервером LetoDB !")
ENDIF

А где коды ошибок для LETO_FERROR() ?

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


Пост N: 1036
Зарегистрирован: 06.07.06
ссылка на сообщение  Отправлено: 10.10.16 18:32. Заголовок: Andrey пишет: Тогда..


Andrey пишет:

 цитата:
Тогда код делать такой ?


Пойдет.


 цитата:
А где коды ошибок для LETO_FERROR() ?


В тексте исходников :).
1000 - как раз сбой соединения.

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




Пост N: 5129
Зарегистрирован: 12.09.06
ссылка на сообщение  Отправлено: 11.10.16 14:13. Заголовок: alkresin пишет: В т..


alkresin пишет:

 цитата:
В тексте исходников :).



Спасибо !

Можно ли сделать следующие:
при изменении базы на сервере - получать событие клиентам, что база изменилась ?
Желательно бы и номер изменённой записи получать.

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


Пост N: 1279
Зарегистрирован: 27.01.07
ссылка на сообщение  Отправлено: 11.10.16 14:25. Заголовок: Andrey пишет: Можно..


Andrey пишет:

 цитата:
Можно ли сделать следующие:
при изменении базы на сервере - получать событие клиентам, что база изменилась ?


Клиент-серверная архитектура подразумевает следующий подход: клиент запросил - сервер ответил и забыл про клиента. Сам сервер не должен никому ничего слать без запроса. Т.е., для того, чтобы клиент знал про изменение баз, он должен сам об этом побеспокоиться.

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


Пост N: 1037
Зарегистрирован: 06.07.06
ссылка на сообщение  Отправлено: 11.10.16 14:57. Заголовок: Andrey пишет: при и..


Andrey пишет:

 цитата:
при изменении базы на сервере - получать событие клиентам, что база изменилась ?
Желательно бы и номер изменённой записи получать.


Правильно тут написали: общение с сервером всегда происходит по схеме запрос - ответ, причем запрос может послать только клиент.
Можно записывать информацию об изменениях в базе, например, в переменную LetoDB (leto_Var...() функции), это может делать как клиент, изменивший базу, так, наверное, и сервер в соответствующем триггере. Но чтобы другой клиент об этом узнал, ему надо время от времени, по таймеру например, читать эту переменную с сервера.

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




Пост N: 5131
Зарегистрирован: 12.09.06
ссылка на сообщение  Отправлено: 12.10.16 00:42. Заголовок: alkresin пишет: Но ..


alkresin пишет:

 цитата:
Но чтобы другой клиент об этом узнал, ему надо время от времени, по таймеру например, читать эту переменную с сервера.



Тогда наверное алгоритм SergKis - построение индекса на сервере по полю TimeStamp (в базе) даёт более простой результат синхронизации БД на сервере и клиенте. Я алгоритм уже попробовал. Хотелось бы понять и другие.

alkresin пишет:

 цитата:
Можно записывать информацию об изменениях в базе, например, в переменную LetoDB (leto_Var...() функции), это может делать как клиент, изменивший базу, так, наверное, и сервер в соответствующем триггере.



Не представляю как это сделать. Покажите пожалуйста схему как это делать.

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


Пост N: 1039
Зарегистрирован: 06.07.06
ссылка на сообщение  Отправлено: 12.10.16 10:07. Заголовок: Andrey пишет: Покаж..


Andrey пишет:

 цитата:
Покажите пожалуйста схему как это делать.


Схема самая простая. Есть Leto-переменные, каждая имеет свое имя, они собраны по группам, каждая группа тоже имеет свое имя. Предположим, вы решили сделать по группе для каждой базы - base1, base2, base3, ... и в каждой группе переменную modtime (modification time), куда будете записывать дату и время последнего изменения в том формате, который вам нравится.
Программа при записи данных в базу пишет одновременно и в соответствующую переменную:
leto_varSet( "base1", "modtime", xTime, LETO_VCREAT )

здесь xTime - текущие дата/время, LETO_VCREAT означает, что если переменная еще не существует, ее надо создать. Вот и все. А по таймеру читайте ее:
IF !Empty( xTime := leto_varGet( "base1","modtime" ) ) 
...
ENDIF

и предпринимайте соответствующие действия.

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



Пост N: 24
Зарегистрирован: 22.01.14
ссылка на сообщение  Отправлено: 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, но это сути не меняет.




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



Пост N: 1
Зарегистрирован: 11.01.24
ссылка на сообщение  Отправлено: 12.02.24 14:48. Заголовок: Помогите, пожалуйста, чайнику.


Первая установка letodb. Команда File не работает (файл есть, пишет .F.). Команда leto_file - тоже, т.к., по-моему, не читает letodb.ini (там разрешил файловые функции). Там путь прописан:DataPath ="/MYwrk/", а в log пишет DataPath =.
Где копать?

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




Пост N: 4515
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 12.02.24 15:12. Заголовок: VI Вот рабочий вари..


VI
Вот рабочий вариант установки Leto2011.exe (2-х поточная) и LetoDbF.exe (в ней изменены имена ini и log файлов на LetoDbF.*), совместная работа (это local работа - отладка, у клиента так же, но с адресами своими)Скрытый текст

Всегда работаю от текущего каталога, т.е. везде в путях стоят точки или .\
LetoDbF всегда добавляет DataPath к исп. именам файлов на клиенте эту добавку, попробуйте задать (внутри имя приводятся к одному разделителю, как надо).
DataPath = C:\Mywrk
от такого задания отказался из за копирования, так от текущего все забрал, вместе с настройками и ...

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



Пост N: 2
Зарегистрирован: 11.01.24
ссылка на сообщение  Отправлено: 12.02.24 15:48. Заголовок: Спасибо за то, что попытались помочь.


Как вижу, основная проблема в том, что функции Leto_file (и другие файловые) у меня не работают, хотя в .ini разрешены. И вообще, ни одна установка, отличная от заданного значения по умолчанию, не меняется (например, CDX/NTX). Letodb.ini лежит там же, где и запускаемый letodb.exe.
Впрочем, и функция File() не работает тоже (а должна ли?), причем перебраны все возможные сочетания путей.

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




Пост N: 4516
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 12.02.24 16:02. Заголовок: VI Может дело в сбо..


VI
Может дело в сборке сервера, у меня никогда не было такой штуки.
Посмотрите в MiniGui пример SAMPLES\Advanced\LetoDbf, там был рабочий вариант сервера

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




Пост N: 7682
Зарегистрирован: 12.09.06
ссылка на сообщение  Отправлено: 12.02.24 18:32. Заголовок: VI пишет: Впрочем, ..


VI пишет:

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


Всё работает.
Активно им пользовался раньше, и сейчас до сих пор работает.

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



Пост N: 3
Зарегистрирован: 11.01.24
ссылка на сообщение  Отправлено: 12.02.24 19:58. Заголовок: Спасибо. Буду пробовать дальше.




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

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