Автор | Сообщение |
alkresin
|
| moderator
|
Пост N: 31
Зарегистрирован: 06.07.06
|
|
Отправлено: 31.01.08 11:36. Заголовок: Leto DB Server
Только что открыл на 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
|
| модератор
|
Пост N: 725
Зарегистрирован: 25.05.05
|
|
Отправлено: 28.02.08 16:57. Заголовок: alkresin пишет: Выл..
|
|
|
Pasha
|
| Администратор
|
Пост N: 835
Зарегистрирован: 23.05.05
|
|
Отправлено: 28.02.08 21:13. Заголовок: После перемещения за..
После перемещения записи в основной РО можно сохранять новое состояние дочерних РО в области данных LETOAREA основной РО Затем, когда letoSyncChildren вызовет letoChildSync дочерних РО, этот метод должен будет отработать изменившеся состояние своей РО, взяв его из области данных master-РО Правда, будет проблема, если у дочерних РО тоже есть свои relations. Но обработку таких каскадных relations можно тоже возложить на сервер при первоначальной операции перемещения. Возникает вопрос: а как сбросить на сервер текущие записи дочерних РО перед перемещением записи в основной РО ? Делать это в letoChildSync уже поздно, поскольку сервер уже выполнил операцию перемещения записи
|
|
|
Andrey
|
| постоянный участник
|
Пост N: 504
Зарегистрирован: 12.09.06
|
|
Отправлено: 29.02.08 00:28. Заголовок: Тестирую сервер, сто..
Тестирую сервер, столкнулся с неудобствами, как писал ранее : 2) пример доступности сервера ??? Как проверить "запущен" ли leto db на сервере ??? alkresin пишет: цитата: | цитата: 5) файловые операции на сервере Это к Pasha, я их сам еще не пробовал. |
| Паша ! Дай пожалуйста эти функции !!! Самый НЕПРИЯТНЫЙ МОМЕНТ, если на сервере сняли letoDb, то "труба" - у пользователей база летит. Нужно наверно повесить сообщение типа ALERT("Есть открытые базы ! Не все клиентские места закрыты!") Это хоть как то защитит от "кривых рук" админов (не у всех есть нормальные) и воплей начальства, ему сложно доказать, что ты не верблюд и не по твоей вине это произошло !!! И еще до кучи: Как править letodb.ini ? Может у меня доступа нет к серверу, а его нужно исправить !!! И как потом перезапустить сервер letodb ? У меня есть на работе Дельфовая задача по Субсидиям. Там решается такая вещь просто. Если все пользователи вышли из клиентских мест, то СЕРВЕРНАЯ ЗАДАЧА завершается. Как кто-нибудь запускает клиенское место, так СЕРВЕРНАЯ ЗАДАЧА сама стартует и в трей !
|
|
|
Pasha
|
| Администратор
|
Пост N: 836
Зарегистрирован: 23.05.05
|
|
Отправлено: 29.02.08 09:10. Заголовок: Andrey пишет: Паша ..
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
|
| moderator
|
Пост N: 119
Зарегистрирован: 06.07.06
|
|
Отправлено: 29.02.08 09:55. Заголовок: Возникает вопрос: а ..
цитата: | Возникает вопрос: а как сбросить на сервер текущие записи дочерних РО перед перемещением записи в основной РО ? Делать это в letoChildSync уже поздно, поскольку сервер уже выполнил операцию перемещения записи |
| Вопросов немало, потому что нарушается стандартная схема. Обычно перемещение в дочерних областях происходит не сразу при перемещении в родительской, а только при попытке чтения/записи в эту конкретную дочернюю область.
|
|
|
alkresin
|
| moderator
|
Пост N: 120
Зарегистрирован: 06.07.06
|
|
Отправлено: 29.02.08 10:13. Заголовок: 2) пример доступност..
цитата: | 2) пример доступности сервера ??? Как проверить "запущен" ли leto db на сервере ??? |
| С помощью manager'а. цитата: | Самый НЕПРИЯТНЫЙ МОМЕНТ, если на сервере сняли letoDb, то "труба" - у пользователей база летит. |
| База от этого не полетит, т.к. при завершении работы сервер все базы аккуратно закрывает. А вот предупреждение выдать стоит. Подумаем, как это лучше сделать. цитата: | И еще до кучи: Как править letodb.ini ? Может у меня доступа нет к серверу, а его нужно исправить !!! |
| Так в том-то и фишка, что без ведома администратора сервера его нельзя править ( если только он не поместит его в расшаренной папке - но я бы не советовал :) ). Иначе к чему все разговоры о безопасности ??? цитата: | И как потом перезапустить сервер letodb ? |
| letodb stop letodb Опять-таки, администратор или доверенный человек должен делать. цитата: | У меня есть на работе Дельфовая задача по Субсидиям. Там решается такая вещь просто. Если все пользователи вышли из клиентских мест, то СЕРВЕРНАЯ ЗАДАЧА завершается. Как кто-нибудь запускает клиенское место, так СЕРВЕРНАЯ ЗАДАЧА сама стартует и в трей ! |
| Так, наверное, там на сервере еще один процесс невидимый ( daemon, как наш сервер, запущен ), он это и делает, управляет "СЕРВЕРНОЙ ЗАДАЧЕЙ", которая общается с клиентами. В чем преимущество-то ?
|
|
|
Pasha
|
| Администратор
|
Пост N: 838
Зарегистрирован: 23.05.05
|
|
Отправлено: 29.02.08 11:30. Заголовок: По-видимому, на серв..
По-видимому, на сервере надо предусмотреть возможность работы с несколькими БД. Наверное, перечислять их в DataPath через точку с запятой Или делать по другому. Ввести алиасы БД и для них указывать каталоги Как лучше ?
|
|
|
alkresin
|
| moderator
|
Пост N: 121
Зарегистрирован: 06.07.06
|
|
Отправлено: 29.02.08 12:53. Заголовок: По-видимому, на серв..
цитата: | По-видимому, на сервере надо предусмотреть возможность работы с несколькими БД. |
| По-моему, понятие БД ( мы тут долго говорили об этом с Петром ) надо вводить, когда в этом действительно возникнет необходимость, тогда и будет ясно, для чего это нам нужно, какие свойства должна иметь БД и как это лучше описать в ini - файле. Сейчас мне представлянтся, что эту лучше будет сделать как, кажется, Петр предлагал - для каждой БД создать секцию в ini-файле и в этой секции - все ее свойства, там же не только путь будет.
|
|
|
spair2k
|
| |
Пост N: 16
Зарегистрирован: 31.05.07
|
|
Отправлено: 29.02.08 14:25. Заголовок: Pasha пишет: Это на..
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
|
| постоянный участник
|
Пост N: 506
Зарегистрирован: 12.09.06
|
|
Отправлено: 29.02.08 15:37. Заголовок: alkresin пишет: ци..
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
|
| Администратор
|
Пост N: 839
Зарегистрирован: 23.05.05
|
|
Отправлено: 29.02.08 15:39. Заголовок: По поводу FOR - в мо..
По поводу FOR - в моих программах индекс создается с этим условием. Проверял как только сделал Возможно, причина в том, что у тебя создаются 2 разных индексных файла для одной таблицы. Вообще-то при использовании dbfcdx принято использовать один индексный файл, я даже не знаю, как rdd на такое отреагирует. Изначально код был для dbfntx ? Descending. Во всяком случае команда создания индекса на сервер послупает с опцией Descending Попробуй указать отдельно OrdDescend(,, .t.) // включить обратную сортировку OrdDescend(,, .f.) // выключить
|
|
|
|
Pasha
|
| Администратор
|
Пост N: 840
Зарегистрирован: 23.05.05
|
|
Отправлено: 29.02.08 15:41. Заголовок: Andrey пишет: Здесь..
Andrey пишет: цитата: | Здесь был кусок кода, но он у меня не работает ! |
| Это не рабочий код, а только предложение Петра по организации БД
|
|
|
alkresin
|
| moderator
|
Пост N: 122
Зарегистрирован: 06.07.06
|
|
Отправлено: 29.02.08 21:55. Заголовок: Или типа такого: hSo..
цитата: | Или типа такого: hSocket := hb_IPConnect( "127.0.0.1", 2812 ) IF hb_IPErrorCode() = 0 ? "Извините, сервер недоступен" ENDIF |
| А... Ну это дело пары минут. Сделаем. Просто, на мой взгляд, пока нет системы идентификации ( логин/пароль ), это - излишество. Сервер ДОЛЖЕН работать всегда. Если не работает, клиентская программа просто вылетает с ошибкой открытия файла и пользователь идет высказывать законное возмущение соответствующим службам.
|
|
|
Andrey
|
| постоянный участник
|
Пост N: 507
Зарегистрирован: 12.09.06
|
|
Отправлено: 01.03.08 02:07. Заголовок: alkresin пишет: это..
alkresin пишет: цитата: | это - излишество. Сервер ДОЛЖЕН работать всегда. Если не работает, клиентская программа просто вылетает с ошибкой открытия файла и пользователь идет высказывать законное возмущение соответствующим службам. |
| А если программы крутяться в других городах (у меня так) и там программист приходящее лицо по вызову, СЕРВЕР не выделенный, а обычный комп для работы... Ну и что они делать будут ??? Да они по телефону задолбают меня ! И сколько будет высказано "всего хорошего" в адрес программиста, написавшего программу.... Знаете, не хочется терять клиентов из-за мелочей !!! Нужна проверка и внятное сообщение для пользователя, чтоб не дергали меня по пустякам из-за своего раздол....................
|
|
|
Pasha
|
| Администратор
|
Пост N: 842
Зарегистрирован: 23.05.05
|
|
Отправлено: 01.03.08 11:36. Заголовок: Начал делать VarFiel..
Начал делать 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
|
| moderator
|
Пост N: 123
Зарегистрирован: 06.07.06
|
|
Отправлено: 01.03.08 14:01. Заголовок: spair2k пишет: созд..
spair2k пишет: цитата: | создаются индексы, TAG с условием прописан, но в индексе все записи... кстати, сейчас проверил - tmp создан тоже без обратного порядка, без сортировки |
| Да, были там ошибки, только что исправил - и с for и с descending.
|
|
|
alkresin
|
| moderator
|
Пост N: 124
Зарегистрирован: 06.07.06
|
|
Отправлено: 01.03.08 14:30. Заголовок: Начал делать VarFiel..
цитата: | Начал делать 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
|
| Администратор
|
Пост N: 843
Зарегистрирован: 23.05.05
|
|
Отправлено: 02.03.08 12:55. Заголовок: alkresin пишет: А ч..
alkresin пишет: цитата: | А что такое HB_FT_ANY ? Это есть в DBFCDX ? |
| Это поля из SIX. Если размер поля 3 байта, тогда значение - дата в Julian формате, если 4 - значение LONG, если больше - любой тип данных Если длина строки превышает длину поля, то хвост строки записывается как memo-поле цитата: | тем более, что еще неизвестно, восполнит ли экономия на 4-х байтах потери времени на кодировку/раскодировку ... |
| Думаю, что нет. Эта перекодировка все равно выполняется Я уже сделал поддержку полей D, 3 и D, 4 (дата в Julian-формате), сейчас проверяю В dbfcdx есть числовые поля с сигнатурой '2' и '4' - соответственно 2-х и 4-х байтовое целое Типов полей там сейчас довольно много
|
|
|
Pasha
|
| Администратор
|
Пост N: 844
Зарегистрирован: 23.05.05
|
|
Отправлено: 02.03.08 12:56. Заголовок: Кстати, в server.prg..
Кстати, в server.prg пропало изменение Miguel: cIndex += OrdBagName(i) + ";" + OrdName(i) + ";" + cName + ";" + OrdFor(i) + ";" + dbOrderInfo(DBOI_KEYTYPE,, i) + ";" + LTrim(Str(dbOrderInfo(DBOI_KEYSIZE,, i))) + ";" Это случайно ? Надо восстановить ?
|
|
|
alkresin
|
| moderator
|
Пост N: 125
Зарегистрирован: 06.07.06
|
|
Отправлено: 03.03.08 11:16. Заголовок: Кстати, в server.prg..
цитата: | Кстати, в server.prg пропало изменение Miguel: Это случайно ? |
| Да, случайно.
|
|
|
Ответов - 325
, стр:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
All
[только новые]
|
|