powered by simpleCommunicator - 2.0.50     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Добавление информации в StatusVector
13 сообщений из 13, страница 1 из 1
Добавление информации в StatusVector
    #39969509
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хочу расширить информацию в StatusVector своим сообщением.

Делаю так
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
procedure Test(AStatus: IStatus; AExcept: FBException);
var
  LStatus: NativeIntPtr;
  LCurStatus: NativeIntPtr;
  LNewStatus: array of NativeInt;
  LCnt: Integer;
  LLogger: ILogger;
begin
  LStatus := AExcept.getStatus.getErrors;
  LCurStatus := LStatus;
  // Вычисляем текущий размер вектора
  LCnt := 0;
  while LCurStatus^ <> isc_arg_end do begin
    Inc(LCurStatus);
    Inc(LCnt);
  end;
  // Расширяем вектор на 5 значений
  SetLength(LNewStatus, LCnt + 5);
  LCurStatus := LStatus;
  LCnt := 0;
  // Копируем значение в новый вектор
  while LCurStatus^ <> isc_arg_end do begin
    LNewStatus[LCnt] := LCurStatus^;
    Inc(LCurStatus);
    Inc(LCnt);
  end;
  // Добавляем дополнительную информацию
  LNewStatus[LCnt + 0] := isc_arg_gds;
  LNewStatus[LCnt + 1] := isc_random;
  LNewStatus[LCnt + 2] := isc_arg_string;
  LNewStatus[LCnt + 3] := NativeInt(PAnsiChar('Additional info'));
  LNewStatus[LCnt + 4] := isc_arg_end;
  AStatus.setErrors(@LNewStatus[0]);
  raise FbException.Create(AStatus);
end;

В итоге на клиенте (IBExpert) я получаю информацию только из исходного вектора. Если же я перенесу свой блок в начало, то получаю ошибку на клиенте
<Missing arg #1 - possibly status vector overflow>, column <Missing arg #2 - possibly status vector overflow>.

Или сама идея работать не будет и я могу возвращать либо стандартный вектор, либо кастомный?

С уважением, Vasilisk
...
Рейтинг: 0 / 0
Добавление информации в StatusVector
    #39969514
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_
Код: pascal
1.
2.
3.
4.
5.
6.
  // Вычисляем текущий размер вектора
  LCnt := 0;
  while LCurStatus^ <> isc_arg_end do begin
    Inc(LCurStatus);
    Inc(LCnt);
  end;

Это не совсем правильно, если где-то есть элемент с аргументами и кто-то из них равен нулю - ты неверно определишь конец вектора.
То же самое при копировании.


_Vasilisk_
В итоге на клиенте (IBExpert) я получаю информацию только из исходного вектора
isc_arg_end из первоначального вектора не остался ?

Как это вообще используется ? Зачем AStatus передан как параметр ?
...
Рейтинг: 0 / 0
Добавление информации в StatusVector
    #39969518
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Все isc_arg_XXX коды, кроме isc_arg_cstring и isc_arg_end имеют 1 параметр.
isc_arg_cstring имеет 2 пар-ра и isc_arg_end не имеет пар-ров.

Поэтому вот так будет лучше, если я правильно помню Pascal

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
  LCurStatus := LStatus;
  // Вычисляем текущий размер вектора
  LCnt := 0;
  while LCurStatus^ <> isc_arg_end do
    if (LCurStatus^ = isc_arg_cstring)
    then Inc(LCurStatus, 3);
    else Inc(LCurStatus, 2);

  LCnt := LCurStatus - LStatus;
...
Рейтинг: 0 / 0
Добавление информации в StatusVector
    #39969534
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Эх, а ведь просил я IStatus::append()...
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Добавление информации в StatusVector
    #39969831
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvlad
Это не совсем правильно, если где-то есть элемент с аргументами и кто-то из них равен нулю - ты неверно определишь конец вектора.
Принимается. Но в данном случае такого элемента не было.
hvlad
isc_arg_end из первоначального вектора не остался ?
Нет.
hvlad
Как это вообще используется ?
Это в UDR. В функции идет цикл по записям. И если на какой-то записи произошла ошибка, хочу дополнить текст ошибки идентификатором этой записи
hvlad
Зачем AStatus передан как параметр ?
Он у меня есть. По нему поднимаю исключение
hvlad
Поэтому вот так будет лучше
Ничего не изменилось.

Код
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
procedure HandleFBExcept(AStatus: IStatus; AExcept: FbException);
var
  LLogger: ILogger;
  LStatus: NativeIntPtr;
  LCurStatus: NativeIntPtr;
  LNewStatus: array of NativeInt;
  LCnt: Integer;
begin
  LLogger := TLoggerFactory.GetLogger('Test');
  LStatus := AExcept.getStatus.getErrors;
  // Логируем текущий вектор
  ShowStatus(LLogger, LStatus);
  LCurStatus := LStatus;
  // Вычисляем длину вектора
  while LCurStatus^ <> isc_arg_end do begin
    if LCurStatus^ = isc_arg_cstring then
      Inc(LCurStatus, 3)
    else
      Inc(LCurStatus, 2);
  end;
  LCnt := (NativeInt(LCurStatus) - NativeInt(LStatus));
  // Выделяем память под новый вектор
  SetLength(LNewStatus, LCnt + 5);
  // Копируем старый вектор, в новый
  Move(LStatus^, LNewStatus[0], LCnt);
  LCnt := LCnt div SizeOf(LNewStatus[0]);
  // Добавляем новый блок
  LNewStatus[LCnt + 0] := isc_arg_gds;
  LNewStatus[LCnt + 1] := isc_random;
  LNewStatus[LCnt + 2] := isc_arg_string;
  LNewStatus[LCnt + 3] := NativeInt(PAnsiChar('Additional info'));
  LNewStatus[LCnt + 4] := isc_arg_end;
  AStatus.setErrors(@LNewStatus[0]);
  LLogger.Log('---------------');
  LStatus := AStatus.getErrors;
  // Логируем новый вектор
  ShowStatus(LLogger, LStatus);
  raise FbException.Create(AStatus);
end;


ShowStatus
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
procedure ShowStatus(const ALogger: ILogger; AVector: NativeIntPtr);
var
  LCur: NativeIntPtr;
  LDesc: string;
  LIdx: Integer;
begin
  LCur := AVector;
  LIdx := 0;
  while True do begin
    ArgCodes.TryGetValue(LCur^, LDesc);
    ALogger.Log('[%2d]: %d (%s)', [LIdx, LCur^, LDesc]);
    case LCur^ of
      isc_arg_end: Break;
      isc_arg_string: begin
        Inc(LIdx);
        Inc(LCur);
        ALogger.Log('[%2d]:   %s', [LIdx, PAnsiChar(LCur^)]);
      end;
      isc_arg_cstring: begin
        Inc(LIdx);
        Inc(LCur);
        ALogger.Log('[%2d]:   %d', [LIdx, LCur^]);
        Inc(LIdx);
        Inc(LCur);
        ALogger.Log('[%2d]:   %s', [LIdx, PAnsiChar(LCur^)]);
      end;
    else
      Inc(LIdx);
      Inc(LCur);
      GDSCodes.TryGetValue(LCur^, LDesc);
      ALogger.Log('[%2d]:   %d (%s)', [LIdx, LCur^, LDesc]);
    end;
    Inc(LIdx);
    Inc(LCur);
  end;
end;


Лог
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
[ 0]: 1 (isc_arg_gds)
[ 1]:   335544569 (isc_dsql_error)
[ 2]: 1 (isc_arg_gds)
[ 3]:   335544436 (isc_sqlerr)
[ 4]: 4 (isc_arg_number)
[ 5]:   -206 ()
[ 6]: 1 (isc_arg_gds)
[ 7]:   335544578 (isc_dsql_field_err)
[ 8]: 1 (isc_arg_gds)
[ 9]:   335544382 (isc_random)
[10]: 2 (isc_arg_string)
[11]:   RT.T_IMESTAMP
[12]: 1 (isc_arg_gds)
[13]:   336397208 (isc_dsql_line_col_error)
[14]: 4 (isc_arg_number)
[15]:   21 ()
[16]: 4 (isc_arg_number)
[17]:   5 ()
[18]: 0 (isc_arg_end)
---------------
[ 0]: 1 (isc_arg_gds)
[ 1]:   335544569 (isc_dsql_error)
[ 2]: 1 (isc_arg_gds)
[ 3]:   335544436 (isc_sqlerr)
[ 4]: 4 (isc_arg_number)
[ 5]:   -206 ()
[ 6]: 1 (isc_arg_gds)
[ 7]:   335544578 (isc_dsql_field_err)
[ 8]: 1 (isc_arg_gds)
[ 9]:   335544382 (isc_random)
[10]: 2 (isc_arg_string)
[11]:   RT.T_IMESTAMP
[12]: 1 (isc_arg_gds)
[13]:   336397208 (isc_dsql_line_col_error)
[14]: 4 (isc_arg_number)
[15]:   21 ()
[16]: 4 (isc_arg_number)
[17]:   5 ()
[18]: 1 (isc_arg_gds)
[19]:   335544382 (isc_random)
[20]: 2 (isc_arg_string)
[21]:   Additional info
[22]: 0 (isc_arg_end)


Сообщение в IBExpert
Column does not belong to referenced table.
Dynamic SQL Error.
SQL error code = -206.
Column unknown.
RT.T_IMESTAMP.
At line 21, column 5.

Если мой блок поставить в начало
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
procedure HandleFBExcept2(AStatus: IStatus; AExcept: FbException);
var
  LLogger: ILogger;
  LStatus: NativeIntPtr;
  LCurStatus: NativeIntPtr;
  LNewStatus: array of NativeInt;
  LCnt: Integer;
begin
  LLogger := TLoggerFactory.GetLogger('ServiceArea');
  LStatus := AExcept.getStatus.getErrors;
  // Логируем текущий вектор
  ShowStatus(LLogger, LStatus);
  LCurStatus := LStatus;
  // Вычисляем длину вектора
  while LCurStatus^ <> isc_arg_end do begin
    if LCurStatus^ = isc_arg_cstring then
      Inc(LCurStatus, 3)
    else
      Inc(LCurStatus, 2);
  end;
  LCnt := (NativeInt(LCurStatus) - NativeInt(LStatus));
  // Выделяем память под новый вектор
  SetLength(LNewStatus, LCnt + 5);
    // Добавляем новый блок
  LNewStatus[0] := isc_arg_gds;
  LNewStatus[1] := isc_random;
  LNewStatus[2] := isc_arg_string;
  LNewStatus[3] := NativeInt(PAnsiChar('Additional info'));
  // Копируем старый вектор, в новый
  Move(LStatus^, LNewStatus[4], LCnt + SizeOf(LNewStatus[0]));
  AStatus.setErrors(@LNewStatus[0]);
  LLogger.Log('---------------');
  LStatus := AStatus.getErrors;
  // Логируем новый вектор
  ShowStatus(LLogger, LStatus);
  raise FbException.Create(AStatus);
end;


то получим такой вектор
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
[ 0]: 1 (isc_arg_gds)
[ 1]:   335544569 (isc_dsql_error)
[ 2]: 1 (isc_arg_gds)
[ 3]:   335544436 (isc_sqlerr)
[ 4]: 4 (isc_arg_number)
[ 5]:   -206 ()
[ 6]: 1 (isc_arg_gds)
[ 7]:   335544578 (isc_dsql_field_err)
[ 8]: 1 (isc_arg_gds)
[ 9]:   335544382 (isc_random)
[10]: 2 (isc_arg_string)
[11]:   RT.T_IMESTAMP
[12]: 1 (isc_arg_gds)
[13]:   336397208 (isc_dsql_line_col_error)
[14]: 4 (isc_arg_number)
[15]:   21 ()
[16]: 4 (isc_arg_number)
[17]:   5 ()
[18]: 0 (isc_arg_end)
---------------
[ 0]: 1 (isc_arg_gds)
[ 1]:   335544382 (isc_random)
[ 2]: 2 (isc_arg_string)
[ 3]:   Additional info
[ 4]: 1 (isc_arg_gds)
[ 5]:   335544569 (isc_dsql_error)
[ 6]: 1 (isc_arg_gds)
[ 7]:   335544436 (isc_sqlerr)
[ 8]: 4 (isc_arg_number)
[ 9]:   -206 ()
[10]: 1 (isc_arg_gds)
[11]:   335544578 (isc_dsql_field_err)
[12]: 1 (isc_arg_gds)
[13]:   335544382 (isc_random)
[14]: 2 (isc_arg_string)
[15]:   RT.T_IMESTAMP
[16]: 1 (isc_arg_gds)
[17]:   336397208 (isc_dsql_line_col_error)
[18]: 4 (isc_arg_number)
[19]:   21 ()
[20]: 4 (isc_arg_number)
[21]:   5 ()
[22]: 0 (isc_arg_end)

и ошибкуColumn does not belong to referenced table.
Additional info.
Dynamic SQL Error.
SQL error code = -206.
Column unknown.
RT.T_IMESTAMP.
At line <Missing arg #1 - possibly status vector overflow>, column <Missing arg #2 - possibly status vector overflow>.
...
Рейтинг: 0 / 0
Добавление информации в StatusVector
    #39969850
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Знаю, что варварство, но сделал так
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
procedure HandleFBExcept3(AUtil: IUtil; AExcept: FbException; const AName: string);
var
  LBuf: array[0..4095] of AnsiChar;
  LStatus: IStatus;
  LLen: Cardinal;
  LMsg: AnsiString;
begin
  LStatus := AExcept.getStatus;
  LLen := AUtil.formatStatus(@LBuf[0], Length(LBuf), LStatus);
  SetString(LMsg, PAnsiChar(@LBuf[0]), LLen);
  raise EUDRException.Create(AName + sLineBreak + string(LMsg));
end;

для моей задачи этого достаточно
...
Рейтинг: 0 / 0
Добавление информации в StatusVector
    #39969897
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_
Код: pascal
1.
2.
3.
4.
5.
6.
7.
  LStatus: NativeIntPtr;
  LCurStatus: NativeIntPtr;
  LNewStatus: array of NativeInt;
  LCnt: Integer;
begin

  LCnt := (NativeInt(LCurStatus) - NativeInt(LStatus));

Гм... А что это тут происходит ? Указатели - в числа и разницу адресов вычисляем ?
И что тут получается ?

_Vasilisk_
Код: plaintext
1.
2.
3.
4.
5.
...
[19]:   335544382 (isc_random)
[20]: 2 (isc_arg_string)
[21]:   Additional info
[22]: 0 (isc_arg_end)

Сообщение в IBExpert
Ставлю на то, что он не понимает более 20 эл-тов в статусе, т.к. использует старое API.

Проверь в isql
...
Рейтинг: 0 / 0
Добавление информации в StatusVector
    #39969913
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvlad
Гм... А что это тут происходит ? Указатели - в числа и разницу адресов вычисляем ?
Ну да. Определяем длину в байтах
hvlad
Ставлю на то, что он не понимает более 20 эл-тов в статусе, т.к. использует старое API.
Блин! Два дня убил.
hvlad
Проверь в isql
Тут все работает.

Как бы грамотно сформулировать баг-репорт на IBExpert
...
Рейтинг: 0 / 0
Добавление информации в StatusVector
    #39969915
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_Как бы грамотно сформулировать баг-репорт на IBExpert

Бесполезно. Даже если кто-то это и посчитает за баг, то точно не в эксперте, а в fbclient,
который кривовато трансформирует новый длинный вектор в старый короткий, разрывая
сообщение посередине.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Добавление информации в StatusVector
    #39969922
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov
то точно не в эксперте, а в fbclient,
А isql работает мимо fbclient?
...
Рейтинг: 0 / 0
Добавление информации в StatusVector
    #39969925
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_А isql работает мимо fbclient?

isql работает мимо ISC_STATUS_ARRAY. Его уже перевели на новое API.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Добавление информации в StatusVector
    #39970143
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov
Его уже перевели на новое API.
Оно реализовано в fbclient?

IBExpert уже пилится под FB4. Имхо, можно задуматься сразу и на переход на новый API.
...
Рейтинг: 0 / 0
Добавление информации в StatusVector
    #39970148
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

Это не так просто как ты думаешь. Из нового API для 4.0 в IBExpert пока только интерфейсы для поддержки новых типов используются
...
Рейтинг: 0 / 0
13 сообщений из 13, страница 1 из 1
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Добавление информации в StatusVector
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]