Помогите разобраться с коллекциями

отредактировано 23:50 Раздел: FastScript
Постановка: написать обертку DOA компонент доступа к oracle для FS

Имеем:
TOracleDataset = class(TDataSet)

Имеем публичный метод-функцию:
TOracleDataset = class(TDataSet)
    …
  Public
    …
    function SearchRecord(const FieldNames: string; const FieldValues: Variant; Options: TSearchRecordOptions): Boolean;
    …
  End;

Имеем последним параметром функции тип TSearchRecordOptions, который описан следующим образом:
  TSearchRecordOption = (srForward, srBackward, srFromCurrent, srFromBeginning,
    srFromEnd, srIgnoreCase, srIgnoreTime, srWildcards, srPartialMatch, srDontNavigate);
  TSearchRecordOptions = set of TSearchRecordOption;

Описываю так:
constructor TFunctions.Create;
begin
  with fsGlobalUnit do
  begin
    AddedBy := Self;

  AddEnumSet('TSearchRecordOptions', 'srForward, srBackward, srFromCurrent, srFromBeginning, ' +
               'srFromEnd, srIgnoreCase, srIgnoreTime, srWildcards, srPartialMatch, srDontNavigate');

    with AddClass(TOracleDataset, 'TDataSet') do
      AddMethod('function  SearchRecord(const FieldNames: string; const FieldValues: Variant; Options: TSearchRecordOptions): Boolean', CallMethod);

    AddedBy := nil;
  end;
end;
function TFunctions.CallMethod(Instance: TObject; ClassType: TClass;
  const MethodName: String; var Params: Variant): Variant;
var
  SearchRecordOptions : TSearchRecordOptions;
  i : Integer;
begin
  Result := 0;
  if ClassType = TOracleDataset then
  Begin
    if ( MethodName = 'SEARCHRECORD' ) then
    Begin
       if ( VarIsArray( Params[2] )) then
       Begin
          SearchRecordOptions := [];
          for i := 0 to VarArrayHighBound( Params[2], 1 ) do
          Begin
              case Integer( Params[2][i] ) of
              1 :   Include( SearchRecordOptions, srForward );
              2 :   Include( SearchRecordOptions, srBackward );
              4 :   Include( SearchRecordOptions, srFromCurrent );
              8 :   Include( SearchRecordOptions, srFromBeginning );
              16 :  Include( SearchRecordOptions, srFromEnd );
              32 :  Include( SearchRecordOptions, srIgnoreCase );
              64 :  Include( SearchRecordOptions, srIgnoreTime );
              128 : Include( SearchRecordOptions, srWildcards );
              256 : Include( SearchRecordOptions, srPartialMatch );
              512 : Include( SearchRecordOptions, srDontNavigate );
              end;
          End;
          Result := TOracleDataset(Instance).SearchRecord( String( Params[0] ), Params[1], SearchRecordOptions )
       End;
    End;
End;

Доктор... а SearchRecordOptions можно формировать из Params[2] другим способом... более коротким и приемлимым? ;) хееееееееееелп!!!

Комментарии

  • отредактировано 23:50
    Два способа:
      function IntToLocateOptions(i: Integer): TLocateOptions;
      begin
        Result := [];
        if (i and 1) <> 0 then
          Result := Result + [loCaseInsensitive];
        if (i and 2) <> 0 then
          Result := Result + [loPartialKey];
      end;
    
      function LocateOptionsToInt(f: TLocateOptions): Integer;
      begin
        Result := 0;
        if loCaseInsensitive in f then
          Result := Result or 1;
        if loPartialKey in f then
          Result := Result or 2;
      end;
    
    type
      TWordSet = set of 0..15;
      PWordSet = ^TWordSet;
      PLocateOptions = ^TLocateOptions;
    
    
    function IntToLocateOptions(i: Integer): TLocateOptions;
    begin
      Result := TLocateOptions(PLocateOptions(@i)^);
    end;
    
    function LocateOptionsToInt(opt: TLocateOptions): Integer;
    begin
      Result := Word(PWordSet(@opt)^);
    end;
    
  • отредактировано 23:50
    У вас совершенно не читабельный код…
    Var  LocateOptions : TLocateOptions;
    …
    Begin
    …
        if ( MethodName = 'LOCATE' ) then
        Begin
           if ( VarIsArray( Params[2] )) then
           Begin
              LocateOptions := [];
              for i := 0 to VarArrayHighBound( Params[2], 1 ) do
              Begin
                case Integer( Params[2][i] ) of
                1 : Include( LocateOptions, loCaseInsensitive );
                2 : Include( LocateOptions, loPartialKey );
                end;
              End;
              Result := TOracleDataset(Instance).Locate( String( Params[0] ), Params[1], LocateOptions );
           End;
        End;
    …
    End;
    
    Но все равно спасибо!
  • отредактировано July 2004
    Хочу обратить внимание: Params[2] - это не массив! Это Integer, в котором множество представлено в виде битов. Множество в FS передается как сумма составляющих: loCaseInsensitive + loPartialKey, а не как [loCaseInsensitive,loPartialKey] (второй вариант используется для передачи open arrays, для оператора IN, для CASE). Можете, конечно, передавать множество именно так, и обрабатывать своим способом, но это неправильно - везде в FS множества сделаны первым способом, будет только лишняя путаница.

Оставить комментарий

Многофункциональный текстовый редактор. Чтобы отредактировать стиль параграфа, нажмите TAB, чтобы перейти к меню абзаца. Там вы можете выбрать стиль. По умолчанию не выбран ни один стиль. Когда вы выберете текст, появится встроенное меню форматирования. Нажмите TAB, чтобы войти в него. Некоторые элементы, такие как многофункциональные вставки ссылок, картинок, индикаторов загрузки и сообщений об ошибок могут быть вставлены в редактор. Вы можете перемещаться по ним, используя стрелки внутри редактора и удалять с помощью клавиш delete или backspace.