1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
#pragma once
#include <QHash>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QString>
#include <gsl/pointers>
#include <map>
#include "library/dao/dao.h"
#include "library/itunes/itunespathmapping.h"
#include "library/treeitem.h"
const int kRootITunesPlaylistId = -1;
struct ITunesTrack {
int id;
QString artist;
QString title;
QString album;
QString albumArtist;
QString genre;
QString grouping;
int year;
int duration;
QString location;
int rating;
QString comment;
int trackNumber;
int bpm;
int bitrate;
#if __cplusplus >= 202002L
bool operator==(const ITunesTrack&) const = default;
bool operator!=(const ITunesTrack&) const = default;
#else
bool operator==(const ITunesTrack& other) const {
return (id == other.id &&
artist == other.artist &&
title == other.title &&
album == other.album &&
albumArtist == other.albumArtist &&
genre == other.genre &&
grouping == other.grouping &&
year == other.year &&
duration == other.duration &&
location == other.location &&
rating == other.rating &&
comment == other.comment &&
trackNumber == other.trackNumber &&
bpm == other.bpm &&
bitrate == other.bitrate);
}
#endif
};
struct ITunesPlaylist {
int id;
QString name;
#if __cplusplus >= 202002L
bool operator==(const ITunesPlaylist&) const = default;
bool operator!=(const ITunesPlaylist&) const = default;
#else
bool operator==(const ITunesPlaylist& other) const {
return (id == other.id &&
name == other.name);
}
#endif
};
std::ostream& operator<<(std::ostream& os, const ITunesTrack& track);
std::ostream& operator<<(std::ostream& os, const ITunesPlaylist& playlist);
/// A wrapper around the iTunes database tables. Keeps track of the
/// playlist tree, deals with duplicate disambiguation and can export
/// the tree afterwards.
class ITunesDAO : public DAO {
public:
~ITunesDAO() override = default;
void initialize(const QSqlDatabase& database) override;
virtual bool importTrack(const ITunesTrack& track);
virtual bool importPlaylist(const ITunesPlaylist& playlist);
virtual bool importPlaylistRelation(int parentId, int childId);
virtual bool importPlaylistTrack(int playlistId, int trackId, int position);
virtual bool applyPathMapping(const ITunesPathMapping& pathMapping);
virtual void appendPlaylistTree(gsl::not_null<TreeItem*> item,
int playlistId = kRootITunesPlaylistId);
private:
QHash<QString, int> m_playlistDuplicatesByName;
QHash<int, QString> m_playlistNameById;
std::multimap<int, int> m_playlistIdsByParentId;
// Keeps track of whether the database has been initialized.
// In tests the database is not used, so the importer will
// only be used to construct a TreeItem.
bool m_isDatabaseInitialized = false;
// Note that these queries reference the database, which is expected
// to outlive the DAO.
QSqlQuery m_insertTrackQuery;
QSqlQuery m_insertPlaylistQuery;
QSqlQuery m_insertPlaylistTrackQuery;
QSqlQuery m_applyPathMappingQuery;
QString uniquifyPlaylistName(QString name);
};
|