database: Return NULL when inserting a duplicate item

This provides us a more straightforward way to determine if the database
changed.

Signed-off-by: Anna Schumaker <Anna@OcarinaProject.net>
This commit is contained in:
Anna Schumaker 2014-04-12 13:48:59 -04:00
parent 5ff68140b5
commit 44f62028c3
5 changed files with 22 additions and 28 deletions

7
DESIGN
View File

@ -114,11 +114,9 @@ On-disk files:
- File:
class File : public std::fstream {
private:
- Return false if the file has FILE_TYPE_LEGACY set
unsigned int version;
OpenMode mode;
FileLocHint hint;
- Return false if the file has FILE_TYPE_LEGACY set
string filepath;
public:
@ -306,7 +304,7 @@ Database:
T *Database :: insert(const T &item);
Look up the item in the _keys map.
If we find an item with the same key:
- Return a pointer to the found item.
- Return NULL.
Otherwise:
- Use new to allocate memory for a new item.
- Add the new item to the end of the _db.
@ -551,9 +549,6 @@ Tag Database:
Add a new track to the track_db and return a pointer to it.
Return NULL if this track is already in the database.
Check the database size both before and after to see if a new
track has been added.
Library *tagdb :: add_library(const std::string &filepath);
Add a new path to library_db. Return a pointer to the new path
or return NULL if the path is already in the database.

View File

@ -85,7 +85,7 @@ T *Database<T> :: insert(const T &val)
T *t = find(val.primary_key());
if (t != NULL)
return t;
return NULL;
t = new T(val);
_db.push_back(t);

View File

@ -213,6 +213,15 @@ static inline const std::string format_tag(const TagLib::String &str)
return str.stripWhiteSpace().to8Bit(true);
}
template <class T>
static T *find_or_insert(const T &tag, Database<T> &db)
{
T *ret = db.find(tag.primary_key());
if (!ret)
ret = db.insert(tag);
return ret;
}
void Track :: tag()
{
TagLib :: Tag *tag;
@ -227,9 +236,9 @@ void Track :: tag()
tag = ref.tag();
audio = ref.audioProperties();
artist = artist_db.insert(Artist(format_tag(tag->artist())));
album = album_db.insert(Album(format_tag(tag->album()), tag->year()));
genre = genre_db.insert(Genre(format_tag(tag->genre())));
artist = find_or_insert(Artist(format_tag(tag->artist())), artist_db);
album = find_or_insert(Album(format_tag(tag->album()), tag->year()), album_db);
genre = find_or_insert(Genre(format_tag(tag->genre())), genre_db);
track = tag->track();
length = audio->length();
title = format_tag(tag->title());
@ -331,21 +340,15 @@ void tagdb :: commit_library()
Track *tagdb :: add_track(const std::string &filepath, Library *library)
{
unsigned int size = track_db.size();
Track *track = track_db.insert(Track(filepath, library));
if (size == track_db.size())
return NULL;
track->tag();
if (track)
track->tag();
return track;
}
Library *tagdb :: add_library(const std::string &filepath)
{
unsigned int size = library_db.size();
Library *library = library_db.insert(Library(filepath));
if (size == library_db.size())
return NULL;
return library;
return library_db.insert(Library(filepath));
}
void tagdb :: remove_track(unsigned int track_id)

View File

@ -119,11 +119,7 @@ int main(int argc, char **argv)
*/
for (unsigned int i = 0; i < n; i++) {
IntEntry *it = db.insert(IntEntry(i));
if (it->id != i)
test_results(false, __LINE__);
if (i == 1 && it != one)
test_results(false, __LINE__);
if (i == 3 && it != three)
if (it != NULL)
test_results(false, __LINE__);
}
test_results(true, __LINE__);
@ -205,14 +201,14 @@ int main(int argc, char **argv)
* 9. Test inserting once again
*/
for (unsigned int i = 0; i < n; i++) {
index = db.insert(IntEntry(i))->id;
IntEntry *it = db.insert(IntEntry(i));
if ((i % 2) == 0) {
size++;
actual++;
if (index != (n + (i / 2)))
if (it->id != (n + (i / 2)))
test_results(false, __LINE__);
} else {
if (index != i)
if (it != NULL)
test_results(false, __LINE__);
}
}

View File

@ -123,7 +123,7 @@ test_tracks:
tagdb :: remove_library(library->id);
test_track_size(0, __LINE__);
library = tagdb :: add_library("Music");
if (init_called == true)
tagdb :: commit();