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: - File:
class File : public std::fstream { class File : public std::fstream {
private: private:
- Return false if the file has FILE_TYPE_LEGACY set
unsigned int version; unsigned int version;
OpenMode mode; OpenMode mode;
FileLocHint hint; FileLocHint hint;
- Return false if the file has FILE_TYPE_LEGACY set
string filepath; string filepath;
public: public:
@ -306,7 +304,7 @@ Database:
T *Database :: insert(const T &item); T *Database :: insert(const T &item);
Look up the item in the _keys map. Look up the item in the _keys map.
If we find an item with the same key: If we find an item with the same key:
- Return a pointer to the found item. - Return NULL.
Otherwise: Otherwise:
- Use new to allocate memory for a new item. - Use new to allocate memory for a new item.
- Add the new item to the end of the _db. - 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. Add a new track to the track_db and return a pointer to it.
Return NULL if this track is already in the database. 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); Library *tagdb :: add_library(const std::string &filepath);
Add a new path to library_db. Return a pointer to the new path 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. 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()); T *t = find(val.primary_key());
if (t != NULL) if (t != NULL)
return t; return NULL;
t = new T(val); t = new T(val);
_db.push_back(t); _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); 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() void Track :: tag()
{ {
TagLib :: Tag *tag; TagLib :: Tag *tag;
@ -227,9 +236,9 @@ void Track :: tag()
tag = ref.tag(); tag = ref.tag();
audio = ref.audioProperties(); audio = ref.audioProperties();
artist = artist_db.insert(Artist(format_tag(tag->artist()))); artist = find_or_insert(Artist(format_tag(tag->artist())), artist_db);
album = album_db.insert(Album(format_tag(tag->album()), tag->year())); album = find_or_insert(Album(format_tag(tag->album()), tag->year()), album_db);
genre = genre_db.insert(Genre(format_tag(tag->genre()))); genre = find_or_insert(Genre(format_tag(tag->genre())), genre_db);
track = tag->track(); track = tag->track();
length = audio->length(); length = audio->length();
title = format_tag(tag->title()); title = format_tag(tag->title());
@ -331,21 +340,15 @@ void tagdb :: commit_library()
Track *tagdb :: add_track(const std::string &filepath, Library *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)); Track *track = track_db.insert(Track(filepath, library));
if (size == track_db.size()) if (track)
return NULL; track->tag();
track->tag();
return track; return track;
} }
Library *tagdb :: add_library(const std::string &filepath) Library *tagdb :: add_library(const std::string &filepath)
{ {
unsigned int size = library_db.size(); return library_db.insert(Library(filepath));
Library *library = library_db.insert(Library(filepath));
if (size == library_db.size())
return NULL;
return library;
} }
void tagdb :: remove_track(unsigned int track_id) 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++) { for (unsigned int i = 0; i < n; i++) {
IntEntry *it = db.insert(IntEntry(i)); IntEntry *it = db.insert(IntEntry(i));
if (it->id != i) if (it != NULL)
test_results(false, __LINE__);
if (i == 1 && it != one)
test_results(false, __LINE__);
if (i == 3 && it != three)
test_results(false, __LINE__); test_results(false, __LINE__);
} }
test_results(true, __LINE__); test_results(true, __LINE__);
@ -205,14 +201,14 @@ int main(int argc, char **argv)
* 9. Test inserting once again * 9. Test inserting once again
*/ */
for (unsigned int i = 0; i < n; i++) { for (unsigned int i = 0; i < n; i++) {
index = db.insert(IntEntry(i))->id; IntEntry *it = db.insert(IntEntry(i));
if ((i % 2) == 0) { if ((i % 2) == 0) {
size++; size++;
actual++; actual++;
if (index != (n + (i / 2))) if (it->id != (n + (i / 2)))
test_results(false, __LINE__); test_results(false, __LINE__);
} else { } else {
if (index != i) if (it != NULL)
test_results(false, __LINE__); test_results(false, __LINE__);
} }
} }

View File

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