Решил задаться мыслю максимально быстро и универсально хранить настройки для всех пользователей в одном месте. Сделал всё через ж JSON с сохранением в BLOB-поле базы данных. В базе ест таблица с тремя полями: | Код |
CREATE TABLE tOptions( id INT(11) NOT NULL AUTO_INCREMENT, ParamName VARCHAR(255) DEFAULT NULL, ParamVal BLOB DEFAULT NULL, PRIMARY KEY (id))
|
В поле ParamVal хранится массив (поток) настроек. Всё сохраняется в JSON, потом JSON в поток, а поток уже в BLOB поле. Использовал стандартные методы Delphi XE2 работы с JSON. Начнём с объявления переменных | Код | type TRecOptions = record// для массива параметров nam: string; val: string; Def: variant; end;
Type TArrOptions = array of TRecOptions;// массив параметров
Var ArrOptions: TArrOptions;
|
Процедура добаление нового параметра в массив параметрв или указанение значения для существующего параметра | Код | procedure SetAllUsersParamS(const ParamName, ParamVal: string); Var i: smallint; begin //передает имя параметра, а получаем значение параметра for I := 0 to High(ArrOptions) do if AnsiUpperCase(ArrOptions[i].nam) = AnsiUpperCase(ParamName) then begin ArrOptions[i].val := ParamVal; exit; end;
//если нужного параметра нет, то добавляем в массив новый (потом он автоматически будет сохранён) SetLength(ArrOptions, length(ArrOptions) + 1); ArrOptions[length(ArrOptions) - 1].val := ParamVal; ArrOptions[length(ArrOptions) - 1].nam := ParamName; end;
//вот так используем: SetAllUsersParamS('iMaxSymbolsAD', s); SetAllUsersParamS('Max', '150'); SetAllUsersParamS('ParamName1', 'MyParamSuperValue');
|
В базу это записывается массив параметров так: | Код | procedure SaveParamsAllUsers(); var JSONObject: TJSONObject; Stream: TStream; i: smallint; begin if Length(ArrOptions) <= 0 then exit;//если массив пуст, то сохранять нечего JSONObject := TJSONObject.Create; Stream := TMemoryStream.Create; try //добавляем пару ("имя":"значение")
for I := 0 to High(ArrOptions) do JSONObject.AddPair(ArrOptions[i].nam, ArrOptions[i].val); with dm.uOptions do begin Close; DeleteWhere; AddWhere('ParamName = ' + QuotedStr('SettingsAllUsers'));//добавляем условие, что нам нужен массив параметров SettingsAllUsers из таблицы Open;
if RecordCount > 0 then Edit else Append;//если первый раз настройки сохраняем, то добавляем запись
MyStringToStream(JSONObject.ToString, Stream); Stream.Position := 0; FieldByName('ParamName').AsString := 'SettingsAllUsers'; TBLOBField(FieldByName('ParamVal')).LoadFromStream(Stream); post; end;// with
finally FreeAndNil(JSONObject); FreeAndNil(Stream); end; end;
|
Как загрузить из таблицы массив параметров: | Код | procedure LoadParamsAllUsers(); var JSONObject: TJSONObject; Stream: TStream; s: string; i: smallint; begin if not DM.connPremier.Connected then exit;
JSONObject := TJSONObject.Create; Stream := TMemoryStream.Create; with dm.uOptions do try //добавляем пару ("имя":"значение")
Close; DeleteWhere; AddWhere('ParamName = ' + QuotedStr('SettingsAllUsers'));// нам нужен какой-то определенный масив настроек, например, для окна fmEdit и т.п. Open;
if RecordCount <= 0 then exit;
Stream.CopyFrom(CreateBlobStream(dm.uOptionsParamVal, bmRead), 0); Stream.Position := 0; s := MyStreamToString(Stream);
JSONObject := TJSONObject(TJSONObject.ParseJSONValue(s));//парсим if JSONObject.Size <= 0 then exit;
SetLength(ArrOptions, JSONObject.Size); for I := 0 to High(ArrOptions) do begin // записываем параметры в массив параметров ArrOptions[i].nam := JSONObject.Get(i).JsonString.Value;; ArrOptions[i].val := JSONObject.Get(i).JsonValue.Value; end;
finally FreeAndNil(JSONObject); FreeAndNil(Stream); dm.uOptions.close; end; end;
|
Как прочитать какой-нибудь параметр из массива: | Код | Function GetAllUsersParamS(const ParamName: string): string; Var i: smallint; begin //передает имя параметра, а получаем значение параметра for I := 0 to High(ArrOptions) do if AnsiUpperCase(ArrOptions[i].nam) = AnsiUpperCase(ParamName) then begin result:= ArrOptions[i].val; Break; end; end;
//используем: cxLabel3.Caption := 'Максимальное количество символов: ' + GetAllUsersParamS('iMaxSymbolsAD');
|
добавка: | Код | procedure MyStringToStream(const AString: string; out AStream: TStream); begin AStream := TStringStream.Create(AString); end;
function MyStreamToString(aStream: TStream): string; var SS: TStringStream; begin if aStream <> nil then begin SS := TStringStream.Create(''); try SS.CopyFrom(aStream, 0); // No need to position at 0 nor provide size Result := SS.DataString; finally SS.Free; end; end else begin Result := ''; end; end;
|
Я так думаю, что от промежуточного массива можно вобще избавиться и упростить немного код. Вместо глобальной перменной ArrOptions: TArrOptions можно использовать непосредственно JSONObject: TJSONObject. Критикуйте, спрашивайте.
|