Navadvipa Chandra das
-
Постов
3 -
Зарегистрирован
-
Посещение
-
Победитель дней
1
Сообщения, опубликованные Navadvipa Chandra das
-
-
Здравствуйте!
Нет, это не сообщение от С++Builder, но ответ от службы техподдержки Embarcadero, что FireDAC не поддерживается в Коммунити Едишн для разных платформ. Вот прислали ссылку возможностей разных версий - https://www.embarcadero.com/docs/rad-studio-feature-matrix.pdf
Но соединение с базой устанавливается, у компонента TFDConnection свойство OidAbLOB == Yes, UnknownFormat == BYTEA, если последнее свойство установить Error, то просто ошибка Invalid pointer operation. А я даже не могу понять где ошибка, может в SQL запросе, может в настройках параметров запроса или еще где.
С уважением, Навадвипа Чандра дас. -
Здравствуйте все!
Потихоньку начал переводит свою библиотеку, написанную для 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
Кто может, помогите!
Спасибо!
С уважением, Навадвипа Чандра дас.
FireDAC, PostgreSQL процедуры и Blob параметры
в Прочие вопросы
Опубликовано
Здравствуйте!
Блоб параметры в процедурах 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;
}
Вопрос закрыт!
Спасибо!
С уважением, Навадвипа Чандра дас.