Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.09.11;
Скачать: CL | DM;

Вниз

Проблема с упаковкой БД при использовании Halcyon 6.95   Найти похожие ветки 

 
Sergant   (2003-08-19 17:24) [0]

Столкнулся с проблемой упаковки Клипперовской базы при использовании Halcyon 6.95. Причем точно знаю, что проблема сия возникает, когда длина поля типа character>251, а у меня в базе 310. Причина косяка ясна, не подскажете, как вылечить?


 
sniknik ©   (2003-08-19 17:53) [1]

не должно структура под запись описана (см. исходники)
GSptrCharArray = ^GSaryCharArray;
GSaryCharArray = array[0..65519] of char;
места хватает, должно хватать. внутри перенос копированием ...

while not File_EOF do {Read .DBF sequentially}
begin
gsStatusUpdate(StatusCopy,RecNumber,0);
move(CurRecord^,FCopy.CurRecord^,RecLen+1);
if WithMemo then gsCopyMemoRecord(FCopy);
FCopy.gsAppend;
gsGetRec(Next_Record);
end;
тоже не должно...

пришли табличку на которой глючит.


 
Sergant   (2003-08-20 05:23) [2]

>sniknik
При упаковке Halcyon, я так понял, создает временную копию исходного файла. Так вот, в эту времянку он криво заносит то самое поле длиной 310 - он его отрезает и делает длину этого поля 310-254=56. В отадке вылетает в gsCopyFile в строке Fcopy.Free


 
sniknik ©   (2003-08-20 11:56) [3]

так и есть, он пытается создать dBase таблицу и перенести туда, у клиперовской размер поля хранится в word-е (16 бит) у дбейса в byte (8 бит). размер поля обрезается, только не на 310- 254=56 а на 256 должно
310 = 00000001 00110110b
первая половинка от ворда отбрасывается при приведении к байту
и имеем то что имеем (00110110b = 54).

(проверь должно быть так а не 56)

как заставить его делать чисто клиперовскую таблицу пока не знаю, но это точно дело не сиюминутное (и главное не рабочего дня ;о)) нужно посидеть поковырятся (через CreateHalcyonDataSet1 клиперовскую то делает), кстати выход на пока, самому делать структуру через CreateHalcyonDataSet1 и копировать.


 
sniknik ©   (2003-08-20 23:07) [4]

честно говоря думал нужно будет больше изменений, но все решилось в 1й строке. (второй байт идет смещением после запятой, и этой версии просто неправильно расчитывало размер поля)

в общем нужно
модуль gs6_dbf
процедура
procedure GSO_DBFBuild.InsertField(const s : gsUTFString; t : char; l,d : integer);

изменить строку
"C" : begin
d := d mod 256; // <Niks> d:= l div 256;
l := l mod 256;
end;
(закоментарено то что было)

и самое главное этот глюк явно внесен поздними исправлениями (вот он недостаток исходного кода :о)))
т.к. позднее есть строка расчета длинны записи (которая для d = 0, старом значении которое будет всегда, просто бессмысленна) вот эта
if f^.dbFieldType = "C" then
dbRecLen := dbRecLen + (d * 256);
(было бы не бессмысленно если бы значение передавалось бы общим word в L)


 
Sergant   (2003-08-21 03:47) [5]

Теперь при попытке упаковать базу или изменить структуру ругается в модуле Halcn6db в процедуре ThalcyonDataSet.AddFieldDesc на
if iFieldType<>ftUnknown then
FieldDefs.Add(Name,iFieldType,Size,false);


 
Sergant   (2003-08-21 04:29) [6]

Дико извиняюсь. Скачал норамальный Halcyon 6.95, исправил и упаковка заработала! А вот индексация по такому полю не проходит


 
sniknik ©   (2003-08-21 10:09) [7]

> А вот индексация по такому полю не проходит
после посмотрю (может сегодня вечером), можеш и сам, том скорее всего чтото аналогичное.
кстати исправление тоже получилось не вполне корректное (это до меня после дошло)
надо размерность сначала сливать а после раскладывать, это на случай если (как и есть правильно) эта же процедура используется для создания баз руками (программистом), вот попробуй создать таблицу по новой (CreateHalcyonDataSet1) поле дллинной > 255, думаю будет ошибка (это покажет что используется эта же процедура). просто когда сам задаеш то вся длинна поля будет в L приходить.


 
sniknik ©   (2003-08-21 21:58) [8]

насчет ошибки при создании новой был не прав, там другие методы (измененный код не вызывается, та что можно оставить)

а что до индексов по такому полю, то все еще проще
в модуле gs6_glbl константа MaxSortSize = 251; {KV} вместо 251 поставь 311 (на еденицу больше длинны поля) и все. удивлен если сам до сих пор не нашол (эта константа прям на месте ексепта)

кстати не советую делать индекс по такому полному полю (ты только на размер получившегося индекса посмотри), и все одно никто для поиска такую строку набирать не будет, делай по первым значимым 10-20 символам.
и главное даже если сделаеш проверь клипер сам его откроет? будет он для него правильным?



Страницы: 1 вся ветка

Текущий архив: 2003.09.11;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.024 c
1-33684
Ау
2003-08-28 23:39
2003.09.11
Выравнивание в РичЕдит


3-33461
Марат
2003-08-21 06:46
2003.09.11
F1Book


3-33492
Владимир
2003-08-20 11:53
2003.09.11
Помогите!!!


14-33762
Viktor Kushnir
2003-08-19 08:58
2003.09.11
Патентование


1-33634
lord
2003-08-30 22:36
2003.09.11
а что рекурсия в потоке не работает ?