/[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 1603 by iliev, Mon Dec 31 10:17:51 2007 UTC revision 1810 by iliev, Sun Dec 14 22:33:46 2008 UTC
# Line 1  Line 1 
1  /***************************************************************************  /***************************************************************************
2   *                                                                         *   *                                                                         *
3   *   Copyright (C) 2007 Grigor Iliev                                       *   *   Copyright (C) 2007, 2008 Grigor Iliev                                 *
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 20  Line 20 
20    
21  #include "InstrumentsDb.h"  #include "InstrumentsDb.h"
22    
23    #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>
 #include <dirent.h>  
30  #include <errno.h>  #include <errno.h>
31  #include <fnmatch.h>  #include <fnmatch.h>
32    
# Line 33  Line 34 
34    
35  namespace LinuxSampler {  namespace LinuxSampler {
36    
37      InstrumentsDb* InstrumentsDb::pInstrumentsDb = new InstrumentsDb;      InstrumentsDb InstrumentsDb::instance;
38    
39      void InstrumentsDb::CreateInstrumentsDb(String File) {      void InstrumentsDb::CreateInstrumentsDb(String FilePath) {
40          struct stat statBuf;          File f = File(FilePath);
41          int res = stat(File.c_str(), &statBuf);          if (f.Exist()) {
42          if (!res) {              throw Exception("File exists: " + FilePath);
             throw Exception("File exists: " + File);  
43          }          }
44                    
45          GetInstrumentsDb()->SetDbFile(File);          GetInstrumentsDb()->SetDbFile(FilePath);
46    
47          String sql =          String sql =
48              "  CREATE TABLE instr_dirs (                                      "              "  CREATE TABLE instr_dirs (                                      "
# Line 95  namespace LinuxSampler { Line 95  namespace LinuxSampler {
95          if (db != NULL) sqlite3_close(db);          if (db != NULL) sqlite3_close(db);
96      }      }
97            
     void InstrumentsDb::Destroy() {  
         if (pInstrumentsDb != NULL) {  
             delete pInstrumentsDb;  
             pInstrumentsDb = NULL;  
         }  
     }  
   
98      void InstrumentsDb::AddInstrumentsDbListener(InstrumentsDb::Listener* l) {      void InstrumentsDb::AddInstrumentsDbListener(InstrumentsDb::Listener* l) {
99          llInstrumentsDbListeners.AddListener(l);          llInstrumentsDbListeners.AddListener(l);
100      }      }
# Line 111  namespace LinuxSampler { Line 104  namespace LinuxSampler {
104      }      }
105            
106      InstrumentsDb* InstrumentsDb::GetInstrumentsDb() {      InstrumentsDb* InstrumentsDb::GetInstrumentsDb() {
107          return pInstrumentsDb;          return &instance;
108      }      }
109            
110      void InstrumentsDb::SetDbFile(String File) {      void InstrumentsDb::SetDbFile(String File) {
# Line 128  namespace LinuxSampler { Line 121  namespace LinuxSampler {
121          if ( db != NULL) return db;          if ( db != NULL) return db;
122    
123          if (DbFile.empty()) DbFile = CONFIG_DEFAULT_INSTRUMENTS_DB_LOCATION;          if (DbFile.empty()) DbFile = CONFIG_DEFAULT_INSTRUMENTS_DB_LOCATION;
124                    #if defined(__APPLE__)  /* 20071224 Toshi Nagata  */
125                    if (DbFile.find("~") == 0)
126                            DbFile.replace(0, 1, getenv("HOME"));
127                    #endif
128          int rc = sqlite3_open(DbFile.c_str(), &db);          int rc = sqlite3_open(DbFile.c_str(), &db);
129          if (rc) {          if (rc) {
130              sqlite3_close(db);              sqlite3_close(db);
# Line 264  namespace LinuxSampler { Line 261  namespace LinuxSampler {
261          return ExecSqlInt(sql.str(), DirName);          return ExecSqlInt(sql.str(), DirName);
262      }      }
263    
264        int InstrumentsDb::GetDirectoryId(int InstrId) {
265            dmsg(2,("InstrumentsDb: GetDirectoryId(InstrId=%d)\n", InstrId));
266            std::stringstream sql;
267            sql << "SELECT dir_id FROM instruments WHERE instr_id=" << InstrId;
268            return ExecSqlInt(sql.str());
269        }
270    
271      String InstrumentsDb::GetDirectoryName(int DirId) {      String InstrumentsDb::GetDirectoryName(int DirId) {
272          String sql = "SELECT dir_name FROM instr_dirs WHERE dir_id=" + ToString(DirId);          String sql = "SELECT dir_name FROM instr_dirs WHERE dir_id=" + ToString(DirId);
273          String name = ExecSqlString(sql);          String name = ExecSqlString(sql);
# Line 288  namespace LinuxSampler { Line 292  namespace LinuxSampler {
292                  path = "/" + path;                  path = "/" + path;
293                  break;                  break;
294              }              }
295              path = GetDirectoryName(DirId) + path;              path = GetDirectoryName(DirId) + "/" + path;
296              DirId = GetParentDirectoryId(DirId);              DirId = GetParentDirectoryId(DirId);
297          }          }
298    
# Line 296  namespace LinuxSampler { Line 300  namespace LinuxSampler {
300    
301          return path;          return path;
302      }      }
303        
304        StringListPtr InstrumentsDb::GetInstrumentsByFile(String File) {
305            dmsg(2,("InstrumentsDb: GetInstrumentsByFile(File=%s)\n", File.c_str()));
306    
307            StringListPtr instrs(new std::vector<String>);
308            
309            BeginTransaction();
310            try {
311                File = toEscapedFsPath(File);
312                IntListPtr ids = ExecSqlIntList("SELECT instr_id FROM instruments WHERE instr_file=?", File);
313                
314                for (int i = 0; i < ids->size(); i++) {
315                    String name = GetInstrumentName(ids->at(i));
316                    String dir = GetDirectoryPath(GetDirectoryId(ids->at(i)));
317                    instrs->push_back(dir + name);
318                }
319            } catch (Exception e) {
320                EndTransaction();
321                throw e;
322            }
323            EndTransaction();
324            
325            return instrs;
326        }
327    
328      void InstrumentsDb::AddDirectory(String Dir) {      void InstrumentsDb::AddDirectory(String Dir) {
329          dmsg(2,("InstrumentsDb: AddDirectory(Dir=%s)\n", Dir.c_str()));          dmsg(2,("InstrumentsDb: AddDirectory(Dir=%s)\n", Dir.c_str()));
# Line 614  namespace LinuxSampler { Line 642  namespace LinuxSampler {
642          FireDirectoryInfoChanged(Dir);          FireDirectoryInfoChanged(Dir);
643      }      }
644    
645      int InstrumentsDb::AddInstruments(ScanMode Mode, String DbDir, String FsDir, bool bBackground) {      int InstrumentsDb::AddInstruments(ScanMode Mode, String DbDir, String FsDir, bool bBackground, bool insDir) {
646          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));
647          if(!bBackground) {          if(!bBackground) {
648              switch (Mode) {              switch (Mode) {
649                  case NON_RECURSIVE:                  case NON_RECURSIVE:
650                      AddInstrumentsNonrecursive(DbDir, FsDir);                      AddInstrumentsNonrecursive(DbDir, FsDir, insDir);
651                      break;                      break;
652                  case RECURSIVE:                  case RECURSIVE:
653                      AddInstrumentsRecursive(DbDir, FsDir);                      AddInstrumentsRecursive(DbDir, FsDir, false, insDir);
654                      break;                      break;
655                  case FLAT:                  case FLAT:
656                      AddInstrumentsRecursive(DbDir, FsDir, true);                      AddInstrumentsRecursive(DbDir, FsDir, true, insDir);
657                      break;                      break;
658                  default:                  default:
659                      throw Exception("Unknown scan mode");                      throw Exception("Unknown scan mode");
# Line 636  namespace LinuxSampler { Line 664  namespace LinuxSampler {
664    
665          ScanJob job;          ScanJob job;
666          int jobId = Jobs.AddJob(job);          int jobId = Jobs.AddJob(job);
667          InstrumentsDbThread.Execute(new AddInstrumentsJob(jobId, Mode, DbDir, FsDir));          InstrumentsDbThread.Execute(new AddInstrumentsJob(jobId, Mode, DbDir, FsDir, insDir));
668    
669          return jobId;          return jobId;
670      }      }
# Line 644  namespace LinuxSampler { Line 672  namespace LinuxSampler {
672      int InstrumentsDb::AddInstruments(String DbDir, String FilePath, int Index, bool bBackground) {      int InstrumentsDb::AddInstruments(String DbDir, String FilePath, int Index, bool bBackground) {
673          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));
674          if(!bBackground) {          if(!bBackground) {
675              AddInstruments(DbDir, FilePath, Index);              AddInstruments(DbDir, false, FilePath, Index);
676              return -1;              return -1;
677          }          }
678    
679          ScanJob job;          ScanJob job;
680          int jobId = Jobs.AddJob(job);          int jobId = Jobs.AddJob(job);
681          InstrumentsDbThread.Execute(new AddInstrumentsFromFileJob(jobId, DbDir, FilePath, Index));          InstrumentsDbThread.Execute(new AddInstrumentsFromFileJob(jobId, DbDir, FilePath, Index, false));
682    
683          return jobId;          return jobId;
684      }      }
685    
686      void InstrumentsDb::AddInstruments(String DbDir, String FilePath, int Index, ScanProgress* pProgress) {      void InstrumentsDb::AddInstruments(String DbDir, bool insDir, String FilePath, int Index, ScanProgress* pProgress) {
687          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));
688          if (DbDir.empty() || FilePath.empty()) return;          if (DbDir.empty() || FilePath.empty()) return;
689                    
690          DbInstrumentsMutex.Lock();          DbInstrumentsMutex.Lock();
# Line 664  namespace LinuxSampler { Line 692  namespace LinuxSampler {
692              int dirId = GetDirectoryId(DbDir);              int dirId = GetDirectoryId(DbDir);
693              if (dirId == -1) throw Exception("Invalid DB directory: " + toEscapedText(DbDir));              if (dirId == -1) throw Exception("Invalid DB directory: " + toEscapedText(DbDir));
694    
695              struct stat statBuf;              File f = File(FilePath);
696              int res = stat(FilePath.c_str(), &statBuf);              if (!f.Exist()) {
             if (res) {  
697                  std::stringstream ss;                  std::stringstream ss;
698                  ss << "Fail to stat `" << FilePath << "`: " << strerror(errno);                  ss << "Fail to stat `" << FilePath << "`: " << f.GetErrorMsg();
699                  throw Exception(ss.str());                  throw Exception(ss.str());
700              }              }
701    
702              if (!S_ISREG(statBuf.st_mode)) {              if (!f.IsFile()) {
703                  std::stringstream ss;                  std::stringstream ss;
704                  ss << "`" << FilePath << "` is not an instrument file";                  ss << "`" << FilePath << "` is not an instrument file";
705                  throw Exception(ss.str());                  throw Exception(ss.str());
706              }              }
707    
708              AddInstrumentsFromFile(DbDir, FilePath, Index, pProgress);              String dir = insDir ? PrepareSubdirectory(DbDir, FilePath) : DbDir;
709                AddInstrumentsFromFile(dir, FilePath, Index, pProgress);
710          } catch (Exception e) {          } catch (Exception e) {
711              DbInstrumentsMutex.Unlock();              DbInstrumentsMutex.Unlock();
712              throw e;              throw e;
# Line 687  namespace LinuxSampler { Line 715  namespace LinuxSampler {
715          DbInstrumentsMutex.Unlock();          DbInstrumentsMutex.Unlock();
716      }      }
717    
718      void InstrumentsDb::AddInstrumentsNonrecursive(String DbDir, String FsDir, ScanProgress* pProgress) {      void InstrumentsDb::AddInstrumentsNonrecursive(String DbDir, String FsDir, bool insDir, ScanProgress* pProgress) {
719          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));
720          if (DbDir.empty() || FsDir.empty()) return;          if (DbDir.empty() || FsDir.empty()) return;
721                    
722          DbInstrumentsMutex.Lock();          DbInstrumentsMutex.Lock();
# Line 696  namespace LinuxSampler { Line 724  namespace LinuxSampler {
724              int dirId = GetDirectoryId(DbDir);              int dirId = GetDirectoryId(DbDir);
725              if (dirId == -1) throw Exception("Invalid DB directory: " + toEscapedPath(DbDir));              if (dirId == -1) throw Exception("Invalid DB directory: " + toEscapedPath(DbDir));
726    
727              struct stat statBuf;              File f = File(FsDir);
728              int res = stat(FsDir.c_str(), &statBuf);              if (!f.Exist()) {
             if (res) {  
729                  std::stringstream ss;                  std::stringstream ss;
730                  ss << "Fail to stat `" << FsDir << "`: " << strerror(errno);                  ss << "Fail to stat `" << FsDir << "`: " << f.GetErrorMsg();
731                  throw Exception(ss.str());                  throw Exception(ss.str());
732              }              }
733    
734              if (!S_ISDIR(statBuf.st_mode)) {              if (!f.IsDirectory()) {
735                  throw Exception("Directory expected");                  throw Exception("Directory expected: " + FsDir);
736              }              }
737                            
738              if (FsDir.at(FsDir.length() - 1) != '/') FsDir.append("/");              if (FsDir.at(FsDir.length() - 1) != File::DirSeparator) {
739                    FsDir.push_back(File::DirSeparator);
             DIR* pDir = opendir(FsDir.c_str());  
             if (pDir == NULL) {  
                 std::stringstream ss;  
                 ss << "The scanning of directory `" << FsDir << "` failed: ";  
                 ss << strerror(errno);  
                 std::cerr << ss.str();  
                 DbInstrumentsMutex.Unlock();  
                 return;  
740              }              }
741                
742              struct dirent* pEnt = readdir(pDir);              try {
743              while (pEnt != NULL) {                  FileListPtr fileList = File::GetFiles(FsDir);
744                  if (pEnt->d_type != DT_REG) {                  for (int i = 0; i < fileList->size(); i++) {
745                      pEnt = readdir(pDir);                      String dir = insDir ? PrepareSubdirectory(DbDir, fileList->at(i)) : DbDir;
746                      continue;                                          AddInstrumentsFromFile(dir, FsDir + fileList->at(i), -1, pProgress);
747                  }                  }
748                } catch(Exception e) {
749                  AddInstrumentsFromFile(DbDir, FsDir + String(pEnt->d_name), -1, pProgress);                  e.PrintMessage();
750                  pEnt = readdir(pDir);                  DbInstrumentsMutex.Unlock();
751              }                  return;
   
             if (closedir(pDir)) {  
                 std::stringstream ss;  
                 ss << "Failed to close directory `" << FsDir << "`: ";  
                 ss << strerror(errno);  
                 std::cerr << ss.str();  
752              }              }
753          } catch (Exception e) {          } catch (Exception e) {
754              DbInstrumentsMutex.Unlock();              DbInstrumentsMutex.Unlock();
# Line 745  namespace LinuxSampler { Line 758  namespace LinuxSampler {
758          DbInstrumentsMutex.Unlock();          DbInstrumentsMutex.Unlock();
759      }      }
760    
761      void InstrumentsDb::AddInstrumentsRecursive(String DbDir, String FsDir, bool Flat, ScanProgress* pProgress) {      void InstrumentsDb::AddInstrumentsRecursive(String DbDir, String FsDir, bool Flat, bool insDir, ScanProgress* pProgress) {
762          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));
763          if (pProgress != NULL) {          if (pProgress != NULL) {
764              pProgress->SetTotalFileCount(InstrumentFileCounter::Count(FsDir));              InstrumentFileCounter c;
765                pProgress->SetTotalFileCount(c.Count(FsDir));
766          }          }
767    
768          DirectoryScanner::Scan(DbDir, FsDir, Flat, pProgress);          DirectoryScanner d;
769            d.Scan(DbDir, FsDir, Flat, insDir, pProgress);
770      }      }
771    
772      int InstrumentsDb::GetInstrumentCount(int DirId) {      int InstrumentsDb::GetInstrumentCount(int DirId) {
# Line 1140  namespace LinuxSampler { Line 1155  namespace LinuxSampler {
1155                  }                  }
1156              }              }
1157          } catch(Exception e) {          } catch(Exception e) {
1158              std::cerr << e.Message() << std::endl;              e.PrintMessage();
1159          }          }
1160      }      }
1161    
1162      void InstrumentsDb::AddGigInstruments(String DbDir, String File, int Index, ScanProgress* pProgress) {      void InstrumentsDb::AddGigInstruments(String DbDir, String FilePath, int Index, ScanProgress* pProgress) {
1163          dmsg(2,("InstrumentsDb: AddGigInstruments(DbDir=%s,File=%s,Index=%d)\n", DbDir.c_str(), File.c_str(), Index));          dmsg(2,("InstrumentsDb: AddGigInstruments(DbDir=%s,FilePath=%s,Index=%d)\n", DbDir.c_str(), FilePath.c_str(), Index));
1164          int dirId = GetDirectoryId(DbDir);          int dirId = GetDirectoryId(DbDir);
1165          if (dirId == -1) throw Exception("Invalid DB directory: " + toEscapedPath(DbDir));          if (dirId == -1) throw Exception("Invalid DB directory: " + toEscapedPath(DbDir));
1166    
1167          struct stat statBuf;          File f = File(FilePath);
1168          int res = stat(File.c_str(), &statBuf);          if (!f.Exist()) {
         if (res) {  
1169              std::stringstream ss;              std::stringstream ss;
1170              ss << "Fail to stat `" << File << "`: " << strerror(errno);              ss << "Fail to stat `" << FilePath << "`: " << f.GetErrorMsg();
1171              throw Exception(ss.str());              throw Exception(ss.str());
1172          }          }
1173    
1174          if (!S_ISREG(statBuf.st_mode)) {          if (!f.IsFile()) {
1175              std::stringstream ss;              std::stringstream ss;
1176              ss << "`" << File << "` is not a regular file";              ss << "`" << FilePath << "` is not a regular file";
1177              throw Exception(ss.str());              throw Exception(ss.str());
1178          }          }
1179    
1180          RIFF::File* riff = NULL;          RIFF::File* riff = NULL;
1181          gig::File* gig = NULL;          gig::File* gig = NULL;
1182          try {          try {
1183              riff = new RIFF::File(File);              riff = new RIFF::File(FilePath);
1184              gig::File* gig = new gig::File(riff);              gig::File* gig = new gig::File(riff);
1185              gig->SetAutoLoad(false); // avoid time consuming samples scanning              gig->SetAutoLoad(false); // avoid time consuming samples scanning
1186    
# Line 1174  namespace LinuxSampler { Line 1188  namespace LinuxSampler {
1188              sql << "INSERT INTO instruments (dir_id,instr_name,instr_file,";              sql << "INSERT INTO instruments (dir_id,instr_name,instr_file,";
1189              sql << "instr_nr,format_family,format_version,instr_size,";              sql << "instr_nr,format_family,format_version,instr_size,";
1190              sql << "description,is_drum,product,artists,keywords) VALUES (";              sql << "description,is_drum,product,artists,keywords) VALUES (";
1191              sql << dirId << ",?,?,?,'GIG',?," << statBuf.st_size << ",?,?,?,?,?)";              sql << dirId << ",?,?,?,'GIG',?," << f.GetSize() << ",?,?,?,?,?)";
1192    
1193              sqlite3_stmt* pStmt = NULL;              sqlite3_stmt* pStmt = NULL;
1194    
# Line 1183  namespace LinuxSampler { Line 1197  namespace LinuxSampler {
1197                  throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));                  throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));
1198              }              }
1199    
1200              String s = toEscapedFsPath(File);              String s = toEscapedFsPath(FilePath);
1201              BindTextParam(pStmt, 2, s);              BindTextParam(pStmt, 2, s);
1202              String ver = "";              String ver = "";
1203              if (gig->pVersion != NULL) ver = ToString(gig->pVersion->major);              if (gig->pVersion != NULL) ver = ToString(gig->pVersion->major);
# Line 1197  namespace LinuxSampler { Line 1211  namespace LinuxSampler {
1211                      BindTextParam(pStmt, 7, gig->pInfo->Product);                      BindTextParam(pStmt, 7, gig->pInfo->Product);
1212                      BindTextParam(pStmt, 8, gig->pInfo->Artists);                      BindTextParam(pStmt, 8, gig->pInfo->Artists);
1213                      BindTextParam(pStmt, 9, gig->pInfo->Keywords);                      BindTextParam(pStmt, 9, gig->pInfo->Keywords);
1214                      AddGigInstrument(pStmt, DbDir, dirId, File, pInstrument, instrIndex);                      AddGigInstrument(pStmt, DbDir, dirId, FilePath, pInstrument, instrIndex);
1215    
1216                      instrIndex++;                      instrIndex++;
1217                      pInstrument = gig->GetNextInstrument();                      pInstrument = gig->GetNextInstrument();
# Line 1210  namespace LinuxSampler { Line 1224  namespace LinuxSampler {
1224                      BindTextParam(pStmt, 7, gig->pInfo->Product);                      BindTextParam(pStmt, 7, gig->pInfo->Product);
1225                      BindTextParam(pStmt, 8, gig->pInfo->Artists);                      BindTextParam(pStmt, 8, gig->pInfo->Artists);
1226                      BindTextParam(pStmt, 9, gig->pInfo->Keywords);                      BindTextParam(pStmt, 9, gig->pInfo->Keywords);
1227                      AddGigInstrument(pStmt, DbDir, dirId, File, pInstrument, Index);                      AddGigInstrument(pStmt, DbDir, dirId, FilePath, pInstrument, Index);
1228                  }                  }
1229              }              }
1230    
# Line 1221  namespace LinuxSampler { Line 1235  namespace LinuxSampler {
1235              if (gig != NULL) delete gig;              if (gig != NULL) delete gig;
1236              if (riff != NULL) delete riff;              if (riff != NULL) delete riff;
1237              std::stringstream ss;              std::stringstream ss;
1238              ss << "Failed to scan `" << File << "`: " << e.Message;              ss << "Failed to scan `" << FilePath << "`: " << e.Message;
1239                            
1240              throw Exception(ss.str());              throw Exception(ss.str());
1241          } catch (Exception e) {          } catch (Exception e) {
# Line 1231  namespace LinuxSampler { Line 1245  namespace LinuxSampler {
1245          } catch (...) {          } catch (...) {
1246              if (gig != NULL) delete gig;              if (gig != NULL) delete gig;
1247              if (riff != NULL) delete riff;              if (riff != NULL) delete riff;
1248              throw Exception("Failed to scan `" + File + "`");              throw Exception("Failed to scan `" + FilePath + "`");
1249          }          }
1250      }      }
1251    
1252      void InstrumentsDb::AddGigInstrument(sqlite3_stmt* pStmt, String DbDir, int DirId, String File, gig::Instrument* pInstrument, int Index) {      void InstrumentsDb::AddGigInstrument(sqlite3_stmt* pStmt, String DbDir, int DirId, String File, gig::Instrument* pInstrument, int Index) {
1253            dmsg(2,("InstrumentsDb: AddGigInstrument(DbDir=%s,DirId=%d,File=%s,Index=%d)\n", DbDir.c_str(), DirId, File.c_str(), Index));
1254          String name = pInstrument->pInfo->Name;          String name = pInstrument->pInfo->Name;
1255          if (name == "") return;          if (name == "") return;
1256          name = GetUniqueInstrumentName(DirId, name);          name = GetUniqueName(DirId, name);
1257                    
1258          std::stringstream sql2;          std::stringstream sql2;
1259          sql2 << "SELECT COUNT(*) FROM instruments WHERE instr_file=? AND ";          sql2 << "SELECT COUNT(*) FROM instruments WHERE instr_file=? AND ";
# Line 1334  namespace LinuxSampler { Line 1349  namespace LinuxSampler {
1349    
1350          return instrumentFinder.GetInstruments();          return instrumentFinder.GetInstruments();
1351      }      }
1352        
1353        StringListPtr InstrumentsDb::FindLostInstrumentFiles() {
1354            dmsg(2,("InstrumentsDb: FindLostInstrumentFiles()\n"));
1355    
1356            BeginTransaction();
1357            try {
1358                StringListPtr files = ExecSqlStringList("SELECT DISTINCT instr_file FROM instruments");
1359                StringListPtr result(new std::vector<String>);
1360                for (int i = 0; i < files->size(); i++) {
1361                    File f(toNonEscapedFsPath(files->at(i)));
1362                    if (!f.Exist()) result->push_back(files->at(i));
1363                }
1364                return result;
1365            } catch (Exception e) {
1366                EndTransaction();
1367                throw e;
1368            }
1369            EndTransaction();
1370        }
1371        
1372        void InstrumentsDb::SetInstrumentFilePath(String OldPath, String NewPath) {
1373            if (OldPath == NewPath) return;
1374            StringListPtr instrs;
1375            BeginTransaction();
1376            try {
1377                std::vector<String> params(2);
1378                params[0] = toEscapedFsPath(NewPath);
1379                params[1] = toEscapedFsPath(OldPath);
1380                instrs = GetInstrumentsByFile(OldPath);
1381                ExecSql("UPDATE instruments SET instr_file=? WHERE instr_file=?", params);
1382            } catch (Exception e) {
1383                EndTransaction();
1384                throw e;
1385            }
1386            EndTransaction();
1387            
1388            for (int i = 0; i < instrs->size(); i++) {
1389                FireInstrumentInfoChanged(instrs->at(i));
1390            }
1391        }
1392    
1393      void InstrumentsDb::BeginTransaction() {      void InstrumentsDb::BeginTransaction() {
1394          dmsg(2,("InstrumentsDb: BeginTransaction(InTransaction=%d)\n", InTransaction));          dmsg(2,("InstrumentsDb: BeginTransaction(InTransaction=%d)\n", InTransaction));
# Line 1395  namespace LinuxSampler { Line 1450  namespace LinuxSampler {
1450    
1451      void InstrumentsDb::ExecSql(String Sql) {      void InstrumentsDb::ExecSql(String Sql) {
1452          dmsg(2,("InstrumentsDb: ExecSql(Sql=%s)\n", Sql.c_str()));          dmsg(2,("InstrumentsDb: ExecSql(Sql=%s)\n", Sql.c_str()));
1453          sqlite3_stmt *pStmt = NULL;          std::vector<String> Params;
1454                    ExecSql(Sql, Params);
         int res = sqlite3_prepare(GetDb(), Sql.c_str(), -1, &pStmt, NULL);  
         if (res != SQLITE_OK) {  
             throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));  
         }  
           
         res = sqlite3_step(pStmt);  
         if(res != SQLITE_DONE) {  
             sqlite3_finalize(pStmt);  
             throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));  
         }  
   
         sqlite3_finalize(pStmt);  
1455      }      }
1456    
1457      void InstrumentsDb::ExecSql(String Sql, String Param) {      void InstrumentsDb::ExecSql(String Sql, String Param) {
1458          dmsg(2,("InstrumentsDb: ExecSql(Sql=%s,Param=%s)\n", Sql.c_str(), Param.c_str()));          dmsg(2,("InstrumentsDb: ExecSql(Sql=%s,Param=%s)\n", Sql.c_str(), Param.c_str()));
1459            std::vector<String> Params;
1460            Params.push_back(Param);
1461            ExecSql(Sql, Params);
1462        }
1463    
1464        void InstrumentsDb::ExecSql(String Sql, std::vector<String>& Params) {
1465            dmsg(2,("InstrumentsDb: ExecSql(Sql=%s,Params)\n", Sql.c_str()));
1466          sqlite3_stmt *pStmt = NULL;          sqlite3_stmt *pStmt = NULL;
1467                    
1468          int res = sqlite3_prepare(GetDb(), Sql.c_str(), -1, &pStmt, NULL);          int res = sqlite3_prepare(GetDb(), Sql.c_str(), -1, &pStmt, NULL);
# Line 1421  namespace LinuxSampler { Line 1471  namespace LinuxSampler {
1471              throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));              throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));
1472          }          }
1473    
1474          BindTextParam(pStmt, 1, Param);          for(int i = 0; i < Params.size(); i++) {
1475                BindTextParam(pStmt, i + 1, Params[i]);
1476            }
1477    
1478          res = sqlite3_step(pStmt);          res = sqlite3_step(pStmt);
1479          if (res != SQLITE_DONE) {          if (res != SQLITE_DONE) {
# Line 1503  namespace LinuxSampler { Line 1555  namespace LinuxSampler {
1555      }      }
1556    
1557      IntListPtr InstrumentsDb::ExecSqlIntList(String Sql) {      IntListPtr InstrumentsDb::ExecSqlIntList(String Sql) {
1558            dmsg(2,("InstrumentsDb: ExecSqlIntList(Sql=%s)\n", Sql.c_str()));
1559            std::vector<String> Params;
1560            return ExecSqlIntList(Sql, Params);
1561        }
1562    
1563        IntListPtr InstrumentsDb::ExecSqlIntList(String Sql, String Param) {
1564            dmsg(2,("InstrumentsDb: ExecSqlIntList(Sql=%s,Param=%s)\n", Sql.c_str(), Param.c_str()));
1565            std::vector<String> Params;
1566            Params.push_back(Param);
1567            return ExecSqlIntList(Sql, Params);
1568        }
1569    
1570        IntListPtr InstrumentsDb::ExecSqlIntList(String Sql, std::vector<String>& Params) {
1571            dmsg(2,("InstrumentsDb: ExecSqlIntList(Sql=%s)\n", Sql.c_str()));
1572          IntListPtr intList(new std::vector<int>);          IntListPtr intList(new std::vector<int>);
1573                    
1574          sqlite3_stmt *pStmt = NULL;          sqlite3_stmt *pStmt = NULL;
# Line 1512  namespace LinuxSampler { Line 1578  namespace LinuxSampler {
1578              throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));              throw Exception("DB error: " + ToString(sqlite3_errmsg(db)));
1579          }          }
1580                    
1581            for(int i = 0; i < Params.size(); i++) {
1582                BindTextParam(pStmt, i + 1, Params[i]);
1583            }
1584            
1585          res = sqlite3_step(pStmt);          res = sqlite3_step(pStmt);
1586          while(res == SQLITE_ROW) {          while(res == SQLITE_ROW) {
1587              intList->push_back(sqlite3_column_int(pStmt, 0));              intList->push_back(sqlite3_column_int(pStmt, 0));
# Line 1529  namespace LinuxSampler { Line 1599  namespace LinuxSampler {
1599      }      }
1600            
1601      StringListPtr InstrumentsDb::ExecSqlStringList(String Sql) {      StringListPtr InstrumentsDb::ExecSqlStringList(String Sql) {
1602            dmsg(2,("InstrumentsDb: ExecSqlStringList(Sql=%s)\n", Sql.c_str()));
1603          StringListPtr stringList(new std::vector<String>);          StringListPtr stringList(new std::vector<String>);
1604                    
1605          sqlite3_stmt *pStmt = NULL;          sqlite3_stmt *pStmt = NULL;
# Line 1656  namespace LinuxSampler { Line 1727  namespace LinuxSampler {
1727          if (File.empty()) throw Exception("Invalid file name: " + File);          if (File.empty()) throw Exception("Invalid file name: " + File);
1728      }      }
1729    
1730      String InstrumentsDb::GetUniqueInstrumentName(int DirId, String Name) {      String InstrumentsDb::GetUniqueName(int DirId, String Name) {
1731          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()));
1732    
1733          if (GetInstrumentId(DirId, Name) == -1 && GetDirectoryId(DirId, Name) == -1) return Name;          if (GetInstrumentId(DirId, Name) == -1 && GetDirectoryId(DirId, Name) == -1) return Name;
# Line 1671  namespace LinuxSampler { Line 1742  namespace LinuxSampler {
1742    
1743          throw Exception("Unable to find an unique name: " + Name);          throw Exception("Unable to find an unique name: " + Name);
1744      }      }
1745        
1746        String InstrumentsDb::PrepareSubdirectory(String DbDir, String FsPath) {
1747            std::string dir = Path::getBaseName(FsPath);
1748            dir = toAbstractName(dir);
1749            if(dir.empty()) dir = "New Directory";
1750            dir = GetUniqueName(GetDirectoryId(DbDir), dir);
1751            dir = AppendNode(DbDir, dir);
1752            AddDirectory(dir);
1753            return dir;
1754        }
1755    
1756        String InstrumentsDb::AppendNode(String DbDir, String Node) {
1757            if(DbDir.length() == 1 && DbDir.at(0) == '/') return DbDir + Node;
1758            if(DbDir.at(DbDir.length() - 1) == '/') return DbDir + Node;
1759            return DbDir + "/" + Node;
1760        }
1761    
1762      String InstrumentsDb::toDbName(String AbstractName) {      String InstrumentsDb::toDbName(String AbstractName) {
1763          for (int i = 0; i < AbstractName.length(); i++) {          for (int i = 0; i < AbstractName.length(); i++) {
# Line 1702  namespace LinuxSampler { Line 1789  namespace LinuxSampler {
1789          return text;          return text;
1790      }      }
1791            
1792        String InstrumentsDb::toNonEscapedText(String text) {
1793            String sb;
1794            for (int i = 0; i < text.length(); i++) {
1795                char c = text.at(i);
1796                            if(c == '\\') {
1797                                    if(i >= text.length()) {
1798                                            std::cerr << "Broken escape sequence!" << std::endl;
1799                                            break;
1800                                    }
1801                                    char c2 = text.at(++i);
1802                                    if(c2 == '\'')      sb.push_back('\'');
1803                                    else if(c2 == '"')  sb.push_back('"');
1804                                    else if(c2 == '\\') sb.push_back('\\');
1805                                    else if(c2 == 'r')  sb.push_back('\r');
1806                                    else if(c2 == 'n')  sb.push_back('\n');
1807                                    else std::cerr << "Unknown escape sequence \\" << c2 << std::endl;
1808                            } else {
1809                                    sb.push_back(c);
1810                            }
1811            }
1812            return sb;
1813        }
1814        
1815      String InstrumentsDb::toEscapedFsPath(String FsPath) {      String InstrumentsDb::toEscapedFsPath(String FsPath) {
1816          return toEscapedText(FsPath);          return toEscapedText(FsPath);
1817      }      }
1818            
1819        String InstrumentsDb::toNonEscapedFsPath(String FsPath) {
1820            return toNonEscapedText(FsPath);
1821        }
1822        
1823      String InstrumentsDb::toAbstractName(String DbName) {      String InstrumentsDb::toAbstractName(String DbName) {
1824          for (int i = 0; i < DbName.length(); i++) {          for (int i = 0; i < DbName.length(); i++) {
1825              if (DbName.at(i) == '/') DbName.at(i) = '\0';              if (DbName.at(i) == '/') DbName.at(i) = '\0';

Legend:
Removed from v.1603  
changed lines
  Added in v.1810

  ViewVC Help
Powered by ViewVC