Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Ошибка в исходниках IBCustomDataSet или в SysUtils?


КаПиБаРа ©   (2004-11-01 06:48:00) 

Предыстория:
В таблице базы (Firebird) определено поле типа Time. При попытке добавления значений поля в таблицу получаю ошибку EConvertError. Начал разбираться откуда ноги растут и набрел на такой интересный код.

При добавлении записи вызывается процедура SetInternalSQLParams из модуля IBCustomDataSet. Для поля типа SQL_TYPE_TIME значение задается преобразуется из TimeStamp, значение которого задается тут же. Обратите внимание на строчку ts.Date := 0; в которой задается "нулевой" день.

procedure TIBCustomDataSet.SetInternalSQLParams(Qry: TIBSQL; Buffer: Pointer);
var
 i, j: Integer;
 cr, data: PChar;
 fn, st: string;
 OldBuffer: Pointer;
 ts: TTimeStamp;
begin
...
           case rdFields[j].fdDataType of
...
           SQL_TYPE_TIME:
           begin
              ts.Date := 0;
             ts.Time := PInt(data)^;
             Qry.Params[i].AsTime :=
               TimeStampToDateTime(ts);
           end;
...


Далее переходим к модулю SysUtils, в котором и рассматриваем код процедуры TimeStampToDateTime. Видим что в процедуре происходит вызов ValidateTimeStamp. Что же там проверяется?

function TimeStampToDateTime(const TimeStamp: TTimeStamp): TDateTime;
asm
       PUSH    EBX
{$IFDEF PIC}
       PUSH    EAX
       CALL    GetGOT
       MOV     EBX,EAX
       POP     EAX
{$ELSE}
       XOR     EBX,EBX
{$ENDIF}
       PUSH    EAX
        CALL    ValidateTimeStamp
...


А проверяется там, то что значение полей записи TimeStamp не выходило за границы допустимого диапазона. В том числе день не должен быть меньше или равен 0.

procedure ValidateTimeStamp(const TimeStamp: TTimeStamp);
begin
 if (TimeStamp.Time < 0) or ( TimeStamp.Date <= 0) then
   ConvertErrorFmt(@SInvalidTimeStamp, [TimeStamp.Date, TimeStamp.Time]);
end;

Таким образом получается что при работе с полем Time будет всегда происходить ошибка.

Вот хотелось бы узнать в D7 что то изменилось? И как по вашему в каком из 2-х модулей была допущена ошибка?


КаПиБаРа   (2004-11-01 13:56:00) [1]

А в D6 как этот код выглядит? Это только у меня или у всех так?


Sergey_Masloff   (2004-11-01 13:37:00) [2]

КаПиБаРа ©   (01.11.04 13:09) [1]
>Никто не сталкивался с этим и никаких мыслей нет?
Есть мысли использовать нормальные версии компонент.
Это в D5:

 SQL_TYPE_TIME:
           begin
             ts.Date := 1;
             ts.Time := PInt(data)^;
             Qry.Params[i].AsTime :=
               TimeStampToDateTime(ts);
           end;


REA   (2004-11-01 13:32:00) [3]

D7:

SQL_TYPE_DATE:
           begin
             ts.Date := PInt(data)^;
             ts.Time := 0;
             Qry.Params[i].AsDate :=
               TimeStampToDateTime(ts);
           end;
           SQL_TYPE_TIME:
           begin
             ts.Date := 1;
             ts.Time := PInt(data)^;
             Qry.Params[i].AsTime :=
               TimeStampToDateTime(ts);
           end;


КаПиБаРа   (2004-11-01 13:09:00) [4]

Никто не сталкивался с этим и никаких мыслей нет?


Наверх

Титульная страница Поиск, карта сайта Написать письмо