Настройки программы в базе данных
От: silentroach Россия  
Дата: 28.07.07 14:41
Оценка:
День добрый.

Есть приложение, есть база данных. Приложение используют несколько пользователей с разных компьютеров.
На каждом компьютере есть мелкий файлик с настройкой подключения, а остальные настройки программы я бы очень хотел хранить в базе данных.
Может, кто-нибудь подскажет красивое решение для хранения определенной структуры в БД ? Учитывая то, что структура может и поменяться.

Буду благодарен любым ответам.
Re: Настройки программы в базе данных
От: Rius Россия  
Дата: 28.07.07 15:16
Оценка:
попробуйте хранить xml-документ с настройками в текстовом поле неопределённой длины
Re[2]: Настройки программы в базе данных
От: silentroach Россия  
Дата: 28.07.07 15:19
Оценка:
Здравствуйте, Rius, Вы писали:

R>попробуйте хранить xml-документ с настройками в текстовом поле неопределённой длины


А потом при добавлении какого-то свойства дописывать парсер?
Сам, если честно, остановился имеено на этом способе, но надеюсь на существование более красивого решения.
Re[3]: Настройки программы в базе данных
От: Rius Россия  
Дата: 28.07.07 15:49
Оценка:
Здравствуйте, silentroach, Вы писали:

S>Здравствуйте, Rius, Вы писали:


R>>попробуйте хранить xml-документ с настройками в текстовом поле неопределённой длины


S>А потом при добавлении какого-то свойства дописывать парсер?

ага, только чтобы парсер при отсутсвии параметра в xml инициализировал соответствующую настройку по умолчанию...
Re[4]: Настройки программы в базе данных
От: silentroach Россия  
Дата: 28.07.07 16:04
Оценка:
Здравствуйте, Rius, Вы писали:

R>ага, только чтобы парсер при отсутсвии параметра в xml инициализировал соответствующую настройку по умолчанию...

ну вот это как раз мне и кажется не очень удобным
Re: Настройки программы в базе данных
От: __Azeroth Россия  
Дата: 29.07.07 10:53
Оценка:
Вы, наверно издеваетесь — любая бд предназначена для хранения структурированой инф-ии, и мне странно видеть предложения хранить в бд структуру типа xml
вполне удобно хранить настройки в таблице со структурой вида "имя-значение",
уже не говоря о том, что можно сделать таблицу _нужной_ структуры.
Re[2]: Настройки программы в базе данных
От: Rius Россия  
Дата: 29.07.07 12:01
Оценка:
Здравствуйте, __Azeroth, Вы писали:

__A>Вы, наверно издеваетесь — любая бд предназначена для хранения структурированой инф-ии, и мне странно видеть предложения хранить в бд структуру типа xml

__A>вполне удобно хранить настройки в таблице со структурой вида "имя-значение",
__A>уже не говоря о том, что можно сделать таблицу _нужной_ структуры.
замечательно! а если в "настройки" входит список значений или N-мерный массив, что тогда? ограничивать программу возможностями БД?
Re[2]: Настройки программы в базе данных
От: silentroach Россия  
Дата: 29.07.07 14:30
Оценка:
Здравствуйте, __Azeroth, Вы писали:

__A>Вы, наверно издеваетесь — любая бд предназначена для хранения структурированой инф-ии, и мне странно видеть предложения хранить в бд структуру типа xml

__A>вполне удобно хранить настройки в таблице со структурой вида "имя-значение",
__A>уже не говоря о том, что можно сделать таблицу _нужной_ структуры.

ну, честно говоря, это уже второй вопрос. главное то, как их получить, имена и параметры.
чтобы и с самими данными можно было удобно работать и обновлять эту структуру было возможно без изменения кода для обновления данных в БД.

например, есть у меня какой-нить класс конфигурации

type 
  TConfig = class
  private
    FColor: TColor;
  public
    property Color: TColor read FColor write FColor default $000000;
  end;


могу я как-нить в рантайме пробежаться по свойствам экземпляра этого класса без ручного указания свойств?
а потом взять значения откуда-то и расставить все по своим местам?

а если значения нет, то бралось бы дефолтное.

т.е. мне нужно что-то наподобие TWriter'а и TReader'а что-ли, я даже и не знаю. только таких, чтобы могли записывать все это и считывать из базы.

что-то я не задумывался над этим, погляжу как они работают пойду =)
Re[3]: Настройки программы в базе данных
От: silentroach Россия  
Дата: 29.07.07 14:31
Оценка:
чорт, извините, похоже, я там уже разобрался =)
Re[4]: Настройки программы в базе данных
От: silentroach Россия  
Дата: 29.07.07 23:51
Оценка:
Если кому будет интересно, вот пример, который у меня получился.

unit tlConfig;

interface

uses
  Classes, RClientDataSet, TypInfo, ADODB;

type
  TString128 = string[128];

  {$M+}  
  TConfig = class(TPersistent)
  private
    cdsConfig: TRClientDataSet;

    FCompanyName: TString128;
  protected
    procedure WriteProperty(PropInfo: PPropInfo);
    procedure GetProperty(PropInfo: PPropInfo);
  public
    constructor Create(const AConnection: TADOConnection);
    destructor Destroy; override;

    procedure LoadConfig;
    procedure SaveConfig;
  published
    property CompanyName: TString128 read FCompanyName write FCompanyName;  
  end;
  {$M-}

var
  Config: TConfig;

implementation

uses
  SysUtils;

{ TConfig }

constructor TConfig.Create(const AConnection: TADOConnection);
begin
  cdsConfig := TRClientDataSet.Create(nil);
  cdsConfig.StoredProc.ProcedureName := 'up_LoadConfig';
  cdsConfig.StoredProc.Parameters.Clear;
  cdsConfig.TableName := 'config';
  cdsConfig.Connection := AConnection;
  cdsConfig.KeyField := 'param';
end;

destructor TConfig.Destroy;
begin
  if Assigned(cdsConfig) then
    cdsConfig.Free;

  inherited;
end;

procedure TConfig.GetProperty(PropInfo: PPropInfo);
var
  Value: string;
begin
  Value := '';

  if cdsConfig.Locate('param', PropInfo^.Name, []) then
  begin
    Value := cdsConfig.FieldByName('value').AsString;

    if Value <> '' then
      SetPropValue(Self, PropInfo, Value);
  end;
end;

procedure TConfig.LoadConfig;
var
  i, Count: integer;
  bChanged, bFinded: boolean;
  PropInfo: PPropInfo;
  PropList: PPropList;
begin
  cdsConfig.Open;
  try
    Count := GetTypeData(ClassInfo)^.PropCount;

    if Count > 0 then
    begin
      GetMem(PropList, Count * SizeOf(Pointer));
      try
        GetPropInfos(Config.ClassInfo, PropList);

        for i := 0 to Count - 1 do
        begin
          PropInfo := PropList^[i];
          if PropInfo = nil then
            break;

          GetProperty(PropInfo);
        end;
      finally
        FreeMem(PropList, Count * SizeOf(Pointer));
      end;
    end;

    // проверяем на несуществующие свойства в базе
    bChanged := false;
    cdsConfig.First;
    while not cdsConfig.EOF do
    begin
      bFinded := false;

      for i := 0 to Count - 1 do
        if PropList^[i].Name = cdsConfig.FieldByName('param').AsString then
        begin
          bFinded := true;
          break;
        end;

      if not bFinded then
      begin
        cdsConfig.Delete;
        bChanged := true;
      end;

      cdsConfig.Next;
    end;

    if bChanged then
      cdsConfig.ApplyUpdates(0);
    // ---
  finally
    cdsConfig.Active := false;
  end;  
end;

procedure TConfig.SaveConfig;
var
  i, Count: integer;
  PropInfo: PPropInfo;
  PropList: PPropList;
begin
  cdsConfig.Open;
  try
    Count := GetTypeData(ClassInfo)^.PropCount;

    if Count > 0 then
    begin
      GetMem(PropList, Count * SizeOf(Pointer));
      try
        GetPropInfos(Config.ClassInfo, PropList);

        for i := 0 to Count - 1 do
        begin
          PropInfo := PropList^[i];
          if PropInfo = nil then
            Break;

          WriteProperty(PropInfo);
        end;
      finally
        FreeMem(PropList, Count * SizeOf(Pointer));
      end;
    end;
  finally
    cdsConfig.Close;
  end;
end;

procedure TConfig.WriteProperty(PropInfo: PPropInfo);
var
  Value: string;
  bChanged: boolean;
begin
  Value := '';
  bChanged := false;

  case PropInfo^.PropType^.Kind of
    tkInteger, tkChar, tkWChar, tkEnumeration, tkSet:
      Value := IntToStr(GetOrdProp(Self, PropInfo));
    tkFloat:
      Value := FloatToStr(GetFloatProp(Self, PropInfo));
    tkString, tkLString, tkWString:
      Value := GetWideStrProp(Self, PropInfo);
  end;

  if cdsConfig.Locate('param', PropInfo^.Name, []) then
  begin
    if cdsConfig.FieldByName('value').AsString <> Value then
    begin
      if Value = '' then
        cdsConfig.Delete
      else
      begin
        cdsConfig.Edit;
        try
          cdsConfig.FieldByName('value').AsString := Value;
        finally
          cdsConfig.Post;
        end;
      end;

      bChanged := true;
    end;
  end else
  begin
    if Value <> '' then
    begin
      cdsConfig.Append;
      try
        cdsConfig.FieldByName('param').AsString := PropInfo^.Name;
        cdsConfig.FieldByName('value').AsString := Value;
      finally
        cdsConfig.Post;
      end;

      bChanged := true;
    end;
  end;

  if bChanged then
    cdsConfig.ApplyUpdates(0);
end;

end.
Re[5]: Настройки программы в базе данных
От: svd71 http://visualdesigner.fatal.ru/
Дата: 31.07.07 13:32
Оценка:
Здравствуйте, silentroach, Вы писали:

посмотри на функции BinaryToObject и ObjectToBinary. Они создают DFM структуру объекта в текстовом виде и соотвественно парсят ее теми же методами, которые очень трудно выкинуть из использования даже при всем желании. Зачем создавать велосипед еще раз и дублировать то, что разработчики вложили изначально. Кроме того, один блок теста намного проще и быстрее прочитать из BLOB, чем собирать кучу значений из таблиц, с последующей модификацией отдельного свойства (как советовали отдельные товарисчи).
Re[6]: Настройки программы в базе данных
От: silentroach Россия  
Дата: 31.07.07 22:26
Оценка:
Здравствуйте, svd71, Вы писали:

S>посмотри на функции BinaryToObject и ObjectToBinary. Они создают DFM структуру объекта в текстовом виде и соотвественно парсят ее теми же методами, которые очень трудно выкинуть из использования даже при всем желании. Зачем создавать велосипед еще раз и дублировать то, что разработчики вложили изначально. Кроме того, один блок теста намного проще и быстрее прочитать из BLOB, чем собирать кучу значений из таблиц, с последующей модификацией отдельного свойства (как советовали отдельные товарисчи).


В чем достоинство моего метода — если изменился один параметр, в базе обновится одна мелкая запись, а если делать по-твоему, то обновится одна большая запись (если настройек много, а их у меня будет действительно много).
В общем, и у того, и у этого способа свои плюсы и минусы

Спасибо за ответ.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.