Гость
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Добавление информации в StatusVector / 13 сообщений из 13, страница 1 из 1
15.06.2020, 19:52
    #39969509
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Добавление информации в StatusVector
Хочу расширить информацию в 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
15.06.2020, 20:27
    #39969514
hvlad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Добавление информации в StatusVector
_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
15.06.2020, 20:46
    #39969518
hvlad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Добавление информации в StatusVector
Все 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
15.06.2020, 22:06
    #39969534
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Добавление информации в StatusVector
Эх, а ведь просил я IStatus::append()...
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
16.06.2020, 16:36
    #39969831
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Добавление информации в StatusVector
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
16.06.2020, 17:21
    #39969850
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Добавление информации в StatusVector
Знаю, что варварство, но сделал так
Код: 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
16.06.2020, 18:30
    #39969897
hvlad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Добавление информации в StatusVector
_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
16.06.2020, 19:05
    #39969913
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Добавление информации в StatusVector
hvlad
Гм... А что это тут происходит ? Указатели - в числа и разницу адресов вычисляем ?
Ну да. Определяем длину в байтах
hvlad
Ставлю на то, что он не понимает более 20 эл-тов в статусе, т.к. использует старое API.
Блин! Два дня убил.
hvlad
Проверь в isql
Тут все работает.

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

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

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

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

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


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