home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / library / dos / database / oodb / dbdemo.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1992-04-29  |  17.9 KB  |  597 lines

  1. uses Objects, Drivers, Views, Menus, Dialogs, App, Layout, OODB;
  2.  
  3. const
  4.  
  5.    DBFileName = 'dbdemo.dat';
  6.  
  7.    MaxLen = 25;
  8.    CollLimit = $7F; CollDelta = 4;
  9.    InvPID = 1;
  10.  
  11.    cmInfo     = 100;
  12.  
  13.    cmOpen     = 101;
  14.    cmShut     = 102;
  15.    cmStat     = 103;
  16.  
  17.    cmCreate   = 105;
  18.    cmGet      = 106;
  19.    cmDelete   = 107;
  20.  
  21.    cmCommit   = 108;
  22.    cmAbort    = 109;
  23.  
  24. type
  25.  
  26.    NameString = String [MaxLen];
  27.  
  28.    ModDialData =
  29.       record
  30.          NameData : NameString
  31.       end;
  32.  
  33.    TInvCard =
  34.       record
  35.          Name : NameString;
  36.          ID   : Word
  37.       end;
  38.    PInvCard = ^TInvCard;
  39.  
  40. { ----- TCatCollection ----- }
  41.  
  42.       TCatCollection =
  43.          object (TSortedCollection)
  44.             procedure FreeItem (Item: Pointer);                  virtual;
  45.             function  GetItem  (var S: TStream): Pointer;        virtual;
  46.             procedure PutItem  (var S: TStream; Item: Pointer);  virtual;
  47.             function  Compare  (Key1, Key2 : Pointer): Integer;  virtual;
  48.          end;
  49.       PCatCollection = ^TCatCollection;
  50.  
  51. { ----- TDemoApplication class ----- }
  52.  
  53.    TDemoApplication =
  54.       object (TApplication)
  55.  
  56.          DB        : PBase;
  57.          DBFile    : PDosStream;
  58.  
  59.          constructor Init;
  60.          destructor  Done;                             virtual;
  61.          procedure   InitMenuBar;                      virtual;
  62.          procedure   InitStatusLine;                   virtual;
  63.          procedure   HandleEvent (var Event: TEvent);  virtual;
  64.          procedure   Idle;                             virtual;
  65.  
  66.          function    NameDialog (Title: TTitleStr):
  67.                                 PDialog;               virtual;
  68.  
  69.          procedure   About;                            virtual;
  70.  
  71.          procedure   OpenDB;                           virtual;
  72.          procedure   ShutDB;                           virtual;
  73.          procedure   StatInfo;                         virtual;
  74.  
  75.          procedure   CreateMod;                        virtual;
  76.          procedure   GetMod;                           virtual;
  77.          procedure   DeleteMod;                        virtual;
  78.  
  79.          procedure   Commit;                           virtual;
  80.          procedure   Rollback;                         virtual;
  81.  
  82.       end;
  83.    PDemoApplication = ^TDemoApplication;
  84.  
  85. { -- Implementation of TCatCollection -- }
  86.  
  87.    procedure TCatCollection.FreeItem (Item: Pointer);
  88.  
  89.       begin
  90.          Dispose (Item)
  91.       end;  { FreeItem }
  92.  
  93.    function TCatCollection.GetItem (var S: TStream): Pointer;
  94.  
  95.       var Item : PInvCard;
  96.  
  97.       begin
  98.          New (Item);
  99.          with S do
  100.               with Item^ do
  101.                    begin
  102.                       Read (Name, SizeOf(Name));
  103.                       Read (ID,   SizeOf(ID))
  104.                    end;
  105.          GetItem := Item
  106.       end;  { GetItem }
  107.  
  108.    procedure TCatCollection.PutItem (var S: TStream; Item: Pointer);
  109.  
  110.       begin
  111.          with S do
  112.               with TInvCard(Item^) do
  113.                    begin
  114.                       Write (Name, SizeOf(Name));
  115.                       Write (ID,   SizeOf(ID))
  116.                    end
  117.       end;  { PutItem }
  118.  
  119.    function TCatCollection.Compare (Key1, Key2 : Pointer): Integer;
  120.  
  121.       var
  122.          N1, N2 : NameString;
  123.       begin
  124.          N1 := TInvCard(Key1^).Name; N2 := TInvCard(Key2^).Name;
  125.          if N1 > N2
  126.             then Compare := 1
  127.             else if N1 < N2
  128.                     then Compare := -1
  129.                     else Compare := 0
  130.       end;  { Compare }
  131.  
  132. { -- End of TCatCollection implementation -- }
  133.  
  134. { ----- TDemoApplication implementation ----- }
  135.  
  136. { ----- Init ----- }
  137.  
  138.    constructor TDemoApplication.Init;
  139.  
  140.       begin
  141.          TApplication.Init;
  142.          DB := nil
  143.       end;
  144.  
  145. { ----- Done ----- }
  146.  
  147.    destructor TDemoApplication.Done;
  148.  
  149.       begin
  150.          if DB <> nil
  151.             then begin
  152.                     Dispose (DB, Done);
  153.                     Dispose (DBFile, Done)
  154.                  end;
  155.          TApplication.Done
  156.       end;
  157.  
  158. { ----- InitMenuBar ----- }
  159.  
  160.    procedure TDemoApplication.InitMenuBar;
  161.  
  162.       var
  163.          MenuRect: TRect;
  164.  
  165.       begin
  166.          GetExtent (MenuRect);
  167.          MenuRect.B.Y := MenuRect.A.Y + 1;
  168.          MenuBar := New (PMenuBar, Init (MenuRect, NewMenu (
  169.              NewItem ( '~I~nfo', '', kbNoKey, cmInfo, hcNoContext,
  170.              NewSubMenu ( '~D~atabase', hcNoContext, NewMenu (
  171.                 NewItem ( '~O~pen', 'F3', kbF3, cmOpen, hcNoContext,
  172.                 NewItem ( '~S~hut', 'F4', kbF4, cmShut, hcNoContext,
  173.                 NewItem ( 'S~t~atistics', '', kbNoKey, cmStat, hcNoContext,
  174.                 NewLine (
  175.                 NewItem ( '~E~xit', 'Alt-X', kbAltX, cmQuit, hcNoContext,
  176.                    nil )))))),
  177.              NewSubMenu ( '~M~odules', hcNoContext, NewMenu (
  178.                 NewItem ( '~C~reate', 'F5', kbF5, cmCreate, hcNoContext,
  179.                 NewItem ( '~G~et', 'F6', kbF6, cmGet, hcNoContext,
  180.                 NewItem ( '~D~elete', '', kbNoKey, cmDelete, hcNoContext,
  181.                    nil )))),
  182.              NewSubMenu ( '~T~ransaction', hcNoContext, NewMenu (
  183.                 NewItem ( '~C~ommit', '', kbNoKey, cmCommit, hcNoContext,
  184.                 NewItem ( '~R~ollback', '', kbNoKey, cmAbort, hcNoContext,
  185.                    nil ))),
  186.                   nil )))))))
  187.       end;
  188.  
  189. { ----- InitStatusLine ----- }
  190.  
  191.    procedure TDemoApplication.InitStatusLine;
  192.  
  193.       var
  194.          StatusRect: TRect;
  195.  
  196.       begin
  197.          GetExtent (StatusRect);
  198.          StatusRect.A.Y := StatusRect.B.Y - 1;
  199.          StatusLine := New (PStatusLine, Init (StatusRect,
  200.             NewStatusDef (0, $FFFF,
  201.                NewStatusKey ('~Alt-X~ - Exit', kbAltX, cmQuit,
  202.                NewStatusKey ('~F3~ - Open database', kbF3, cmOpen,
  203.                NewStatusKey ('~F10~ - Menu', kbF10, cmMenu,
  204.                   nil ))),
  205.                  nil )))
  206.       end;
  207.  
  208. { ----- HandleEvent ----- }
  209.  
  210.    procedure TDemoApplication.HandleEvent (var Event: TEvent);
  211.  
  212.       begin
  213.          TApplication.HandleEvent (Event);
  214.          with Event do
  215.               if What = evCommand
  216.                  then begin
  217.                          case Command of
  218.  
  219.                               cmInfo   : About;
  220.  
  221.                               cmOpen   : OpenDB;
  222.                               cmShut   : ShutDB;
  223.                               cmStat   : StatInfo;
  224.  
  225.                               cmCreate : CreateMod;
  226.                               cmGet    : GetMod;
  227.                               cmDelete : DeleteMod;
  228.  
  229.                               cmCommit : Commit;
  230.                               cmAbort  : Rollback;
  231.  
  232.                               else
  233.                                          Exit
  234.                           end;
  235.                           ClearEvent (Event)
  236.                       end
  237.       end;
  238.  
  239. { ----- Idle ----- }
  240.  
  241.    procedure TDemoApplication.Idle;
  242.  
  243.       begin
  244.          TApplication.Idle;
  245.          if DB <> nil
  246.             then DB^.IdlePack
  247.       end;
  248.  
  249. { ----- NameDialog ----- }
  250.  
  251.    function TDemoApplication.NameDialog (Title: TTitleStr): PDialog;
  252.  
  253.       var
  254.          X, Y     : Word;
  255.          R        : TRect;
  256.          Dial     : PDialog;
  257.          Bruce    : PView;
  258.  
  259.       begin
  260.          if DB = nil
  261.             then begin
  262.                     HandleError ( ^C'Open database at first !' );
  263.                     NameDialog := nil;
  264.                     Exit
  265.                  end;
  266.          Randomize;
  267.          X := 2 + Random (50); Y := 2 + Random (12);
  268.          R.Assign (X,Y,X+28,Y+9);
  269.          New (Dial, Init (R, Title));
  270.          with Dial^ do
  271.               begin
  272.                  R.Assign (2,6,12,8);
  273.                  Insert (New (PButton, Init (R, '~O~k', cmOK, bfDefault)));
  274.                  R.Assign (14,6,24,8);
  275.                  Insert (New (PButton,
  276.                               Init (R, '~C~ancel', cmCancel, bfNormal)));
  277.                  R.Assign (3,3,25,4);
  278.                  Bruce := New (PInputLine, Init (R, MaxLen));
  279.                  Insert (Bruce);
  280.                  R.Assign (2,2,20,3);
  281.                  Insert (New (PLabel, Init (R, 'Module name:', Bruce)))
  282.               end;
  283.          NameDialog := Dial
  284.       end;
  285.  
  286. { ----- About ----- }
  287.  
  288.    procedure TDemoApplication.About;
  289.  
  290.       var
  291.          R: TRect;
  292.  
  293.       begin
  294.          R.Assign (15,3,65,16);
  295.          Inform
  296.             ( R,
  297.               ^C'This program is intended to demonstrate'^M +
  298.               ^C'some features of OODBMS'^M +
  299.               ^C'(object-oriented database management system).'^M +
  300.               ^C'OODBMS as well as this demo'^M +
  301.               ^C'is developed independently by Shmatikov V.'^M^M +
  302.               ^C'Spring 1992',
  303.               nil )
  304.       end;
  305.  
  306. { ----- OpenDB ----- }
  307.  
  308.    procedure TDemoApplication.OpenDB;
  309.  
  310.       var
  311.          Dial    : PDialog;
  312.          C       : Word;
  313.          DBIsNew : Boolean;
  314.          Invent  : PCatCollection;
  315.  
  316.       begin
  317.          DBIsNew := False;
  318.          if DB = nil
  319.             then begin
  320.                     if Confirm ( ^C'You are to open database.'^M +
  321.                                  ^C'Choose Ok to proceed ...' ) =
  322.                        cmCancel
  323.                        then Exit;
  324.                     New (DBFile, Init (DBFileName, stOpen));
  325.                     if DBFile^.Status <> stOk
  326.                        then begin
  327.                                Dispose (DBFile, Done);
  328.                                New (DBFile, Init (DBFileName, stCreate));
  329.                                DBIsNew := True;
  330.                             end;
  331.                     New (DB, Init (DBFile));
  332.                     if DBIsNew
  333.                        then begin
  334.                                New (Invent, Init (CollLimit, CollDelta));
  335.                                DB^.Put (InvPID, Invent);
  336.                                Inc (DB^.PIDCurrent);
  337.                                Dispose (Invent, Done)
  338.                             end;
  339.                     DB^.Commit
  340.                  end
  341.             else HandleError ( ^C'Database is in use already !' )
  342.       end;
  343.  
  344. { ----- ShutDB ----- }
  345.  
  346.    procedure TDemoApplication.ShutDB;
  347.  
  348.       var
  349.          Dial : PDialog;
  350.          C    : Word;
  351.  
  352.       begin
  353.          if DB <> nil
  354.             then begin
  355.                     if Confirm ( ^C'You are about to close database'^M +
  356.                                  ^C'Choose Ok to do it !' ) =
  357.                        cmCancel
  358.                        then Exit;
  359.                     Dispose (DB, Done); DB := nil;
  360.                     Dispose (DBFile, Done); DBFile := nil
  361.                  end
  362.             else HandleError ( ^C'No database is in use now !' )
  363.       end;
  364.  
  365. { ----- StatInfo ----- }
  366.  
  367.    procedure TDemoApplication.StatInfo;
  368.  
  369.       type
  370.            InfoRec =
  371.               record
  372.                  FileName            : PString;
  373.                  NumObj,   SizeObj,
  374.                  NumHoles, SizeHoles,
  375.                  SizeAnc,  TotalSize : Longint
  376.               end;
  377.  
  378.       var
  379.          R       : TRect;
  380.          DataRec : InfoRec;
  381.          i       : Integer;
  382.  
  383.       begin
  384.          if DB = nil
  385.             then begin
  386.                     HandleError ( ^C'Open database at first !' );
  387.                     Exit
  388.                  end;
  389.          with DB^ do
  390.               with DataRec do
  391.                    begin
  392.                       FileName^ := DBFileName;
  393.                       NumObj := 0; SizeObj := 0;
  394.                       For i := 2 to DBIndex^.Count - 1 do
  395.                           if (IndRec(DBIndex^.At(i)^).Base = i) and
  396.                              (IndRec(DBIndex^.At(1)^).Base <> i)
  397.                              then begin
  398.                                      Inc (NumObj);
  399.                                      SizeObj := SizeObj +
  400.                                                 IndRec(DBIndex^.At(i)^).Size
  401.                                   end;
  402.                       NumHoles := HolesIndex^.Count; SizeHoles := 0;
  403.                       For i := 0 to NumHoles-1 do
  404.                           SizeHoles := SizeHoles +
  405.                                        IndRec(HolesIndex^.At(i)^).Size;
  406.                       SizeAnc := DBFile^.GetSize - SizeObj - SizeHoles;
  407.                       TotalSize := DBFile^.GetSize
  408.                    end;
  409.          R.Assign (10,2,70,15);
  410.          Inform
  411.             ( R,
  412.               'Database file "%s" is in use'^M^M +
  413.               ' - %d user object(s) hold(s) %d byte(s) in file'^M +
  414.               ' - %d hole(s) hold(s) %d byte(s) in file'^M +
  415.               ' - Ancillary information holds %d byte(s)'^M +
  416.               ' - Total size of database is %d byte(s)',
  417.               @DataRec )
  418.       end;
  419.  
  420. { ----- CreateMod ----- }
  421.  
  422.    procedure TDemoApplication.CreateMod;
  423.  
  424.       var
  425.          NewDial  : PDialog;
  426.          C        : Word;
  427.          DialData : ModDialData;
  428.          Card     : PInvCard;
  429.          Invent   : PCatCollection;
  430.          PID      : Word;
  431.  
  432.       begin
  433.          NewDial := NameDialog ('New module');
  434.          if NewDial = nil
  435.             then Exit;
  436.          C := DeskTop^.ExecView (NewDial);
  437.          if C <> CmCancel
  438.             then begin
  439.                     NewDial^.GetData (DialData);
  440.                     if DialData.NameData <> ''
  441.                        then begin
  442.                                Invent := PCatCollection (DB^.Get (InvPID));
  443.                                New (Card);
  444.                                PID := DB^.Create;
  445.                                Card^.Name := DialData.NameData;
  446.                                Card^.ID := PID;
  447.                                Invent^.Insert (Card);
  448.                                DB^.Put (PID, NewDial);
  449.                                DB^.Destroy (InvPID);
  450.                                DB^.Put (InvPID, Invent);
  451.                                Dispose (Invent, Done)
  452.                             end
  453.                  end;
  454.          Dispose (NewDial, Done)
  455.       end;
  456.  
  457. { ----- GetMod ----- }
  458.  
  459.    procedure TDemoApplication.GetMod;
  460.  
  461.       var
  462.          Dial,
  463.          DialFromDB : PDialog;
  464.          C          : Word;
  465.          DialData   : ModDialData;
  466.          Card       : PInvCard;
  467.          Invent     : PCatCollection;
  468.          Ind        : Integer;
  469.  
  470.       begin
  471.          Dial := NameDialog ('Get');
  472.          if Dial = nil
  473.             then Exit;
  474.          C := DeskTop^.ExecView (Dial);
  475.          if C <> CmCancel
  476.             then begin
  477.                     Dial^.GetData (DialData);
  478.                     New (Card);
  479.                     Card^.Name := DialData.NameData;
  480.                     Invent := PCatCollection (DB^.Get (InvPID));
  481.                     if Invent^.Search (Card, Ind)
  482.                        then begin
  483.                                DialFromDB :=
  484.                                    PDialog (DB^.Get
  485.                                            (TInvCard(Invent^.At(Ind)^).ID));
  486.                                C := ExecView (DialFromDB);
  487.                                Dispose (DialFromDB, Done)
  488.                             end;
  489.                     Dispose (Invent, Done)
  490.                  end;
  491.          Dispose (Dial, Done)
  492.       end;
  493.  
  494. { ----- DeleteMod ----- }
  495.  
  496.    procedure TDemoApplication.DeleteMod;
  497.  
  498.       var
  499.          Dial     : PDialog;
  500.          C        : Word;
  501.          DialData : ModDialData;
  502.          Card     : PInvCard;
  503.          Invent   : PCatCollection;
  504.          Ind      : Integer;
  505.  
  506.       begin
  507.          Dial := NameDialog ('Delete');
  508.          if Dial = nil
  509.             then Exit;
  510.          C := DeskTop^.ExecView (Dial);
  511.          if C <> CmCancel
  512.             then begin
  513.                     Dial^.GetData (DialData);
  514.                     New (Card);
  515.                     Card^.Name := DialData.NameData;
  516.                     Invent := PCatCollection (DB^.Get (InvPID));
  517.                     if Invent^.Search (Card, Ind)
  518.                        then begin
  519.                                DB^.Destroy (TInvCard(Invent^.At(Ind)^).ID);
  520.                                Invent^.AtDelete (Ind);
  521.                                DB^.Destroy (InvPID);
  522.                                DB^.Put (InvPID, Invent)
  523.                             end;
  524.                     Dispose (Invent, Done)
  525.                  end;
  526.          Dispose (Dial, Done)
  527.       end;
  528.  
  529. { ----- Commit ----- }
  530.  
  531.    procedure TDemoApplication.Commit;
  532.  
  533.       var
  534.          Dial : PDialog;
  535.          C    : Word;
  536.  
  537.       begin
  538.          if DB <> nil
  539.             then begin
  540.                     if Confirm
  541.                        ( ^C'All changes you''ve made since last Commit '^M +
  542.                          ^C'will be placed into the database forever !' ) =
  543.                        cmCancel
  544.                        then Exit;
  545.                     DB^.Commit
  546.                  end
  547.             else HandleError ( ^C'No database is in use now !' )
  548.       end;
  549.  
  550. { ----- Rollback ----- }
  551.  
  552.    procedure TDemoApplication.Rollback;
  553.  
  554.       var
  555.          Dial   : PDialog;
  556.          C      : Word;
  557.  
  558.       begin
  559.          if DB <> nil
  560.             then begin
  561.                     if Confirm
  562.                        ( ^C'You are restoring database to its old state.'^M +
  563.                          ^C'Changes since last Commit will be lost !' ) =
  564.                        cmCancel
  565.                        then Exit;
  566.                     DB^.Abort;
  567.                  end
  568.             else HandleError ( ^C'No database is in use now !' )
  569.       end;
  570.  
  571. procedure RegisterAll;
  572.  
  573.     const
  574.        RCatCollection: TStreamRec =
  575.            ( ObjType : 10001;
  576.              VMTLink : Ofs(TypeOf(TCatCollection)^);
  577.              Load    : @TCatCollection.Load;
  578.              Store   : @TCatCollection.Store );
  579.  
  580.     begin
  581.        RegisterObjects;
  582.        RegisterViews;
  583.        RegisterDialogs;
  584.        RegisterType (RCatCollection)
  585.     end;
  586.  
  587. { ----- Program body ----- }
  588.  
  589.    var
  590.       DA     : TDemoApplication;
  591.  
  592.    begin
  593.       RegisterAll;
  594.       DA.Init;
  595.       DA.Run;
  596.       DA.Done
  597.    end.