Delphi: Как избавиться от published свойств
Вводная
Работая над PostgresDAC'ом наша комманда встречалась с этой проблемой дважды. И оба раза изменения затрагивали компонент TPSQLDump, как наиболее интенсивно изменяющийся. Это и понятно, каждый серьезный релиз сервера PostgreSQL вносит порой в параметры pg_dump существенные изменения. А нашей задачей является полная совместимость TPSQLDump с pg_dump.
Дело в том, что информация об опубликованных свойствах храниться в DFM файлах. И просто удалив свойство (или изменив его), при загрузке компонента мы получим сообщение об ошибке. Если таких компонентов много, процесс обещает быть нудным.
Задача
Заменить свойство
TPSQLDump.TableName: string
на свойство TPSQLDump.TableNames: TStrings
. По сути необходимо реализовать возможность дампа нескольких указанных таблиц вместо одной.Решение
Код говорит сам за себя:
TPSQLDump = class(TComponent)
private
...
procedure ReadTableName(Reader: TReader);
protected
procedure DefineProperties(Filer: TFiler); override;
...
published
...
//property TableName: string ...
property TableNames: TStrings read FTableNames
write SetTableNames;
...
end; //TPSQLDump
implementation
...
procedure TPSQLDump.DefineProperties(Filer: TFiler);
begin
inherited;
Filer.DefineProperty('TableName', ReadTableName, nil, False);
end;
procedure TPSQLDump.ReadTableName(Reader: TReader);
var S: string;
begin
S := Reader.ReadString;
if S > '' then FTableNames.Append(S);
end;
Пояснения
Мы определяем (
Filer.DefineProperty
) свойство TableName
в перекрытом методе DefineProperties
. Метод ReadTableName
будет читать значения свойства TableName
. Так как метода для записи мы не присвоили (мы передали nil
вторым параметром), то это свойство никогда не будет сохранено в будущем. Проблема решена.Кстати, таким трюком часто пользуются и разработчики VCL.
PS
Спасибо Алексею Вуколову aka vuk за идею.