/[svn]/linuxsampler/trunk/src/db/InstrumentsDb.cpp
ViewVC logotype

Diff of /linuxsampler/trunk/src/db/InstrumentsDb.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1781 by iliev, Mon Sep 29 18:21:21 2008 UTC revision 1911 by senoner, Sat Jun 6 13:50:36 2009 UTC
# Line 1  Line 1 
1  /***************************************************************************  /***************************************************************************
2   *                                                                         *   *                                                                         *
3   *   Copyright (C) 2007, 2008 Grigor Iliev                                 *   *   Copyright (C) 2007-2009 Grigor Iliev, Benno Senoner                   *
4   *                                                                         *   *                                                                         *
5   *   This program is free software; you can redistribute it and/or modify  *   *   This program is free software; you can redistribute it and/or modify  *
6   *   it under the terms of the GNU General Public License as published by  *   *   it under the terms of the GNU General Public License as published by  *
# Line 21  Line 21 
21  #include "InstrumentsDb.h"  #include "InstrumentsDb.h"
22    
23  #include "../common/File.h"  #include "../common/File.h"
24    #include "../common/Path.h"
25  #include "../common/global_private.h"  #include "../common/global_private.h"
26    
27  #include <iostream>  #include <iostream>
28  #include <sstream>  #include <sstream>
29  #include <vector>  #include <vector>
30  #include <errno.h>  #include <errno.h>
31    #ifndef WIN32
32  #include <fnmatch.h>  #include <fnmatch.h>
33    #endif
34    
35  #include "../common/Exception.h"  #include "../common/Exception.h"
36    
# Line 86  namespace LinuxSampler { Line 89  namespace LinuxSampler {
89    
90      InstrumentsDb::InstrumentsDb() {      InstrumentsDb::InstrumentsDb() {
91          db = NULL;          db = NULL;
         DbInstrumentsMutex = Mutex();  
92          InTransaction = false;          InTransaction = false;
93      }      }
94    
# Line 119  namespace LinuxSampler { Line 121  namespace LinuxSampler {
121      sqlite3* InstrumentsDb::GetDb() {      sqlite3* InstrumentsDb::GetDb() {
122          if ( db != NULL) return db;          if ( db != NULL) return db;
123    
124          if (DbFile.empty()) DbFile = CONFIG_DEFAULT_INSTRUMENTS_DB_LOCATION;          if (DbFile.empty()) {
125                        #ifndef WIN32
126                        DbFile = CONFIG_DEFAULT_INSTRUMENTS_DB_LOCATION;
127                            #else
128                            char *userprofile = getenv("USERPROFILE");
129                            if(userprofile) {
130                                DbFile = userprofile;
131                                    DbFile += "\\.linuxsampler\\instruments.db";
132                        }
133                            else {
134                                // in case USERPROFILE is not set (which should not occur)
135                                DbFile = "instruments.db";
136                            }
137                            #endif
138                }
139                  #if defined(__APPLE__)  /* 20071224 Toshi Nagata  */                  #if defined(__APPLE__)  /* 20071224 Toshi Nagata  */
140                  if (DbFile.find("~") == 0)                  if (DbFile.find("~") == 0)
141                          DbFile.replace(0, 1, getenv("HOME"));                          DbFile.replace(0, 1, getenv("HOME"));
# Line 130  namespace LinuxSampler { Line 146  namespace LinuxSampler {
146              db = NULL;              db = NULL;
147              throw Exception("Cannot open instruments database: " + DbFile);              throw Exception("Cannot open instruments database: " + DbFile);
148          }          }
149    #ifndef WIN32
150          rc = sqlite3_create_function(db, "regexp", 2, SQLITE_UTF8, NULL, Regexp, NULL, NULL);          rc = sqlite3_create_function(db, "regexp", 2, SQLITE_UTF8, NULL, Regexp, NULL, NULL);
151          if (rc) { throw Exception("Failed to add user function for handling regular expressions."); }          if (rc) { throw Exception("Failed to add user function for handling regular expressions."); }
152    #endif
153    
154          // TODO: remove this in the next version          // TODO: remove this in the next version
155          try {          try {
# Line 704  namespace LinuxSampler { Line 722  namespace LinuxSampler {
722                  throw Exception(ss.str());                  throw Exception(ss.str());
723              }              }
724    
725                          if(insDir) {              String dir = insDir ? PrepareSubdirectory(DbDir, FilePath) : DbDir;
726                                  std::string tmp = f.basename(FilePath, ".");              AddInstrumentsFromFile(dir, FilePath, Index, pProgress);
                                 String gigDir;  
                                 if(DbDir.length() == 1 && DbDir.at(0) == '/') //DbDir is /  
                                         gigDir = DbDir + (String)tmp + "/";  
                                 else  
                                         gigDir = DbDir +"/"+ (String)tmp + "/";  
                                 dmsg(2,("InstrumentsDb: AddInstrumentsNonrecursive(Dir from file mode=%d, Created SubDir=%s)\n",insDir, gigDir.c_str()));  
                 DbInstrumentsMutex.Unlock();  
                                 AddDirectory(gigDir);//TODO: Add some error checking here to make sure the dir is created  
                 DbInstrumentsMutex.Lock();  
                 AddInstrumentsFromFile(gigDir, FilePath, Index, pProgress);  
                         } else {  
                 AddInstrumentsFromFile(DbDir, FilePath, Index, pProgress);  
                         }  
727          } catch (Exception e) {          } catch (Exception e) {
728              DbInstrumentsMutex.Unlock();              DbInstrumentsMutex.Unlock();
729              throw e;              throw e;
# Line 754  namespace LinuxSampler { Line 759  namespace LinuxSampler {
759              try {              try {
760                  FileListPtr fileList = File::GetFiles(FsDir);                  FileListPtr fileList = File::GetFiles(FsDir);
761                  for (int i = 0; i < fileList->size(); i++) {                  for (int i = 0; i < fileList->size(); i++) {
762                                          if(insDir)                      String dir = insDir ? PrepareSubdirectory(DbDir, fileList->at(i)) : DbDir;
763                                          {                                          AddInstrumentsFromFile(dir, FsDir + fileList->at(i), -1, pProgress);
                                                 //File gFile = File(fileList->at(i));  
                                                 String gigDir;  
                                                 if(DbDir.length() == 1 && DbDir.at(0) == '/') //DbDir is /  
                                                         gigDir  = DbDir + f.basename(fileList->at(i),".") + "/";  
                                                 else  
                                                         gigDir  = DbDir +"/"+ f.basename(fileList->at(i),".") + "/";  
                                                 dmsg(2,("InstrumentsDb: AddInstrumentsNonrecursive(Dir from file mode=%d, Created SubDir=%s)\n",insDir, gigDir.c_str()));  
                                 DbInstrumentsMutex.Unlock(); // UnLock the db so we can add our extra directory  
                                                 AddDirectory(gigDir);//TODO: Add some error checking here to make sure the dir is created  
                                         DbInstrumentsMutex.Lock(); //Lock and carry on  
                         AddInstrumentsFromFile(gigDir, FsDir + fileList->at(i), -1, pProgress);  
                                         }  
                                         else  
                                         {  
                         AddInstrumentsFromFile(DbDir, FsDir + fileList->at(i), -1, pProgress);  
                                         }  
764                  }                  }
765              } catch(Exception e) {              } catch(Exception e) {
766                  e.PrintMessage();                  e.PrintMessage();
# Line 1205  namespace LinuxSampler { Line 1194  namespace LinuxSampler {
1194              throw Exception(ss.str());              throw Exception(ss.str());
1195          }          }
1196    
1197            bool unlocked = false;
1198          RIFF::File* riff = NULL;          RIFF::File* riff = NULL;
1199          gig::File* gig = NULL;          gig::File* gig = NULL;
1200          try {          try {
# Line 1225  namespace LinuxSampler { Line 1215  namespace LinuxSampler {
1215                  throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));                  throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));
1216              }              }
1217    
1218              String s = toEscapedFsPath(FilePath);              String s = FilePath;
1219    
1220                #if WIN32
1221                for (int i = 0; i < s.length(); i++) {
1222                    if (s[i] == '\\') s[i] = '/';
1223                }
1224                #endif
1225    
1226                s = toEscapedFsPath(s);
1227              BindTextParam(pStmt, 2, s);              BindTextParam(pStmt, 2, s);
1228              String ver = "";              String ver = "";
1229              if (gig->pVersion != NULL) ver = ToString(gig->pVersion->major);              if (gig->pVersion != NULL) ver = ToString(gig->pVersion->major);
# Line 1233  namespace LinuxSampler { Line 1231  namespace LinuxSampler {
1231    
1232              if (Index == -1) {              if (Index == -1) {
1233                  int instrIndex = 0;                  int instrIndex = 0;
1234                    // Assume that it's locked and should be unlocked at this point
1235                    // to be able to use the database from another threads
1236                    if (!InTransaction) {
1237                        DbInstrumentsMutex.Unlock();
1238                        unlocked = true;
1239                    } else {
1240                        std::cerr << "Shouldn't be in transaction when adding instruments." << std::endl;
1241                    }
1242    
1243                  if (pProgress != NULL) gig->GetInstrument(0, &(pProgress->GigFileProgress)); // TODO: this workaround should be fixed                  if (pProgress != NULL) gig->GetInstrument(0, &(pProgress->GigFileProgress)); // TODO: this workaround should be fixed
1244                  gig::Instrument* pInstrument = gig->GetFirstInstrument();                  gig::Instrument* pInstrument = gig->GetFirstInstrument();
1245    
1246                    if (!InTransaction) DbInstrumentsMutex.Lock();
1247                  while (pInstrument) {                  while (pInstrument) {
1248                      BindTextParam(pStmt, 7, gig->pInfo->Product);                      BindTextParam(pStmt, 7, gig->pInfo->Product);
1249                      BindTextParam(pStmt, 8, gig->pInfo->Artists);                      BindTextParam(pStmt, 8, gig->pInfo->Artists);
# Line 1262  namespace LinuxSampler { Line 1271  namespace LinuxSampler {
1271          } catch (RIFF::Exception e) {          } catch (RIFF::Exception e) {
1272              if (gig != NULL) delete gig;              if (gig != NULL) delete gig;
1273              if (riff != NULL) delete riff;              if (riff != NULL) delete riff;
1274                if (unlocked) DbInstrumentsMutex.Lock();
1275              std::stringstream ss;              std::stringstream ss;
1276              ss << "Failed to scan `" << FilePath << "`: " << e.Message;              ss << "Failed to scan `" << FilePath << "`: " << e.Message;
1277                            
# Line 1269  namespace LinuxSampler { Line 1279  namespace LinuxSampler {
1279          } catch (Exception e) {          } catch (Exception e) {
1280              if (gig != NULL) delete gig;              if (gig != NULL) delete gig;
1281              if (riff != NULL) delete riff;              if (riff != NULL) delete riff;
1282                if (unlocked) DbInstrumentsMutex.Lock();
1283              throw e;              throw e;
1284          } catch (...) {          } catch (...) {
1285              if (gig != NULL) delete gig;              if (gig != NULL) delete gig;
1286              if (riff != NULL) delete riff;              if (riff != NULL) delete riff;
1287                if (unlocked) DbInstrumentsMutex.Lock();
1288              throw Exception("Failed to scan `" + FilePath + "`");              throw Exception("Failed to scan `" + FilePath + "`");
1289          }          }
1290      }      }
# Line 1281  namespace LinuxSampler { Line 1293  namespace LinuxSampler {
1293          dmsg(2,("InstrumentsDb: AddGigInstrument(DbDir=%s,DirId=%d,File=%s,Index=%d)\n", DbDir.c_str(), DirId, File.c_str(), Index));          dmsg(2,("InstrumentsDb: AddGigInstrument(DbDir=%s,DirId=%d,File=%s,Index=%d)\n", DbDir.c_str(), DirId, File.c_str(), Index));
1294          String name = pInstrument->pInfo->Name;          String name = pInstrument->pInfo->Name;
1295          if (name == "") return;          if (name == "") return;
1296          name = GetUniqueInstrumentName(DirId, name);          name = GetUniqueName(DirId, name);
1297                    
1298          std::stringstream sql2;          std::stringstream sql2;
1299          sql2 << "SELECT COUNT(*) FROM instruments WHERE instr_file=? AND ";          sql2 << "SELECT COUNT(*) FROM instruments WHERE instr_file=? AND ";
# Line 1671  namespace LinuxSampler { Line 1683  namespace LinuxSampler {
1683          }          }
1684      }      }
1685    
1686    #ifndef WIN32
1687      void InstrumentsDb::Regexp(sqlite3_context* pContext, int argc, sqlite3_value** ppValue) {      void InstrumentsDb::Regexp(sqlite3_context* pContext, int argc, sqlite3_value** ppValue) {
1688          if (argc != 2) return;          if (argc != 2) return;
1689    
# Line 1681  namespace LinuxSampler { Line 1694  namespace LinuxSampler {
1694              sqlite3_result_int(pContext, 1);              sqlite3_result_int(pContext, 1);
1695          }          }
1696      }      }
1697    #endif
1698    
1699      String InstrumentsDb::GetDirectoryPath(String File) {      String InstrumentsDb::GetDirectoryPath(String File) {
1700          if (File.empty()) return String("");          if (File.empty()) return String("");
# Line 1755  namespace LinuxSampler { Line 1769  namespace LinuxSampler {
1769          if (File.empty()) throw Exception("Invalid file name: " + File);          if (File.empty()) throw Exception("Invalid file name: " + File);
1770      }      }
1771    
1772      String InstrumentsDb::GetUniqueInstrumentName(int DirId, String Name) {      String InstrumentsDb::GetUniqueName(int DirId, String Name) {
1773          dmsg(2,("InstrumentsDb: GetUniqueInstrumentName(DirId=%d,Name=%s)\n", DirId, Name.c_str()));          dmsg(2,("InstrumentsDb: GetUniqueInstrumentName(DirId=%d,Name=%s)\n", DirId, Name.c_str()));
1774    
1775          if (GetInstrumentId(DirId, Name) == -1 && GetDirectoryId(DirId, Name) == -1) return Name;          if (GetInstrumentId(DirId, Name) == -1 && GetDirectoryId(DirId, Name) == -1) return Name;
# Line 1770  namespace LinuxSampler { Line 1784  namespace LinuxSampler {
1784    
1785          throw Exception("Unable to find an unique name: " + Name);          throw Exception("Unable to find an unique name: " + Name);
1786      }      }
1787        
1788        String InstrumentsDb::PrepareSubdirectory(String DbDir, String FsPath) {
1789            std::string dir = Path::getBaseName(FsPath);
1790            dir = toAbstractName(dir);
1791            if(dir.empty()) dir = "New Directory";
1792            dir = GetUniqueName(GetDirectoryId(DbDir), dir);
1793            dir = AppendNode(DbDir, dir);
1794            AddDirectory(dir);
1795            return dir;
1796        }
1797    
1798        String InstrumentsDb::AppendNode(String DbDir, String Node) {
1799            if(DbDir.length() == 1 && DbDir.at(0) == '/') return DbDir + Node;
1800            if(DbDir.at(DbDir.length() - 1) == '/') return DbDir + Node;
1801            return DbDir + "/" + Node;
1802        }
1803    
1804      String InstrumentsDb::toDbName(String AbstractName) {      String InstrumentsDb::toDbName(String AbstractName) {
1805          for (int i = 0; i < AbstractName.length(); i++) {          for (int i = 0; i < AbstractName.length(); i++) {

Legend:
Removed from v.1781  
changed lines
  Added in v.1911

  ViewVC Help
Powered by ViewVC