Перейти к содержанию
Fire Monkey от А до Я

Navadvipa Chandra das

Пользователи
  • Постов

    3
  • Зарегистрирован

  • Посещение

  • Победитель дней

    1

Сообщения, опубликованные Navadvipa Chandra das

  1. Здравствуйте!
    Блоб параметры в процедурах PostgreSQL победить не удалось, а вот та же функциональность через Блоб-поля TFDQuery была достигнута. В целом такой вариант более универсален.

    void __fastcall TNNConfig::SaveToDB()
    {
      if ( Connection && !Connection->Connected )
        return;

      TMemoryStream* ms = new TMemoryStream();
      fFiler = new TNNTextStream( ms );

      try {
        SaveFilerFromUserEvent();

        std::unique_ptr< TFDQuery > quReg( new TFDQuery( this ) );
        std::unique_ptr< TFDTransaction > trReg( new TFDTransaction( this ) );

        quReg->Connection  = Connection;
        trReg->Connection  = Connection;
        quReg->Transaction = trReg.get();

        String RK = RegistryKey();
        Connection->StartTransaction();
        try {
          quReg->SQL->Text = "SELECT \"UserRegKey\", \"UserData\" FROM \"UserReg\" where \"UserRegKey\" = :UserRegKey_";
          quReg->Params->Items[ 0 ]->DataType   = ftString;
          quReg->Params->Items[ 0 ]->AsString   = RK;
          quReg->Open();

          if ( quReg->RecordCount == 0 ) {
            quReg->Insert();
            quReg->Fields->Fields[ 0 ]->AsString = RK;
          } else
            quReg->Edit();

          TBlobField *bf = ((TBlobField *)(quReg->Fields->Fields[ 1 ]));
          bf->LoadFromStream( Filer );

          quReg->Post();
          Connection->Commit();
        } catch ( ... ) {
          Connection->Rollback();
        }
      } __finally {
        delete fFiler;
        fFiler = nullptr;
      }
    }

    bool __fastcall TNNConfig::LoadFromDB()
    {
      if ( Connection && !Connection->Connected )
        return false;

      bool B = false;

      std::unique_ptr< TFDQuery > quReg( new TFDQuery( this ) );
      std::unique_ptr< TFDTransaction > trReg( new TFDTransaction( this ) );

      quReg->Connection  = Connection;
      trReg->Connection  = Connection;
      quReg->Transaction = trReg.get();

      quReg->SQL->Text = "SELECT \"UserRegKey\", \"UserData\" FROM \"UserReg\" where \"UserRegKey\" = :UserRegKey_";
      quReg->Params->Items[ 0 ]->DataType   = ftString;
      quReg->Params->Items[ 0 ]->AsString   = RegistryKey();
      quReg->Open();

      if ( quReg->RecordCount == 1 ) {
        TBlobField *bf = ((TBlobField *)(quReg->Fields->Fields[ 1 ]));
        bf->SaveToStream( Filer );
        B = true;
      }

      return B;
    }
     

    Вопрос закрыт!
    Спасибо!
    С уважением, Навадвипа Чандра дас.

  2. Здравствуйте!
    Нет, это не сообщение от С++Builder, но ответ от службы техподдержки Embarcadero, что FireDAC не поддерживается в Коммунити Едишн для разных платформ. Вот прислали ссылку возможностей разных версий - https://www.embarcadero.com/docs/rad-studio-feature-matrix.pdf
    Но соединение с базой устанавливается, у компонента TFDConnection свойство OidAbLOB == Yes, UnknownFormat == BYTEA, если последнее свойство установить Error, то просто ошибка Invalid pointer operation. А я даже не могу понять где ошибка, может в SQL запросе, может в настройках параметров запроса или еще где.
    С уважением, Навадвипа Чандра дас.

  3. Здравствуйте все!
    Потихоньку начал переводит свою библиотеку, написанную для C++Builder 6 на новые рельсы C++Builder 10.3.3.
    Компонент сохранения настроек TNNConfig работает с бинарным форматом и уже отлажен для сохранения и чтения настроек в файл:
    TNNConfig->StoreKind = skFile; А вот если свойство StoreKind установить в значение skDB, то не получается сохранение в базе данных. База данных  PostgreSQL  13. Таблица сохранения настроек выглядит так:
    -- Table: public.UserReg

    -- DROP TABLE public."UserReg";

    CREATE TABLE public."UserReg"
    (
        "UserRegKey" character varying(720) COLLATE pg_catalog."default" NOT NULL,
        "UserData" bytea
    )

    TABLESPACE pg_default;

    ALTER TABLE public."UserReg"
        OWNER to "Navadvipa_Chandra_das";

    COMMENT ON TABLE public."UserReg"
        IS 'Таблица, содержащая настройки пользователей в бинарном виде!';

    COMMENT ON COLUMN public."UserReg"."UserRegKey"
        IS 'Поле - первичный ключ для настройки!';

    COMMENT ON COLUMN public."UserReg"."UserData"
        IS 'Поле - настройки пользователей в бинарном виде!';

    -- PROCEDURE: public.SelectUserReg(character varying, bytea)

    -- DROP PROCEDURE public."SelectUserReg"(character varying, bytea);

    CREATE OR REPLACE PROCEDURE public."SelectUserReg"(
        "UserRegKey_" character varying,
        INOUT "UserData_" bytea)
    LANGUAGE 'plpgsql'
    AS $BODY$
    begin
      select a."UserData" into "UserData_" from "UserReg" a
      where a."UserRegKey" = "UserRegKey_";
      --if not found then
      --  "UserData_" := Null;
      --end if;
    end;
    $BODY$;

    -- PROCEDURE: public.UpdateUserReg(character varying, bytea)

    -- DROP PROCEDURE public."UpdateUserReg"(character varying, bytea);

    CREATE OR REPLACE PROCEDURE public."UpdateUserReg"(
        "UserRegKey_" character varying,
        INOUT "UserData_" bytea)
    LANGUAGE 'plpgsql'
    AS $BODY$
    begin
      update "UserReg" a set a."UserData" = "UserData_"
      where a."UserRegKey" = "UserRegKey_";
      if not found then
        insert into "UserReg" ( "UserRegKey", "UserData" ) values ( "UserRegKey_", "UserData_" );
      end if;
    end;
    $BODY$;

    COMMENT ON PROCEDURE public."UpdateUserReg"(character varying, bytea)
        IS 'Запись настроек пользователя';
     


    Клиент PosgreSQL - 32 бит ODBC. 64 бит FireDAC недоступен для Community Edition.

    Методы LoadFromDB и SaveToDB я приведу ниже, но они нерабочие и не понятно где копать, так как документация по этому вопросу крайне скудна.

    bool __fastcall TNNConfig::LoadFromDB()
    {
      if ( Connection && !Connection->Connected )
        return false;

      bool B = false;

      std::unique_ptr< TFDQuery > quReg( new TFDQuery( this ) );
      std::unique_ptr< TFDTransaction > trReg( new TFDTransaction( this ) );

      quReg->Connection  = Connection;
      trReg->Connection  = Connection;
      quReg->Transaction = trReg.get();

      Connection->StartTransaction();
      try {
        quReg->SQL->Text =
          "begin\n"
          "  \"SelectUserReg\"( :key_, :lob_ );\n"
          "end;";
        quReg->Params->Items[ 0 ]->DataType = ftString;
        quReg->Params->Items[ 0 ]->AsString = RegistryKey();
        quReg->Params->Items[ 1 ]->DataType = ftStream;
        quReg->Params->Items[ 1 ]->AsStream = Filer;

        //quReg->Params->Items[ 0 ]->DataType   = ftStream;
        //quReg->Params->Items[ 0 ]->FDDataType = dtBlob;
        quReg->Params->Items[ 1 ]->ParamType  = ptOutput;
        quReg->Params->Items[ 1 ]->StreamMode = smOpenRead;

        quReg->ExecSQL();

        TStream *LOB = quReg->Params->Items[ 0 ]->AsStream;

        if ( LOB && LOB->Size > 0 ) {
          ((TMemoryStream*)Filer->Stream)->Size = LOB->Size;
          LOB->Read( ((TMemoryStream*)(Filer->Stream))->Memory, Filer->Stream->Size );
        }

        Connection->Commit();
        B = true;
      } catch ( ... ) {
        Connection->Rollback();
      }
      return B;
    }

    Вот тестовое приложение - https://github.com/Navadvipa-Chandra-das/TestFMX
    Вот библиотека Нижняя Навадвипа - https://github.com/Navadvipa-Chandra-das/NizhnyayaNavadvipa

    Кто может, помогите!
    Спасибо!

    С уважением, Навадвипа Чандра дас.

×
×
  • Создать...