home *** CD-ROM | disk | FTP | other *** search
/ CD Shareware Magazine 1996 December / CD_shareware_12-96.iso / WIN / Programa / OORDB.ZIP / OORDB.EXE / MAPPING.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1996-08-12  |  19.2 KB  |  795 lines

  1. unit Mapping;
  2.  
  3. interface
  4. uses
  5.   SysUtils,
  6.   Assert_,
  7.   TypInfo,
  8.   Classes,
  9.   DB,
  10.   DBTables;
  11.  
  12.  
  13. type
  14.   TORMapping  = class;
  15.   TORList     = class;
  16.   TORFile     = class;
  17.   TORObject   = class;
  18.  
  19.   TORObjClass   = class of TORObject;
  20.   TProcessProp  = procedure (O :TORObject; PropInfo :PPropInfo) of object;
  21.  
  22.   TORMapping = class
  23.   private
  24.     FDatabase :TDatabase;
  25.     FFiles    :TStringList;
  26.  
  27.     procedure AddFile(AFile :TORFile);          virtual;
  28.   protected
  29.     function  GetFile(C :TORObjClass) :TORFile; virtual;
  30.  
  31.   public
  32.     constructor Create(db :TDatabase);
  33.     destructor  Destroy; override;
  34.     procedure   ApplyUpdates;                   virtual;
  35.  
  36.     property  Database :TDatabase read FDatabase write FDatabase;
  37.     property  Files[C :TORObjClass] :TORFile read GetFile; default;
  38.   end;
  39.  
  40.   TORList    = class
  41.   protected
  42.     FMapping  :TORMapping;
  43.     FClass    :TORObjClass;
  44.     FDataSet  :TDataSet;
  45.  
  46.     function  Load(const Key :Variant):TORObject;         virtual; abstract;
  47.     function  LoadCurrent(const Key :Variant):TORObject;  virtual; abstract;
  48.  
  49.     procedure OpenStorage;                      virtual;
  50.     function  GetObject(i :Integer):TORObject;  virtual;
  51.     procedure Update;                           virtual;
  52.  
  53.     property  DataSet     :TDataSet    read FDataSet;
  54.     property  MappedClass :TORObjClass read FClass;
  55.   public
  56.     constructor Create(AMapping :TORMapping; AClass :TORObjClass; ADataSet :TDataSet);
  57.     destructor  Destroy;                       override;
  58.     function    Count :Integer;                virtual;
  59.  
  60.     property    Mapping     :TORMapping  read FMapping;
  61.     property    Objects[i :Integer]:TORObject read GetObject;
  62.   end;
  63.  
  64.   TORFile    = class(TORList)
  65.   protected
  66.     FCache      :TStringList;
  67.     FDependants :TList;
  68.  
  69.     constructor Create(AMapping :TORMapping; AClass :TORObjClass; ADataSet :TDataSet);
  70.     destructor  Destroy;        override;
  71.  
  72.     function  Load(  const Key :Variant):TORObject;       override;
  73.     function  LoadCurrent(const Key :Variant):TORObject;  override;
  74.  
  75.     procedure Delete(const Key :Variant);            virtual;
  76.     procedure Release(O:TORObject);                  virtual;
  77.     procedure Store(O:TORObject);                    virtual;
  78.     procedure New(O:TORObject);                      virtual;
  79.  
  80.     procedure AddDependant(Dep :TORList);            virtual;
  81.     procedure RemoveDependant(Dep :TORList);         virtual;
  82.     procedure UpdateDependants;                      virtual;
  83.  
  84.     procedure ApplyUpdates;   virtual;
  85.     procedure Clear;          virtual;
  86.   public
  87.     function  FindInCached(const Key :Variant) :TORObject;
  88.   end;
  89.  
  90.   TORQuery = class(TORList)
  91.   private
  92.     FBaseFile :TORFile;
  93.  
  94.   protected
  95.     function  Load(  const Key :Variant):TORObject;       override;
  96.     function  LoadCurrent(const Key :Variant):TORObject;  override;
  97.  
  98.     property  BaseFile :TORFile read FBaseFile;
  99.   public
  100.     constructor Create(AMapping :TORMapping; AClass :TORObjClass; ADataSet :TDataSet; ABaseFile :TORFile);
  101.     destructor  Destroy; override;
  102.   end;
  103.  
  104.   TORCachedQuery = class(TORQuery)
  105.   protected
  106.     FList :TList;
  107.     destructor  Destroy;        override;
  108.  
  109.     procedure OpenStorage;                      override;
  110.     function  Count :Integer;                   override;
  111.     function  GetObject(i :Integer):TORObject;  override;
  112.     procedure Update;                           override;
  113.   end;
  114.  
  115.   TORreader = class
  116.   private
  117.     FFile :TORFile;
  118.   protected
  119.  
  120.     function  GetValue(const Name :string):Variant;            virtual;
  121.     procedure ReadPropInfo(O :TORObject; PropInfo :PPropInfo); virtual;
  122.     procedure ReadObjInfo (O :TORObject; PropInfo :PPropInfo); virtual;
  123.     function  ReadProperty(const ProName :string) : Variant;   virtual;
  124.   public
  125.     constructor Create(AFile :TORFile);
  126.     property FieldValues[const Name :string] :Variant read GetValue; default;
  127.   end;
  128.  
  129.   TORWriter = class(TORReader)
  130.     procedure SetValue(const Name :string; const Value :Variant);         virtual;
  131.     procedure WritePropInfo(O :TORObject; PropInfo :PPropInfo);           virtual;
  132.     procedure WriteObjInfo (O :TORObject; PropInfo :PPropInfo);           virtual;
  133.     procedure WriteProperty(const ProName :string; const Value :Variant); virtual;
  134.   public
  135.     property FieldValues[const Name :string] :Variant
  136.     read  GetValue
  137.     write SetValue;
  138.   end;
  139.  
  140.   TORObject = class(TPersistent)
  141.   private
  142.     FFile :TORFile;
  143.   protected
  144.  
  145.     class function DefaultTableName :string;  virtual;
  146.     class function KeyName   :string;         virtual; abstract;
  147.     function  GetKey :Variant;                virtual; abstract;
  148.     procedure SetKey (Value :Variant);        virtual; abstract;
  149.  
  150.     procedure ReadData( Reader :TORReader);   virtual;
  151.     procedure WriteData(Writer :TORWriter);   virtual;
  152.  
  153.     procedure ForEachProperty(ProcessProp :TProcessProp);  virtual;
  154.     property  Key :Variant read GetKey write SetKey;
  155.  
  156.     property  ORFile :TORFile read FFile;
  157.  
  158.   public
  159.     constructor Create(AMapping :TORMapping); virtual;
  160.     destructor  Destroy; override;
  161.  
  162.     procedure  Store;
  163.     procedure  Release;
  164.   end;
  165.  
  166.   EDBFailed = class(EFailed);
  167.   EDBObjectNotFound       = class(EDBFailed);
  168.   EDBObjectNotInDatabase  = class(EDBFailed);
  169.   EDBCommitFailed         = class(EDBFailed);
  170.   EDBCannotOpenStorage    = class(EDBFailed);
  171.   EDBNoDatabase           = class(EDBFailed);
  172.   EDBClassNotSpecified    = class(EDBFailed);
  173.   EDBNoDataset            = class(EDBFailed);
  174.   EDBNoBaseFile           = class(EDBFailed);
  175.   EDBNewFailed            = class(EDBFailed);
  176.   EDBLoadFailed           = class(EDBFailed);
  177.  
  178. implementation
  179.  
  180.  
  181. { TORMapping }
  182.  
  183. constructor TORMapping.Create(db :TDatabase);
  184. begin
  185.    inherited Create;
  186.    FDatabase := db;
  187.    FFiles := TStringList.Create;
  188.    FFiles.Sorted     := True;
  189.    FFiles.Duplicates := dupError;
  190. end;
  191.  
  192. destructor  TORMapping.Destroy;
  193. var
  194.   i :Integer;
  195. begin
  196.   for i := 0 to FFiles.Count-1 do
  197.     TORFile(FFiles.Objects[i]).Free;
  198.   FFiles.Free;
  199.   inherited Destroy;
  200. end;
  201.  
  202. procedure TORMapping.ApplyUpdates;
  203. var
  204.    i :Integer;
  205. begin
  206.    if FDatabase = nil then
  207.      raise EDBNoDatabase.Create;
  208.    try
  209.       FDatabase.Connected := True;
  210.  
  211.       if FFiles.Count > 0 then begin
  212.          FDatabase.StartTransaction;
  213.          try
  214.             for i := 0 to FFiles.Count-1 do
  215.               TORFile(FFiles.Objects[i]).ApplyUpdates;
  216.             FDatabase.Commit
  217.          except
  218.             FDatabase.Rollback;
  219.             raise;
  220.          end;
  221.             for i := 0 to FFiles.Count-1 do
  222.               TORFile(FFiles.Objects[i]).Clear;
  223.       end
  224.    except
  225.      raise EDBCommitFailed.Create;
  226.    end
  227. end;
  228.  
  229. procedure TORMapping.AddFile(AFile :TORFile);
  230. begin
  231.   FFiles.AddObject(AFile.MappedClass.ClassName, AFile)
  232. end;
  233.  
  234. function TORMapping.GetFile(C :TORObjClass) :TORFile;
  235. var
  236.   i :Integer;
  237. begin
  238.    i := FFiles.IndexOf(C.ClassName);
  239.    if i < 0 then
  240.      Result := nil
  241.    else
  242.      Result := TORFile(FFiles.Objects[i])
  243. end;
  244.  
  245. { TORList }
  246.  
  247. constructor TORList.Create(AMapping :TORMapping; AClass :TORObjClass; ADataSet :TDataSet);
  248. begin
  249.    Require(AMapping <> nil, nil);
  250.    Require(AClass <> nil, nil);
  251.    Require(ADataSet <> nil, nil);
  252.  
  253.    inherited Create;
  254.    FMapping := AMapping;
  255.    FClass   := AClass;
  256.    FDataset := ADataset;
  257. end;
  258.  
  259. destructor  TORList.Destroy;
  260. begin
  261.   FDataSet := nil;
  262.   inherited Destroy;
  263. end;
  264.  
  265. function TORList.Count :Integer;
  266. begin
  267.   OpenStorage;
  268.   Result := FDataSet.RecordCount
  269. end;
  270.  
  271. function  TORList.GetObject(i :Integer) :TORObject;
  272. begin
  273.   OpenStorage;
  274.   try
  275.      if FDataSet.RecNo >= 0 then
  276.         FDataSet.MoveBy((i+1) - FDataSet.RecNo)
  277.      else begin
  278.         FDataSet.First;
  279.         FDataSet.MoveBy(i)
  280.      end
  281.   except
  282.     raise EDBFailed.Create
  283.   end;
  284.   Result := LoadCurrent(FDataSet[MappedClass.KeyName])
  285. end;
  286.  
  287. procedure TORList.OpenStorage;
  288. begin
  289.   if FDataset = nil then
  290.     raise EDBNoDataset.Create
  291.   else
  292.     try
  293.        FDataset.Active := True
  294.     except
  295.        raise EDBCannotOpenStorage.Create
  296.     end
  297. end;
  298.  
  299. procedure TORList.Update;
  300. begin
  301.   Dataset.Close
  302. end;
  303.  
  304. { TORFile }
  305.  
  306. constructor TORFile.Create(AMapping :TORMapping; AClass :TORObjClass; ADataSet :TDataSet);
  307. begin
  308.   inherited Create(AMapping, AClass, ADataSet);
  309.   FCache            := TStringList.Create;
  310.   FDependants       := TList.Create;
  311.   FCache.Sorted     := True;
  312.   FCache.Duplicates := dupError;
  313.   AMapping.AddFile(Self);
  314. end;
  315.  
  316. destructor  TORFile.Destroy;
  317. begin
  318.    Clear;
  319.    FCache.Free;
  320.    FDependants.Free;
  321.    inherited Destroy;
  322. end;
  323.  
  324. function TORFile.LoadCurrent(const Key :Variant):TORObject;
  325. var
  326.   Reader :TORReader;
  327. begin
  328.   OpenStorage;
  329.   Result := FindInCached(Key);
  330.   if Result = nil then begin
  331.     Result := MappedClass.Create(nil);
  332.     try
  333.        Result.FFile := Self;
  334.        Result.Key   := Key;
  335.        Reader := TORReader.Create(Self);
  336.        try
  337.           Result.ReadData(Reader)
  338.        finally
  339.           Reader.Free
  340.        end;
  341.        FCache.AddObject(Key, Result)
  342.     except
  343.        Result.FFile := nil;
  344.        Result.Free;
  345.        raise EDBLoadFailed.Create
  346.     end
  347.   end;
  348. end;
  349.  
  350. function TORFile.Load(const Key :Variant):TORObject;
  351. var
  352.   Reader :TORReader;
  353. begin
  354.   OpenStorage;
  355.   Result := FindInCached(Key);
  356.   if Result = nil then begin
  357.     Result := MappedClass.Create(nil);
  358.     try
  359.        Result.FFile := Self;
  360.        Result.Key   := Key;
  361.  
  362.        if not FDataSet.Locate(MappedClass.KeyName, Key, []) then
  363.           raise EDBObjectNotFound.Create
  364.        else begin
  365.           Reader := TORReader.Create(Self);
  366.           try
  367.              Result.ReadData(Reader)
  368.           finally
  369.              Reader.Free
  370.           end
  371.        end;
  372.        FCache.AddObject(Key, Result)
  373.     except
  374.        Result.FFile := nil;
  375.        Result.Free;
  376.        raise EDBLoadFailed.Create
  377.     end
  378.   end;
  379. end;
  380.  
  381. procedure TORFile.Store(O:TORObject);
  382. var
  383.   Writer :TORWriter;
  384. begin
  385.   UpdateDependants;
  386.   OpenStorage;
  387.   Writer := TORWriter.Create(Self);
  388.   if FDataSet.Locate(O.KeyName, O.Key, []) then
  389.      FDataSet.Edit
  390.   else
  391.      raise EDBObjectNotFound.Create;
  392.   try
  393.      try
  394.         O.WriteData(Writer);
  395.         FDataSet.Post
  396.      finally
  397.         Writer.Free
  398.      end
  399.   except
  400.     FDataSet.Cancel
  401.   end
  402. end;
  403.  
  404. procedure TORFile.New(O:TORObject);
  405. var
  406.   Writer :TORWriter;
  407. begin
  408.   UpdateDependants;
  409.   OpenStorage;
  410.   FDataSet.Append;
  411.   try
  412.     FDataset.Post;
  413.     O.Key := FDataset[MappedClass.KeyName];
  414.     FCache.AddObject(O.Key, O);
  415.   except
  416.     FDataset.Cancel;
  417.     raise EDBNewFailed.Create;
  418.   end
  419. end;
  420.  
  421. procedure TORFile.Delete(const Key :Variant);
  422. var
  423.   O :TORObject;
  424.   i :Integer;
  425. begin
  426.   UpdateDependants;
  427.   OpenStorage;
  428.   if not FDataSet.Locate(MappedClass.KeyName, Key, []) then
  429.      raise EDBObjectNotFound.Create
  430.   else begin
  431.     FDataSet.Delete;
  432.     if FCache.Find(Key, i) then begin
  433.       O := TORObject(FCache.Objects[i]);
  434.       FCache.Delete(i);
  435.       O.FFile := nil;
  436.       O.Free;
  437.     end
  438.   end;
  439. end;
  440.  
  441.  
  442. procedure TORFile.Release(O :TORObject);
  443. var
  444.   i :Integer;
  445. begin
  446.    UpdateDependants;
  447.    if not FCache.Find(O.Key, i) then
  448.      raise EDBObjectNotFound.Create;
  449.    FCache.Delete(i);
  450.    O.FFile := nil;
  451.    Assert(not FCache.Find(O.Key, i), nil)
  452. end;
  453.  
  454. function TORFile.FindInCached(const Key :Variant) :TORObject;
  455. var
  456.    i :Integer;
  457. begin
  458.    if FCache.Find(Key, i) then
  459.      Result := TORObject(FCache.Objects[i])
  460.    else
  461.      Result := nil;
  462.    Assert((Result = nil) or (Result.FFile <> nil), nil)
  463. end;
  464.  
  465. procedure TORFile.ApplyUpdates;
  466. var
  467.    i :Integer;
  468. begin
  469.    OpenStorage;
  470.    for i := 0 to FCache.Count-1 do
  471.       Store(TORObject(FCache.Objects[i]));
  472.    with DataSet do
  473.      if CachedUpdates and UpdatesPending then
  474.         ApplyUpdates;
  475. end;
  476.  
  477. procedure TORFile.Clear;
  478. var
  479.    i :Integer;
  480. begin
  481.     if (FDataSet <> nil) and FDataSet.CachedUpdates then
  482.        FDataSet.CancelUpdates;
  483.     for i := 0 to FCache.Count-1 do
  484.        with TORObject(FCache.Objects[i])do begin
  485.           FFile := nil;
  486.           Free
  487.        end
  488. end;
  489.  
  490. procedure TORFile.AddDependant(Dep :TORList);
  491. begin
  492.   Require(Dep <> nil, nil);
  493.   FDependants.Add(Dep);
  494. end;
  495.  
  496. procedure TORFile.RemoveDependant(Dep :TORList);
  497. begin
  498.   Require(Dep <> nil, nil);
  499.   FDependants.Remove(Dep);
  500. end;
  501.  
  502.  
  503. procedure TORFile.UpdateDependants;
  504. var
  505.   i :Integer;
  506. begin
  507.   for i := 0 to FDependants.Count-1 do
  508.     TORList(FDependants[i]).Update;
  509. end;
  510.  
  511. { TORQuery }
  512.  
  513. constructor TORQuery.Create(AMapping :TORMapping; AClass :TORObjClass; ADataSet :TDataSet; ABaseFile :TORFile);
  514. begin
  515.   Require(ABaseFile <> nil, nil);
  516.   inherited Create(AMapping, AClass, ADataSet);
  517.   FBaseFile := ABaseFile;
  518.   FBaseFile.AddDependant(Self);
  519. end;
  520.  
  521. destructor TORQuery.Destroy;
  522. begin
  523.   FBaseFile.RemoveDependant(Self);
  524.   inherited Destroy;
  525. end;
  526.  
  527. function  TORQuery.Load(  const Key :Variant):TORObject;
  528. begin
  529.    Require(FBaseFile <> nil, EDBNoBaseFile);
  530.    Result := FBaseFile.Load(Key)
  531. end;
  532.  
  533. function  TORQuery.LoadCurrent(  const Key :Variant):TORObject;
  534. begin
  535.    Require(FBaseFile <> nil, EDBNoBaseFile);
  536.    Result := FBaseFile.Load(Key)
  537. end;
  538.  
  539. { TORCachedQuery }
  540.  
  541. destructor  TORCachedQuery.Destroy;
  542. begin
  543.   FList.Free;
  544.   inherited Destroy;
  545. end;
  546.  
  547. procedure TORCachedQuery.OpenStorage;
  548. var
  549.   i :Integer;
  550. begin
  551.   if FList = nil then begin
  552.     FList := TList.Create;
  553.     inherited OpenStorage;
  554.     { cache the objects }
  555.     for i := 0 to inherited Count-1 do
  556.       FList.Add(inherited GetObject(i));
  557.     FDataSet.Close
  558.   end
  559. end;
  560.  
  561. function  TORCachedQuery.GetObject(i :Integer):TORObject;
  562. begin
  563.   if FList = nil then
  564.     OpenStorage;
  565.   Assert(FList <> nil, nil);
  566.   FDataset.Close; { not needed for now }
  567.   Result := FList[i];
  568. end;
  569.  
  570. procedure TORCachedQuery.Update;
  571. begin
  572.   inherited Update;
  573.   FList.Free;
  574.   FList := nil
  575. end;
  576.  
  577. function TORCachedQuery.Count :Integer;
  578. begin
  579.   OpenStorage;
  580.   Result := FList.Count
  581. end;
  582.  
  583. { TORReader }
  584.  
  585. constructor TORReader.Create(AFile :TORFile);
  586. begin
  587.    inherited Create;
  588.    FFile := AFile;
  589. end;
  590.  
  591. function TORReader.GetValue(const Name :string):Variant;
  592. begin
  593.   Result := FFile.FDataSet[Name]
  594. end;
  595.  
  596. function TORReader.ReadProperty(const ProName :string): Variant;
  597. begin
  598.      Result := FFile.FDataset[ProName]
  599. end;
  600.  
  601.  
  602. procedure TORReader.ReadPropInfo(O :TORObject; PropInfo :PPropInfo);
  603. var
  604.   Value :Variant;
  605. begin
  606.     with PropInfo^, PropType^ do
  607.       if PropInfo^.SetProc <> nil then begin
  608.          Value := ReadProperty(PropInfo^.Name);
  609.          case Kind of
  610.             tkInteger,
  611.             tkChar,
  612.             tkEnumeration,
  613.             tkSet:
  614.               if VarIsNull(Value) then
  615.                  SetOrdProp(O, PropInfo, 0)
  616.               else
  617.                  SetOrdProp(O, PropInfo, Value);
  618.             tkString,
  619.             tkLString,
  620.             tkLWString:
  621.               if VarIsNull(Value) then
  622.                  SetStrProp(O, PropInfo, '')
  623.               else
  624.                  SetStrProp(O, PropInfo, Value);
  625.             tkFloat:
  626.               if VarIsNull(Value) then
  627.                  SetFloatProp(O, PropInfo, 0.0)
  628.               else
  629.                  SetFloatProp(O, PropInfo, Value);
  630.             tkVariant:
  631.               SetVariantProp(O, PropInfo, Value);
  632.          end
  633.       end
  634. end;
  635.  
  636. procedure TORReader.ReadObjInfo(O :TORObject; PropInfo :PPropInfo);
  637. var
  638.   Key   :Variant;
  639.   C     :TClass;
  640.   obj   :TORObject;
  641. begin
  642.     with PropInfo^, PropType^ do
  643.       if (PropInfo^.SetProc <> nil) and (Kind = tkClass) then begin
  644.          C   := GetTypeData(PropType)^.ClassType;
  645.          if C.InheritsFrom(TORObject) then begin
  646.             Key := ReadProperty(PropInfo^.Name);
  647.             if VarIsNull(Key) or VarIsEmpty(Key) then
  648.               SetOrdProp(O, PropInfo, 0)
  649.             else begin
  650.               obj := FFile.Mapping[TORObjClass(C)].Load(Key);
  651.               SetOrdProp(O, PropInfo, Longint(obj))
  652.             end
  653.          end
  654.       end
  655. end;
  656.  
  657. { TOBReader }
  658.  
  659. procedure TORWriter.SetValue(const Name :string; const Value :Variant);
  660. begin
  661.    FFile.FDataSet[Name] := Value
  662. end;
  663.  
  664. procedure TORWriter.WriteProperty(const ProName :string; const Value :Variant);
  665. begin
  666.      FFile.FDataset[ProName] := Value
  667. end;
  668.  
  669. procedure TORWriter.WritePropInfo(O :TORObject; PropInfo :PPropInfo);
  670. var
  671.    Value   :Variant;
  672. begin
  673.     with PropInfo^, PropType^ do begin
  674.         if GetProc <> nil then begin
  675.           case Kind of
  676.              tkInteger,
  677.              tkChar,
  678.              tkEnumeration,
  679.              tkSet:
  680.                Value := GetOrdProp(O, PropInfo);
  681.              tkString,
  682.              tkLString,
  683.              tkLWString:
  684.                Value := GetStrProp(O, PropInfo);
  685.              tkFloat:
  686.                Value := GetFloatProp(O, PropInfo);
  687.              tkVariant:
  688.                Value := GetVariantProp(O, PropInfo)
  689.              else
  690.                { do nothing } Exit;
  691.           end;
  692.           WriteProperty(PropInfo^.Name, Value)
  693.         end
  694.     end
  695. end;
  696.  
  697. procedure TORWriter.WriteObjInfo(O :TORObject; PropInfo :PPropInfo);
  698. var
  699.    Value   :Variant;
  700.    C       :TClass;
  701.    obj     :TORObject;
  702. begin
  703.     with PropInfo^, PropType^ do begin
  704.         if (GetProc <> nil) and (Kind = tkClass) then begin
  705.             C := GetTypeData(PropType)^.ClassType;
  706.             if C.InheritsFrom(TORObject) then begin
  707.                 obj := Pointer(GetOrdProp(O, PropInfo));
  708.                 if obj = nil then
  709.                     WriteProperty(PropInfo^.Name, Null)
  710.                 else
  711.                     WriteProperty(PropInfo^.Name, obj.Key)
  712.             end
  713.         end
  714.     end
  715. end;
  716.  
  717.  
  718.  
  719. { TORObject }
  720.  
  721. constructor TORObject.Create(AMapping :TORMapping);
  722. begin
  723.   inherited Create;
  724.   if AMapping <> nil then begin
  725.      FFile := AMapping[TORObjClass(Self.ClassType)];
  726.      Assert(FFile <> nil, nil);
  727.      FFile.New(Self)
  728.   end
  729. end;
  730.  
  731. destructor TORObject.Destroy;
  732. var
  733.   F :TORFile;
  734. begin
  735.   if  FFile <> nil then begin
  736.     F := FFile;      {!!!}{Deletions are not being cached !}
  737.     FFile := nil;
  738.     F.Delete(Key);
  739.   end;
  740.   inherited Destroy;
  741. end;
  742.  
  743. procedure  TORObject.Release;
  744. begin
  745.   FFile.Release(Self)
  746. end;
  747.  
  748. class function TORObject.DefaultTableName :string;
  749. begin
  750.    if ClassName[1] = 'T' then
  751.       Result := Copy(ClassName, 2, Length(ClassName))
  752.    else
  753.       Result := ClassName
  754. end;
  755.  
  756. procedure TORObject.Store;
  757. begin
  758.   if FFile = nil then
  759.      raise EDBObjectNotInDatabase.Create
  760.   else
  761.      FFile.Store(Self)
  762. end;
  763.  
  764. procedure TORObject.ReadData( Reader :TORReader);
  765. begin
  766.    ForEachProperty(Reader.ReadPropInfo);
  767.    ForEachProperty(Reader.ReadObjInfo);
  768. end;
  769.  
  770. procedure TORObject.WriteData(Writer :TORWriter);
  771. begin
  772.    ForEachProperty(Writer.WritePropInfo);
  773.    ForEachProperty(Writer.WriteObjInfo);
  774. end;
  775.  
  776. procedure TORObject.ForEachProperty(ProcessProp :TProcessProp);
  777. var
  778.   i        :Integer;
  779.   Count    :Integer;
  780.   Info     :PPropInfo;
  781.   PropList :array[0..255] of PPropInfo;
  782. begin
  783.    Count := GetTypeData(ClassInfo)^.PropCount;
  784.    Assert((Count < 256), nil);
  785.  
  786.    GetPropInfos(ClassInfo, PPropList(@PropList));
  787.  
  788.    for i := 0 to Count-1 do begin
  789.      if IsStoredProp(Self, PropList[i]) then
  790.         ProcessProp(Self, PropList[i])
  791.    end
  792. end;
  793.  
  794. end.
  795.