summaryrefslogtreecommitdiff
path: root/music.cpp
diff options
context:
space:
mode:
authorJon Bergli Heier <snakebite@jvnv.net>2011-01-06 04:01:17 +0100
committerJon Bergli Heier <snakebite@jvnv.net>2011-01-06 04:05:46 +0100
commit78c5f37d50ed5687bd5525954838f62b50de0690 (patch)
tree2def0d74af305f040f6e48e8f644621cd8add64e /music.cpp
parente755f01e631e832e3ef529049888d62af38d2b38 (diff)
Reworked "find" to allow for more sophisticated searches.
The usage of the "find" command is as follows: find SEARCH where SEARCH is either a simple string to search for, or key:value pairs with the following keys: artist album title
Diffstat (limited to 'music.cpp')
-rw-r--r--music.cpp70
1 files changed, 64 insertions, 6 deletions
diff --git a/music.cpp b/music.cpp
index eb16226..7356274 100644
--- a/music.cpp
+++ b/music.cpp
@@ -24,7 +24,7 @@ void music::init(std::string root) {
root_directory = root;
}
-/** Fetches a MusicListing object from the given path.
+/** Fetches a MusicListing object from the given \p path.
* Prefixes the given path with the music root directory.
* This can be either a track (file) or a directory.
*/
@@ -52,7 +52,7 @@ MusicListing::p music::get(const HTTP::Connection::PathList& path) {
return MusicListing::p();
}
-/** Fetches a MusicListing object from the given path.
+/** Fetches a MusicListing object from the given \p path.
* Splits the given string and calls the above function.
*/
MusicListing::p music::get(const std::string& path) {
@@ -74,21 +74,76 @@ MusicDirectory::p music::get_directory(const std::string& path) {
return dir;
}
-std::vector<MusicListing::p> music::find_artist(const std::string artist) {
+/** Find tracks in the database.
+ * Does a search on specific fields given by \p search.
+ */
+std::vector<MusicListing::p> music::find(std::map<std::string, std::string> search) {
+ soci::session sql(config::vm["audist.database"].as<std::string>());
+ soci::statement st(sql);
+ std::string filename, artist, album, title;
+ st.exchange(soci::into(filename));
+ std::string query = "SELECT file_name FROM tracks WHERE ";
+ std::vector<std::string> where_conditions;
+
+ if(search.find("artist") != search.end()) {
+ where_conditions.push_back("artist_id IN (SELECT id FROM artists WHERE name LIKE :artist)");
+ artist = "%"+search["artist"]+"%";
+ st.exchange(soci::use(artist, "artist"));
+ }
+
+ if(search.find("album") != search.end()) {
+ where_conditions.push_back("album_id IN (SELECT id FROM albums WHERE name LIKE :album)");
+ album = "%"+search["album"]+"%";
+ st.exchange(soci::use(album, "album"));
+ }
+
+ if(search.find("title") != search.end()) {
+ where_conditions.push_back("name LIKE :title");
+ artist = "%"+search["title"]+"%";
+ st.exchange(soci::use(title, "title"));
+ }
+
+ query += boost::algorithm::join(where_conditions, " AND ");
+ st.alloc();
+ st.prepare(query);
+ st.define_and_bind();
+ std::cout << "query: " << query << std::endl;
+ std::cout << "st.execute: " << st.execute(true) << std::endl;
+ std::cout << "st.got_data: " << st.got_data() << std::endl;
+
+ std::vector<MusicListing::p> results;
+ while(st.fetch()) {
+ MusicListing::p ml(new MusicTrack(filename));
+ results.push_back(ml);
+ }
+ sql.close();
+
+ return results;
+}
+
+/** Find tracks in the database.
+ * Returns tracks where title, artist, album or filename matches \p search.
+ */
+std::vector<MusicListing::p> music::find(std::string search) {
soci::session sql(config::vm["audist.database"].as<std::string>());
- soci::rowset<std::string> rs = (sql.prepare << "SELECT file_name FROM tracks WHERE artist_id IN (SELECT id FROM artists WHERE name LIKE :name)",
- soci::use("%"+artist+"%"));
+ search = "%"+search+"%";
+ soci::rowset<std::string> rs = (sql.prepare << "SELECT DISTINCT file_name FROM tracks WHERE name LIKE :search OR file_name LIKE :search OR "
+ "artist_id IN (SELECT id FROM artists WHERE name LIKE :search) OR album_id IN (SELECT id FROM albums WHERE name LIKE :search)",
+ soci::use(search, "search"));
std::vector<MusicListing::p> results;
for(soci::rowset<std::string>::const_iterator it = rs.begin(); it != rs.end(); it++) {
- boost::shared_ptr<MusicListing> ml(new MusicTrack(*it));
+ MusicListing::p ml(new MusicTrack(*it));
results.push_back(ml);
}
return results;
}
+/** Initiate an update on \p path and its subdirs.
+ * music::update does the actual work.
+ */
void music::begin_update(const std::string path) {
MusicDirectory::p dir = get_directory(path);
std::cout << boost::format("updater(%s) called") % path << std::endl;
@@ -97,7 +152,10 @@ void music::begin_update(const std::string path) {
}
}
+/** Recursively update \p dir and its subdirectories.
+ */
void music::update(const MusicDirectory& dir) {
+ // TODO: Fix engine-specific SQL syntax inside this function.
soci::session sql(config::vm["audist.database"].as<std::string>());
BOOST_FOREACH(fs::path t, dir.tracks) {