powered by simpleCommunicator - 2.0.52     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Написание UDR
25 сообщений из 94, страница 3 из 4
Написание UDR
    #39136544
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Viktor_bs,

у меня в пакетах всё работает. Ты бы хоть ошибку показал. Ах да, если делаешь через IBE то надо бы его обновить.
Его внутренний парсер только недавно научился распознавать UDR.

Viktor_bsREADME.packages.txt нашел следующее:
UDFs (DECLARE EXTERNAL FUNCTION) are currently not supported inside packages.

нет это качается только UDF.
...
Рейтинг: 0 / 0
Написание UDR
    #39136574
Viktor_bs
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов ДенисViktor_bs,

у меня в пакетах всё работает. Ты бы хоть ошибку показал. Ах да, если делаешь через IBE то надо бы его обновить.
Его внутренний парсер только недавно научился распознавать UDR.

Viktor_bsREADME.packages.txt нашел следующее:
UDFs (DECLARE EXTERNAL FUNCTION) are currently not supported inside packages.

нет это качается только UDF.

Да, сори, это был IBE
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Написание UDR
    #39377260
vladimiromsk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем привет!
Не могу из udr вернуть varchar.
Делаю так:

create or alter function test_varchar(
aString varchar(255))
returns varchar(255)
EXTERNAL NAME 'test!test_varchar'
ENGINE UDR




type
TVarCharMessage = record
Length: Word;
Value: array [0..0] of ansichar;
end;
PVarCharMessage = ^TVarCharMessage;

procedure TTestVarCharFunction.execute(aStatus: IStatus; aContext: IExternalContext; aInMsg, aOutMsg: Pointer);
begin
try
if (PVarCharMessage(aInMsg)^.Length = 0) then
begin
PVarCharMessage(aOutMsg)^.Length:= 0;
// PVarCharMessage(aOutMsg)^.Value:= nil;
end
else
begin
PVarCharMessage(aOutMsg)^.Length:= PVarCharMessage(aInMsg)^.Length;
Move(PVarCharMessage(aInMsg)^.Value, PVarCharMessage(aOutMsg)^.Value, PVarCharMessage(aOutMsg)^.Length);
end;
except
on E: Exception do
FbException.catchException(aStatus, E);
end;
end;



Вызываем
select test_varchar('hi test') from rdb$database


Смотрим дамп в Delphi
aInMsg: 0700 6869 2074 6573 74 все верно длина 7, строка hi test
aOutMsg: 0700 6869 2074 6573 74 все верно длина 7, строка hi test


Но результат NULL
Подскажите что не так.
За ранее спасибо
...
Рейтинг: 0 / 0
Написание UDR
    #39377262
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А где у тебя null indicator в выходном буфере?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Написание UDR
    #39377284
vladimiromsk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry Sibiryakov,

Спасибо получилось, по смещению SizeOf(Word) + 255*4(utf8) как раз IsNull индикатор.
Вопрос тогда напрашивается сам как мне узнать длину входной строки, которая объявлена в FB, или только работа идет с заранее известной длиной строки?

Заранее спасибо за ответ
...
Рейтинг: 0 / 0
Написание UDR
    #39377297
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vladimiromskВопрос тогда напрашивается сам как мне узнать длину входной строки, которая объявлена в
FB, или только работа идет с заранее известной длиной строки?

А про это пусть тебе идеолухи "нового API" расскажут: в какое место они спрятали описание
формата буфера.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Написание UDR
    #39377301
vladimiromsk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry Sibiryakov,

Что то, я не понял! В общем нет информации где можно получить максимальную длину входной строки и она должно быть зерлально одинакова как в функции, так и в объявлении FB! Правильно?
...
Рейтинг: 0 / 0
Написание UDR
    #39377306
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vladimiromskПравильно?
Нет, неправильно.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Написание UDR
    #39377307
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vladimiromsk,

получить можно из IMessageMetadata см. метод getLength, а метаданных входного сообщения через metadata.getInputMetadata(status), где metadata: IRoutineMetadata
...
Рейтинг: 0 / 0
Написание UDR
    #39377312
vladimiromsk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Симонов Денис,

Спасибо за ответ!

Получается что это надо проверять на NewItem или Setup. Вопрос где лучше? А будут ли не битые ссылки если я запишу эти "а ля Интерфейсы"(Классы) в поля своего класс, предварительно увеличив у них количество ссылок через AddRef.
...
Рейтинг: 0 / 0
Написание UDR
    #39380950
seertrue
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Коллеги, помогайте теперь мне.
Скачал пример с гита
Скомпилированную Udr.dll я должен положить сюда "C:\Program Files (x86)\Firebird\Firebird_3_0\plugins"?
Положил.
Пытаюсь объявить ф-цию:
Код: sql
1.
2.
3.
4.
5.
6.
create function sum_args (
  n1 integer not null,
  n2 integer not null
) returns integer
external name 'Udr!sum_args'
engine udr;



В ответ (после подтверждения транзакции) получаю:
Код: plaintext
1.
Unsuccessful execution caused by system error that does not preclude successful execution of subsequent statements.
Module not found.

т.е. udr.dll он не видит, отлуп в при поиске модуля, а не ф-ции в нем?
Где я ошибаюсь?

Прошу канделябром не бить, я еще новичек, официальной информации ноль.

пысы: Win 7*64, firebird3*32, Delphi XE7, IBExpert
...
Рейтинг: 0 / 0
Написание UDR
    #39380955
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
seertrue,

а конфигурировать кто будет?

в udr_engine.conf что написано?
...
Рейтинг: 0 / 0
Написание UDR
    #39381153
seertrue
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Симонов Денисseertrue,
а конфигурировать кто будет?


Вот об этом где на писано? Хоть комментов бы написали, я же заглядывал в этот файл.

Симонов Денисв udr_engine.conf что написано?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
external_engine = UDR {
	plugin_module = UDR_engine
}

plugin_module = UDR_engine {
	filename = $(this)/udr_engine
	plugin_config = UDR_config
}

plugin_config = UDR_config {
	path = $(this)/udr
}
...
Рейтинг: 0 / 0
Написание UDR
    #39381159
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Написание UDR
    #39381195
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
seertrue,

конфигурация говорит о том что ваша dll должна быть расположена в папке (fbroot)/plugins/udr

Впрочем hvlad дал описание.
...
Рейтинг: 0 / 0
Написание UDR
    #39382024
seertrue
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Симонов Денисseertrue,

конфигурация говорит о том что ваша dll должна быть расположена в папке (fbroot)/plugins/udr

Впрочем hvlad дал описание.

Все работает, спасибо, ребята!

Разбираюсь дальше, мне нравится продуманность структуры!!!
Если бы было все документировано...
...
Рейтинг: 0 / 0
Написание UDR
    #39383130
seertrue
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
С целыми и другими числами все ок.
А как строки?

Допустим из того же примера объявляю:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
create or alter procedure GEN_ROWS (
    START_N integer,
    END_N integer)
returns (
    RESULT integer,
    BINRES double precision,
    STR varchar(200))
EXTERNAL NAME 'udr!gen_rows'
ENGINE UDR;

в delphi:
...
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
  TGenRowsOutMessage = record
    result: Integer;
    resultNull: WordBool;
    binRes: Double;
    binResNull: WordBool;
    str: PAnsiChar;
    strNull: WordBool;
  end;


...

Код: pascal
1.
2.
3.
function TGenRowsResultSet.fetch(status: status): Boolean;
var str: string;
begin


...
Код: pascal
1.
2.
3.
4.
5.
      outMessage.strNull:=False;
      str:='Строка № '+FloatToStr(outMessage.result);

      outMessage.str:=malloc(Length(str) + 1);
      StrPCopy(outMessage.str, str);



в запросе:

Код: plaintext
1.
2.
select t.result, t.binres, t.str
from gen_rows(1, 50) t

в str получаю NULL

Что не так?
...
Рейтинг: 0 / 0
Написание UDR
    #39383136
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а там точно maloc должен быть, а не что-то иное?
я не разбирался в UDR, но для UDF это не так.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Написание UDR
    #39383150
__Avenger__
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Посмотри пример тут
...
Рейтинг: 0 / 0
Написание UDR
    #39383166
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
seertrue,

потому что формат для строки у тебя не правильный. Где длина строки?
...
Рейтинг: 0 / 0
Написание UDR
    #39383181
seertrue
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Мимопроходящийа там точно maloc должен быть, а не что-то иное?
я не разбирался в UDR, но для UDF это не так.


outMessage.str:=ib_util_malloc(Length(str) + 1);

это тоже не помогло
...
Рейтинг: 0 / 0
Написание UDR
    #39383185
seertrue
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
__Avenger__Посмотри пример тут

во, спасибо, то что надо
...
Рейтинг: 0 / 0
Написание UDR
    #39384232
seertrue
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Симонов Денисseertrue,

потому что формат для строки у тебя не правильный. Где длина строки?

Вроде все сделал по примеру, ниже код.

Код: 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.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
unit UdrStrings;

interface

uses
  System.SysUtils, FbApi;

type
  PTestStrInMessage = ^TTestStrInMessage;

  TTestStrInMessage = record
    StrLen: Word;
    Str: array [0 .. 4 * 255 - 1] of AnsiChar;
    StrNull: WordBool;
  end;

  PTestStrOutMessage = ^TTestStrOutMessage;

  TTestStrOutMessage = record
    StrLen: Word;
    Str: array [0 .. 4 * 255 - 1] of AnsiChar;
    StrNull: WordBool;
  end;

  TTestStrFunction = class(ExternalFunctionImpl)
    procedure dispose(); override;
    procedure getCharSet(status: status; context: ExternalContext;
      name: PAnsiChar; nameSize: Cardinal); override;
    procedure execute(status: status; context: ExternalContext; inMsg: Pointer;
      outMsg: Pointer); override;
  end;

  TTestStrFactory = class(UdrFunctionFactoryImpl)
    procedure dispose(); override;
    procedure setup(status: status; context: ExternalContext;
      metadata: RoutineMetadata; inBuilder: MetadataBuilder;
      outBuilder: MetadataBuilder); override;
    function newItem(status: status; context: ExternalContext;
      metadata: RoutineMetadata): ExternalFunction; override;
  end;

implementation

uses
  System.AnsiStrings;

{ TTestStrFunction }

procedure TTestStrFunction.dispose();
begin
  destroy;
end;

procedure TTestStrFunction.getCharSet(status: status; context: ExternalContext;
  name: PAnsiChar; nameSize: Cardinal);
begin
end;

procedure TTestStrFunction.execute(status: status; context: ExternalContext;
  inMsg: Pointer; outMsg: Pointer);
var
  AInMsg: PTestStrInMessage;
  AOutMsg: PTestStrOutMessage;
  AStr: UTF8String;
begin
  try
    AInMsg := PTestStrInMessage(inMsg);
    AOutMsg := PTestStrOutMessage(outMsg);
    if AInMsg.StrNull then begin
      with AOutMsg^ do begin
        StrLen := 0;
        StrNull := StrLen = 0;
      end;
    end
    else begin
      AStr := UTF8Encode(System.AnsiStrings.AnsiReverseString(UTF8ToString(AInMsg.Str)));
      with AOutMsg^ do begin
        StrLen := Length(AStr);
        StrNull := StrLen = 0;
        if StrLen > 0 then
          Move(PAnsiChar(AStr)^, Str[0], StrLen * SizeOf(AnsiChar));
      end;
    end;
  except
    on E: Exception do
      FbException.catchException(status, E);
  end;
end;

{ TTestStrFactory }

procedure TTestStrFactory.dispose();
begin
  destroy;
end;

procedure TTestStrFactory.setup(status: status; context: ExternalContext;
  metadata: RoutineMetadata; inBuilder: MetadataBuilder;
  outBuilder: MetadataBuilder);
begin
end;

function TTestStrFactory.newItem(status: status; context: ExternalContext;
  metadata: RoutineMetadata): ExternalFunction;
begin
  Result := TTestStrFunction.create;
end;

end.




функция подключается,
Код: plaintext
1.
2.
3.
4.
create function test_str (
    n1 varchar(200)
  ) returns varchar(200)
  external name 'udr!test_str'
  engine udr;
запрос
Код: plaintext
1.
2.
select test_str('12345')
from rdb$database

отладчик показывает что все поля заполняются правильно:
AInMsg.Str = '12345'
AOutMsg.Str = '54321'
StrLen = 5 в обоих случаях

но в IBExpert упорно NULL.

Коллеги, помогайте.
...
Рейтинг: 0 / 0
Написание UDR
    #39384238
__Avenger__
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А так:
Код: sql
1.
2.
3.
4.
5.
create function test_str (
    n1 varchar(255) CHARACTER SET UTF8
  ) returns varchar(255) CHARACTER SET UTF8
  external name 'udr!test_str'
  engine udr;



?
...
Рейтинг: 0 / 0
Написание UDR
    #39384240
__Avenger__
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот этот код, вас не на какие мысли не наводит?

Код: sql
1.
array [0 .. 4 * 255 - 1] of AnsiChar;
...
Рейтинг: 0 / 0
25 сообщений из 94, страница 3 из 4
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Написание UDR
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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