-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
TrackRef = Track Location + Track ID #901
Closed
Closed
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
e2f8010
Cleanup includes for TrackInfoObject
uklotzde e732c44
Reorder member function in TrackInfoObject
uklotzde f02e7fc
Reorder some includes
uklotzde d673284
Encapsulate location and id of tracks in TrackRef
uklotzde 2eacde6
Move construction from QFileInfo into a separate factory function
uklotzde File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
#include <gtest/gtest.h> | ||
|
||
#include <QDir> | ||
#include <QTemporaryFile> | ||
#include <QtDebug> | ||
|
||
#include "track/trackref.h" | ||
|
||
namespace { | ||
|
||
class TrackRefTest : public testing::Test { | ||
protected: | ||
|
||
TrackRefTest() | ||
: m_tempFile("TrackRefTest.tmp"), | ||
m_tempFileDir(QDir::tempPath()), | ||
m_tempFileName(m_tempFile.fileName()), | ||
m_tempFileInfo(m_tempFileDir, m_tempFileName), | ||
m_validTrackId(123) { | ||
} | ||
|
||
virtual void SetUp() { | ||
ASSERT_TRUE(m_validTrackId.isValid()); | ||
ASSERT_FALSE(m_invalidTrackId.isValid()); | ||
} | ||
|
||
virtual void TearDown() { | ||
} | ||
|
||
static void verifyFileInfo(const TrackRef& actual, const QFileInfo& fileInfo) { | ||
EXPECT_TRUE(actual.hasLocation()); | ||
EXPECT_EQ(TrackRef::location(fileInfo), actual.getLocation()); | ||
EXPECT_TRUE(actual.hasCanonicalLocation()); | ||
EXPECT_EQ(TrackRef::canonicalLocation(fileInfo), actual.getCanonicalLocation()); | ||
} | ||
|
||
const QTemporaryFile m_tempFile; | ||
const QDir m_tempFileDir; | ||
const QString m_tempFileName; | ||
const QFileInfo m_tempFileInfo; | ||
const TrackId m_validTrackId; | ||
const TrackId m_invalidTrackId; | ||
}; | ||
|
||
TEST_F(TrackRefTest, DefaultConstructor) { | ||
TrackRef actual; | ||
|
||
EXPECT_FALSE(actual.hasLocation()); | ||
EXPECT_FALSE(actual.hasCanonicalLocation()); | ||
EXPECT_FALSE(actual.hasId()); | ||
} | ||
|
||
TEST_F(TrackRefTest, FromFileInfoWithId) { | ||
const TrackRef actual( | ||
TrackRef::fromFileInfo(m_tempFileInfo, m_validTrackId)); | ||
|
||
verifyFileInfo(actual, m_tempFileInfo); | ||
EXPECT_TRUE(actual.hasId()); | ||
EXPECT_EQ(m_validTrackId, actual.getId()); | ||
} | ||
|
||
TEST_F(TrackRefTest, FromFileInfoWithoutId) { | ||
const TrackRef actual( | ||
TrackRef::fromFileInfo(m_tempFileInfo)); | ||
|
||
verifyFileInfo(actual, m_tempFileInfo); | ||
EXPECT_FALSE(actual.hasId()); | ||
EXPECT_EQ(m_invalidTrackId, actual.getId()); | ||
} | ||
|
||
TEST_F(TrackRefTest, CopyAndSetId) { | ||
const TrackRef withoutId( | ||
TrackRef::fromFileInfo(m_tempFileInfo)); | ||
|
||
const TrackRef actual(withoutId, m_validTrackId); | ||
|
||
verifyFileInfo(actual, m_tempFileInfo); | ||
EXPECT_TRUE(actual.hasId()); | ||
EXPECT_EQ(m_validTrackId, actual.getId()); | ||
} | ||
|
||
} // namespace |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
#include "track/trackref.h" | ||
|
||
|
||
bool TrackRef::verifyConsistency() const { | ||
DEBUG_ASSERT_AND_HANDLE(hasLocation() || !hasCanonicalLocation()) { | ||
return false; | ||
} | ||
DEBUG_ASSERT_AND_HANDLE(hasLocation() || !hasId()) { | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
std::ostream& operator<<(std::ostream& os, const TrackRef& trackRef) { | ||
return os << '[' << trackRef.getLocation().toStdString() | ||
<< " | " << trackRef.getCanonicalLocation().toStdString() | ||
<< " | " << trackRef.getId() | ||
<< ']'; | ||
|
||
} | ||
|
||
QDebug operator<<(QDebug debug, const TrackRef& trackRef) { | ||
debug.nospace() << '[' << trackRef.getLocation() | ||
<< " | " << trackRef.getCanonicalLocation() | ||
<< " | " << trackRef.getId() | ||
<< ']'; | ||
return debug.space(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
#ifndef TRACKREF_H | ||
#define TRACKREF_H | ||
|
||
|
||
#include <QFileInfo> | ||
|
||
#include "track/trackid.h" | ||
|
||
|
||
// A track in the library is identified by a location and an id. | ||
// The location is mandatory to identify the file, whereas the id | ||
// only exists after the track has been inserted into the database. | ||
// | ||
// This class is intended to be used as a simple, almost immutable | ||
// value object. Only the id can be set once. | ||
class TrackRef { | ||
public: | ||
// All file-related track properties are snapshots from the provided | ||
// QFileInfo. Obtaining them might involve accessing the file system | ||
// and should be used consciously! The QFileInfo class does some | ||
// caching behind the scenes. | ||
// Please note that the canonical location of QFileInfo may change at | ||
// any time, when the underlying file system structure is modified. | ||
// It becomes empty if the file is deleted. | ||
static QString location(const QFileInfo& fileInfo) { | ||
return fileInfo.absoluteFilePath(); | ||
} | ||
static QString canonicalLocation(const QFileInfo& fileInfo) { | ||
return fileInfo.canonicalFilePath(); | ||
} | ||
|
||
// Converts a QFileInfo and an optional TrackId into a TrackRef. This | ||
// involves obtaining the file-related track properties from QFileInfo | ||
// (see above) and should used consciously! | ||
static TrackRef fromFileInfo( | ||
const QFileInfo& fileInfo, | ||
TrackId id = TrackId()) { | ||
return TrackRef( | ||
location(fileInfo), | ||
canonicalLocation(fileInfo), | ||
id); | ||
} | ||
|
||
// Default constructor | ||
TrackRef() { | ||
DEBUG_ASSERT(verifyConsistency()); | ||
} | ||
// Regular copy constructor | ||
TrackRef(const TrackRef& other) = default; | ||
// Custom copy constructor: Creates a copy of an existing TrackRef, | ||
// but overwrite the TrackId with a custom value. | ||
TrackRef( | ||
const TrackRef& other, | ||
TrackId id) | ||
: m_location(other.m_location), | ||
m_canonicalLocation(other.m_canonicalLocation), | ||
m_id(id) { | ||
DEBUG_ASSERT(verifyConsistency()); | ||
} | ||
|
||
// The human-readable identifier of a track in Mixxx. The location is | ||
// immutable and the starting point for accessing a track's file. | ||
const QString& getLocation() const { | ||
return m_location; | ||
} | ||
bool hasLocation() const { | ||
return !getLocation().isEmpty(); | ||
} | ||
|
||
// The unique identifier of a track's file at runtime and used | ||
// for caching. The canonical location is empty for inexistent | ||
// files. | ||
const QString& getCanonicalLocation() const { | ||
return m_canonicalLocation; | ||
} | ||
bool hasCanonicalLocation() const { | ||
return !getCanonicalLocation().isEmpty(); | ||
} | ||
|
||
// The primary key of a track in the Mixxx library. The id must only | ||
// be set once after inserting into or after loading from the database. | ||
// Tracks that have not been stored in the database don't have an id. | ||
const TrackId& getId() const { | ||
return m_id; | ||
} | ||
bool hasId() const { | ||
return getId().isValid(); | ||
} | ||
|
||
bool isValid() const { | ||
return hasId() || hasCanonicalLocation(); | ||
} | ||
protected: | ||
// Initializing constructor | ||
TrackRef( | ||
const QString& location, | ||
const QString& canonicalLocation, | ||
TrackId id = TrackId()) | ||
: m_location(location), | ||
m_canonicalLocation(canonicalLocation), | ||
m_id(id) { | ||
DEBUG_ASSERT(verifyConsistency()); | ||
} | ||
|
||
private: | ||
bool verifyConsistency() const; | ||
|
||
QString m_location; | ||
QString m_canonicalLocation; | ||
TrackId m_id; | ||
}; | ||
|
||
inline | ||
bool operator==(const TrackRef& lhs, const TrackRef& rhs) { | ||
return (lhs.getId() == rhs.getId()) && | ||
(lhs.getLocation() == rhs.getLocation()) && | ||
(lhs.getCanonicalLocation() == rhs.getCanonicalLocation()); | ||
} | ||
|
||
inline | ||
bool operator!=(const TrackRef& lhs, const TrackRef& rhs) { | ||
return !(lhs == rhs); | ||
} | ||
|
||
Q_DECLARE_METATYPE(TrackRef) | ||
|
||
std::ostream& operator<<(std::ostream& os, const TrackRef& trackRef); | ||
|
||
QDebug operator<<(QDebug debug, const TrackRef& trackRef); | ||
|
||
|
||
#endif // TRACKREF_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a candidate for missus since it might fail even if we reference the same track.
I would prefer to introduce a named function for comparing.
Like isRefferencingTheSameTrack() or similar.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't agree. This is the canonical implementation of the equality operator
for a simple value object, member by member.
If on the other hand the class name of TrackRef is misleading than we should
instead choose a different one.
On 03/04/2016 04:02 PM, Daniel Schürmann wrote: