Форум » LetoDB, HbNetio. » Leto DB Server » Ответить

Leto DB Server

alkresin: Только что открыл на Sourceforge новый проект - Leto DB Server - https://sourceforge.net/projects/letodb Это мультиплатформенный ( Windows, Unix/Linux ) сервер баз данных, предоставляющий клиентским программам доступ к dbf/cdx файлам, находящимся на удаленном сервере ( можно и на локальном компьютере запускать - в отладочных целях ). В общем, как ADS :). Проект - на стадии разработки, не все даже базовые функции еще реализованы, до оптимизации дело еще не дошло. Но работает :). Крутится у меня на сервере несколько дней, подключал до 15 клиентов, пока не падает. Мои программы работают с ним нормально. Преимущества по сравнению с обычным файл-сервером: 1) Безопасность - базы могут быть в каталоге, недоступном для клиентских компьютеров - никто их случайно не удалит и не повредит. 2) Поскольку базы открываются серверной программой, а не клиентской, ее целостности ничего не грозит при случайном отключении клиентского компьютера. 3) значительное уменьшение сетевого траффика. 4) Должен быть, по идее, выигрыш в скорости. 5) Возможность контроля за пользователями с помощью утилиты manage ( можно придумать и другие формы контроля ). 6) Можно будет сделать транзакции, stored procedures на Харборе, ... и вообще все в наших руках :). Кто хочет участвовать в разработке, тестировании - пишите.

Ответов - 325, стр: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 All

gfilatov: alkresin пишет: Выложил build4 Выложил готовую к использованию полную сборку LetoDB build 0.4 по адресу: http://minigui.mylivepage.ru/file/16/4777_letodb-bin-w32-bcc-5-5.zip.zip

Pasha: После перемещения записи в основной РО можно сохранять новое состояние дочерних РО в области данных LETOAREA основной РО Затем, когда letoSyncChildren вызовет letoChildSync дочерних РО, этот метод должен будет отработать изменившеся состояние своей РО, взяв его из области данных master-РО Правда, будет проблема, если у дочерних РО тоже есть свои relations. Но обработку таких каскадных relations можно тоже возложить на сервер при первоначальной операции перемещения. Возникает вопрос: а как сбросить на сервер текущие записи дочерних РО перед перемещением записи в основной РО ? Делать это в letoChildSync уже поздно, поскольку сервер уже выполнил операцию перемещения записи

Andrey: Тестирую сервер, столкнулся с неудобствами, как писал ранее : 2) пример доступности сервера ??? Как проверить "запущен" ли leto db на сервере ??? alkresin пишет: цитата: 5) файловые операции на сервере Это к Pasha, я их сам еще не пробовал. Паша ! Дай пожалуйста эти функции !!! Самый НЕПРИЯТНЫЙ МОМЕНТ, если на сервере сняли letoDb, то "труба" - у пользователей база летит. Нужно наверно повесить сообщение типа ALERT("Есть открытые базы ! Не все клиентские места закрыты!") Это хоть как то защитит от "кривых рук" админов (не у всех есть нормальные) и воплей начальства, ему сложно доказать, что ты не верблюд и не по твоей вине это произошло !!! И еще до кучи: Как править letodb.ini ? Может у меня доступа нет к серверу, а его нужно исправить !!! И как потом перезапустить сервер letodb ? У меня есть на работе Дельфовая задача по Субсидиям. Там решается такая вещь просто. Если все пользователи вышли из клиентских мест, то СЕРВЕРНАЯ ЗАДАЧА завершается. Как кто-нибудь запускает клиенское место, так СЕРВЕРНАЯ ЗАДАЧА сама стартует и в трей !


Pasha: Andrey пишет: Паша ! Дай пожалуйста эти функции !!! Leto_File(<cFile>) Leto_FErase(<cFile>) Leto_FRename(<cFile>, <cNewName>) cFile имеет такую же структуру, какая используется для use: //ip_address:port/data_path/file_name Чтобы разрешить их использование, надо в letidb.ini на сервере указать EnableFileFunc = 1

alkresin: Возникает вопрос: а как сбросить на сервер текущие записи дочерних РО перед перемещением записи в основной РО ? Делать это в letoChildSync уже поздно, поскольку сервер уже выполнил операцию перемещения записи Вопросов немало, потому что нарушается стандартная схема. Обычно перемещение в дочерних областях происходит не сразу при перемещении в родительской, а только при попытке чтения/записи в эту конкретную дочернюю область.

alkresin: 2) пример доступности сервера ??? Как проверить "запущен" ли leto db на сервере ??? С помощью manager'а. Самый НЕПРИЯТНЫЙ МОМЕНТ, если на сервере сняли letoDb, то "труба" - у пользователей база летит. База от этого не полетит, т.к. при завершении работы сервер все базы аккуратно закрывает. А вот предупреждение выдать стоит. Подумаем, как это лучше сделать. И еще до кучи: Как править letodb.ini ? Может у меня доступа нет к серверу, а его нужно исправить !!! Так в том-то и фишка, что без ведома администратора сервера его нельзя править ( если только он не поместит его в расшаренной папке - но я бы не советовал :) ). Иначе к чему все разговоры о безопасности ??? И как потом перезапустить сервер letodb ? letodb stop letodb Опять-таки, администратор или доверенный человек должен делать. У меня есть на работе Дельфовая задача по Субсидиям. Там решается такая вещь просто. Если все пользователи вышли из клиентских мест, то СЕРВЕРНАЯ ЗАДАЧА завершается. Как кто-нибудь запускает клиенское место, так СЕРВЕРНАЯ ЗАДАЧА сама стартует и в трей ! Так, наверное, там на сервере еще один процесс невидимый ( daemon, как наш сервер, запущен ), он это и делает, управляет "СЕРВЕРНОЙ ЗАДАЧЕЙ", которая общается с клиентами. В чем преимущество-то ?

Pasha: По-видимому, на сервере надо предусмотреть возможность работы с несколькими БД. Наверное, перечислять их в DataPath через точку с запятой Или делать по другому. Ввести алиасы БД и для них указывать каталоги Как лучше ?

alkresin: По-видимому, на сервере надо предусмотреть возможность работы с несколькими БД. По-моему, понятие БД ( мы тут долго говорили об этом с Петром ) надо вводить, когда в этом действительно возникнет необходимость, тогда и будет ясно, для чего это нам нужно, какие свойства должна иметь БД и как это лучше описать в ini - файле. Сейчас мне представлянтся, что эту лучше будет сделать как, кажется, Петр предлагал - для каждой БД создать секцию в ini-файле и в этой секции - все ее свойства, там же не только путь будет.

spair2k: Pasha пишет: Это на build2 или на свежих сырцах ? Пару недель назад я добавлял OrdCondSet(), должно работать Уже успел проверит на build4 - результат тот же Команду, которой создается индекс, в студию Задача: Есть табличка с ценами услуг,цены с историей, нужны свежие Код: USE (server+'price') NEW INDEX ON date TAG tmp UNIQUE DESCENDING //сортируем в обратном порядке GO TOP // нахожу самую свежую дату изменения cDT := chr(39)+dtos(price->date)+chr(39) // создаю подстановку для FOR INDEX ON usluga TAG usluga FOR dtos(date)='20080201' //&cDT //(два варианта - работают одинаково) создаются индексы, TAG с условием прописан, но в индексе все записи... кстати, сейчас проверил - tmp создан тоже без обратного порядка, без сортировки

Andrey: alkresin пишет: цитата: 2) пример доступности сервера ??? Как проверить "запущен" ли leto db на сервере ??? С помощью manager'а. И что, каждого юзера научить пользоваться этим manager'ом ? Нужно до открытия БД в программе сделать проверку. Здесь был кусок кода, но он у меня не работает ! Петр пишет: CREATE CONNECTION cn USER "user" PASSWORD "password" IF cn:ErrorCode() != 0 ? "Извините, сервер недоступен" Return 1 ENDIF Или типа такого: hSocket := hb_IPConnect( "127.0.0.1", 2812 ) IF hb_IPErrorCode() = 0 ? "Извините, сервер недоступен" ENDIF hSocket := NIL

Pasha: По поводу FOR - в моих программах индекс создается с этим условием. Проверял как только сделал Возможно, причина в том, что у тебя создаются 2 разных индексных файла для одной таблицы. Вообще-то при использовании dbfcdx принято использовать один индексный файл, я даже не знаю, как rdd на такое отреагирует. Изначально код был для dbfntx ? Descending. Во всяком случае команда создания индекса на сервер послупает с опцией Descending Попробуй указать отдельно OrdDescend(,, .t.) // включить обратную сортировку OrdDescend(,, .f.) // выключить

Pasha: Andrey пишет: Здесь был кусок кода, но он у меня не работает ! Это не рабочий код, а только предложение Петра по организации БД

alkresin: Или типа такого: hSocket := hb_IPConnect( "127.0.0.1", 2812 ) IF hb_IPErrorCode() = 0 ? "Извините, сервер недоступен" ENDIF А... Ну это дело пары минут. Сделаем. Просто, на мой взгляд, пока нет системы идентификации ( логин/пароль ), это - излишество. Сервер ДОЛЖЕН работать всегда. Если не работает, клиентская программа просто вылетает с ошибкой открытия файла и пользователь идет высказывать законное возмущение соответствующим службам.

Andrey: alkresin пишет: это - излишество. Сервер ДОЛЖЕН работать всегда. Если не работает, клиентская программа просто вылетает с ошибкой открытия файла и пользователь идет высказывать законное возмущение соответствующим службам. А если программы крутяться в других городах (у меня так) и там программист приходящее лицо по вызову, СЕРВЕР не выделенный, а обычный комп для работы... Ну и что они делать будут ??? Да они по телефону задолбают меня ! И сколько будет высказано "всего хорошего" в адрес программиста, написавшего программу.... Знаете, не хочется терять клиентов из-за мелочей !!! Нужна проверка и внятное сообщение для пользователя, чтоб не дергали меня по пустякам из-за своего раздол....................

Pasha: Начал делать VarField aka "V", HB_FT_ANY, и столкнулся с необходимостью в ParseRec уже формировать готовый ITEM, поскольку нет необходимости повторять на клиенте разбор этого поля Может быть, где-то записывать этот Item и затем в GetValue его брать ? Клиенту лучше абстрагироваться от низкоуровневого формата данных сервера Написал такой код в leto_rec, и вижу, что корректно обработать такие данные в ParseRec не получается, поскольку полученные данные могут вылезти за пределы отведенной области pRecord для такого поля case HB_FT_ANY: SELF_GETVALUE( (AREAP)pArea, ui+1, pItem ); if( pField->uiLen == 3 || HB_IS_DATE( pItem ) ) { *pData++ = 'D'; hb_itemGetDS( pItem, (char *) pData); pData += 8; } else if( pField->uiLen == 4 || HB_IS_NUMERIC( pItem ) ) { char * szString = hb_itemStr( pItem, NULL, NULL ); char * szTemp; *pData++ = 'N'; if( szString ) { szTemp = szString; while( HB_ISSPACE( *szTemp ) ) szTemp ++; uiLen = strlen( szTemp ); memcpy( pData, szTemp, uiLen ); pData += uiLen; hb_xfree( szString ); } *pData++ = '\0'; } else if( HB_IS_STRING( pItem ) ) { uiLen = hb_itemGetCLen( pItem ); if( uiLen <= pField->uiLen ) { char * szString = hb_itemGetC( pItem ); *pData++ = 'C'; *pData++ = (BYTE) uiLen & 0xFF; *pData++ = (BYTE) (uiLen >> 8) & 0xFF; memcpy( pData, szString, uiLen ); } else { *pData++ = '!'; } } else { *pData++ = 'U'; } break; Еще предложение: передавать HB_FT_DATE в 3-х или 4-х байтовом формате, а HB_IT_DATETIME (дата и время) в 8-ми байтовом Есть еще двоичные Numeric-поля размером 2 и 4 байта

alkresin: spair2k пишет: создаются индексы, TAG с условием прописан, но в индексе все записи... кстати, сейчас проверил - tmp создан тоже без обратного порядка, без сортировки Да, были там ошибки, только что исправил - и с for и с descending.

alkresin: Начал делать VarField aka "V", HB_FT_ANY А что такое HB_FT_ANY ? Это есть в DBFCDX ? Еще предложение: передавать HB_FT_DATE в 3-х или 4-х байтовом формате Я сначала так и сделал, а потом из-за того, что функции, которые я использовал при этом, оказались не во всех версиях Harbour/xHarbour, стал передавать Date без перекодировки. Не было времени копаться в посках совместимого решения, тем более, что еще неизвестно, восполнит ли экономия на 4-х байтах потери времени на кодировку/раскодировку ... HB_IT_DATETIME (дата и время) в 8-ми байтовом Есть еще двоичные Numeric-поля размером 2 и 4 байта И это все в DBFCDX есть ?

Pasha: alkresin пишет: А что такое HB_FT_ANY ? Это есть в DBFCDX ? Это поля из SIX. Если размер поля 3 байта, тогда значение - дата в Julian формате, если 4 - значение LONG, если больше - любой тип данных Если длина строки превышает длину поля, то хвост строки записывается как memo-поле тем более, что еще неизвестно, восполнит ли экономия на 4-х байтах потери времени на кодировку/раскодировку ... Думаю, что нет. Эта перекодировка все равно выполняется Я уже сделал поддержку полей D, 3 и D, 4 (дата в Julian-формате), сейчас проверяю В dbfcdx есть числовые поля с сигнатурой '2' и '4' - соответственно 2-х и 4-х байтовое целое Типов полей там сейчас довольно много

Pasha: Кстати, в server.prg пропало изменение Miguel: cIndex += OrdBagName(i) + ";" + OrdName(i) + ";" + cName + ";" + OrdFor(i) + ";" + dbOrderInfo(DBOI_KEYTYPE,, i) + ";" + LTrim(Str(dbOrderInfo(DBOI_KEYSIZE,, i))) + ";" Это случайно ? Надо восстановить ?

alkresin: Кстати, в server.prg пропало изменение Miguel: Это случайно ? Да, случайно.



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