On-line: Andrey, гостей 1. Всего: 2 [подробнее..]
АвторСообщение





Пост N: 33
Зарегистрирован: 25.07.06
ссылка на сообщение  Отправлено: 11.09.06 21:33. Заголовок: Ломаются fpt


Недавно перешел с dbt на fpt файлы. С месяц поработали вроде было все нормально.
И вот сегодня с одной конторы кинули мне базу, которую я месяц назад конвертнул dbt -> fpt и пересадил под SIX3 (idx) Порядка десятка записей оказались запорченными. Произошло то же, что ИЗРЕДКА раньше происходило и с dbt файлами. В разных записях указатели на номер блока (смещения) в memo файле оказываются одинаковыми. Обычно это происходило при сбоях питания. Буду надеяться, что причина в этом.

Кто работал с fpt файлами, отзовитесь, насколько часто они имеют тенденцию ломаться? У меня сложилось впечатление, что они менее устойчивы к сбоям по питанию и всякии некорректным действиям пользователей типа некорректноговыхода/выключения по сравнению с dbt файлами. Может следует придерживаться каких-то мер предостородности при работе с ними?


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


администратор




Пост N: 358
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 13.09.06 07:56. Заголовок: Re:


Имено из за таких проблем лично я отказался от использования DBT и FPT.

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





Пост N: 37
Зарегистрирован: 08.07.06
ссылка на сообщение  Отправлено: 13.09.06 12:16. Заголовок: Re:


Вообще не понимаю: какой смысл хранить длинные memo в одном файле: какой-бы не был формат таблицы, все равно неизбежны проблемы: фрагментация, разбухание, кривость индексов и т.п.

Я давно перешел у себя на такую структуру: когда мне нужны блоки данных более 64Кб, я завожу у себя в каталоге (например, D:\DATA) с dbf файлами директорий, к примеру, D:\DATA\IMAGES и храню там все, связанное с картинками товара. в рабочей таблице связываю код товара с ИМЕНЕМ ФАЙЛА с картинкой (в данном случае) и при необходимости (архивация, копирование и тп) ЛЕГКО получаю доступ ко всей необходимой мне информации.

Никаких проблем (тьфу*3) с кривыми индексами, сыпящимися таблицами и тп... Простой справочник: код товара - имя файла с нужной мне информацией. Вместо DBT или FPT - просто доп.каталог, часто со своей, любой по сложности структурой.

В таких структурах я храню изображения товара, отсканированные копии сертификатов и можно много чего ещё...
----------------
Надеюсь, что помог...


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





Пост N: 35
Зарегистрирован: 25.07.06
ссылка на сообщение  Отправлено: 13.09.06 14:18. Заголовок: Re:


Мне это самому не очень нравится. Но в memo у меня хранятся массивы произвольной структуры и степени вложенности. И, при наличии даже пары десятков тысяч записей в основной базе, способ хранения неструктурированных данных по каждой записи в отдельном файле мне кажется неэффективным. Размеры массивов динамические, поэтому вычислить размер поля оптимальный размер обычного для их хранения проблематично. Поэтому и остановился на memo полях.

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





Пост N: 39
Зарегистрирован: 08.07.06
ссылка на сообщение  Отправлено: 13.09.06 14:20. Заголовок: Re:


для таких случаев я предусмотрел нечто типа своего "реестра" - код скину чуть позже.


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





Пост N: 36
Зарегистрирован: 25.07.06
ссылка на сообщение  Отправлено: 13.09.06 14:33. Заголовок: Re:


В данном случае меня больше всего смущает тот факт, что до перехода на FPT, случаи таких поломок случались ОЧЕНЬ РЕДКО (1-2 раза в год при работе с программой более чем на 20 предприятиях и с учетом того, что были и вырубления питения и неправильный выход при зависаниях). А после перехода на FPT такое случилось уже через месяц работы. Поэтому и интересовал вопрос: кто-нить исследовал сравнительную отказоустойчивость DBT и FPT файлов.

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





Пост N: 40
Зарегистрирован: 08.07.06
ссылка на сообщение  Отправлено: 13.09.06 15:57. Заголовок: Re:


смотри, может и зря я "со своим уставом в чужой монастырь..." но тем не менее, ИМХО - dbt и вся структура хранения разнородных BLOB в одном файле - изврат изначально...

примеры:

читаем значение из "реестра" x:=KnowValue(SAVED_COLORS)
пишем значение в "реестр" KnowValue(SAVED_COLORS,aColorTable)

т.е. первое значение - константа, определяющая КАКУЮ переменную мы хотим прочесть или сохранить

формат таблицы know.dbf:

struct:={;
{"id" ,"N", 3,0},; // идентификатор
{"user" ,"N", 3,0},; // код юзера
{"part" ,"N", 4,0},; // N-я часть для длинной цепочки
{"type" ,"C", 1,0},; // тип в формате "CLNAD"
{"size" ,"N", 4,0},; // общая длина переменной
{"value" ,"C",KNOW_CLUSTER_SIZE,0}} // значение

KNOW_CLUSTER_SIZE = у меня равен 25, т.к. записи небольшие и представляют собой одно-двухмерные массивы параметров.
его размер выбирается примерно исходя из тех-же соображений, что и размер кластера в FAT: маленький размер - много "кусков", большой размер - "много хвостов"

индексный ключ:

"STR(know->id,3)+STR(know->user,3)+STR(know->part,4)"

* ---------------------------------------------------------------- *
FUNC KnowValue(nId,xValue,xDefault,nUser,cValtype,nLen)

LOCAL area,used,result
DEFAULT nUser TO current_user[1]
OpenBase("know",@area,@used)
IF xValue = NIL // читаем
result := KnowGet(nId,nUser)
IF (result = NIL) .OR. ;
((VALTYPE(cValtype) = "C") .AND. (VALTYPE(result) # cValtype)) .OR. ;
((VALTYPE(result) $ "CA") .AND. (VALTYPE(nLen)="N") .AND. (LEN(result) # nLen))
IF xDefault # NIL
result := xDefault
ENDI
ENDI
ELSE // пишем
result := KnowPut(nId,xValue,nUser)
ENDI
CloseBase("know",area,used)
RETURN result

* -------------------------------------------- *
STATIC FUNC KnowPut(nId,xValue,nUser)

LOCAL vsize,parts,i,sx

vsize := KnowCalcSize(xValue)
parts := 1+INT(vsize / KNOW_CLUSTER_SIZE)
sx := KnowX2C(xValue)

i:=1
SEEK STR(nId,3)+STR(nUser,3)+STR(i,4) // ищем первую часть "1"
REPEAT
IF (know->id = nId) .AND. (know->user = nUser) .AND. (know->part = i)
IF !RecLock(time_out)
RETURN FALSE
ENDI
ELSE
IF InsertRec()
know->id := nId
know->user := nUser
know->part := i
ELSE
RETURN FALSE
ENDI
ENDI
know->type := VALTYPE(xValue)
know->size := vsize
know->value := SUBSTR(sx,(i-1)*KNOW_CLUSTER_SIZE+1,KNOW_CLUSTER_SIZE)
DBUNLOCK()
i++
SKIP // берем след.часть
UNTIL i>parts

DO WHILE (know->id = nId) .AND. (know->user = nUser) // стираем "хвосты"
DeleteRec()
SKIP
ENDD
RETURN TRUE

* ------------------------------------ *
STATIC FUNC KnowGet(nId,nUser)

LOCAL sx:="",vtype,vsize,result
SEEK STR(nId,3)+STR(nUser,3) // ищем первую часть
IF FOUND()
vtype := know->type
vsize := know->size
DO WHILE (know->id = nId) .AND. (know->user = nUser) // скидываем в буфер
sx += know->value
SKIP
ENDD
result := KnowC2X(@sx,vtype,vsize)
ELSE
result := NIL
ENDI
RETURN result

* -------------------------------------- *
STATIC FUNC KnowCalcSize(xValue)

LOCAL ch,res
ch:=VALTYPE(xValue)
IF ch="C"; res := LEN(xValue)
ELSEIF ch="N"; res := LEN(STR(xValue))
ELSEIF ch="D"; res := 8
ELSEIF ch="L"; res := 1
ELSEIF ch="A"; res := LEN(Var2Str({xValue}))
ELSE
ShowAlert("KnowCalcSize(): неподдерживаемый тип: "+ch)
ErrorExitProgram()
ENDI
RETURN res

* --------------------------------- *
STATIC FUNC KnowX2C(xValue)

LOCAL ch,res
ch:=VALTYPE(xValue)
IF ch="C"; res := xValue
ELSEIF ch="N"; res := STR(xValue)
ELSEIF ch="D"; res := DTOC(xValue)
ELSEIF ch="L"; res := IIF(xValue,"T","F")
ELSEIF ch="A"; res := Var2Str({xValue})
ELSE
ShowAlert("KnowX2C(): неподдерживаемый тип: "+ch)
ErrorExitProgram()
ENDI
RETURN res

* ------------------------------------------------ *
STATIC FUNC KnowC2X(cString,cType,nSize)

LOCAL ch,res
IF cType="C"; res := LEFT(cString,nSize)
ELSEIF cType="N"; res := VAL(cString)
ELSEIF cType="D"; res := CTOD(cString)
ELSEIF cType="L"; res := (cString == "T")
ELSEIF cType="A"; res := Str2Var(LEFT(cString,nSize))[1]
ELSE
ShowAlert("KnowC2X(): неподдерживаемый тип: "+ch)
ErrorExitProgram()
ENDI
RETURN res

* ----------------------------------------------------- *
надеюсь, что помог...

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





Пост N: 37
Зарегистрирован: 25.07.06
ссылка на сообщение  Отправлено: 13.09.06 17:42. Заголовок: Re:


Спасибо, в общем, разобрался. Попробую переделать на Clipper под свои нужды.
Sergy пишет:

 цитата:
первое значение - константа, определяющая КАКУЮ переменную мы хотим прочесть или сохранить


Sergy пишет:

 цитата:
{"id" ,"N", 3,0},; // идентификатор


Я так понимаю, что нужен еще словарь идентификаторов? Иначе как можно прочесть или записать значение, допустим, в массив MyArray

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




Пост N: 69
Зарегистрирован: 24.09.05
ссылка на сообщение  Отправлено: 14.09.06 10:38. Заголовок: Re:


alexmar пишет:

 цитата:
Кто работал с fpt файлами, отзовитесь, насколько часто они имеют тенденцию ломаться? У меня сложилось впечатление, что они менее устойчивы к сбоям по питанию и всякии некорректным действиям пользователей типа некорректноговыхода/выключения по сравнению с dbt файлами.



Сбои питания и некорректный выход - не основная причина ломания фпт. Причина в том, что ФПТ устроен сложнее, чем ДБТ, отсюда - более сложный код и как следствие - бОльшее количество ошибок в реализации.

Печально, что никакие блокировки записей не устраняют дыр в коде записи в ФПТ. Например, станция А и Б блокировали разные записи и пытаются добавить новое значение МЕМО-поля. При этом блокировака собственно записей не устраняет потенциальную возможность добавить с этих станций мемо в одно и то же место, в случае ошибок в коде.

ФПТ хранит в заголовке адрес первого свободного блока, а кроме этого - до первого фпт-значения там хранится некоторое количество блоков, которые могут быть повторно использованы. Для того, чтобы корректно добавить значение надо полностью исключить попытки сделать то же самое со стороны других станций, а SIx этого не делает. Он пишет, устанавливая временные блокировки. Поэтому существуют такие временные дыры, в которые может встрять другая станция, пытаясь сделать то же самое.

Сказанное относится не только к ФПТ, но даже и к ДБФ. Если рабочие станции интенсивно добавляют записи, то они могу добавить их на одно и то же место в драйвере SIxCDX. SIxNSX более устойчив (в этом отношении), но не идеален.

Решение - хз.

Вариант 1 - SIxNSX.

Вариант 2 - Возможно поможет установка бинарной блокировки на заголовок мемо до записи и снятие его после записи низкоуровневыми функциями.



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




Пост N: 74
Зарегистрирован: 24.09.05
ссылка на сообщение  Отправлено: 14.09.06 11:13. Заголовок: Re:


alexmar пишет:

 цитата:
Произошло то же, что ИЗРЕДКА раньше происходило и с dbt файлами. В разных записях указатели на номер блока (смещения) в memo файле оказываются одинаковыми.



А каким образом ты это проверяешь? А как насчет частичного налезания блоков друг на друга? В этом случае номера блоков будут разными, проверяешь ли ты это?

В ASC ( http://www.listsoft.ru/program.php?id=11358 ) есть операция "Доктор". Она проверяет многие вещи, в т.ч. имеются ли перекрестные/дублирующиеся ссылки мемо-значений. Кроме того - проверка мемо-значений на допустимость типов (мемо ведь может хранить числа, массивы..), проверки на превышение максимального размера, на наличие chr(26) в значениях для DBT, корректность числовых данных в самом DBF (наличие мусора), корректность номеров блоков мемо (наличие мусора), ссылки за пределы файла...

Выдается подробная hex-карта ошибок при проверке одного файла или кратнкая информация при проверке группы файлов.

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





Пост N: 41
Зарегистрирован: 08.07.06
ссылка на сообщение  Отправлено: 14.09.06 11:43. Заголовок: Re:



 цитата:

Sergy пишет:
цитата:
{"id" ,"N", 3,0},; // идентификатор
Я так понимаю, что нужен еще словарь идентификаторов? Иначе как можно прочесть или записать значение, допустим, в массив MyArray



Вместо словаря идентификаторов я определил все нужные мне константы через #define, например:

#define KNOW_CLUSTER_SIZE 25 // размер кластера в таблице know.dbf
#define KV_EDPRICE 1 // первое реально нужное значение!
#define KV_MARKETING_PROGS 2 // то, ради чего все это началось... ;-)
#define KV_PRICELIST 3 // параметры прайс-листа
#define KV_COLORTABLE 4 // таблица цветов
#define KV_STOCKREMAIN 5 // параметры бланка учета
#define KV_LISTUSERS 6 // список выбранных пользователей
#define KV_FILESORT_MODE 7 // режим сортировки файлов на экране
#define KV_GODSMOVING 8 // параметры бланка движения товара
#define KV_PICS_EXPORT 9 // параметры экспорта картинок
#define KV_PICS_VIEW 10 // SETUP: параметры просм.картинок: каталог,viewer
#define KV_VIEWER_SETUP 11 // SETUP: установки проcмотра текста
#define KV_NETWORK_TEST 12 // SETUP: параметры проверки сети
#define KV_FIND_STRING 13 // строка поиска
#define KV_LABEL_COPY_TO 14 // куда копировать граф.ценник в RLGUIrun()
#define KV_COMPARE_STOCKS 15 // параметры отчета "сравнение остатков"
#define KV_SAVEDATA_PATH 16 // куда сохранять данные
#define KV_STOCK_FILTER 17 // параметры фильтрации в SelectStock()
#define KV_ICQ_SETUP 18 // параметры icq
#define KV_DOS_COMMAND 19 // сохр.команды ДОС
#define KV_DEF_SALE_STK 20 // склад - продавец по умолчанию
#define KV_SERVER_COMMANDS 21 // серверные команды
#define KV_ENV_COMMANDS 22 // SETUP: команды при запуске/выходе

* ------------------------------------------ *

параметры с пометкой SETUP привязываются не к конкретному пользователю, а к машине, на которой происходит вызов KnowValue

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

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




Пост N: 75
Зарегистрирован: 24.09.05
ссылка на сообщение  Отправлено: 14.09.06 13:54. Заголовок: Re:


Проведем простой тест.

Программа номер 1. Открывает базу тест. Далее для одной и той же записи номер 1 пишет в мемо поле MEMO значение случайно длины в интервале [текущая длина - 20 ...... текущая длина+80]. Таким образом примерно в 20% случаев мемо надо будет записать в тот же блок, а в 80% случаев - в новый. То есть мемо-поле преимущественно растет по длине. Если текущая длина мемо уже превышает 500 байт - пишет в мемо короткую строку с длиной [1...64] При этом на конце значения всегда идет строка "йцукенг" для контроля правильности чтения и записи значения программой номер два. Примечание: Функция abcRandom(Len) - возвращает случайный набор символов, длиной Len. iRandom(low,Max) - случайное целое в интервале [Low,Max]


#define TESTRDD "SIXCDX"

proc main1()
local i,Count:=0
?"запись"
use TEST new shared via TESTRDD
while inkey()#K_ESC
dbGoto(1)
sx_Rlock(recno())
if len(field->MEMO) > 500
field->MEMO := abcRandom(iRandom(1,64))+"йцукенг"
else
field->MEMO := abcRandom(iRandom(len(field->MEMO)-20,len(field->MEMO)+80))+"йцукенг"
end
sx_UnLock(recno())
??chr(13),++Count
end

Программа номер 2) Открывает базу тест. Далее для одной и той же записи номер 1 читает значение поля MEMO и проверяет, содержится ли на конце "йцукенг".

proc main2()
local i,Count:=0

use ordbook new shared via RddDetect("ordbook")
?"Чтение"
while inkey() # K_ESC
dbGoto(1)
i := ("йцукенг" $ field->MEMO)
if at("йцукенг",field->MEMO) # (len(field->MEMO) - 7 +1)
?field->MEMO
wait
end
??chr(13),++Count
end
ret

Результаты. Запускаем обе программы одновременно. И в SIxNSX, и в SIxCDX часто происходит неправильное чтение MEMO (примерно 1 раз на 3000 тыщ циклов, результаты могут отличаться на другом компьютере).

Запись мемо - длительный процесс. Например, если существенно изменилась длина мемо и значение надо писать в другой блок, этот блок нужно сначала найти в memo-файле (в списке резервных или в конце файла), потом записать номер блока в соответствующее поле DBF, потом записать само значение и его длину. Все это время другие попытки записи в мемо-файл должны быть исключены и программы должны терпеливо ждать. С чтением - то же самое. Нельзя же читать что попало в середине процесса записи. Например, есть следующая конфликтная ситуация. Мы сначала внесли изменения в дбф, не не успели внести изменения в мемо. Если кто-то попытается в этот момент времени считать значение, то прочитает полную фигню. Алгоритм наоборот. Мы метим текущий блок как свободный. (момент X) Затем пишем новое значение в мемо. Затем меняем номер блока в дфб. В (момент X) с другой раб станции произвели запись в этот уже свободный блок, а еще одна станция прочитала значение для изменяемой нами записи и получила значение совершенно другой записи. Как быть? Делаем так: пишем новое значение в мемо-файл, пишем новый номер блока в дбф, пишем, что старый блок свободный. Отлично? Нет, так делать нельзя. До того, как буфер записи не будет сброшен на диск (разблокировка или уход с записи) - нельзя ничего писать в дбф, так уж в клиппере принято.

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

О том, что происходит при одновременной ЗАПИСИ в мемо - можно представить. Но для этого надо написать более сложную программу. На косяки легко налететь не то что при записи в МЕМО - даже при записи в ДБФ. Несложные тесты это тоже подтверждают. При интенсивном добавлении бывают случаи, когда две станции добавляют запись в одно и то же физическое место.

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




Пост N: 76
Зарегистрирован: 24.09.05
ссылка на сообщение  Отправлено: 14.09.06 13:59. Заголовок: Re:


Дим! Убери нахрен аватар этот! ) Я молодой и красивый, а ты какого-то пердуна-мутанта залепил)

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




Пост N: 359
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 14.09.06 14:37. Заголовок: Re:


suv2
Убрал

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




Пост N: 79
Зарегистрирован: 24.09.05
ссылка на сообщение  Отправлено: 14.09.06 14:51. Заголовок: Re:


гыгы))) этот ничего так)

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





Пост N: 40
Зарегистрирован: 25.07.06
ссылка на сообщение  Отправлено: 14.09.06 16:40. Заголовок: Re:


глюк


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




Пост N: 81
Зарегистрирован: 24.09.05
ссылка на сообщение  Отправлено: 14.09.06 17:07. Заголовок: Re:


alexmar пишет:

 цитата:
глюк



не глюк, а косорукий код

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





Пост N: 41
Зарегистрирован: 25.07.06
ссылка на сообщение  Отправлено: 14.09.06 17:45. Заголовок: Re:


suv2 пишет:
 цитата:
А каким образом ты это проверяешь? А как насчет частичного налезания блоков друг на друга? В этом случае номера блоков будут разными, проверяешь ли ты это?

Я через HEX редактор меняю тип поля в заголовке на символьный и тогда в бывших memo полях видны адреса смещений.
suv2 пишет:

 цитата:
В ASC ( http://www.listsoft.ru/program.php?id=11358 ) есть операция "Доктор".

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

Номер Смещение Смещение Длина Длина Описание
записи Поле в DBF в MEMO значения в MEMO ошибки

7093 NAUD 647FB 382CA0 FB 103 Общие данные с зап.6634 поле DNA
7093 DNA 64805 382C20 60 68
7093 DUD 6480F

В связи э этим, несколько вопросов:
1 Я правильно понимаю, что "Длина значения" - это длина в заголовке memo, а "Ддлина в MEMO" - это длина данных в самом файле?
2 Чем может быть вызвано то, что эти длины отличаются. Или это не ошибка? У меня они отличаются практически для всех записей. Очевидно, что это возникло еще при конвертировании DBT -> FPT, так, как задеты и старые записи, к которым обращения после конвертирования не было.
3 Каким образом "Доктор" лечит перекрестные/дублирующиеся ссылки мемо-значений.

suv2, спасибо тебе огромное за подробную информацию. Хотя выводы, конечно, неутешительные. По всей видимости, придется отказываться от использования memo полей в пользу алгоритма, предложенного Sergy. Sergy, тебе тоже спасибо за помощь.

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





Пост N: 46
Зарегистрирован: 25.07.06
ссылка на сообщение  Отправлено: 14.09.06 18:48. Заголовок: Re:


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

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





Пост N: 48
Зарегистрирован: 25.07.06
ссылка на сообщение  Отправлено: 15.09.06 08:50. Заголовок: Re:


Все-таки мне не дает покоя вопрос. По какой причине может поломаться fpt, если:

1 База находится в сети
2 Реально с базой работала 1 рабочая станция
3 Работа велась в режиме ручного ввода данных, т.е о быстром обновления данных говорить не приходится
4 В одно и то же время работа шла с 1 записью.
5 Зависаний сервера (кажется Линукс) и рабочей станции (Win98) не было
6 Корректность открытия/закрытия/флагов блокировок/разблокировок баз/индексов проверена временем (программа уже больше 10лет до этого работала с dbt файлами в том числе и в многопользовательском режиме)
7 Обращение к базе во время работы из других программ исключено.

Изменения в условиях работы:
1 Программа переведена с Clipper 5.01 - 5.2e и работает в Dual mode
2 DBT сконвертированы в FPT, под SIXCDX и индексы переведены с NTX в IDX

Что скажет общественность?

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




Пост N: 84
Зарегистрирован: 24.09.05
ссылка на сообщение  Отправлено: 15.09.06 12:46. Заголовок: Re:


alexmar пишет:

 цитата:
1 Я правильно понимаю, что "Длина значения" - это длина в заголовке memo, а "Ддлина в MEMO" - это длина данных в самом файле?
2 Чем может быть вызвано то, что эти длины отличаются



Длина значения - полная длина мемо-значения согласно данным в DBF или согласно данным в МЕМО.
Длина в мемо - длина части значения, которая хранится в мемо.

По традиции применяют тип поля "M" и хранят в нем символьные данные.

Однако, мемо-поля могут быть разных типов (M,V) и могут хранить значения разных типов ("C","N","D","L"). Значение может быть полностью в DBF, частично в DBF + частично в MEMO, полностью в мемо.

В твоем случае (М-поле, С-значения) драйвер в дбф хранит номер блока, а в мемо - 8 байт с информацией о типе значения + о длине значения + само значение.

Информация об ошибке (если она есть) - в соответствующем поле. Если оно пустое - ошибки нет. Остальные цифры - справочные, они помогают спозиционироваться на нужное место в hex-редакторе

halexmar пишет:

 цитата:
3 Каким образом "Доктор" лечит перекрестные/дублирующиеся ссылки мемо-значений.

.

А никаким. Основной метод восстановления хоть каких-то данных мемо - копирование в другую базу. В этом случае все перекрестные ссылки уйдут. Однако некоторые ошибочные значения копировать не имеет смысла. Например, при чтении клиппером данного поля возвращается некоторая строка, однако доктор сказал, что это значение ошибочно. Если мемо хранило не текстовое примечание - это не страшно, его можно отредактировать. А если в мемо хранились программой некие ссылки на некие взаимосвязанные документы - такое значение нужно сразу отбросить как заведомо ложное и вводящее в заблуждение боевую программу.


Кроме этого, есть значения, которые мешают чтению базы - т.к. приводят к GPF. Например, если значение превышает макс длину "С". Или хранит мусор, который сикс пытается воспринять как многомерный массив. Такие значения нужно просто очистить. В старой версии доктора была очистка поля, потом я полностью переделал доктора и очистка поля прямо в нем потерялась))) Но по информации, которая есть в hex-карте это можно сделать вручную.

alexmar пишет:

 цитата:
По всей видимости, придется отказываться от использования memo полей в пользу алгоритма, предложенного Sergy



Часто причина ошибок в мемо - неаккуратность при копировании (копируется ДБФ и не копируется МЕМО).

Кроме этого, попробуй SIXNSX. ДА и SIXCDX тоже довольно стоек, косяки происходят не так уж часто.

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

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