Hydra 0.20
hydra.src/hydra/Records.h
00001 
00002 /*
00003  * Copyright (c) 2010 Aleksander B. Demko
00004  * This source code is distributed under the MIT license.
00005  * See the accompanying file LICENSE.MIT.txt for details.
00006  */
00007 
00008 #ifndef __INCLUDED_HYDRA_RECORDS_H__
00009 #define __INCLUDED_HYDRA_RECORDS_H__
00010 
00011 #include <set>
00012 
00013 #include <QUuid>
00014 #include <QDateTime>
00015 
00016 #include <hydra/DB.h>
00017 
00018 namespace hydra
00019 {
00020   inline quint64 dateTimeAsInt64(const QDateTime &dt) {
00021     // in the future, make this 64-bit compatible
00022     if (dt.isValid())
00023       return dt.toTime_t();
00024     else
00025       return 0;
00026   }
00027 
00028   inline void int64ToDateTime(quint64 i, QDateTime &out) {
00029     // in the future, make this 64-bit compatible
00030     if (i == 0)
00031       out = QDateTime();
00032     else
00033       out.setTime_t(static_cast<uint>(i));
00034   }
00035 
00036   class FilePathRecord;
00037   class FileHashRecord;
00038 
00039   class Tags;
00040 
00041   class FileItemRecord;
00042 }
00043 
00044 /**
00045  * Keys file paths to hashes.
00046  *
00047  * These are stored in the cache database, as this
00048  * information can always be regenerated by
00049  * rehashing the disk files.
00050  *
00051  * key=full_path_name
00052  * dbfile=cache1.sqlite table=filepaths
00053  *
00054  * @author Aleksander Demko
00055  */ 
00056 class hydra::FilePathRecord : public hydra::Record
00057 {
00058   public:
00059     QString hash;      // the hash this filepath last hased too
00060     double file_time;   // for change checking
00061     qint64 file_size;    // for change checking
00062   public:
00063     FilePathRecord(void);
00064     virtual void save(QDataStream &out) const;
00065     virtual void load(QDataStream &in);
00066 };
00067 
00068 /**
00069  * Keys hashes to item ids.
00070  *
00071  * This maps a hash string to a file item id.
00072  * Since a "file" can have multiple hashes,
00073  * there can be multiple hydra::FileHashRecord
00074  * pointing to the same hydra::FileItemRecord
00075  *
00076  * key=hash_string
00077  * dbfile=main.sqlite table=filehashes
00078  *
00079  * @author Aleksander Demko
00080  */ 
00081 class hydra::FileHashRecord : public hydra::Record
00082 {
00083   public:
00084     QUuid id;    // the id of the fileitem this hash is refering too
00085   public:
00086     FileHashRecord(void);
00087     virtual void save(QDataStream &out) const;
00088     virtual void load(QDataStream &in);
00089 };
00090 
00091 /**
00092  * A set or tags (strings).
00093  *
00094  * A std::set derived class that provides additional
00095  * useful functions for dealing with tag sets.
00096  *
00097  * @author Aleksander Demko
00098  */ 
00099 class hydra::Tags : public std::set<QString>
00100 {
00101   public:
00102     const static char SEP_CHAR = '=';
00103 
00104     typedef std::set<QString> parent_t;
00105     typedef std::set<QString> set_t;
00106   public:
00107     Tags(void);
00108 
00109     /// debugPrint function
00110     void debugPrint(void) const;
00111 
00112     /**
00113      * Sets the given tag, while maintaining some consistancy (for example, = key values).
00114      * This is prefered over direct write access to the std::set class. In the future,
00115      * direct access may be eliminated (or the whole thing replaced with a map?)
00116      *
00117      * If imageChanged is non-null AND this operation changes the image (rotate tags),
00118      * then *imageChanged will be set to true. It will be untouched otherwise.
00119      *
00120      * @param tag the tag to insert/set.
00121      * @param imageChanged was the image "changed"
00122      * @return true if the tags where modified (and probably need to be commited)
00123      * @author Aleksander Demko
00124      */ 
00125     bool insertTag(const QString &newtag, bool *imageChanged=0);
00126 
00127     /**
00128      * Erases a tag. See insertTag for API info.
00129      *
00130      * @author Aleksander Demko
00131      */ 
00132     bool eraseTag(const QString &newtag, bool *imageChanged=0);
00133 
00134     /**
00135      * Erases all the tags. See insertTag for API info.
00136      *
00137      * @author Aleksander Demko
00138      */ 
00139     bool clearTags(bool *imageChanged=0);
00140 
00141     /**
00142      * Check if this tag set has the given key.
00143      * Key-values look like: key=value
00144      * Note that if there is no =, then it is not a valid key-value. Therefore basic tags will return false for this test.
00145      *
00146      * TODO in the future, switch the hole Tags concept to a std::map, which would
00147      * be optimized for empty-values (as 99% of the tags wont have any values)... or not
00148      *
00149      * @author Aleksander Demko
00150      */ 
00151     bool containsKey(const QString &key) const;
00152 
00153     /**
00154      * Sets the current value for the given key.
00155      * Returns true if anything was done.
00156      *
00157      * @author Aleksander Demko
00158      */ 
00159     bool insertKey(const QString &key, const QString &value, bool *imageChanged=0);
00160 
00161     /**
00162      * Erase the given key, no matter what's its value.
00163      * Returns true if anything was erased, false otherwise.
00164      *
00165      * @author Aleksander Demko
00166      */
00167     bool eraseKey(const QString &key, bool *imageChanged=0);
00168 
00169     /**
00170      * Return the given value for the given key.
00171      * Returns "" if this key doesnt exist.
00172      * Key-values look like: key=value
00173      * Note that if there is no =, then it is not a valid key-value. Therefore basic tags will return false for this test.
00174      *
00175      * TODO in the future, switch the hole Tags concept to a std::map, which would
00176      * be optimized for empty-values (as 99% of the tags wont have any values)... or not
00177      *
00178      * @author Aleksander Demko
00179      */ 
00180     QString keyValue(const QString &key) const;
00181 
00182     /**
00183      * Returns the index of the keyvalue seperator, or -1 for not found.
00184      *
00185      * @author Aleksander Demko
00186      */ 
00187     static inline int indexOfKeyValue(const QString &s) { return s.indexOf(SEP_CHAR); }
00188 };
00189 
00190 /**
00191  * The main file record, keyed by their UUID.
00192  * This contains all the information, like tags,
00193  * for a particular file.
00194  *
00195  * key=UUID
00196  * db=main.sqlite table=fileitems
00197  *
00198  * @author Aleksander Demko
00199  */ 
00200 class hydra::FileItemRecord : public hydra::Record
00201 {
00202   public:
00203     typedef hydra::Tags tags_t;
00204 
00205     QUuid id;    // my own id, duplicated from the key, to ease processing (technically redundant)
00206 
00207     QString title, desc;
00208 
00209     qint32 filetype; // 0 for image, 1 for "other" ... for now...
00210 
00211     tags_t tags;      // although you can have 0 tags, tag strings themselve cannot be empty (0-length)
00212 
00213     /**
00214      * The modificationTime of this record
00215      * new records are created with invalid QDateTime
00216      * only after the user deliberatly updates the record
00217      * does the record get a real modtime.
00218      *
00219      * (move this to the DB layer eventually? - probably not, as this is very specific)
00220      * @author Aleksander Demko
00221      */ 
00222     QDateTime modtime;
00223 
00224     // comments, permissions, etc
00225 
00226   public:
00227     FileItemRecord(void);
00228     virtual void save(QDataStream &out) const;
00229     virtual void load(QDataStream &in);
00230 
00231     quint64 modtimeAsInt64(void) const {
00232       return dateTimeAsInt64(modtime);
00233     }
00234     void setModtimeFromInt64(quint64 i) {
00235       int64ToDateTime(i, modtime);
00236     }
00237 };
00238 
00239 #endif
00240 
 All Classes Namespaces Functions Variables