include/Ottoman.h
author Jens Alfke <jens@mooseyard.com>
Thu Sep 24 10:36:08 2009 -0700 (2009-09-24)
changeset 4 715d6147ba3a
parent 0 31a43d94cc26
permissions -rw-r--r--
* Fixed a bug in Ottoman: the parameterless constructor didn't initialize _file, leaving it garbage and leading to a crash if you deleted the object without saving.
* This bug was being hidden by another bug in saveAs which didn't delete the old _file.
* Also added a versionsChanged hook that subclasses can override.
     1 /*
     2  *  Ottoman.h
     3  *  Ottoman
     4  *
     5  *  Created by Jens Alfke on 8/31/09.
     6  *  Copyright 2009 Jens Alfke. All rights reserved.
     7  *  BSD-Licensed: See the file "LICENSE.txt" for details.
     8  */
     9 
    10 #ifndef _MOOSEYARD_OTTOMAN_
    11 #define _MOOSEYARD_OTTOMAN_
    12 
    13 namespace Mooseyard {
    14     
    15     class ChunkIterator;
    16     class Dictionary;
    17     class File;
    18     class VersionDictionary;
    19     class OverlayDictionary;
    20     
    21     
    22     /** A version-controlled persistent dictionary. 
    23         Each version is stored as a VersionDictionary, unsaved changes as an OverlayDictionary. */
    24     class Ottoman {
    25     public:
    26         /** Creates an "untitled" Ottoman with no file and no lastVersion.
    27             After adding values to the currentVersion, use saveAs to save it. */
    28         Ottoman ();
    29         
    30         /** Opens an existing Ottoman file. */
    31         explicit Ottoman (const char *filename, bool writeable =true);
    32         
    33         /** Closes an Ottoman. */
    34         virtual ~Ottoman();
    35         
    36         /** The current filename, or NULL if the receiver is still in the "untitled" state. */
    37         virtual const char* filename() const                {return _filename;}
    38         
    39         /** The latest saved version of the dictionary. 
    40             Earlier versions can be accessed through its previousVersion() accessor.
    41             This will be NULL if the receiver is still in the "untitled" state. */
    42         virtual VersionDictionary* lastVersion() const         {return _lastVersion;}
    43         
    44         /** A mutable overlay representing the current state of the dictionary.
    45             Changes are made in memory until save() is called.
    46             This will be NULL if the receiver was opened read-only (writeable=false). */
    47         virtual OverlayDictionary* currentVersion() const   {return _current;}
    48         
    49         /** Has the on-disk file been updated with newer revisions than what I know about? */
    50         virtual bool needsSync() const;
    51         
    52         /** Reads any newer versions from disk.
    53             Returns true if new versions were read, false if there were none.
    54             Afterwards, lastVersion() will return the latest version in the file. 
    55             (The old lastVersion dictionary is still around, so you can save a pointer to it 
    56             before the call and use it later to see what changed.)
    57             Changes made to the currentVersion dictionary are not lost, but are now relative
    58             to the new lastVersion. You may want to scan them and resolve conflicts. */
    59         virtual bool sync();
    60         
    61         /** Saves the current version to the file, by appending.
    62             Returns false if there is a version conflict; in that case you need to call sync(),
    63             possibly resolve conflicts, and then call save() again. */
    64         virtual bool save();
    65         
    66         /** Saves the current version to the file, by writing to a new temporary file and
    67             then atomically replacing the original. 
    68             Older versions, and older copies of the data, are not preserved, so this
    69             will typically shrink the file quite a bit.
    70             Returns false if there is a version conflict. */
    71         virtual bool saveAndCompact();
    72          
    73         /** Saves the current version to a new file, leaving the new file open, 
    74             so subsequent saves will be written to it. */
    75         virtual void saveAs (const char *newFilename, bool overwriteAllowed =true);
    76         
    77         /** Scans the file for damage. Returns true if the file is OK, false if problems are found.
    78             If the 'repair' flag is set, will truncate the file to the last valid version. */
    79         bool scavenge (bool repair =false);
    80         
    81         ChunkIterator* chunkIterator() const;       // for testing purposes
    82         
    83     protected:
    84         /** Hook for subclassers: Called when new versions are added. */
    85         virtual void versionsChanged()                          { }
    86 
    87     private:
    88         Ottoman(const Ottoman&);            // forbid copying/assignment
    89         Ottoman& operator=(const Ottoman&);
    90         
    91         void _open();
    92         void _append (File *dstFile);
    93         File* _writeTo (const char *dstFileName, bool overwriteAllowed);
    94         
    95         bool _writeable;
    96         File *_file;
    97         char *_filename;
    98         VersionDictionary *_lastVersion;
    99         OverlayDictionary *_current;
   100     };
   101     
   102 }
   103 #endif // _MOOSEYARD_OTTOMAN_