TDataModule, IBX и консольное приложение

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

TDataModule, IBX и консольное приложение

Сообщение slyubez » 30.03.2022 09:46:37

Привет всем.

Встала задача написания телеграм-бота для передачи в телеграм данных из БД Firebird; при этом программа должна работать на линуксовом сервере без графики. По понятным причинам я выбрал Lazarus, который хорошо дружит с Firebird через компоненты IBX (использую модификацию от Rik). Оптимальный вариант - это написание демона, но это я пока не осилил, поэтому хочу для начала сделать консольное приложение.

Однако добавление TDataModule в консольное приложение - это не так просто, как в LCL. Где бы почитать, как это делать правильно? Я перепробовал разные варианты, в том числе ручное создание компонентов, и всегда получаю при попытке соединения с БД непонятную ошибку: Failed to create win32 control, error: 1407 : Не удается найти класс окна. Как это получается - не пойму.

Добавлено спустя 7 минут 54 секунды:
Забыл написать, что пока пишу под виндой, чтобы отработать процесс. Потом буду открывать в линуксовом Лазаре.

Добавлено спустя 25 минут 46 секунд:
Немного деталей, как пытаюсь делать сейчас.
Основной код
Код: Выделить всё
program docbotapp;

{$mode objfpc}{$H+}

uses
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads,
  {$ENDIF}{$ENDIF}
  Classes, Interfaces, SysUtils, ibexpress, CustApp, dbunit
  { you can add units after this };

type

  { DocBot }

  DocBot = class(TCustomApplication)
  protected
    procedure DoRun; override;
  public
    constructor Create(TheOwner: TComponent); override;
    destructor Destroy; override;
  end;

{ DocBot }

procedure DocBot.DoRun;
begin 
  if DM.Start then
   { add your program here }
   while not Terminated do DM.Loop;
  // stop program loop
  Terminate;
end;

constructor DocBot.Create(TheOwner: TComponent);
begin
  inherited Create(TheOwner);
  DM:=TDM.Create(TheOwner);
end;

destructor DocBot.Destroy;
begin
  DM.Free;
  inherited Destroy;
end;

var
  Application: DocBot;
begin
  Application:=DocBot.Create(nil);
  Application.Title:='Bot Application';
  Application.Run;
  Application.Free;
end.   


Модуль данных:
Код: Выделить всё
unit dbunit;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, IBDatabase, IBSQL, tgsendertypes, tgtypes,
  tgfclhttpclientbroker;

type

  { TDM }

  TDM = class(TDataModule)
    DB: TIBDatabase;
    Qry: TIBSQL;
    ReadTransaction: TIBTransaction;
    procedure DataModuleCreate(Sender: TObject);
    procedure DataModuleDestroy(Sender: TObject);
    procedure BotReceiveMessage(ASender: TObject; AMessage: TTelegramMessageObj);   
  private
    FBot: TTelegramSender;
  public
    function Start: Boolean;
    procedure Loop;
  end;

const
  BOTTOKEN = 'MyToken';
  ERRORMESSAGE = 'Ошибка: неверный запрос или нет соединения с базой данных.';

var
  DM: TDM;

implementation

{$R *.lfm}

{ TDM }

procedure TDM.DataModuleCreate(Sender: TObject);
begin
DB:=TIBDatabase.Create(Self);
with DB
  do begin
      Connected:=False;
      AllowStreamedConnected:=False;
      DatabaseName:='localhost:E:\DB\MyDB.fdb';
      {$IFDEF WINDOWS}
       DB.LibraryName:='fbclient.dll';
      {$ELSE}
       DB.LibraryName:='libfbclient.so.2.5.9';
      {$ENDIF}
      Params.Text:='user_name=SYSDBA'+sLineBreak
                  +'password=masterke'+sLineBreak
                //+'role='+DBConfig.role+sLineBreak
                  +'lc_ctype=UTF8'+sLineBreak;
      DefaultTransaction:=Nil;
      DefaultUpdTransaction:=Nil;
      IdleTimer:=0;
      TraceFlags:=[];
      //Left:=49;
      //Top:=30;
     end;
ReadTransaction:=TIBTransaction.Create(Self);
with ReadTransaction
  do begin
      Active:=False;
      DefaultDatabase:=DB;
      Params.Text:='read'+sLineBreak+'read_committed'+sLineBreak
                 +'rec_version';
      //Left:=136;
      //Top:=30;
     end;
DB.DefaultTransaction:=ReadTransaction;
DB.DefaultUpdTransaction:=ReadTransaction;
Qry:=TIBSQL.Create(Self);
with Qry
  do begin
       Database:=DB;
       ParamCheck:=True;
       Transaction:=ReadTransaction;
       SelectOnBlock:=False;
       //Left:=216;
       //Top:=32;
     end;
FBot:=TTelegramSender.Create (BOTTOKEN);
FBot.OnReceiveMessage:=@BotReceiveMessage;
end;

function TDM.Start: Boolean;
begin
Result:=True;
try
  DB.Connected:=True; //на этой строке вылетает приведенная ошибка
  ReadTransaction.StartTransaction;
except
  on E: Exception
   do begin
       with TStringList.Create
        do try
            Add (E.Message);
            SaveToFile ('error.log');
           finally
            Free;
           end;
       writeln (E.Message);
       Result:=False;
       Exit;
      end;
end;
if not FBot.getMe then Result:=False;
end;

procedure TDM.Loop;
begin
FBot.getUpdatesEx(0, 10);
end;

procedure TDM.BotReceiveMessage(ASender: TObject; AMessage: TTelegramMessageObj);
var
AChatID: Int64;
SendingMessage, RcvMessage: String;
label SendStr;
begin
RcvMessage:=AMessage.Text;
AChatID:=AMessage.Chat.ID;
if (Length(RcvMessage)>50) or (Length(RcvMessage)=0)
  then begin
        SendingMessage:=ERRORMESSAGE;
        goto SendStr;
       end;
//...
SendingMessage:='Ответ: '+RcvMessage;
SendStr:
FBot.sendMessage(AChatID, SendingMessage);
end;

procedure TDM.DataModuleDestroy(Sender: TObject);
begin
DB.Connected:=False;
FBot.Free;
end;

end.
slyubez
постоялец
 
Сообщения: 173
Зарегистрирован: 31.03.2015 08:44:07

Re: TDataModule, IBX и консольное приложение

Сообщение Alex2013 » 30.03.2022 19:25:27

Знаю для линукса это вроде не обязательно но на всякий пожарный попробуй добавить {$APPTYPE CONSOLE} . :idea:
Alex2013
долгожитель
 
Сообщения: 2923
Зарегистрирован: 03.04.2013 11:59:44

Re: TDataModule, IBX и консольное приложение

Сообщение slyubez » 30.03.2022 19:28:10

Добрался до линуксового лазаря. Запускаю проект в нем. При вызове DB.Connected:=True... вдруг появляется окно входа в базу. Отключил свойство LoginPrompt - соединение прошло, первичный запрос идет правильно, ожидаемый результат возвращается в телеграм-бот. Можно дописывать дальше.

Добавлено спустя 1 минуту 27 секунд:
Знаю для линукса это вроде не обязательно но на всякий пожарный попробуй добавить {$APPTYPE CONSOLE} .

Лазарь при создании консольных приложений не предлагает это в своих дефолтных шаблонах для консольных приложений. Скорее всего, это не требуется.
slyubez
постоялец
 
Сообщения: 173
Зарегистрирован: 31.03.2015 08:44:07

Re: TDataModule, IBX и консольное приложение

Сообщение ogorodov » 31.03.2022 09:57:42

В файле IBDef.inc есть отключение LCL.

Добавлено спустя 1 минуту 18 секунд:
Для консоли должно выглядеть вот так
{$IFDEF LCL}
//{$DEFINE LCLSUPPORT}
{$ENDIF}
ogorodov
новенький
 
Сообщения: 37
Зарегистрирован: 22.10.2009 11:32:07

Re: TDataModule, IBX и консольное приложение

Сообщение slyubez » 31.03.2022 15:46:08

В файле IBDef.inc есть отключение LCL.

За это отдельное спасибо. Буду сейчас пробовать.

Добавлено спустя 2 часа 12 минут 30 секунд:
Никак не получается. Когда комментирую вышеприведенную строчку, среда не пересобирается - ругается на отсутствие файла диалога. Переписал проект в виде демона - все равно без LCL собираться не хочет, несмотря на убранные зависимости в проекте.

Добавлено спустя 38 минут 10 секунд:
Удалил пакет dclibx, оставив ibx. Среда пересобралась, но проект не собирается - требует модулей из LCL.

Добавлено спустя 9 минут 58 секунд:
Что-то не то с линковкой. Идут ошибки наподобие
linker: /usr/bin/ld: /usr/share/lazarus/2.0.12/lcl/units/x86_64-linux/wsdialogs.o: в функции «REGISTERCOLORBUTTON»:
/home/mattias/tmp/lazarus-project2.0.12/lazarus-project_build/usr/share/lazarus/2.0.12/lcl//widgetset/wsdialogs.pp:264: неопределённая ссылка на «WSRegisterColorButton»


Добавлено спустя 57 минут:
Подправил несколько файлов в сорцах IBX.
IBDatabase.pas: в uses переместил модуль Dialogs под IFDEF LCLSUPPORT. То же самое - в еще каком-то DesignTime-модуле. Убрал LCL из зависимостей пакета ibexpress, добавил в зависимости LazUtils.

Добавлено спустя 1 минуту 23 секунды:
Пакет собрался. Попробую испытать демон на сервере.

Добавлено спустя 1 час 11 минут 19 секунд:
Демон не заводится... Создам-ка по этому вопросу отдельную тему.
slyubez
постоялец
 
Сообщения: 173
Зарегистрирован: 31.03.2015 08:44:07


Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 35

Рейтинг@Mail.ru