/[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 1727 by iliev, Tue Apr 29 15:44:09 2008 UTC revision 1912 by senoner, Sat Jun 6 16:48:00 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    #else
34    #include <direct.h>
35    #endif
36  #include "../common/Exception.h"  #include "../common/Exception.h"
37    
38  namespace LinuxSampler {  namespace LinuxSampler {
# Line 86  namespace LinuxSampler { Line 90  namespace LinuxSampler {
90    
91      InstrumentsDb::InstrumentsDb() {      InstrumentsDb::InstrumentsDb() {
92          db = NULL;          db = NULL;
         DbInstrumentsMutex = Mutex();  
93          InTransaction = false;          InTransaction = false;
94      }      }
95    
# Line 119  namespace LinuxSampler { Line 122  namespace LinuxSampler {
122      sqlite3* InstrumentsDb::GetDb() {      sqlite3* InstrumentsDb::GetDb() {
123          if ( db != NULL) return db;          if ( db != NULL) return db;
124    
125          if (DbFile.empty()) DbFile = CONFIG_DEFAULT_INSTRUMENTS_DB_LOCATION;          if (DbFile.empty()) {
126                        #ifndef WIN32
127                        DbFile = CONFIG_DEFAULT_INSTRUMENTS_DB_LOCATION;
128                            #else
129                            char *userprofile = getenv("USERPROFILE");
130                            if(userprofile) {
131                                String DbPath = userprofile;
132                                    DbPath += "\\.linuxsampler";
133                                DbFile = DbPath + "\\instruments.db";
134                                    File InstrumentsDbFile(DbFile);
135                                    // if no DB exists create the subdir and then the DB
136                                    if( !InstrumentsDbFile.Exist() ) {
137                                        _mkdir( DbPath.c_str() );
138                                            // formats the DB, which creates a new instruments.db file
139                                            Format();
140                                    }
141                        }
142                            else {
143                                // in case USERPROFILE is not set (which should not occur)
144                                DbFile = "instruments.db";
145                            }
146                            #endif
147                }
148                  #if defined(__APPLE__)  /* 20071224 Toshi Nagata  */                  #if defined(__APPLE__)  /* 20071224 Toshi Nagata  */
149                  if (DbFile.find("~") == 0)                  if (DbFile.find("~") == 0)
150                          DbFile.replace(0, 1, getenv("HOME"));                          DbFile.replace(0, 1, getenv("HOME"));
# Line 130  namespace LinuxSampler { Line 155  namespace LinuxSampler {
155              db = NULL;              db = NULL;
156              throw Exception("Cannot open instruments database: " + DbFile);              throw Exception("Cannot open instruments database: " + DbFile);
157          }          }
158    #ifndef WIN32
159          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);
160          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."); }
161    #endif
162    
163          // TODO: remove this in the next version          // TODO: remove this in the next version
164          try {          try {
# Line 641  namespace LinuxSampler { Line 668  namespace LinuxSampler {
668          FireDirectoryInfoChanged(Dir);          FireDirectoryInfoChanged(Dir);
669      }      }
670    
671      int InstrumentsDb::AddInstruments(ScanMode Mode, String DbDir, String FsDir, bool bBackground) {      int InstrumentsDb::AddInstruments(ScanMode Mode, String DbDir, String FsDir, bool bBackground, bool insDir) {
672          dmsg(2,("InstrumentsDb: AddInstruments(Mode=%d,DbDir=%s,FsDir=%s,bBackground=%d)\n", Mode, DbDir.c_str(), FsDir.c_str(), bBackground));          dmsg(2,("InstrumentsDb: AddInstruments(Mode=%d,DbDir=%s,FsDir=%s,bBackground=%d,insDir=%d)\n", Mode, DbDir.c_str(), FsDir.c_str(), bBackground, insDir));
673          if(!bBackground) {          if(!bBackground) {
674              switch (Mode) {              switch (Mode) {
675                  case NON_RECURSIVE:                  case NON_RECURSIVE:
676                      AddInstrumentsNonrecursive(DbDir, FsDir);                      AddInstrumentsNonrecursive(DbDir, FsDir, insDir);
677                      break;                      break;
678                  case RECURSIVE:                  case RECURSIVE:
679                      AddInstrumentsRecursive(DbDir, FsDir);                      AddInstrumentsRecursive(DbDir, FsDir, false, insDir);
680                      break;                      break;
681                  case FLAT:                  case FLAT:
682                      AddInstrumentsRecursive(DbDir, FsDir, true);                      AddInstrumentsRecursive(DbDir, FsDir, true, insDir);
683                      break;                      break;
684                  default:                  default:
685                      throw Exception("Unknown scan mode");                      throw Exception("Unknown scan mode");
# Line 663  namespace LinuxSampler { Line 690  namespace LinuxSampler {
690    
691          ScanJob job;          ScanJob job;
692          int jobId = Jobs.AddJob(job);          int jobId = Jobs.AddJob(job);
693          InstrumentsDbThread.Execute(new AddInstrumentsJob(jobId, Mode, DbDir, FsDir));          InstrumentsDbThread.Execute(new AddInstrumentsJob(jobId, Mode, DbDir, FsDir, insDir));
694    
695          return jobId;          return jobId;
696      }      }
# Line 671  namespace LinuxSampler { Line 698  namespace LinuxSampler {
698      int InstrumentsDb::AddInstruments(String DbDir, String FilePath, int Index, bool bBackground) {      int InstrumentsDb::AddInstruments(String DbDir, String FilePath, int Index, bool bBackground) {
699          dmsg(2,("InstrumentsDb: AddInstruments(DbDir=%s,FilePath=%s,Index=%d,bBackground=%d)\n", DbDir.c_str(), FilePath.c_str(), Index, bBackground));          dmsg(2,("InstrumentsDb: AddInstruments(DbDir=%s,FilePath=%s,Index=%d,bBackground=%d)\n", DbDir.c_str(), FilePath.c_str(), Index, bBackground));
700          if(!bBackground) {          if(!bBackground) {
701              AddInstruments(DbDir, FilePath, Index);              AddInstruments(DbDir, false, FilePath, Index);
702              return -1;              return -1;
703          }          }
704    
705          ScanJob job;          ScanJob job;
706          int jobId = Jobs.AddJob(job);          int jobId = Jobs.AddJob(job);
707          InstrumentsDbThread.Execute(new AddInstrumentsFromFileJob(jobId, DbDir, FilePath, Index));          InstrumentsDbThread.Execute(new AddInstrumentsFromFileJob(jobId, DbDir, FilePath, Index, false));
708    
709          return jobId;          return jobId;
710      }      }
711    
712      void InstrumentsDb::AddInstruments(String DbDir, String FilePath, int Index, ScanProgress* pProgress) {      void InstrumentsDb::AddInstruments(String DbDir, bool insDir, String FilePath, int Index, ScanProgress* pProgress) {
713          dmsg(2,("InstrumentsDb: AddInstruments(DbDir=%s,FilePath=%s,Index=%d)\n", DbDir.c_str(), FilePath.c_str(), Index));          dmsg(2,("InstrumentsDb: AddInstruments(DbDir=%s,insDir=%d,FilePath=%s,Index=%d)\n", DbDir.c_str(), insDir, FilePath.c_str(), Index));
714          if (DbDir.empty() || FilePath.empty()) return;          if (DbDir.empty() || FilePath.empty()) return;
715                    
716          DbInstrumentsMutex.Lock();          DbInstrumentsMutex.Lock();
# Line 704  namespace LinuxSampler { Line 731  namespace LinuxSampler {
731                  throw Exception(ss.str());                  throw Exception(ss.str());
732              }              }
733    
734              AddInstrumentsFromFile(DbDir, FilePath, Index, pProgress);              String dir = insDir ? PrepareSubdirectory(DbDir, FilePath) : DbDir;
735                AddInstrumentsFromFile(dir, FilePath, Index, pProgress);
736          } catch (Exception e) {          } catch (Exception e) {
737              DbInstrumentsMutex.Unlock();              DbInstrumentsMutex.Unlock();
738              throw e;              throw e;
# Line 713  namespace LinuxSampler { Line 741  namespace LinuxSampler {
741          DbInstrumentsMutex.Unlock();          DbInstrumentsMutex.Unlock();
742      }      }
743    
744      void InstrumentsDb::AddInstrumentsNonrecursive(String DbDir, String FsDir, ScanProgress* pProgress) {      void InstrumentsDb::AddInstrumentsNonrecursive(String DbDir, String FsDir, bool insDir, ScanProgress* pProgress) {
745          dmsg(2,("InstrumentsDb: AddInstrumentsNonrecursive(DbDir=%s,FsDir=%s)\n", DbDir.c_str(), FsDir.c_str()));          dmsg(2,("InstrumentsDb: AddInstrumentsNonrecursive(DbDir=%s,FsDir=%s,insDir=%d)\n", DbDir.c_str(), FsDir.c_str(), insDir));
746          if (DbDir.empty() || FsDir.empty()) return;          if (DbDir.empty() || FsDir.empty()) return;
747                    
748          DbInstrumentsMutex.Lock();          DbInstrumentsMutex.Lock();
# Line 740  namespace LinuxSampler { Line 768  namespace LinuxSampler {
768              try {              try {
769                  FileListPtr fileList = File::GetFiles(FsDir);                  FileListPtr fileList = File::GetFiles(FsDir);
770                  for (int i = 0; i < fileList->size(); i++) {                  for (int i = 0; i < fileList->size(); i++) {
771                      AddInstrumentsFromFile(DbDir, FsDir + fileList->at(i), -1, pProgress);                      String dir = insDir ? PrepareSubdirectory(DbDir, fileList->at(i)) : DbDir;
772                                            AddInstrumentsFromFile(dir, FsDir + fileList->at(i), -1, pProgress);
773                  }                  }
774              } catch(Exception e) {              } catch(Exception e) {
775                  e.PrintMessage();                  e.PrintMessage();
# Line 755  namespace LinuxSampler { Line 784  namespace LinuxSampler {
784          DbInstrumentsMutex.Unlock();          DbInstrumentsMutex.Unlock();
785      }      }
786    
787      void InstrumentsDb::AddInstrumentsRecursive(String DbDir, String FsDir, bool Flat, ScanProgress* pProgress) {      void InstrumentsDb::AddInstrumentsRecursive(String DbDir, String FsDir, bool Flat, bool insDir, ScanProgress* pProgress) {
788          dmsg(2,("InstrumentsDb: AddInstrumentsRecursive(DbDir=%s,FsDir=%s,Flat=%d)\n", DbDir.c_str(), FsDir.c_str(), Flat));          dmsg(2,("InstrumentsDb: AddInstrumentsRecursive(DbDir=%s,FsDir=%s,Flat=%d,insDir=%d)\n", DbDir.c_str(), FsDir.c_str(), Flat, insDir));
789          if (pProgress != NULL) {          if (pProgress != NULL) {
790              InstrumentFileCounter c;              InstrumentFileCounter c;
791              pProgress->SetTotalFileCount(c.Count(FsDir));              pProgress->SetTotalFileCount(c.Count(FsDir));
792          }          }
793    
794          DirectoryScanner d;          DirectoryScanner d;
795          d.Scan(DbDir, FsDir, Flat, pProgress);          d.Scan(DbDir, FsDir, Flat, insDir, pProgress);
796      }      }
797    
798      int InstrumentsDb::GetInstrumentCount(int DirId) {      int InstrumentsDb::GetInstrumentCount(int DirId) {
# Line 1174  namespace LinuxSampler { Line 1203  namespace LinuxSampler {
1203              throw Exception(ss.str());              throw Exception(ss.str());
1204          }          }
1205    
1206            bool unlocked = false;
1207          RIFF::File* riff = NULL;          RIFF::File* riff = NULL;
1208          gig::File* gig = NULL;          gig::File* gig = NULL;
1209          try {          try {
# Line 1194  namespace LinuxSampler { Line 1224  namespace LinuxSampler {
1224                  throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));                  throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));
1225              }              }
1226    
1227              String s = toEscapedFsPath(FilePath);              String s = FilePath;
1228    
1229                #if WIN32
1230                for (int i = 0; i < s.length(); i++) {
1231                    if (s[i] == '\\') s[i] = '/';
1232                }
1233                #endif
1234    
1235                s = toEscapedFsPath(s);
1236              BindTextParam(pStmt, 2, s);              BindTextParam(pStmt, 2, s);
1237              String ver = "";              String ver = "";
1238              if (gig->pVersion != NULL) ver = ToString(gig->pVersion->major);              if (gig->pVersion != NULL) ver = ToString(gig->pVersion->major);
# Line 1202  namespace LinuxSampler { Line 1240  namespace LinuxSampler {
1240    
1241              if (Index == -1) {              if (Index == -1) {
1242                  int instrIndex = 0;                  int instrIndex = 0;
1243                    // Assume that it's locked and should be unlocked at this point
1244                    // to be able to use the database from another threads
1245                    if (!InTransaction) {
1246                        DbInstrumentsMutex.Unlock();
1247                        unlocked = true;
1248                    } else {
1249                        std::cerr << "Shouldn't be in transaction when adding instruments." << std::endl;
1250                    }
1251    
1252                  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
1253                  gig::Instrument* pInstrument = gig->GetFirstInstrument();                  gig::Instrument* pInstrument = gig->GetFirstInstrument();
1254    
1255                    if (!InTransaction) DbInstrumentsMutex.Lock();
1256                  while (pInstrument) {                  while (pInstrument) {
1257                      BindTextParam(pStmt, 7, gig->pInfo->Product);                      BindTextParam(pStmt, 7, gig->pInfo->Product);
1258                      BindTextParam(pStmt, 8, gig->pInfo->Artists);                      BindTextParam(pStmt, 8, gig->pInfo->Artists);
# Line 1231  namespace LinuxSampler { Line 1280  namespace LinuxSampler {
1280          } catch (RIFF::Exception e) {          } catch (RIFF::Exception e) {
1281              if (gig != NULL) delete gig;              if (gig != NULL) delete gig;
1282              if (riff != NULL) delete riff;              if (riff != NULL) delete riff;
1283                if (unlocked) DbInstrumentsMutex.Lock();
1284              std::stringstream ss;              std::stringstream ss;
1285              ss << "Failed to scan `" << FilePath << "`: " << e.Message;              ss << "Failed to scan `" << FilePath << "`: " << e.Message;
1286                            
# Line 1238  namespace LinuxSampler { Line 1288  namespace LinuxSampler {
1288          } catch (Exception e) {          } catch (Exception e) {
1289              if (gig != NULL) delete gig;              if (gig != NULL) delete gig;
1290              if (riff != NULL) delete riff;              if (riff != NULL) delete riff;
1291                if (unlocked) DbInstrumentsMutex.Lock();
1292              throw e;              throw e;
1293          } catch (...) {          } catch (...) {
1294              if (gig != NULL) delete gig;              if (gig != NULL) delete gig;
1295              if (riff != NULL) delete riff;              if (riff != NULL) delete riff;
1296                if (unlocked) DbInstrumentsMutex.Lock();
1297              throw Exception("Failed to scan `" + FilePath + "`");              throw Exception("Failed to scan `" + FilePath + "`");
1298          }          }
1299      }      }
# Line 1250  namespace LinuxSampler { Line 1302  namespace LinuxSampler {
1302          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));
1303          String name = pInstrument->pInfo->Name;          String name = pInstrument->pInfo->Name;
1304          if (name == "") return;          if (name == "") return;
1305          name = GetUniqueInstrumentName(DirId, name);          name = GetUniqueName(DirId, name);
1306                    
1307          std::stringstream sql2;          std::stringstream sql2;
1308          sql2 << "SELECT COUNT(*) FROM instruments WHERE instr_file=? AND ";          sql2 << "SELECT COUNT(*) FROM instruments WHERE instr_file=? AND ";
# Line 1640  namespace LinuxSampler { Line 1692  namespace LinuxSampler {
1692          }          }
1693      }      }
1694    
1695    #ifndef WIN32
1696      void InstrumentsDb::Regexp(sqlite3_context* pContext, int argc, sqlite3_value** ppValue) {      void InstrumentsDb::Regexp(sqlite3_context* pContext, int argc, sqlite3_value** ppValue) {
1697          if (argc != 2) return;          if (argc != 2) return;
1698    
# Line 1650  namespace LinuxSampler { Line 1703  namespace LinuxSampler {
1703              sqlite3_result_int(pContext, 1);              sqlite3_result_int(pContext, 1);
1704          }          }
1705      }      }
1706    #endif
1707    
1708      String InstrumentsDb::GetDirectoryPath(String File) {      String InstrumentsDb::GetDirectoryPath(String File) {
1709          if (File.empty()) return String("");          if (File.empty()) return String("");
# Line 1724  namespace LinuxSampler { Line 1778  namespace LinuxSampler {
1778          if (File.empty()) throw Exception("Invalid file name: " + File);          if (File.empty()) throw Exception("Invalid file name: " + File);
1779      }      }
1780    
1781      String InstrumentsDb::GetUniqueInstrumentName(int DirId, String Name) {      String InstrumentsDb::GetUniqueName(int DirId, String Name) {
1782          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()));
1783    
1784          if (GetInstrumentId(DirId, Name) == -1 && GetDirectoryId(DirId, Name) == -1) return Name;          if (GetInstrumentId(DirId, Name) == -1 && GetDirectoryId(DirId, Name) == -1) return Name;
# Line 1739  namespace LinuxSampler { Line 1793  namespace LinuxSampler {
1793    
1794          throw Exception("Unable to find an unique name: " + Name);          throw Exception("Unable to find an unique name: " + Name);
1795      }      }
1796        
1797        String InstrumentsDb::PrepareSubdirectory(String DbDir, String FsPath) {
1798            std::string dir = Path::getBaseName(FsPath);
1799            dir = toAbstractName(dir);
1800            if(dir.empty()) dir = "New Directory";
1801            dir = GetUniqueName(GetDirectoryId(DbDir), dir);
1802            dir = AppendNode(DbDir, dir);
1803            AddDirectory(dir);
1804            return dir;
1805        }
1806    
1807        String InstrumentsDb::AppendNode(String DbDir, String Node) {
1808            if(DbDir.length() == 1 && DbDir.at(0) == '/') return DbDir + Node;
1809            if(DbDir.at(DbDir.length() - 1) == '/') return DbDir + Node;
1810            return DbDir + "/" + Node;
1811        }
1812    
1813      String InstrumentsDb::toDbName(String AbstractName) {      String InstrumentsDb::toDbName(String AbstractName) {
1814          for (int i = 0; i < AbstractName.length(); i++) {          for (int i = 0; i < AbstractName.length(); i++) {

Legend:
Removed from v.1727  
changed lines
  Added in v.1912

  ViewVC Help
Powered by ViewVC